Pure OCaml Yaml 1.2 reader and writer using Bytesrw
1(*--------------------------------------------------------------------------- 2 Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org>. All rights reserved. 3 SPDX-License-Identifier: ISC 4 ---------------------------------------------------------------------------*) 5 6(** YAML mapping (object) values with metadata *) 7 8type ('k, 'v) t = { 9 anchor : string option; 10 tag : string option; 11 implicit : bool; 12 style : Layout_style.t; 13 members : ('k * 'v) list; 14} 15 16let make 17 ?(anchor : string option) 18 ?(tag : string option) 19 ?(implicit = true) 20 ?(style = `Any) 21 members = 22 { anchor; tag; implicit; style; members } 23 24let members t = t.members 25let anchor t = t.anchor 26let tag t = t.tag 27let implicit t = t.implicit 28let style t = t.style 29 30let with_anchor anchor t = { t with anchor = Some anchor } 31let with_tag tag t = { t with tag = Some tag } 32let with_style style t = { t with style } 33 34let map_keys f t = { t with members = List.map (fun (k, v) -> (f k, v)) t.members } 35let map_values f t = { t with members = List.map (fun (k, v) -> (k, f v)) t.members } 36let map f t = { t with members = List.map (fun (k, v) -> f k v) t.members } 37 38let length t = List.length t.members 39 40let is_empty t = t.members = [] 41 42let find pred t = 43 List.find_opt (fun (k, _) -> pred k) t.members |> Option.map snd 44 45let find_key pred t = 46 List.find_opt (fun (k, _) -> pred k) t.members 47 48let mem pred t = 49 List.exists (fun (k, _) -> pred k) t.members 50 51let keys t = List.map fst t.members 52 53let values t = List.map snd t.members 54 55let iter f t = List.iter (fun (k, v) -> f k v) t.members 56 57let fold f init t = List.fold_left (fun acc (k, v) -> f acc k v) init t.members 58 59let pp pp_key pp_val fmt t = 60 Format.fprintf fmt "@[<hv 2>mapping(@,"; 61 (match t.anchor with 62 | Some a -> Format.fprintf fmt "anchor=%s,@ " a 63 | None -> ()); 64 (match t.tag with 65 | Some tag -> Format.fprintf fmt "tag=%s,@ " tag 66 | None -> ()); 67 Format.fprintf fmt "style=%a,@ " Layout_style.pp t.style; 68 Format.fprintf fmt "members={@,"; 69 List.iteri (fun i (k, v) -> 70 if i > 0 then Format.fprintf fmt ",@ "; 71 Format.fprintf fmt "@[<hv 2>%a:@ %a@]" pp_key k pp_val v 72 ) t.members; 73 Format.fprintf fmt "@]@,})" 74 75let equal eq_k eq_v a b = 76 Option.equal String.equal a.anchor b.anchor && 77 Option.equal String.equal a.tag b.tag && 78 a.implicit = b.implicit && 79 Layout_style.equal a.style b.style && 80 List.equal (fun (k1, v1) (k2, v2) -> eq_k k1 k2 && eq_v v1 v2) a.members b.members 81 82let compare cmp_k cmp_v a b = 83 let c = Option.compare String.compare a.anchor b.anchor in 84 if c <> 0 then c else 85 let c = Option.compare String.compare a.tag b.tag in 86 if c <> 0 then c else 87 let c = Bool.compare a.implicit b.implicit in 88 if c <> 0 then c else 89 let c = Layout_style.compare a.style b.style in 90 if c <> 0 then c else 91 let cmp_pair (k1, v1) (k2, v2) = 92 let c = cmp_k k1 k2 in 93 if c <> 0 then c else cmp_v v1 v2 94 in 95 List.compare cmp_pair a.members b.members