Pure OCaml Yaml 1.2 reader and writer using Bytesrw
at main 2.3 kB view raw
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 | '!' -> 24 (* !! handle *) 25 Some { handle = "!!"; suffix = String.sub s 2 (len - 2) } 26 | '<' -> 27 (* Verbatim tag !<...> *) 28 if len > 2 && s.[len - 1] = '>' then 29 Some { handle = "!"; suffix = String.sub s 2 (len - 3) } 30 else None 31 | _ -> 32 (* Primary handle or local tag *) 33 Some { handle = "!"; suffix = String.sub s 1 (len - 1) }) 34 35let to_string t = 36 if t.handle = "!" && t.suffix = "" then "!" else t.handle ^ t.suffix 37 38let to_uri t = 39 match t.handle with 40 | "!!" -> "tag:yaml.org,2002:" ^ t.suffix 41 | "!" -> "!" ^ t.suffix 42 | h -> h ^ t.suffix 43 44let pp fmt t = Format.pp_print_string fmt (to_string t) 45let equal a b = String.equal a.handle b.handle && String.equal a.suffix b.suffix 46 47let compare a b = 48 let c = String.compare a.handle b.handle in 49 if c <> 0 then c else String.compare a.suffix b.suffix 50 51(** Standard tags *) 52 53let null = { handle = "!!"; suffix = "null" } 54let bool = { handle = "!!"; suffix = "bool" } 55let int = { handle = "!!"; suffix = "int" } 56let float = { handle = "!!"; suffix = "float" } 57let str = { handle = "!!"; suffix = "str" } 58let seq = { handle = "!!"; suffix = "seq" } 59let map = { handle = "!!"; suffix = "map" } 60let binary = { handle = "!!"; suffix = "binary" } 61let timestamp = { handle = "!!"; suffix = "timestamp" } 62 63(** Check if tag matches a standard type *) 64 65let is_null t = equal t null || (t.handle = "!" && t.suffix = "") 66let is_bool t = equal t bool 67let is_int t = equal t int 68let is_float t = equal t float 69let is_str t = equal t str 70let is_seq t = equal t seq 71let is_map t = equal t map