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 tags for type information *) 7 8type t = { 9 handle : string; (** e.g., "!" or "!!" or "!foo!" *) 10 suffix : string; (** e.g., "str", "int", "custom/type" *) 11} 12 13let make ~handle ~suffix = { handle; suffix } 14 15let of_string s = 16 let len = String.length s in 17 match len with 18 | 0 -> None 19 | _ when s.[0] <> '!' -> None 20 | 1 -> Some { handle = "!"; suffix = "" } 21 | _ -> 22 match s.[1] with 23 | '!' -> (* !! handle *) 24 Some { handle = "!!"; suffix = String.sub s 2 (len - 2) } 25 | '<' -> (* Verbatim tag !<...> *) 26 if len > 2 && s.[len - 1] = '>' then 27 Some { handle = "!"; suffix = String.sub s 2 (len - 3) } 28 else 29 None 30 | _ -> (* Primary handle or local tag *) 31 Some { handle = "!"; suffix = String.sub s 1 (len - 1) } 32 33let to_string t = 34 if t.handle = "!" && t.suffix = "" then "!" 35 else t.handle ^ t.suffix 36 37let to_uri t = 38 match t.handle with 39 | "!!" -> "tag:yaml.org,2002:" ^ t.suffix 40 | "!" -> "!" ^ t.suffix 41 | h -> h ^ t.suffix 42 43let pp fmt t = 44 Format.pp_print_string fmt (to_string t) 45 46let equal a b = 47 String.equal a.handle b.handle && String.equal a.suffix b.suffix 48 49let compare a b = 50 let c = String.compare a.handle b.handle in 51 if c <> 0 then c else String.compare a.suffix b.suffix 52 53(** Standard tags *) 54 55let null = { handle = "!!"; suffix = "null" } 56let bool = { handle = "!!"; suffix = "bool" } 57let int = { handle = "!!"; suffix = "int" } 58let float = { handle = "!!"; suffix = "float" } 59let str = { handle = "!!"; suffix = "str" } 60let seq = { handle = "!!"; suffix = "seq" } 61let map = { handle = "!!"; suffix = "map" } 62let binary = { handle = "!!"; suffix = "binary" } 63let timestamp = { handle = "!!"; suffix = "timestamp" } 64 65(** Check if tag matches a standard type *) 66 67let is_null t = equal t null || (t.handle = "!" && t.suffix = "") 68let is_bool t = equal t bool 69let is_int t = equal t int 70let is_float t = equal t float 71let is_str t = equal t str 72let is_seq t = equal t seq 73let is_map t = equal t map