My working unpac space for OCaml projects in development
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge opam/patches/yamlt

+6008
+20
vendor/opam/yamlt/.gitignore
··· 1 + # OCaml build artifacts 2 + _build/ 3 + *.install 4 + *.merlin 5 + 6 + # Third-party sources (fetch locally with opam source) 7 + third_party/ 8 + 9 + # Symlinked dependencies 10 + ocaml-yamlrw 11 + 12 + # Editor and OS files 13 + .DS_Store 14 + *.swp 15 + *~ 16 + .vscode/ 17 + .idea/ 18 + 19 + # Opam local switch 20 + _opam/
+1
vendor/opam/yamlt/.ocamlformat
··· 1 + version=0.28.1
+53
vendor/opam/yamlt/.tangled/workflows/build.yml
··· 1 + when: 2 + - event: ["push", "pull_request"] 3 + branch: ["main"] 4 + 5 + engine: nixery 6 + 7 + dependencies: 8 + nixpkgs: 9 + - shell 10 + - stdenv 11 + - findutils 12 + - binutils 13 + - libunwind 14 + - ncurses 15 + - opam 16 + - git 17 + - gawk 18 + - gnupatch 19 + - gnum4 20 + - gnumake 21 + - gnutar 22 + - gnused 23 + - gnugrep 24 + - diffutils 25 + - gzip 26 + - bzip2 27 + - gcc 28 + - ocaml 29 + - pkg-config 30 + 31 + steps: 32 + - name: opam 33 + command: | 34 + opam init --disable-sandboxing -a -y 35 + - name: repo 36 + command: | 37 + opam repo add aoah https://tangled.org/anil.recoil.org/aoah-opam-repo.git 38 + - name: switch 39 + command: | 40 + opam install . --confirm-level=unsafe-yes --deps-only 41 + - name: build 42 + command: | 43 + opam exec -- dune build 44 + - name: switch-test 45 + command: | 46 + opam install . --confirm-level=unsafe-yes --deps-only --with-test 47 + - name: test 48 + command: | 49 + opam exec -- dune runtest --verbose 50 + - name: doc 51 + command: | 52 + opam install -y odoc 53 + opam exec -- dune build @doc
+15
vendor/opam/yamlt/LICENSE.md
··· 1 + ISC License 2 + 3 + Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org> 4 + 5 + Permission to use, copy, modify, and distribute this software for any 6 + purpose with or without fee is hereby granted, provided that the above 7 + copyright notice and this permission notice appear in all copies. 8 + 9 + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+62
vendor/opam/yamlt/README.md
··· 1 + # yamlt - YAML codec using Jsont type descriptions 2 + 3 + Yamlt provides YAML streaming encode/decode that interprets Jsont.t type descriptions, allowing the same codec definitions to work for both JSON and YAML. 4 + 5 + ## Key Features 6 + 7 + - Use the same Jsont.t codec for both JSON and YAML formats 8 + - Streaming encode/decode with configurable depth and node limits 9 + - Support for YAML-specific features (scalars, sequences, mappings) 10 + - Billion laughs protection with configurable limits 11 + - Multiple output formats (block, flow, layout preservation) 12 + 13 + ## Usage 14 + 15 + ```ocaml 16 + (* Define a codec once using Jsont *) 17 + module Config = struct 18 + type t = { name: string; port: int } 19 + let make name port = { name; port } 20 + let jsont = 21 + Jsont.Object.map ~kind:"Config" make 22 + |> Jsont.Object.mem "name" Jsont.string ~enc:(fun c -> c.name) 23 + |> Jsont.Object.mem "port" Jsont.int ~enc:(fun c -> c.port) 24 + |> Jsont.Object.finish 25 + end 26 + 27 + (* Use the same codec for both JSON and YAML *) 28 + let from_json = Jsont_bytesrw.decode_string Config.jsont json_str 29 + let from_yaml = Yamlt.decode_string Config.jsont yaml_str 30 + ``` 31 + 32 + For encoding: 33 + 34 + ```ocaml 35 + (* Encode to YAML with different formats *) 36 + let config = Config.make "server" 8080 37 + 38 + (* Block style (default) *) 39 + let yaml_block = Yamlt.encode_string Config.jsont config 40 + 41 + (* Flow style (JSON-like) *) 42 + let yaml_flow = Yamlt.encode_string ~format:Flow Config.jsont config 43 + ``` 44 + 45 + ## Installation 46 + 47 + ``` 48 + opam install yamlt 49 + ``` 50 + 51 + ## Documentation 52 + 53 + API documentation is available at https://tangled.org/@anil.recoil.org/ocaml-yamlt or via: 54 + 55 + ``` 56 + opam install yamlt 57 + odig doc yamlt 58 + ``` 59 + 60 + ## License 61 + 62 + ISC
+5
vendor/opam/yamlt/dune
··· 1 + ; Root dune file 2 + 3 + ; Ignore third_party directory (for fetched dependency sources) 4 + 5 + (data_only_dirs third_party)
+23
vendor/opam/yamlt/dune-project
··· 1 + (lang dune 3.18) 2 + 3 + (name yamlt) 4 + 5 + (generate_opam_files true) 6 + 7 + (license ISC) 8 + (authors "Anil Madhavapeddy") 9 + (homepage "https://tangled.org/@anil.recoil.org/ocaml-yamlt") 10 + (maintainers "Anil Madhavapeddy <anil@recoil.org>") 11 + (bug_reports "https://tangled.org/@anil.recoil.org/ocaml-yamlt/issues") 12 + (maintenance_intent "(latest)") 13 + 14 + (package 15 + (name yamlt) 16 + (synopsis "YAML codec using Jsont type descriptions") 17 + (description "Allows the same Jsont.t codec definitions to work for both JSON and YAML") 18 + (depends 19 + (ocaml (>= 4.14.0)) 20 + yamlrw 21 + jsont 22 + bytesrw 23 + (odoc :with-doc)))
+4
vendor/opam/yamlt/lib/dune
··· 1 + (library 2 + (name yamlt) 3 + (public_name yamlt) 4 + (libraries yamlrw jsont bytesrw))
+968
vendor/opam/yamlt/lib/yamlt.ml
··· 1 + (*--------------------------------------------------------------------------- 2 + Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org>. All rights reserved. 3 + SPDX-License-Identifier: ISC 4 + ---------------------------------------------------------------------------*) 5 + 6 + open Jsont.Repr 7 + open Yamlrw 8 + 9 + (* YAML format *) 10 + 11 + type yaml_format = Block | Flow | Layout 12 + 13 + (* Decoder *) 14 + 15 + type decoder = { 16 + parser : Parser.t; 17 + file : string; 18 + locs : bool; 19 + _layout : bool; (* For future layout preservation *) 20 + max_depth : int; 21 + max_nodes : int; 22 + mutable node_count : int; 23 + mutable current : Event.spanned option; 24 + _anchors : (string, Jsont.json) Hashtbl.t; (* For future anchor resolution *) 25 + meta_none : Jsont.Meta.t; 26 + } 27 + 28 + let make_decoder ?(locs = false) ?(layout = false) ?(file = "-") 29 + ?(max_depth = 100) ?(max_nodes = 10_000_000) parser = 30 + let meta_none = Jsont.Meta.make (Jsont.Textloc.(set_file none) file) in 31 + { 32 + parser; 33 + file; 34 + locs; 35 + _layout = layout; 36 + max_depth; 37 + max_nodes; 38 + node_count = 0; 39 + current = None; 40 + _anchors = Hashtbl.create 16; 41 + meta_none; 42 + } 43 + 44 + (* Decoder helpers *) 45 + 46 + (* Local helper to reduce Jsont.Error.msgf boilerplate *) 47 + let err_msg meta fmt = Jsont.Error.msgf meta fmt 48 + let err_msg_none fmt = Jsont.Error.msgf Jsont.Meta.none fmt 49 + 50 + let check_depth d ~nest = 51 + if nest > d.max_depth then 52 + err_msg_none "Maximum nesting depth %d exceeded" d.max_depth 53 + 54 + let check_nodes d = 55 + d.node_count <- d.node_count + 1; 56 + if d.node_count > d.max_nodes then 57 + err_msg_none "Maximum node count %d exceeded" d.max_nodes 58 + 59 + let meta_of_span d span = 60 + if not d.locs then d.meta_none 61 + else 62 + let start = span.Span.start and stop = span.Span.stop in 63 + let first_byte = start.Position.index in 64 + let last_byte = max first_byte (stop.Position.index - 1) in 65 + (* line_pos is (line_number, byte_position_of_line_start) *) 66 + let first_line = 67 + (start.Position.line, start.Position.index - start.Position.column + 1) 68 + in 69 + (* Handle case where stop is at the start of a new line (column 1) 70 + This happens when the span includes a trailing newline. 71 + The last_byte is on the previous line, so we need to calculate 72 + the line start position based on last_byte, not stop. *) 73 + let last_line = 74 + if stop.Position.column = 1 && stop.Position.line > start.Position.line then 75 + (* last_byte is on the previous line (stop.line - 1) 76 + We need to estimate where that line starts. Since we don't have 77 + the full text, we can't calculate it exactly, but we can use: 78 + last_byte - (estimated_column - 1) 79 + For now, we'll use the same line as start if they're close, 80 + or just report it as the previous line. *) 81 + let last_line_num = stop.Position.line - 1 in 82 + (* Estimate: assume last_byte is somewhere on the previous line. 83 + We'll use the byte position minus a reasonable offset. 84 + This is approximate but better than wrapping to the next line. *) 85 + if last_line_num = start.Position.line then 86 + (* Same line as start - use start's line position *) 87 + first_line 88 + else 89 + (* Different line - estimate line start as last_byte minus some offset 90 + Since we subtracted 1 from stop.index to get last_byte, and stop.column was 1, 91 + last_byte should be the newline character on the previous line. 92 + The line likely started much earlier, but we'll estimate conservatively. *) 93 + (last_line_num, last_byte) 94 + else 95 + (stop.Position.line, stop.Position.index - stop.Position.column + 1) 96 + in 97 + let textloc = 98 + Jsont.Textloc.make ~file:d.file ~first_byte ~last_byte ~first_line 99 + ~last_line 100 + in 101 + Jsont.Meta.make textloc 102 + 103 + let next_event d = 104 + d.current <- Parser.next d.parser; 105 + d.current 106 + 107 + let peek_event d = 108 + match d.current with Some _ -> d.current | None -> next_event d 109 + 110 + let skip_event d = d.current <- None 111 + 112 + let _expect_event d pred name = 113 + match peek_event d with 114 + | Some ev when pred ev.Event.event -> 115 + skip_event d; 116 + ev 117 + | Some ev -> 118 + let span = ev.Event.span in 119 + let meta = meta_of_span d span in 120 + err_msg meta "Expected %s but found %a" name Event.pp ev.Event.event 121 + | None -> err_msg_none "Expected %s but reached end of stream" name 122 + 123 + (* Error helpers *) 124 + 125 + let _err_expected_scalar d ev = 126 + let meta = meta_of_span d ev.Event.span in 127 + err_msg meta "Expected scalar but found %a" Event.pp ev.Event.event 128 + 129 + let err_type_mismatch d span t ~fnd = 130 + let open Jsont.Repr in 131 + let meta = meta_of_span d span in 132 + err_msg meta "Expected %s but found %s" (kinded_sort t) fnd 133 + 134 + (* YAML scalar resolution *) 135 + 136 + let is_null_scalar s = 137 + s = "" || s = "~" || s = "null" || s = "Null" || s = "NULL" 138 + 139 + let bool_of_scalar_opt s = 140 + match s with 141 + | "true" | "True" | "TRUE" | "yes" | "Yes" | "YES" | "on" | "On" | "ON" -> 142 + Some true 143 + | "false" | "False" | "FALSE" | "no" | "No" | "NO" | "off" | "Off" | "OFF" -> 144 + Some false 145 + | _ -> None 146 + 147 + let float_of_scalar_opt s = 148 + (* Handle YAML special floats *) 149 + match s with 150 + | ".inf" | ".Inf" | ".INF" -> Some Float.infinity 151 + | "+.inf" | "+.Inf" | "+.INF" -> Some Float.infinity 152 + | "-.inf" | "-.Inf" | "-.INF" -> Some Float.neg_infinity 153 + | ".nan" | ".NaN" | ".NAN" -> Some Float.nan 154 + | _ -> ( 155 + (* Try parsing as number, allowing underscores *) 156 + let s' = String.concat "" (String.split_on_char '_' s) in 157 + (* Try int first (supports 0o, 0x, 0b) then float *) 158 + match int_of_string_opt s' with 159 + | Some i -> Some (float_of_int i) 160 + | None -> float_of_string_opt s') 161 + 162 + let _int_of_scalar_opt s = 163 + (* Handle hex, octal, and regular integers with underscores *) 164 + let s' = String.concat "" (String.split_on_char '_' s) in 165 + int_of_string_opt s' 166 + 167 + (* Decode a scalar value according to expected type *) 168 + let rec decode_scalar_as : type a. 169 + decoder -> Event.spanned -> string -> Scalar_style.t -> a t -> a = 170 + fun d ev value style t -> 171 + check_nodes d; 172 + let meta = meta_of_span d ev.Event.span in 173 + match t with 174 + | Null map -> 175 + if is_null_scalar value then map.dec meta () 176 + else err_type_mismatch d ev.span t ~fnd:("scalar " ^ value) 177 + | Bool map -> ( 178 + match bool_of_scalar_opt value with 179 + | Some b -> map.dec meta b 180 + | None -> 181 + (* For explicitly quoted strings, fail *) 182 + if style <> `Plain then 183 + err_type_mismatch d ev.span t ~fnd:("string " ^ value) 184 + else err_type_mismatch d ev.span t ~fnd:("scalar " ^ value)) 185 + | Number map -> ( 186 + if 187 + (* Handle null -> nan mapping like jsont *) 188 + is_null_scalar value 189 + then map.dec meta Float.nan 190 + else 191 + match float_of_scalar_opt value with 192 + | Some f -> map.dec meta f 193 + | None -> err_type_mismatch d ev.span t ~fnd:("scalar " ^ value)) 194 + | String map -> 195 + (* Don't decode null values as strings - they should fail so outer combinators 196 + like 'option' or 'any' can handle them properly. 197 + BUT: quoted strings should always be treated as strings, even if they 198 + look like null (e.g., "" or "null") *) 199 + if style = `Plain && is_null_scalar value then 200 + err_type_mismatch d ev.span t ~fnd:"null" 201 + else 202 + (* Strings accept quoted scalars or non-null plain scalars *) 203 + map.dec meta value 204 + | Array map -> 205 + (* Treat null as an empty array for convenience *) 206 + if is_null_scalar value then 207 + let end_meta = meta_of_span d ev.Event.span in 208 + map.dec_finish end_meta 0 (map.dec_empty ()) 209 + else 210 + err_type_mismatch d ev.span t ~fnd:"scalar" 211 + | Object map -> 212 + (* Treat null as an empty object for convenience *) 213 + if is_null_scalar value then 214 + (* Build a dict with all default values from absent members *) 215 + let add_default _ (Mem_dec mem_map) dict = 216 + match mem_map.dec_absent with 217 + | Some v -> Dict.add mem_map.id v dict 218 + | None -> 219 + (* Required field without default - error *) 220 + let exp = String_map.singleton mem_map.name (Mem_dec mem_map) in 221 + missing_mems_error meta map ~exp ~fnd:[] 222 + in 223 + let dict = String_map.fold add_default map.mem_decs Dict.empty in 224 + let dict = Dict.add object_meta_arg meta dict in 225 + apply_dict map.dec dict 226 + else 227 + err_type_mismatch d ev.span t ~fnd:"scalar" 228 + | Map m -> 229 + (* Handle Map combinators (e.g., from Jsont.option) *) 230 + m.dec (decode_scalar_as d ev value style m.dom) 231 + | Rec lazy_t -> 232 + (* Handle recursive types *) 233 + decode_scalar_as d ev value style (Lazy.force lazy_t) 234 + | _ -> err_type_mismatch d ev.span t ~fnd:"scalar" 235 + 236 + (* Forward declaration for mutual recursion *) 237 + let rec decode : type a. decoder -> nest:int -> a t -> a = 238 + fun d ~nest t -> 239 + check_depth d ~nest; 240 + match peek_event d with 241 + | None -> err_msg_none "Unexpected end of YAML stream" 242 + | Some ev -> ( 243 + match (ev.Event.event, t) with 244 + (* Scalar events *) 245 + | Event.Scalar { value; style; anchor; _ }, _ -> 246 + skip_event d; 247 + let result = decode_scalar d ~nest ev value style t in 248 + (* Store anchor if present - TODO: implement anchor storage *) 249 + (match anchor with 250 + | Some _name -> 251 + (* We need generic JSON for anchors - decode as json and convert back *) 252 + () 253 + | None -> ()); 254 + result 255 + (* Alias *) 256 + | Event.Alias { anchor }, _ -> 257 + skip_event d; 258 + decode_alias d ev anchor t 259 + (* Map combinator - must come before specific event matches *) 260 + | _, Map m -> m.dec (decode d ~nest m.dom) 261 + (* Recursive types - must come before specific event matches *) 262 + | _, Rec lazy_t -> decode d ~nest (Lazy.force lazy_t) 263 + (* Sequence -> Array *) 264 + | Event.Sequence_start _, Array map -> decode_array d ~nest ev map 265 + | Event.Sequence_start _, Any map -> decode_any_sequence d ~nest ev t map 266 + | Event.Sequence_start _, _ -> 267 + err_type_mismatch d ev.span t ~fnd:"sequence" 268 + (* Mapping -> Object *) 269 + | Event.Mapping_start _, Object map -> decode_object d ~nest ev map 270 + | Event.Mapping_start _, Any map -> decode_any_mapping d ~nest ev t map 271 + | Event.Mapping_start _, _ -> err_type_mismatch d ev.span t ~fnd:"mapping" 272 + (* Unexpected events *) 273 + | Event.Sequence_end, _ -> 274 + err_msg (meta_of_span d ev.span) "Unexpected sequence end" 275 + | Event.Mapping_end, _ -> 276 + err_msg (meta_of_span d ev.span) "Unexpected mapping end" 277 + | Event.Document_start _, _ -> 278 + err_msg (meta_of_span d ev.span) "Unexpected document start" 279 + | Event.Document_end _, _ -> 280 + err_msg (meta_of_span d ev.span) "Unexpected document end" 281 + | Event.Stream_start _, _ -> 282 + err_msg (meta_of_span d ev.span) "Unexpected stream start" 283 + | Event.Stream_end, _ -> 284 + err_msg (meta_of_span d ev.span) "Unexpected stream end") 285 + 286 + and decode_scalar : type a. 287 + decoder -> nest:int -> Event.spanned -> string -> Scalar_style.t -> a t -> a 288 + = 289 + fun d ~nest ev value style t -> 290 + match t with 291 + | Any map -> decode_any_scalar d ev value style t map 292 + | Map m -> m.dec (decode_scalar d ~nest ev value style m.dom) 293 + | Rec lazy_t -> decode_scalar d ~nest ev value style (Lazy.force lazy_t) 294 + | _ -> decode_scalar_as d ev value style t 295 + 296 + and decode_any_scalar : type a. 297 + decoder -> 298 + Event.spanned -> 299 + string -> 300 + Scalar_style.t -> 301 + a t -> 302 + a any_map -> 303 + a = 304 + fun d ev value style t map -> 305 + check_nodes d; 306 + let meta = meta_of_span d ev.span in 307 + let type_err fnd = Jsont.Repr.type_error meta t ~fnd in 308 + (* Determine which decoder to use based on scalar content *) 309 + if is_null_scalar value then 310 + match map.dec_null with 311 + | Some t' -> decode_scalar_as d ev value style t' 312 + | None -> type_err Jsont.Sort.Null 313 + else if style = `Plain then 314 + (* Try bool, then number, then string *) 315 + match bool_of_scalar_opt value with 316 + | Some _ -> ( 317 + match map.dec_bool with 318 + | Some t' -> decode_scalar_as d ev value style t' 319 + | None -> ( 320 + match map.dec_string with 321 + | Some t' -> decode_scalar_as d ev value style t' 322 + | None -> type_err Jsont.Sort.Bool)) 323 + | None -> ( 324 + match float_of_scalar_opt value with 325 + | Some _ -> ( 326 + match map.dec_number with 327 + | Some t' -> decode_scalar_as d ev value style t' 328 + | None -> ( 329 + match map.dec_string with 330 + | Some t' -> decode_scalar_as d ev value style t' 331 + | None -> type_err Jsont.Sort.Number)) 332 + | None -> ( 333 + (* Plain scalar that's not bool/number -> string *) 334 + match map.dec_string with 335 + | Some t' -> decode_scalar_as d ev value style t' 336 + | None -> type_err Jsont.Sort.String)) 337 + else 338 + (* Quoted scalars are strings *) 339 + match map.dec_string with 340 + | Some t' -> decode_scalar_as d ev value style t' 341 + | None -> type_err Jsont.Sort.String 342 + 343 + and decode_alias : type a. decoder -> Event.spanned -> string -> a t -> a = 344 + fun d ev anchor t -> 345 + check_nodes d; 346 + match Hashtbl.find_opt d._anchors anchor with 347 + | None -> 348 + let meta = meta_of_span d ev.span in 349 + err_msg meta "Unknown anchor: %s" anchor 350 + | Some json_value -> 351 + (* Decode the stored JSON value through the type *) 352 + let t' = Jsont.Repr.unsafe_to_t t in 353 + match Jsont.Json.decode' t' json_value with 354 + | Ok v -> v 355 + | Error e -> raise (Jsont.Error e) 356 + 357 + and decode_array : type a elt b. 358 + decoder -> nest:int -> Event.spanned -> (a, elt, b) array_map -> a = 359 + fun d ~nest start_ev array_map -> 360 + skip_event d; 361 + (* consume Sequence_start *) 362 + check_nodes d; 363 + let meta = meta_of_span d start_ev.span in 364 + let builder = ref (array_map.dec_empty ()) in 365 + let idx = ref 0 in 366 + let rec loop () = 367 + match peek_event d with 368 + | Some { Event.event = Event.Sequence_end; span } -> 369 + skip_event d; 370 + let end_meta = meta_of_span d span in 371 + array_map.dec_finish end_meta !idx !builder 372 + | Some _ -> 373 + let i = !idx in 374 + (try 375 + if array_map.dec_skip i !builder then begin 376 + (* Skip this element by decoding as ignore *) 377 + let _ : unit = 378 + decode d ~nest:(nest + 1) (Jsont.Repr.of_t Jsont.ignore) 379 + in 380 + () 381 + end 382 + else begin 383 + let elt = decode d ~nest:(nest + 1) array_map.elt in 384 + builder := array_map.dec_add i elt !builder 385 + end 386 + with Jsont.Error e -> 387 + Jsont.Repr.error_push_array meta array_map (i, Jsont.Meta.none) e); 388 + incr idx; 389 + loop () 390 + | None -> err_msg meta "Unclosed sequence" 391 + in 392 + loop () 393 + 394 + and decode_any_sequence : type a. 395 + decoder -> nest:int -> Event.spanned -> a t -> a any_map -> a = 396 + fun d ~nest ev t map -> 397 + match map.dec_array with 398 + | Some t' -> ( 399 + (* The t' decoder might be wrapped (e.g., Map for option types) 400 + Directly decode the array and let the wrapper handle it *) 401 + match t' with 402 + | Array array_map -> decode_array d ~nest ev array_map 403 + | _ -> 404 + (* For wrapped types like Map (Array ...), use full decode *) 405 + decode d ~nest t') 406 + | None -> 407 + Jsont.Repr.type_error (meta_of_span d ev.span) t ~fnd:Jsont.Sort.Array 408 + 409 + and decode_object : type o. 410 + decoder -> nest:int -> Event.spanned -> (o, o) object_map -> o = 411 + fun d ~nest start_ev map -> 412 + skip_event d; 413 + (* consume Mapping_start *) 414 + check_nodes d; 415 + let meta = meta_of_span d start_ev.span in 416 + let dict = 417 + decode_object_members d ~nest meta map String_map.empty Dict.empty 418 + in 419 + let dict = Dict.add object_meta_arg meta dict in 420 + apply_dict map.dec dict 421 + 422 + and decode_object_members : type o. 423 + decoder -> 424 + nest:int -> 425 + Jsont.Meta.t -> 426 + (o, o) object_map -> 427 + mem_dec String_map.t -> 428 + Dict.t -> 429 + Dict.t = 430 + fun d ~nest obj_meta map mem_miss dict -> 431 + (* Merge expected member decoders *) 432 + let u _ _ _ = assert false in 433 + let mem_miss = String_map.union u mem_miss map.mem_decs in 434 + match map.shape with 435 + | Object_basic umems -> 436 + decode_object_basic d ~nest obj_meta map umems mem_miss dict 437 + | Object_cases (umems_opt, cases) -> 438 + (* Wrap umems_opt to hide existential types *) 439 + let umems = Unknown_mems umems_opt in 440 + decode_object_cases d ~nest obj_meta map umems cases mem_miss [] dict 441 + 442 + and decode_object_basic : type o mems builder. 443 + decoder -> 444 + nest:int -> 445 + Jsont.Meta.t -> 446 + (o, o) object_map -> 447 + (o, mems, builder) unknown_mems -> 448 + mem_dec String_map.t -> 449 + Dict.t -> 450 + Dict.t = 451 + fun d ~nest obj_meta object_map umems mem_miss dict -> 452 + let ubuilder = 453 + ref 454 + (match umems with 455 + | Unknown_skip | Unknown_error -> Obj.magic () 456 + | Unknown_keep (mmap, _) -> mmap.dec_empty ()) 457 + in 458 + let mem_miss = ref mem_miss in 459 + let dict = ref dict in 460 + let rec loop () = 461 + match peek_event d with 462 + | Some { Event.event = Event.Mapping_end; _ } -> 463 + skip_event d; 464 + (* Finalize *) 465 + finish_object obj_meta object_map umems !ubuilder !mem_miss !dict 466 + | Some ev -> 467 + (* Expect a scalar key *) 468 + let name, name_meta = decode_mapping_key d ev in 469 + (* Look up member decoder *) 470 + (match String_map.find_opt name object_map.mem_decs with 471 + | Some (Mem_dec mem) -> ( 472 + mem_miss := String_map.remove name !mem_miss; 473 + try 474 + let v = decode d ~nest:(nest + 1) mem.type' in 475 + dict := Dict.add mem.id v !dict 476 + with Jsont.Error e -> 477 + Jsont.Repr.error_push_object obj_meta object_map (name, name_meta) 478 + e) 479 + | None -> ( 480 + (* Unknown member *) 481 + match umems with 482 + | Unknown_skip -> 483 + let _ : unit = 484 + decode d ~nest:(nest + 1) (Jsont.Repr.of_t Jsont.ignore) 485 + in 486 + () 487 + | Unknown_error -> 488 + Jsont.Repr.unexpected_mems_error obj_meta object_map 489 + ~fnd:[ (name, name_meta) ] 490 + | Unknown_keep (mmap, _) -> ( 491 + try 492 + let v = decode d ~nest:(nest + 1) mmap.mems_type in 493 + ubuilder := mmap.dec_add name_meta name v !ubuilder 494 + with Jsont.Error e -> 495 + Jsont.Repr.error_push_object obj_meta object_map 496 + (name, name_meta) e))); 497 + loop () 498 + | None -> err_msg obj_meta "Unclosed mapping" 499 + in 500 + loop () 501 + 502 + and finish_object : type o mems builder. 503 + Jsont.Meta.t -> 504 + (o, o) object_map -> 505 + (o, mems, builder) unknown_mems -> 506 + builder -> 507 + mem_dec String_map.t -> 508 + Dict.t -> 509 + Dict.t = 510 + fun meta map umems ubuilder mem_miss dict -> 511 + let open Jsont.Repr in 512 + let dict = Dict.add object_meta_arg meta dict in 513 + let dict = 514 + match umems with 515 + | Unknown_skip | Unknown_error -> dict 516 + | Unknown_keep (mmap, _) -> 517 + Dict.add mmap.id (mmap.dec_finish meta ubuilder) dict 518 + in 519 + (* Check for missing required members *) 520 + let add_default _ (Mem_dec mem_map) dict = 521 + match mem_map.dec_absent with 522 + | Some v -> Dict.add mem_map.id v dict 523 + | None -> raise Exit 524 + in 525 + try String_map.fold add_default mem_miss dict 526 + with Exit -> 527 + let no_default _ (Mem_dec mm) = Option.is_none mm.dec_absent in 528 + let exp = String_map.filter no_default mem_miss in 529 + missing_mems_error meta map ~exp ~fnd:[] 530 + 531 + and decode_object_cases : type o cases tag. 532 + decoder -> 533 + nest:int -> 534 + Jsont.Meta.t -> 535 + (o, o) object_map -> 536 + unknown_mems_option -> 537 + (o, cases, tag) object_cases -> 538 + mem_dec String_map.t -> 539 + (Jsont.name * Jsont.json) list -> 540 + Dict.t -> 541 + Dict.t = 542 + fun d ~nest obj_meta object_map umems cases mem_miss delayed dict -> 543 + match peek_event d with 544 + | Some { Event.event = Event.Mapping_end; _ } -> ( 545 + skip_event d; 546 + (* No tag found - use dec_absent if available *) 547 + match cases.tag.dec_absent with 548 + | Some tag -> 549 + decode_with_case_tag d ~nest obj_meta object_map umems cases tag 550 + mem_miss delayed dict 551 + | None -> 552 + (* Missing required case tag *) 553 + let exp = String_map.singleton cases.tag.name (Mem_dec cases.tag) in 554 + let fnd = List.map (fun ((n, _), _) -> n) delayed in 555 + Jsont.Repr.missing_mems_error obj_meta object_map ~exp ~fnd) 556 + | Some ev -> 557 + let name, name_meta = decode_mapping_key d ev in 558 + if String.equal name cases.tag.name then begin 559 + (* Found the case tag *) 560 + let tag = decode d ~nest:(nest + 1) cases.tag.type' in 561 + decode_with_case_tag d ~nest obj_meta object_map umems cases tag 562 + mem_miss delayed dict 563 + end 564 + else begin 565 + (* Not the case tag - check if known member or delay *) 566 + match String_map.find_opt name object_map.mem_decs with 567 + | Some (Mem_dec mem) -> ( 568 + let mem_miss = String_map.remove name mem_miss in 569 + try 570 + let v = decode d ~nest:(nest + 1) mem.type' in 571 + let dict = Dict.add mem.id v dict in 572 + decode_object_cases d ~nest obj_meta object_map umems cases 573 + mem_miss delayed dict 574 + with Jsont.Error e -> 575 + Jsont.Repr.error_push_object obj_meta object_map (name, name_meta) 576 + e) 577 + | None -> 578 + (* Unknown member - decode as generic JSON and delay *) 579 + let v = 580 + decode d ~nest:(nest + 1) (Jsont.Repr.of_t Jsont.json) 581 + in 582 + let delayed = ((name, name_meta), v) :: delayed in 583 + decode_object_cases d ~nest obj_meta object_map umems cases 584 + mem_miss delayed dict 585 + end 586 + | None -> err_msg obj_meta "Unclosed mapping" 587 + 588 + and decode_with_case_tag : type o cases tag. 589 + decoder -> 590 + nest:int -> 591 + Jsont.Meta.t -> 592 + (o, o) object_map -> 593 + unknown_mems_option -> 594 + (o, cases, tag) object_cases -> 595 + tag -> 596 + mem_dec String_map.t -> 597 + (Jsont.name * Jsont.json) list -> 598 + Dict.t -> 599 + Dict.t = 600 + fun d ~nest obj_meta map umems cases tag mem_miss delayed dict -> 601 + let open Jsont.Repr in 602 + let eq_tag (Case c) = cases.tag_compare c.tag tag = 0 in 603 + match List.find_opt eq_tag cases.cases with 604 + | None -> unexpected_case_tag_error obj_meta map cases tag 605 + | Some (Case case) -> 606 + (* Continue decoding with the case's object map *) 607 + let case_dict = 608 + decode_case_remaining d ~nest obj_meta case.object_map umems mem_miss 609 + delayed dict 610 + in 611 + let case_value = apply_dict case.object_map.dec case_dict in 612 + Dict.add cases.id (case.dec case_value) dict 613 + 614 + and decode_case_remaining : type o. 615 + decoder -> 616 + nest:int -> 617 + Jsont.Meta.t -> 618 + (o, o) object_map -> 619 + unknown_mems_option -> 620 + mem_dec String_map.t -> 621 + (Jsont.name * Jsont.json) list -> 622 + Dict.t -> 623 + Dict.t = 624 + fun d ~nest obj_meta case_map _umems mem_miss delayed dict -> 625 + (* First, process delayed members against the case map *) 626 + let u _ _ _ = assert false in 627 + let mem_miss = String_map.union u mem_miss case_map.mem_decs in 628 + let dict, mem_miss = 629 + List.fold_left 630 + (fun (dict, mem_miss) ((name, meta), json_value) -> 631 + match String_map.find_opt name case_map.mem_decs with 632 + | Some (Mem_dec mem) -> ( 633 + let t' = Jsont.Repr.unsafe_to_t mem.type' in 634 + match Jsont.Json.decode' t' json_value with 635 + | Ok v -> 636 + let dict = Dict.add mem.id v dict in 637 + let mem_miss = String_map.remove name mem_miss in 638 + (dict, mem_miss) 639 + | Error e -> 640 + Jsont.Repr.error_push_object obj_meta case_map (name, meta) e) 641 + | None -> 642 + (* Unknown for case too - skip them *) 643 + (dict, mem_miss)) 644 + (dict, mem_miss) delayed 645 + in 646 + (* Then continue reading remaining members using case's own unknown handling *) 647 + match case_map.shape with 648 + | Object_basic case_umems -> 649 + decode_object_basic d ~nest obj_meta case_map case_umems mem_miss dict 650 + | Object_cases _ -> 651 + (* Nested cases shouldn't happen - use skip for safety *) 652 + decode_object_basic d ~nest obj_meta case_map Unknown_skip mem_miss dict 653 + 654 + and decode_any_mapping : type a. 655 + decoder -> nest:int -> Event.spanned -> a t -> a any_map -> a = 656 + fun d ~nest ev t map -> 657 + match map.dec_object with 658 + | Some t' -> decode d ~nest t' 659 + | None -> 660 + Jsont.Repr.type_error (meta_of_span d ev.span) t ~fnd:Jsont.Sort.Object 661 + 662 + and decode_mapping_key : decoder -> Event.spanned -> string * Jsont.Meta.t = 663 + fun d ev -> 664 + match ev.Event.event with 665 + | Event.Scalar { value; _ } -> 666 + skip_event d; 667 + let meta = meta_of_span d ev.span in 668 + (value, meta) 669 + | _ -> 670 + let meta = meta_of_span d ev.span in 671 + err_msg meta "Mapping keys must be scalars (strings), found %a" Event.pp 672 + ev.event 673 + 674 + (* Skip stream/document wrappers *) 675 + let skip_to_content d = 676 + let rec loop () = 677 + match peek_event d with 678 + | Some { Event.event = Event.Stream_start _; _ } -> 679 + skip_event d; 680 + loop () 681 + | Some { Event.event = Event.Document_start _; _ } -> 682 + skip_event d; 683 + loop () 684 + | _ -> () 685 + in 686 + loop () 687 + 688 + let skip_end_wrappers d = 689 + let rec loop () = 690 + match peek_event d with 691 + | Some { Event.event = Event.Document_end _; _ } -> 692 + skip_event d; 693 + loop () 694 + | Some { Event.event = Event.Stream_end; _ } -> 695 + skip_event d; 696 + loop () 697 + | None -> () 698 + | Some ev -> 699 + let meta = meta_of_span d ev.span in 700 + err_msg meta "Expected end of document but found %a" Event.pp ev.event 701 + in 702 + loop () 703 + 704 + (* Skip to the end of the current document after an error *) 705 + let skip_to_document_end d = 706 + let rec loop depth = 707 + match peek_event d with 708 + | None -> () 709 + | Some { Event.event = Event.Stream_end; _ } -> () 710 + | Some { Event.event = Event.Document_end _; _ } -> 711 + skip_event d; 712 + if depth = 0 then () else loop (depth - 1) 713 + | Some { Event.event = Event.Document_start _; _ } -> 714 + skip_event d; 715 + loop (depth + 1) 716 + | Some _ -> 717 + skip_event d; 718 + loop depth 719 + in 720 + loop 0 721 + 722 + (* Public decode API *) 723 + 724 + (* Decode all documents from a multi-document YAML stream *) 725 + let decode_all' ?(layout = false) ?(locs = false) ?(file = "-") 726 + ?(max_depth = 100) ?(max_nodes = 10_000_000) t reader = 727 + let parser = Parser.of_reader reader in 728 + let d = make_decoder ~layout ~locs ~file ~max_depth ~max_nodes parser in 729 + let t' = Jsont.Repr.of_t t in 730 + let rec next_doc () = 731 + match peek_event d with 732 + | None -> Seq.Nil 733 + | Some { Event.event = Event.Stream_end; _ } -> 734 + skip_event d; 735 + Seq.Nil 736 + | Some _ -> ( 737 + try 738 + skip_to_content d; 739 + (* Reset node count for each document *) 740 + d.node_count <- 0; 741 + let v = decode d ~nest:0 t' in 742 + (* Skip document end marker if present *) 743 + (match peek_event d with 744 + | Some { Event.event = Event.Document_end _; _ } -> skip_event d 745 + | _ -> ()); 746 + Seq.Cons (Ok v, next_doc) 747 + with 748 + | Jsont.Error e -> 749 + skip_to_document_end d; 750 + Seq.Cons (Error e, next_doc) 751 + | Error.Yamlrw_error err -> 752 + skip_to_document_end d; 753 + let msg = Error.to_string err in 754 + let e = Jsont.(Error.make_msg Error.Context.empty Meta.none msg) in 755 + Seq.Cons (Error e, next_doc)) 756 + in 757 + next_doc 758 + 759 + let decode_all ?layout ?locs ?file ?max_depth ?max_nodes t reader = 760 + decode_all' ?layout ?locs ?file ?max_depth ?max_nodes t reader 761 + |> Seq.map (Result.map_error Jsont.Error.to_string) 762 + 763 + let decode' ?layout ?locs ?file ?max_depth ?max_nodes t reader = 764 + let parser = Parser.of_reader reader in 765 + let d = make_decoder ?layout ?locs ?file ?max_depth ?max_nodes parser in 766 + try 767 + skip_to_content d; 768 + let t' = Jsont.Repr.of_t t in 769 + let v = decode d ~nest:0 t' in 770 + skip_end_wrappers d; 771 + Ok v 772 + with 773 + | Jsont.Error e -> Error e 774 + | Error.Yamlrw_error err -> 775 + let msg = Error.to_string err in 776 + Error Jsont.(Error.make_msg Error.Context.empty Meta.none msg) 777 + 778 + let decode ?layout ?locs ?file ?max_depth ?max_nodes t reader = 779 + Result.map_error Jsont.Error.to_string 780 + (decode' ?layout ?locs ?file ?max_depth ?max_nodes t reader) 781 + 782 + (* Encoder *) 783 + 784 + type encoder = { 785 + emitter : Emitter.t; 786 + format : yaml_format; 787 + _indent : int; (* Stored for future use in custom formatting *) 788 + explicit_doc : bool; 789 + scalar_style : Scalar_style.t; 790 + } 791 + 792 + let make_encoder ?(format = Block) ?(indent = 2) ?(explicit_doc = false) 793 + ?(scalar_style = `Any) emitter = 794 + { emitter; format; _indent = indent; explicit_doc; scalar_style } 795 + 796 + let layout_style_of_format = function 797 + | Block -> `Block 798 + | Flow -> `Flow 799 + | Layout -> `Any 800 + 801 + (* Choose appropriate scalar style for a string *) 802 + let choose_scalar_style ~preferred s = 803 + if preferred <> `Any then preferred 804 + else if String.contains s '\n' then `Literal 805 + else if String.length s > 80 then `Folded 806 + else `Plain 807 + 808 + (* Helper to create scalar events with common defaults *) 809 + let scalar_event ?(anchor = None) ?(tag = None) ~value ~style () = 810 + Event.Scalar 811 + { 812 + anchor; 813 + tag; 814 + value; 815 + plain_implicit = true; 816 + quoted_implicit = true; 817 + style; 818 + } 819 + 820 + (* Helper to emit events *) 821 + let emit e = Emitter.emit e.emitter 822 + 823 + (* Encode null *) 824 + let encode_null e _meta = emit e (scalar_event ~value:"null" ~style:`Plain ()) 825 + 826 + (* Encode boolean *) 827 + let encode_bool e _meta b = 828 + emit e (scalar_event ~value:(if b then "true" else "false") ~style:`Plain ()) 829 + 830 + (* Encode number *) 831 + let encode_number e _meta f = 832 + let value = 833 + match Float.classify_float f with 834 + | FP_nan -> ".nan" 835 + | FP_infinite -> if f > 0.0 then ".inf" else "-.inf" 836 + | _ -> 837 + if Float.is_integer f && Float.abs f < 1e15 then Printf.sprintf "%.0f" f 838 + else Printf.sprintf "%g" f 839 + in 840 + emit e (scalar_event ~value ~style:`Plain ()) 841 + 842 + (* Encode string *) 843 + let encode_string e _meta s = 844 + let style = choose_scalar_style ~preferred:e.scalar_style s in 845 + emit e (scalar_event ~value:s ~style ()) 846 + 847 + let rec encode : type a. encoder -> a t -> a -> unit = 848 + fun e t v -> 849 + match t with 850 + | Null map -> 851 + let meta = map.enc_meta v in 852 + let () = map.enc v in 853 + encode_null e meta 854 + | Bool map -> 855 + let meta = map.enc_meta v in 856 + let b = map.enc v in 857 + encode_bool e meta b 858 + | Number map -> 859 + let meta = map.enc_meta v in 860 + let f = map.enc v in 861 + encode_number e meta f 862 + | String map -> 863 + let meta = map.enc_meta v in 864 + let s = map.enc v in 865 + encode_string e meta s 866 + | Array map -> encode_array e map v 867 + | Object map -> encode_object e map v 868 + | Any map -> 869 + let t' = map.enc v in 870 + encode e t' v 871 + | Map m -> encode e m.dom (m.enc v) 872 + | Rec lazy_t -> encode e (Lazy.force lazy_t) v 873 + 874 + and encode_array : type a elt b. encoder -> (a, elt, b) array_map -> a -> unit = 875 + fun e map v -> 876 + let style = layout_style_of_format e.format in 877 + emit e 878 + (Event.Sequence_start { anchor = None; tag = None; implicit = true; style }); 879 + let _ = 880 + map.enc 881 + (fun () _idx elt -> 882 + encode e map.elt elt; 883 + ()) 884 + () v 885 + in 886 + emit e Event.Sequence_end 887 + 888 + and encode_object : type o. encoder -> (o, o) object_map -> o -> unit = 889 + fun e map v -> 890 + let style = layout_style_of_format e.format in 891 + emit e (Event.Mapping_start { anchor = None; tag = None; implicit = true; style }); 892 + (* Encode each member *) 893 + List.iter 894 + (fun (Mem_enc mem) -> 895 + let mem_v = mem.enc v in 896 + if not (mem.enc_omit mem_v) then begin 897 + (* Emit key *) 898 + emit e (scalar_event ~value:mem.name ~style:`Plain ()); 899 + (* Emit value *) 900 + encode e mem.type' mem_v 901 + end) 902 + map.mem_encs; 903 + (* Handle case objects *) 904 + (match map.shape with 905 + | Object_basic _ -> () 906 + | Object_cases (_, cases) -> 907 + let (Case_value (case_map, case_v)) = cases.enc_case (cases.enc v) in 908 + (* Emit case tag *) 909 + if not (cases.tag.enc_omit case_map.tag) then begin 910 + emit e (scalar_event ~value:cases.tag.name ~style:`Plain ()); 911 + encode e cases.tag.type' case_map.tag 912 + end; 913 + (* Emit case members *) 914 + List.iter 915 + (fun (Mem_enc mem) -> 916 + let mem_v = mem.enc case_v in 917 + if not (mem.enc_omit mem_v) then begin 918 + emit e (scalar_event ~value:mem.name ~style:`Plain ()); 919 + encode e mem.type' mem_v 920 + end) 921 + case_map.object_map.mem_encs); 922 + emit e Event.Mapping_end 923 + 924 + (* Public encode API *) 925 + 926 + let encode' ?buf:_ ?format ?indent ?explicit_doc ?scalar_style t v ~eod writer = 927 + let config = 928 + { 929 + Emitter.default_config with 930 + indent = Option.value ~default:2 indent; 931 + layout_style = (match format with Some Flow -> `Flow | _ -> `Block); 932 + } 933 + in 934 + let emitter = Emitter.of_writer ~config writer in 935 + let e = make_encoder ?format ?indent ?explicit_doc ?scalar_style emitter in 936 + try 937 + emit e (Event.Stream_start { encoding = `Utf8 }); 938 + emit e (Event.Document_start { version = None; implicit = not e.explicit_doc }); 939 + let t' = Jsont.Repr.of_t t in 940 + encode e t' v; 941 + emit e (Event.Document_end { implicit = not e.explicit_doc }); 942 + emit e Event.Stream_end; 943 + if eod then Emitter.flush e.emitter; 944 + Ok () 945 + with 946 + | Jsont.Error err -> Error err 947 + | Error.Yamlrw_error err -> 948 + let msg = Error.to_string err in 949 + Error Jsont.(Error.make_msg Error.Context.empty Meta.none msg) 950 + 951 + let encode ?buf ?format ?indent ?explicit_doc ?scalar_style t v ~eod writer = 952 + Result.map_error Jsont.Error.to_string 953 + (encode' ?buf ?format ?indent ?explicit_doc ?scalar_style t v ~eod writer) 954 + 955 + (* Recode *) 956 + 957 + let recode ?layout ?locs ?file ?max_depth ?max_nodes ?buf ?format ?indent 958 + ?explicit_doc ?scalar_style t reader writer ~eod = 959 + let format = 960 + match (layout, format) with Some true, None -> Some Layout | _, f -> f 961 + in 962 + let layout = 963 + match (layout, format) with None, Some Layout -> Some true | l, _ -> l 964 + in 965 + match decode' ?layout ?locs ?file ?max_depth ?max_nodes t reader with 966 + | Ok v -> 967 + encode ?buf ?format ?indent ?explicit_doc ?scalar_style t v ~eod writer 968 + | Error e -> Error (Jsont.Error.to_string e)
+257
vendor/opam/yamlt/lib/yamlt.mli
··· 1 + (*--------------------------------------------------------------------------- 2 + Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org>. All rights reserved. 3 + SPDX-License-Identifier: ISC 4 + ---------------------------------------------------------------------------*) 5 + 6 + (** YAML codec using Jsont type descriptions. 7 + 8 + This module provides YAML streaming encode/decode that interprets {!Jsont.t} 9 + type descriptions, allowing the same codec definitions to work for both JSON 10 + and YAML. 11 + 12 + {b Example:} 13 + {[ 14 + (* Define a codec once using Jsont *) 15 + module Config = struct 16 + type t = { name : string; port : int } 17 + 18 + let make name port = { name; port } 19 + 20 + let jsont = 21 + Jsont.Object.map ~kind:"Config" make 22 + |> Jsont.Object.mem "name" Jsont.string ~enc:(fun c -> c.name) 23 + |> Jsont.Object.mem "port" Jsont.int ~enc:(fun c -> c.port) 24 + |> Jsont.Object.finish 25 + end 26 + 27 + (* Use the same codec for both JSON and YAML *) 28 + let from_json = Jsont_bytesrw.decode_string Config.jsont json_str 29 + let from_yaml = Yamlt.decode_string Config.jsont yaml_str 30 + ]} 31 + 32 + {2 Related Libraries} 33 + 34 + {ul 35 + {- [Jsont] - JSON codec library whose type descriptions this library interprets} 36 + {- [Yamlrw] - Pure OCaml YAML parser/emitter used for low-level YAML processing} 37 + {- [Bytesrw] - Byte-level I/O abstraction for streaming encode/decode}} 38 + 39 + See notes about {{!yaml_mapping}YAML to JSON mapping}, 40 + {{!yaml_scalars}YAML scalar resolution}, and 41 + {{!null_handling}null value handling}. *) 42 + 43 + open Bytesrw 44 + 45 + (** {1:decode Decode} *) 46 + 47 + val decode : 48 + ?layout:bool -> 49 + ?locs:bool -> 50 + ?file:Jsont.Textloc.fpath -> 51 + ?max_depth:int -> 52 + ?max_nodes:int -> 53 + 'a Jsont.t -> 54 + Bytes.Reader.t -> 55 + ('a, string) result 56 + (** [decode t r] decodes a value from YAML reader [r] according to type [t]. 57 + - If [layout] is [true], style information is preserved in {!Jsont.Meta.t} 58 + values (for potential round-tripping). Defaults to [false]. 59 + - If [locs] is [true], source locations are preserved in {!Jsont.Meta.t} 60 + values and error messages are precisely located. Defaults to [false]. 61 + - [file] is the file path for error messages. Defaults to 62 + {!Jsont.Textloc.file_none}. 63 + - [max_depth] limits nesting depth to prevent stack overflow (billion laughs 64 + protection). Defaults to [100]. 65 + - [max_nodes] limits total decoded nodes (billion laughs protection). 66 + Defaults to [10_000_000]. 67 + 68 + The YAML input must contain exactly one document. Multi-document streams are 69 + not supported; use {!decode_all} for those. *) 70 + 71 + val decode' : 72 + ?layout:bool -> 73 + ?locs:bool -> 74 + ?file:Jsont.Textloc.fpath -> 75 + ?max_depth:int -> 76 + ?max_nodes:int -> 77 + 'a Jsont.t -> 78 + Bytes.Reader.t -> 79 + ('a, Jsont.Error.t) result 80 + (** [decode'] is like {!val-decode} but preserves the error structure. *) 81 + 82 + val decode_all : 83 + ?layout:bool -> 84 + ?locs:bool -> 85 + ?file:Jsont.Textloc.fpath -> 86 + ?max_depth:int -> 87 + ?max_nodes:int -> 88 + 'a Jsont.t -> 89 + Bytes.Reader.t -> 90 + ('a, string) result Seq.t 91 + (** [decode_all t r] decodes all documents from a multi-document YAML stream. 92 + Returns a sequence where each element is a result of decoding one document. 93 + Parameters are as in {!val-decode}. Use this for YAML streams containing 94 + multiple documents separated by [---]. *) 95 + 96 + val decode_all' : 97 + ?layout:bool -> 98 + ?locs:bool -> 99 + ?file:Jsont.Textloc.fpath -> 100 + ?max_depth:int -> 101 + ?max_nodes:int -> 102 + 'a Jsont.t -> 103 + Bytes.Reader.t -> 104 + ('a, Jsont.Error.t) result Seq.t 105 + (** [decode_all'] is like {!val-decode_all} but preserves the error structure. *) 106 + 107 + (** {1:encode Encode} *) 108 + 109 + (** YAML output format. *) 110 + type yaml_format = 111 + | Block (** Block style (indented) - default. Clean, readable YAML. *) 112 + | Flow (** Flow style (JSON-like). Compact, single-line collections. *) 113 + | Layout (** Preserve layout from {!Jsont.Meta.t} when available. *) 114 + 115 + val encode : 116 + ?buf:Stdlib.Bytes.t -> 117 + ?format:yaml_format -> 118 + ?indent:int -> 119 + ?explicit_doc:bool -> 120 + ?scalar_style:Yamlrw.Scalar_style.t -> 121 + 'a Jsont.t -> 122 + 'a -> 123 + eod:bool -> 124 + Bytes.Writer.t -> 125 + (unit, string) result 126 + (** [encode t v w] encodes value [v] according to type [t] to YAML on [w]. 127 + - If [buf] is specified, it is used as a buffer for output slices. Defaults 128 + to a buffer of length {!Bytesrw.Bytes.Writer.slice_length}[ w]. 129 + - [format] controls the output style. Defaults to {!Block}. 130 + - [indent] is the indentation width in spaces. Defaults to [2]. 131 + - [explicit_doc] if [true], emits explicit document markers ([---] and 132 + [...]). Defaults to [false]. 133 + - [scalar_style] is the preferred style for string scalars. Defaults to 134 + [`Any] (auto-detect based on content). 135 + - [eod] indicates whether {!Bytesrw.Bytes.Slice.eod} should be written on 136 + [w] after encoding. *) 137 + 138 + val encode' : 139 + ?buf:Stdlib.Bytes.t -> 140 + ?format:yaml_format -> 141 + ?indent:int -> 142 + ?explicit_doc:bool -> 143 + ?scalar_style:Yamlrw.Scalar_style.t -> 144 + 'a Jsont.t -> 145 + 'a -> 146 + eod:bool -> 147 + Bytes.Writer.t -> 148 + (unit, Jsont.Error.t) result 149 + (** [encode'] is like {!val-encode} but preserves the error structure. *) 150 + 151 + (** {1:recode Recode} 152 + 153 + The defaults in these functions are those of {!val-decode} and 154 + {!val-encode}, except if [layout] is [true], [format] defaults to {!Layout} 155 + and vice-versa. *) 156 + 157 + val recode : 158 + ?layout:bool -> 159 + ?locs:bool -> 160 + ?file:Jsont.Textloc.fpath -> 161 + ?max_depth:int -> 162 + ?max_nodes:int -> 163 + ?buf:Stdlib.Bytes.t -> 164 + ?format:yaml_format -> 165 + ?indent:int -> 166 + ?explicit_doc:bool -> 167 + ?scalar_style:Yamlrw.Scalar_style.t -> 168 + 'a Jsont.t -> 169 + Bytes.Reader.t -> 170 + Bytes.Writer.t -> 171 + eod:bool -> 172 + (unit, string) result 173 + (** [recode t r w] is {!val-decode} followed by {!val-encode}. *) 174 + 175 + (** {1:yaml_mapping YAML to JSON Mapping} 176 + 177 + YAML is a superset of JSON. This module maps YAML structures to the JSON 178 + data model that {!Jsont.t} describes: 179 + 180 + - YAML scalars map to JSON null, boolean, number, or string depending on 181 + content and the expected type 182 + - YAML sequences map to JSON arrays 183 + - YAML mappings map to JSON objects (keys must be strings) 184 + - YAML aliases are resolved during decoding 185 + - YAML tags are used to guide type resolution when present 186 + 187 + {b Limitations:} 188 + - Only string keys are supported in mappings (JSON object compatibility) 189 + - Anchors and aliases are resolved; the alias structure is not preserved 190 + - Multi-document streams require {!decode_all} *) 191 + 192 + (** {1:yaml_scalars YAML Scalar Resolution} 193 + 194 + YAML scalars are resolved to JSON types as follows: 195 + 196 + {b Null:} [null], [Null], [NULL], [~], or empty string 197 + 198 + {b Boolean:} [true], [True], [TRUE], [false], [False], [FALSE], [yes], 199 + [Yes], [YES], [no], [No], [NO], [on], [On], [ON], [off], [Off], [OFF] 200 + 201 + {b Number:} Decimal integers, floats, hex ([0x...]), octal ([0o...]), 202 + infinity ([.inf], [-.inf]), NaN ([.nan]) 203 + 204 + {b String:} Anything else, or explicitly quoted scalars 205 + 206 + When decoding against a specific {!Jsont.t} type, the expected type takes 207 + precedence over automatic resolution. For example, decoding ["yes"] against 208 + {!Jsont.string} yields the string ["yes"], not [true]. *) 209 + 210 + (** {1:null_handling Null Value Handling} 211 + 212 + YAML null values are handled according to the expected type to provide 213 + friendly defaults while maintaining type safety: 214 + 215 + {b Collections (Arrays and Objects):} 216 + 217 + Null values decode as empty collections when the codec expects a collection 218 + type. This provides convenient defaults for optional collection fields in 219 + YAML: 220 + {[ 221 + # YAML with null collection fields 222 + config: 223 + items: null # Decodes as [] 224 + settings: ~ # Decodes as {} 225 + tags: # Missing value = null, decodes as [] 226 + ]} 227 + 228 + For arrays, null decodes to an empty array. For objects, null decodes to an 229 + object with all fields set to their [dec_absent] defaults. If any required 230 + field lacks a default, decoding fails with a missing member error. 231 + 232 + This behavior makes yamlt more forgiving for schemas with many optional 233 + collection fields, where writing [field:] (which parses as null) is natural 234 + and semantically equivalent to [field: []]. 235 + 236 + {b Numbers:} 237 + 238 + Null values decode to [Float.nan] when the codec expects a number. 239 + 240 + {b Primitive Types (Int, Bool, String):} 241 + 242 + Null values {e fail} when decoding into primitive scalar types ([int], 243 + [bool], [string]). Null typically indicates genuinely missing or incorrect 244 + data for these types, and silent conversion could clash with a manual 245 + setting of the default value (e.g. 0 and [null] for an integer would be 246 + indistinguishable). 247 + 248 + To accept null for primitive fields, explicitly use {!val:Jsont.option}: 249 + {[ 250 + (* Accepts null, decodes as None *) 251 + Jsont.Object.mem "count" (Jsont.option Jsont.int) ~dec_absent:None 252 + 253 + (* Rejects null, requires a number *) 254 + Jsont.Object.mem "count" Jsont.int ~dec_absent:0 255 + ]} 256 + 257 + *)
+77
vendor/opam/yamlt/tests/bin/dune
··· 1 + (executable 2 + (name test_scalars) 3 + (public_name test_scalars) 4 + (libraries yamlt jsont jsont.bytesrw bytesrw)) 5 + 6 + (executable 7 + (name test_objects) 8 + (public_name test_objects) 9 + (libraries yamlt jsont jsont.bytesrw bytesrw)) 10 + 11 + (executable 12 + (name test_arrays) 13 + (public_name test_arrays) 14 + (libraries yamlt jsont jsont.bytesrw bytesrw)) 15 + 16 + (executable 17 + (name test_formats) 18 + (public_name test_formats) 19 + (libraries yamlt jsont jsont.bytesrw bytesrw)) 20 + 21 + (executable 22 + (name test_roundtrip) 23 + (public_name test_roundtrip) 24 + (libraries yamlt jsont jsont.bytesrw bytesrw)) 25 + 26 + (executable 27 + (name test_complex) 28 + (public_name test_complex) 29 + (libraries yamlt jsont jsont.bytesrw bytesrw)) 30 + 31 + (executable 32 + (name test_edge) 33 + (public_name test_edge) 34 + (libraries yamlt jsont jsont.bytesrw bytesrw)) 35 + 36 + (executable 37 + (name test_null_fix) 38 + (libraries yamlt jsont jsont.bytesrw bytesrw)) 39 + 40 + (executable 41 + (name test_null_complete) 42 + (libraries yamlt jsont jsont.bytesrw bytesrw)) 43 + 44 + (executable 45 + (name test_null_collections) 46 + (public_name test_null_collections) 47 + (libraries yamlt jsont jsont.bytesrw bytesrw)) 48 + 49 + (executable 50 + (name test_opt_array) 51 + (libraries yamlt jsont jsont.bytesrw bytesrw)) 52 + 53 + (executable 54 + (name test_array_variants) 55 + (libraries yamlt jsont jsont.bytesrw bytesrw)) 56 + 57 + (executable 58 + (name test_some_vs_option) 59 + (libraries yamlt jsont jsont.bytesrw bytesrw)) 60 + 61 + (executable 62 + (name test_comprehensive) 63 + (libraries yamlt jsont jsont.bytesrw bytesrw)) 64 + 65 + (executable 66 + (name test_flow_newline) 67 + (libraries yamlt jsont jsont.bytesrw bytesrw)) 68 + 69 + (executable 70 + (name test_locations) 71 + (public_name test_locations) 72 + (libraries yamlt jsont jsont.bytesrw bytesrw)) 73 + 74 + (executable 75 + (name test_multidoc) 76 + (public_name test_multidoc) 77 + (libraries yamlt jsont jsont.bytesrw bytesrw))
+32
vendor/opam/yamlt/tests/bin/test_array_variants.ml
··· 1 + open Bytesrw 2 + 3 + let () = 4 + let codec1 = 5 + Jsont.Object.map ~kind:"Test" (fun arr -> arr) 6 + |> Jsont.Object.mem "values" (Jsont.array Jsont.string) ~enc:(fun arr -> 7 + arr) 8 + |> Jsont.Object.finish 9 + in 10 + 11 + let yaml1 = "values: [a, b, c]" in 12 + 13 + Printf.printf "Test 1: Non-optional array:\n"; 14 + (match Yamlt.decode codec1 (Bytes.Reader.of_string yaml1) with 15 + | Ok arr -> Printf.printf "Result: [%d items]\n" (Array.length arr) 16 + | Error e -> Printf.printf "Error: %s\n" e); 17 + 18 + let codec2 = 19 + Jsont.Object.map ~kind:"Test" (fun arr -> arr) 20 + |> Jsont.Object.mem "values" 21 + (Jsont.option (Jsont.array Jsont.string)) 22 + ~enc:(fun arr -> arr) 23 + |> Jsont.Object.finish 24 + in 25 + 26 + Printf.printf "\nTest 2: Jsont.option (Jsont.array):\n"; 27 + match Yamlt.decode codec2 (Bytes.Reader.of_string yaml1) with 28 + | Ok arr -> ( 29 + match arr with 30 + | None -> Printf.printf "Result: None\n" 31 + | Some a -> Printf.printf "Result: Some([%d items])\n" (Array.length a)) 32 + | Error e -> Printf.printf "Error: %s\n" e
+326
vendor/opam/yamlt/tests/bin/test_arrays.ml
··· 1 + (*--------------------------------------------------------------------------- 2 + Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org>. All rights reserved. 3 + SPDX-License-Identifier: ISC 4 + ---------------------------------------------------------------------------*) 5 + 6 + (** Test array codec functionality with Yamlt *) 7 + 8 + open Bytesrw 9 + 10 + (* Helper to read file *) 11 + let read_file path = 12 + let ic = open_in path in 13 + let len = in_channel_length ic in 14 + let s = really_input_string ic len in 15 + close_in ic; 16 + s 17 + 18 + (* Helper to show results *) 19 + let show_result label = function 20 + | Ok v -> Printf.printf "%s: %s\n" label v 21 + | Error e -> Printf.printf "%s: ERROR: %s\n" label e 22 + 23 + let show_result_both label json_result yaml_result = 24 + Printf.printf "JSON: "; 25 + show_result label json_result; 26 + Printf.printf "YAML: "; 27 + show_result label yaml_result 28 + 29 + (* Test: Simple int array *) 30 + let test_int_array file = 31 + let module M = struct 32 + type numbers = { values : int array } 33 + 34 + let numbers_codec = 35 + Jsont.Object.map ~kind:"Numbers" (fun values -> { values }) 36 + |> Jsont.Object.mem "values" (Jsont.array Jsont.int) ~enc:(fun n -> 37 + n.values) 38 + |> Jsont.Object.finish 39 + 40 + let show n = 41 + Printf.sprintf "[%s]" 42 + (String.concat "; " (Array.to_list (Array.map string_of_int n.values))) 43 + end in 44 + let yaml = read_file file in 45 + let json = read_file (file ^ ".json") in 46 + let json_result = Jsont_bytesrw.decode_string M.numbers_codec json in 47 + let yaml_result = Yamlt.decode M.numbers_codec (Bytes.Reader.of_string yaml) in 48 + 49 + show_result_both "int_array" 50 + (Result.map M.show json_result) 51 + (Result.map M.show yaml_result) 52 + 53 + (* Test: String array *) 54 + let test_string_array file = 55 + let module M = struct 56 + type tags = { items : string array } 57 + 58 + let tags_codec = 59 + Jsont.Object.map ~kind:"Tags" (fun items -> { items }) 60 + |> Jsont.Object.mem "items" (Jsont.array Jsont.string) ~enc:(fun t -> 61 + t.items) 62 + |> Jsont.Object.finish 63 + 64 + let show t = 65 + Printf.sprintf "[%s]" 66 + (String.concat "; " 67 + (Array.to_list (Array.map (Printf.sprintf "%S") t.items))) 68 + end in 69 + let yaml = read_file file in 70 + let json = read_file (file ^ ".json") in 71 + let json_result = Jsont_bytesrw.decode_string M.tags_codec json in 72 + let yaml_result = Yamlt.decode M.tags_codec (Bytes.Reader.of_string yaml) in 73 + 74 + show_result_both "string_array" 75 + (Result.map M.show json_result) 76 + (Result.map M.show yaml_result) 77 + 78 + (* Test: Float/number array *) 79 + let test_float_array file = 80 + let module M = struct 81 + type measurements = { values : float array } 82 + 83 + let measurements_codec = 84 + Jsont.Object.map ~kind:"Measurements" (fun values -> { values }) 85 + |> Jsont.Object.mem "values" (Jsont.array Jsont.number) ~enc:(fun m -> 86 + m.values) 87 + |> Jsont.Object.finish 88 + 89 + let show m = 90 + Printf.sprintf "[%s]" 91 + (String.concat "; " 92 + (Array.to_list (Array.map (Printf.sprintf "%.2f") m.values))) 93 + end in 94 + let yaml = read_file file in 95 + let json = read_file (file ^ ".json") in 96 + let json_result = Jsont_bytesrw.decode_string M.measurements_codec json in 97 + let yaml_result = Yamlt.decode M.measurements_codec (Bytes.Reader.of_string yaml) in 98 + 99 + show_result_both "float_array" 100 + (Result.map M.show json_result) 101 + (Result.map M.show yaml_result) 102 + 103 + (* Test: Empty array *) 104 + let test_empty_array file = 105 + let module M = struct 106 + type empty = { items : int array } 107 + 108 + let empty_codec = 109 + Jsont.Object.map ~kind:"Empty" (fun items -> { items }) 110 + |> Jsont.Object.mem "items" (Jsont.array Jsont.int) ~enc:(fun e -> 111 + e.items) 112 + |> Jsont.Object.finish 113 + 114 + let show e = Printf.sprintf "length=%d" (Stdlib.Array.length e.items) 115 + end in 116 + let yaml = read_file file in 117 + let json = read_file (file ^ ".json") in 118 + let json_result = Jsont_bytesrw.decode_string M.empty_codec json in 119 + let yaml_result = Yamlt.decode M.empty_codec (Bytes.Reader.of_string yaml) in 120 + 121 + show_result_both "empty_array" 122 + (Result.map M.show json_result) 123 + (Result.map M.show yaml_result) 124 + 125 + (* Test: Array of objects *) 126 + let test_object_array file = 127 + let module M = struct 128 + type person = { name : string; age : int } 129 + type people = { persons : person array } 130 + 131 + let person_codec = 132 + Jsont.Object.map ~kind:"Person" (fun name age -> { name; age }) 133 + |> Jsont.Object.mem "name" Jsont.string ~enc:(fun p -> p.name) 134 + |> Jsont.Object.mem "age" Jsont.int ~enc:(fun p -> p.age) 135 + |> Jsont.Object.finish 136 + 137 + let people_codec = 138 + Jsont.Object.map ~kind:"People" (fun persons -> { persons }) 139 + |> Jsont.Object.mem "persons" (Jsont.array person_codec) ~enc:(fun p -> 140 + p.persons) 141 + |> Jsont.Object.finish 142 + 143 + let show_person p = Printf.sprintf "{%s,%d}" p.name p.age 144 + 145 + let show ps = 146 + Printf.sprintf "[%s]" 147 + (String.concat "; " (Array.to_list (Array.map show_person ps.persons))) 148 + end in 149 + let yaml = read_file file in 150 + let json = read_file (file ^ ".json") in 151 + let json_result = Jsont_bytesrw.decode_string M.people_codec json in 152 + let yaml_result = Yamlt.decode M.people_codec (Bytes.Reader.of_string yaml) in 153 + 154 + show_result_both "object_array" 155 + (Result.map M.show json_result) 156 + (Result.map M.show yaml_result) 157 + 158 + (* Test: Nested arrays *) 159 + let test_nested_arrays file = 160 + let module M = struct 161 + type matrix = { data : int array array } 162 + 163 + let matrix_codec = 164 + Jsont.Object.map ~kind:"Matrix" (fun data -> { data }) 165 + |> Jsont.Object.mem "data" 166 + (Jsont.array (Jsont.array Jsont.int)) 167 + ~enc:(fun m -> m.data) 168 + |> Jsont.Object.finish 169 + 170 + let show_row row = 171 + Printf.sprintf "[%s]" 172 + (String.concat "; " (Array.to_list (Array.map string_of_int row))) 173 + 174 + let show m = 175 + Printf.sprintf "[%s]" 176 + (String.concat "; " (Array.to_list (Array.map show_row m.data))) 177 + end in 178 + let yaml = read_file file in 179 + let json = read_file (file ^ ".json") in 180 + let json_result = Jsont_bytesrw.decode_string M.matrix_codec json in 181 + let yaml_result = Yamlt.decode M.matrix_codec (Bytes.Reader.of_string yaml) in 182 + 183 + show_result_both "nested_arrays" 184 + (Result.map M.show json_result) 185 + (Result.map M.show yaml_result) 186 + 187 + (* Test: Mixed types in array (should fail with homogeneous codec) *) 188 + let test_type_mismatch file = 189 + let module M = struct 190 + type numbers = { values : int array } 191 + 192 + let numbers_codec = 193 + Jsont.Object.map ~kind:"Numbers" (fun values -> { values }) 194 + |> Jsont.Object.mem "values" (Jsont.array Jsont.int) ~enc:(fun n -> 195 + n.values) 196 + |> Jsont.Object.finish 197 + end in 198 + let yaml = read_file file in 199 + let result = Yamlt.decode M.numbers_codec (Bytes.Reader.of_string yaml) in 200 + match result with 201 + | Ok _ -> Printf.printf "Unexpected success\n" 202 + | Error e -> Printf.printf "Expected error: %s\n" e 203 + 204 + (* Test: Bool array *) 205 + let test_bool_array file = 206 + let module M = struct 207 + type flags = { values : bool array } 208 + 209 + let flags_codec = 210 + Jsont.Object.map ~kind:"Flags" (fun values -> { values }) 211 + |> Jsont.Object.mem "values" (Jsont.array Jsont.bool) ~enc:(fun f -> 212 + f.values) 213 + |> Jsont.Object.finish 214 + 215 + let show f = 216 + Printf.sprintf "[%s]" 217 + (String.concat "; " (Array.to_list (Array.map string_of_bool f.values))) 218 + end in 219 + let yaml = read_file file in 220 + let json = read_file (file ^ ".json") in 221 + let json_result = Jsont_bytesrw.decode_string M.flags_codec json in 222 + let yaml_result = Yamlt.decode M.flags_codec (Bytes.Reader.of_string yaml) in 223 + 224 + show_result_both "bool_array" 225 + (Result.map M.show json_result) 226 + (Result.map M.show yaml_result) 227 + 228 + (* Test: Array with nulls *) 229 + let test_nullable_array file = 230 + let module M = struct 231 + type nullable = { values : string option array } 232 + 233 + let nullable_codec = 234 + Jsont.Object.map ~kind:"Nullable" (fun values -> { values }) 235 + |> Jsont.Object.mem "values" 236 + (Jsont.array (Jsont.some Jsont.string)) 237 + ~enc:(fun n -> n.values) 238 + |> Jsont.Object.finish 239 + 240 + let show_opt = function None -> "null" | Some s -> Printf.sprintf "%S" s 241 + 242 + let show n = 243 + Printf.sprintf "[%s]" 244 + (String.concat "; " (Array.to_list (Array.map show_opt n.values))) 245 + end in 246 + let yaml = read_file file in 247 + let json = read_file (file ^ ".json") in 248 + let json_result = Jsont_bytesrw.decode_string M.nullable_codec json in 249 + let yaml_result = Yamlt.decode M.nullable_codec (Bytes.Reader.of_string yaml) in 250 + 251 + show_result_both "nullable_array" 252 + (Result.map M.show json_result) 253 + (Result.map M.show yaml_result) 254 + 255 + (* Test: Encoding arrays to different formats *) 256 + let test_encode_arrays () = 257 + let module M = struct 258 + type data = { numbers : int array; strings : string array } 259 + 260 + let data_codec = 261 + Jsont.Object.map ~kind:"Data" (fun numbers strings -> 262 + { numbers; strings }) 263 + |> Jsont.Object.mem "numbers" (Jsont.array Jsont.int) ~enc:(fun d -> 264 + d.numbers) 265 + |> Jsont.Object.mem "strings" (Jsont.array Jsont.string) ~enc:(fun d -> 266 + d.strings) 267 + |> Jsont.Object.finish 268 + end in 269 + let data = 270 + { M.numbers = [| 1; 2; 3; 4; 5 |]; strings = [| "hello"; "world" |] } 271 + in 272 + 273 + (* Encode to JSON *) 274 + (match Jsont_bytesrw.encode_string M.data_codec data with 275 + | Ok s -> Printf.printf "JSON: %s\n" (String.trim s) 276 + | Error e -> Printf.printf "JSON ERROR: %s\n" e); 277 + 278 + (* Encode to YAML Block *) 279 + (let b = Buffer.create 256 in 280 + let writer = Bytes.Writer.of_buffer b in 281 + match Yamlt.encode ~format:Yamlt.Block M.data_codec data ~eod:true writer with 282 + | Ok () -> Printf.printf "YAML Block:\n%s" (Buffer.contents b) 283 + | Error e -> Printf.printf "YAML Block ERROR: %s\n" e); 284 + 285 + (* Encode to YAML Flow *) 286 + let b = Buffer.create 256 in 287 + let writer = Bytes.Writer.of_buffer b in 288 + match Yamlt.encode ~format:Yamlt.Flow M.data_codec data ~eod:true writer with 289 + | Ok () -> Printf.printf "YAML Flow: %s" (Buffer.contents b) 290 + | Error e -> Printf.printf "YAML Flow ERROR: %s\n" e 291 + 292 + let () = 293 + let usage = "Usage: test_arrays <command> [args...]" in 294 + 295 + if Array.length Sys.argv < 2 then begin 296 + prerr_endline usage; 297 + exit 1 298 + end; 299 + 300 + match Sys.argv.(1) with 301 + | "int" when Array.length Sys.argv = 3 -> test_int_array Sys.argv.(2) 302 + | "string" when Array.length Sys.argv = 3 -> test_string_array Sys.argv.(2) 303 + | "float" when Array.length Sys.argv = 3 -> test_float_array Sys.argv.(2) 304 + | "empty" when Array.length Sys.argv = 3 -> test_empty_array Sys.argv.(2) 305 + | "objects" when Array.length Sys.argv = 3 -> test_object_array Sys.argv.(2) 306 + | "nested" when Array.length Sys.argv = 3 -> test_nested_arrays Sys.argv.(2) 307 + | "type-mismatch" when Array.length Sys.argv = 3 -> 308 + test_type_mismatch Sys.argv.(2) 309 + | "bool" when Array.length Sys.argv = 3 -> test_bool_array Sys.argv.(2) 310 + | "nullable" when Array.length Sys.argv = 3 -> 311 + test_nullable_array Sys.argv.(2) 312 + | "encode" when Array.length Sys.argv = 2 -> test_encode_arrays () 313 + | _ -> 314 + prerr_endline usage; 315 + prerr_endline "Commands:"; 316 + prerr_endline " int <file> - Test int array"; 317 + prerr_endline " string <file> - Test string array"; 318 + prerr_endline " float <file> - Test float array"; 319 + prerr_endline " empty <file> - Test empty array"; 320 + prerr_endline " objects <file> - Test array of objects"; 321 + prerr_endline " nested <file> - Test nested arrays"; 322 + prerr_endline " type-mismatch <file> - Test type mismatch error"; 323 + prerr_endline " bool <file> - Test bool array"; 324 + prerr_endline " nullable <file> - Test array with nulls"; 325 + prerr_endline " encode - Test encoding arrays"; 326 + exit 1
+206
vendor/opam/yamlt/tests/bin/test_complex.ml
··· 1 + (*--------------------------------------------------------------------------- 2 + Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org>. All rights reserved. 3 + SPDX-License-Identifier: ISC 4 + ---------------------------------------------------------------------------*) 5 + 6 + (** Test complex nested types with Yamlt *) 7 + 8 + open Bytesrw 9 + 10 + (* Helper to read file *) 11 + let read_file path = 12 + let ic = open_in path in 13 + let len = in_channel_length ic in 14 + let s = really_input_string ic len in 15 + close_in ic; 16 + s 17 + 18 + (* Helper to show results *) 19 + let show_result label = function 20 + | Ok v -> Printf.printf "%s: %s\n" label v 21 + | Error e -> Printf.printf "%s: ERROR: %s\n" label e 22 + 23 + let show_result_both label json_result yaml_result = 24 + Printf.printf "JSON: "; 25 + show_result label json_result; 26 + Printf.printf "YAML: "; 27 + show_result label yaml_result 28 + 29 + (* Test: Deeply nested objects *) 30 + let test_deep_nesting file = 31 + let module M = struct 32 + type level3 = { value : int } 33 + type level2 = { data : level3 } 34 + type level1 = { nested : level2 } 35 + type root = { top : level1 } 36 + 37 + let level3_codec = 38 + Jsont.Object.map ~kind:"Level3" (fun value -> { value }) 39 + |> Jsont.Object.mem "value" Jsont.int ~enc:(fun l -> l.value) 40 + |> Jsont.Object.finish 41 + 42 + let level2_codec = 43 + Jsont.Object.map ~kind:"Level2" (fun data -> { data }) 44 + |> Jsont.Object.mem "data" level3_codec ~enc:(fun l -> l.data) 45 + |> Jsont.Object.finish 46 + 47 + let level1_codec = 48 + Jsont.Object.map ~kind:"Level1" (fun nested -> { nested }) 49 + |> Jsont.Object.mem "nested" level2_codec ~enc:(fun l -> l.nested) 50 + |> Jsont.Object.finish 51 + 52 + let root_codec = 53 + Jsont.Object.map ~kind:"Root" (fun top -> { top }) 54 + |> Jsont.Object.mem "top" level1_codec ~enc:(fun r -> r.top) 55 + |> Jsont.Object.finish 56 + 57 + let show r = Printf.sprintf "depth=4, value=%d" r.top.nested.data.value 58 + end in 59 + let yaml = read_file file in 60 + let json = read_file (file ^ ".json") in 61 + let json_result = Jsont_bytesrw.decode_string M.root_codec json in 62 + let yaml_result = Yamlt.decode M.root_codec (Bytes.Reader.of_string yaml) in 63 + 64 + show_result_both "deep_nesting" 65 + (Result.map M.show json_result) 66 + (Result.map M.show yaml_result) 67 + 68 + (* Test: Array of objects with nested arrays *) 69 + let test_mixed_structure file = 70 + let module M = struct 71 + type item = { id : int; tags : string array } 72 + type collection = { name : string; items : item array } 73 + 74 + let item_codec = 75 + Jsont.Object.map ~kind:"Item" (fun id tags -> { id; tags }) 76 + |> Jsont.Object.mem "id" Jsont.int ~enc:(fun i -> i.id) 77 + |> Jsont.Object.mem "tags" (Jsont.array Jsont.string) ~enc:(fun i -> 78 + i.tags) 79 + |> Jsont.Object.finish 80 + 81 + let collection_codec = 82 + Jsont.Object.map ~kind:"Collection" (fun name items -> { name; items }) 83 + |> Jsont.Object.mem "name" Jsont.string ~enc:(fun c -> c.name) 84 + |> Jsont.Object.mem "items" (Jsont.array item_codec) ~enc:(fun c -> 85 + c.items) 86 + |> Jsont.Object.finish 87 + 88 + let show c = 89 + let total_tags = 90 + Stdlib.Array.fold_left 91 + (fun acc item -> acc + Stdlib.Array.length item.tags) 92 + 0 c.items 93 + in 94 + Printf.sprintf "name=%S, items=%d, total_tags=%d" c.name 95 + (Stdlib.Array.length c.items) 96 + total_tags 97 + end in 98 + let yaml = read_file file in 99 + let json = read_file (file ^ ".json") in 100 + let json_result = Jsont_bytesrw.decode_string M.collection_codec json in 101 + let yaml_result = Yamlt.decode M.collection_codec (Bytes.Reader.of_string yaml) in 102 + 103 + show_result_both "mixed_structure" 104 + (Result.map M.show json_result) 105 + (Result.map M.show yaml_result) 106 + 107 + (* Test: Complex optional and nullable combinations *) 108 + let test_complex_optional file = 109 + let module M = struct 110 + type config = { 111 + host : string; 112 + port : int option; 113 + ssl : bool option; 114 + cert_path : string option; 115 + fallback_hosts : string array option; 116 + } 117 + 118 + let config_codec = 119 + Jsont.Object.map ~kind:"Config" 120 + (fun host port ssl cert_path fallback_hosts -> 121 + { host; port; ssl; cert_path; fallback_hosts }) 122 + |> Jsont.Object.mem "host" Jsont.string ~enc:(fun c -> c.host) 123 + |> Jsont.Object.opt_mem "port" Jsont.int ~enc:(fun c -> c.port) 124 + |> Jsont.Object.opt_mem "ssl" Jsont.bool ~enc:(fun c -> c.ssl) 125 + |> Jsont.Object.opt_mem "cert_path" Jsont.string ~enc:(fun c -> 126 + c.cert_path) 127 + |> Jsont.Object.opt_mem "fallback_hosts" (Jsont.array Jsont.string) 128 + ~enc:(fun c -> c.fallback_hosts) 129 + |> Jsont.Object.finish 130 + 131 + let show c = 132 + let port_str = 133 + match c.port with None -> "None" | Some p -> string_of_int p 134 + in 135 + let ssl_str = 136 + match c.ssl with None -> "None" | Some b -> string_of_bool b 137 + in 138 + let fallbacks = 139 + match c.fallback_hosts with 140 + | None -> 0 141 + | Some arr -> Stdlib.Array.length arr 142 + in 143 + Printf.sprintf "host=%S, port=%s, ssl=%s, fallbacks=%d" c.host port_str 144 + ssl_str fallbacks 145 + end in 146 + let yaml = read_file file in 147 + let json = read_file (file ^ ".json") in 148 + let json_result = Jsont_bytesrw.decode_string M.config_codec json in 149 + let yaml_result = Yamlt.decode M.config_codec (Bytes.Reader.of_string yaml) in 150 + 151 + show_result_both "complex_optional" 152 + (Result.map M.show json_result) 153 + (Result.map M.show yaml_result) 154 + 155 + (* Test: Heterogeneous data via any type *) 156 + let test_heterogeneous file = 157 + let module M = struct 158 + type data = { mixed : Jsont.json array } 159 + 160 + let data_codec = 161 + Jsont.Object.map ~kind:"Data" (fun mixed -> { mixed }) 162 + |> Jsont.Object.mem "mixed" 163 + (Jsont.array (Jsont.any ())) 164 + ~enc:(fun d -> d.mixed) 165 + |> Jsont.Object.finish 166 + 167 + let show d = Printf.sprintf "items=%d" (Stdlib.Array.length d.mixed) 168 + end in 169 + let yaml = read_file file in 170 + let json = read_file (file ^ ".json") in 171 + let json_result = Jsont_bytesrw.decode_string M.data_codec json in 172 + let yaml_result = Yamlt.decode M.data_codec (Bytes.Reader.of_string yaml) in 173 + 174 + show_result_both "heterogeneous" 175 + (Result.map M.show json_result) 176 + (Result.map M.show yaml_result) 177 + 178 + let () = 179 + let usage = "Usage: test_complex <command> [args...]" in 180 + 181 + if Stdlib.Array.length Sys.argv < 2 then begin 182 + prerr_endline usage; 183 + exit 1 184 + end; 185 + 186 + match Sys.argv.(1) with 187 + | "deep-nesting" when Stdlib.Array.length Sys.argv = 3 -> 188 + test_deep_nesting Sys.argv.(2) 189 + | "mixed-structure" when Stdlib.Array.length Sys.argv = 3 -> 190 + test_mixed_structure Sys.argv.(2) 191 + | "complex-optional" when Stdlib.Array.length Sys.argv = 3 -> 192 + test_complex_optional Sys.argv.(2) 193 + | "heterogeneous" when Stdlib.Array.length Sys.argv = 3 -> 194 + test_heterogeneous Sys.argv.(2) 195 + | _ -> 196 + prerr_endline usage; 197 + prerr_endline "Commands:"; 198 + prerr_endline " deep-nesting <file> - Test deeply nested objects"; 199 + prerr_endline 200 + " mixed-structure <file> - Test arrays of objects with nested arrays"; 201 + prerr_endline 202 + " complex-optional <file> - Test complex optional/nullable \ 203 + combinations"; 204 + prerr_endline 205 + " heterogeneous <file> - Test heterogeneous data via any type"; 206 + exit 1
+96
vendor/opam/yamlt/tests/bin/test_comprehensive.ml
··· 1 + open Bytesrw 2 + 3 + let () = 4 + (* Test 1: Null handling with option types *) 5 + Printf.printf "=== NULL HANDLING ===\n"; 6 + let opt_codec = 7 + Jsont.Object.map ~kind:"Test" (fun v -> v) 8 + |> Jsont.Object.mem "value" (Jsont.option Jsont.string) ~enc:(fun v -> v) 9 + |> Jsont.Object.finish 10 + in 11 + 12 + (match Yamlt.decode opt_codec (Bytes.Reader.of_string "value: null") with 13 + | Ok None -> Printf.printf "✓ Plain 'null' with option codec: None\n" 14 + | _ -> Printf.printf "✗ FAIL\n"); 15 + 16 + (match Yamlt.decode opt_codec (Bytes.Reader.of_string "value: hello") with 17 + | Ok (Some "hello") -> 18 + Printf.printf "✓ Plain 'hello' with option codec: Some(hello)\n" 19 + | _ -> Printf.printf "✗ FAIL\n"); 20 + 21 + let string_codec = 22 + Jsont.Object.map ~kind:"Test" (fun v -> v) 23 + |> Jsont.Object.mem "value" Jsont.string ~enc:(fun v -> v) 24 + |> Jsont.Object.finish 25 + in 26 + 27 + (match Yamlt.decode string_codec (Bytes.Reader.of_string "value: null") with 28 + | Error _ -> 29 + Printf.printf "✓ Plain 'null' with string codec: ERROR (expected)\n" 30 + | _ -> Printf.printf "✗ FAIL\n"); 31 + 32 + (match Yamlt.decode string_codec (Bytes.Reader.of_string "value: \"\"") with 33 + | Ok "" -> Printf.printf "✓ Quoted empty string: \"\"\n" 34 + | _ -> Printf.printf "✗ FAIL\n"); 35 + 36 + (match Yamlt.decode string_codec (Bytes.Reader.of_string "value: \"null\"") with 37 + | Ok "null" -> Printf.printf "✓ Quoted 'null': \"null\"\n" 38 + | _ -> Printf.printf "✗ FAIL\n"); 39 + 40 + (* Test 2: Number formats *) 41 + Printf.printf "\n=== NUMBER FORMATS ===\n"; 42 + let num_codec = 43 + Jsont.Object.map ~kind:"Test" (fun v -> v) 44 + |> Jsont.Object.mem "value" Jsont.number ~enc:(fun v -> v) 45 + |> Jsont.Object.finish 46 + in 47 + 48 + (match Yamlt.decode num_codec (Bytes.Reader.of_string "value: 0xFF") with 49 + | Ok 255. -> Printf.printf "✓ Hex 0xFF: 255\n" 50 + | _ -> Printf.printf "✗ FAIL\n"); 51 + 52 + (match Yamlt.decode num_codec (Bytes.Reader.of_string "value: 0o77") with 53 + | Ok 63. -> Printf.printf "✓ Octal 0o77: 63\n" 54 + | _ -> Printf.printf "✗ FAIL\n"); 55 + 56 + (match Yamlt.decode num_codec (Bytes.Reader.of_string "value: 0b1010") with 57 + | Ok 10. -> Printf.printf "✓ Binary 0b1010: 10\n" 58 + | _ -> Printf.printf "✗ FAIL\n"); 59 + 60 + (* Test 3: Optional arrays *) 61 + Printf.printf "\n=== OPTIONAL ARRAYS ===\n"; 62 + let opt_array_codec = 63 + Jsont.Object.map ~kind:"Test" (fun v -> v) 64 + |> Jsont.Object.opt_mem "values" (Jsont.array Jsont.string) ~enc:(fun v -> 65 + v) 66 + |> Jsont.Object.finish 67 + in 68 + 69 + (match Yamlt.decode opt_array_codec (Bytes.Reader.of_string "values: [a, b, c]") with 70 + | Ok (Some arr) when Array.length arr = 3 -> 71 + Printf.printf "✓ Optional array [a, b, c]: Some([3 items])\n" 72 + | _ -> Printf.printf "✗ FAIL\n"); 73 + 74 + (match Yamlt.decode opt_array_codec (Bytes.Reader.of_string "{}") with 75 + | Ok None -> Printf.printf "✓ Missing optional array: None\n" 76 + | _ -> Printf.printf "✗ FAIL\n"); 77 + 78 + (* Test 4: Flow encoding *) 79 + Printf.printf "\n=== FLOW ENCODING ===\n"; 80 + let encode_codec = 81 + Jsont.Object.map ~kind:"Test" (fun name values -> (name, values)) 82 + |> Jsont.Object.mem "name" Jsont.string ~enc:fst 83 + |> Jsont.Object.mem "values" (Jsont.array Jsont.number) ~enc:snd 84 + |> Jsont.Object.finish 85 + in 86 + 87 + let b = Buffer.create 256 in 88 + let writer = Bytes.Writer.of_buffer b in 89 + match 90 + Yamlt.encode ~format:Flow encode_codec ("test", [| 1.; 2.; 3. |]) ~eod:true writer 91 + with 92 + | Ok () 93 + when String.equal (Buffer.contents b) "{name: test, values: [1.0, 2.0, 3.0]}\n" -> 94 + Printf.printf "✓ Flow encoding with comma separator\n" 95 + | Ok () -> Printf.printf "✗ FAIL: %S\n" (Buffer.contents b) 96 + | Error e -> Printf.printf "✗ ERROR: %s\n" e
+214
vendor/opam/yamlt/tests/bin/test_edge.ml
··· 1 + (*--------------------------------------------------------------------------- 2 + Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org>. All rights reserved. 3 + SPDX-License-Identifier: ISC 4 + ---------------------------------------------------------------------------*) 5 + 6 + (** Test edge cases with Yamlt *) 7 + 8 + open Bytesrw 9 + 10 + (* Helper to read file *) 11 + let read_file path = 12 + let ic = open_in path in 13 + let len = in_channel_length ic in 14 + let s = really_input_string ic len in 15 + close_in ic; 16 + s 17 + 18 + (* Helper to show results *) 19 + let show_result label = function 20 + | Ok v -> Printf.printf "%s: %s\n" label v 21 + | Error e -> Printf.printf "%s: ERROR: %s\n" label e 22 + 23 + let show_result_both label json_result yaml_result = 24 + Printf.printf "JSON: "; 25 + show_result label json_result; 26 + Printf.printf "YAML: "; 27 + show_result label yaml_result 28 + 29 + (* Test: Very large numbers *) 30 + let test_large_numbers file = 31 + let module M = struct 32 + type numbers = { 33 + large_int : float; 34 + large_float : float; 35 + small_float : float; 36 + } 37 + 38 + let numbers_codec = 39 + Jsont.Object.map ~kind:"Numbers" (fun large_int large_float small_float -> 40 + { large_int; large_float; small_float }) 41 + |> Jsont.Object.mem "large_int" Jsont.number ~enc:(fun n -> n.large_int) 42 + |> Jsont.Object.mem "large_float" Jsont.number ~enc:(fun n -> 43 + n.large_float) 44 + |> Jsont.Object.mem "small_float" Jsont.number ~enc:(fun n -> 45 + n.small_float) 46 + |> Jsont.Object.finish 47 + 48 + let show n = 49 + Printf.sprintf "large_int=%.0f, large_float=%e, small_float=%e" 50 + n.large_int n.large_float n.small_float 51 + end in 52 + let yaml = read_file file in 53 + let json = read_file (file ^ ".json") in 54 + let json_result = Jsont_bytesrw.decode_string M.numbers_codec json in 55 + let yaml_result = Yamlt.decode M.numbers_codec (Bytes.Reader.of_string yaml) in 56 + 57 + show_result_both "large_numbers" 58 + (Result.map M.show json_result) 59 + (Result.map M.show yaml_result) 60 + 61 + (* Test: Special characters in strings *) 62 + let test_special_chars file = 63 + let module M = struct 64 + type text = { content : string } 65 + 66 + let text_codec = 67 + Jsont.Object.map ~kind:"Text" (fun content -> { content }) 68 + |> Jsont.Object.mem "content" Jsont.string ~enc:(fun t -> t.content) 69 + |> Jsont.Object.finish 70 + 71 + let show t = 72 + Printf.sprintf "length=%d, contains_newline=%b, contains_tab=%b" 73 + (String.length t.content) 74 + (String.contains t.content '\n') 75 + (String.contains t.content '\t') 76 + end in 77 + let yaml = read_file file in 78 + let json = read_file (file ^ ".json") in 79 + let json_result = Jsont_bytesrw.decode_string M.text_codec json in 80 + let yaml_result = Yamlt.decode M.text_codec (Bytes.Reader.of_string yaml) in 81 + 82 + show_result_both "special_chars" 83 + (Result.map M.show json_result) 84 + (Result.map M.show yaml_result) 85 + 86 + (* Test: Unicode strings *) 87 + let test_unicode file = 88 + let module M = struct 89 + type text = { emoji : string; chinese : string; rtl : string } 90 + 91 + let text_codec = 92 + Jsont.Object.map ~kind:"Text" (fun emoji chinese rtl -> 93 + { emoji; chinese; rtl }) 94 + |> Jsont.Object.mem "emoji" Jsont.string ~enc:(fun t -> t.emoji) 95 + |> Jsont.Object.mem "chinese" Jsont.string ~enc:(fun t -> t.chinese) 96 + |> Jsont.Object.mem "rtl" Jsont.string ~enc:(fun t -> t.rtl) 97 + |> Jsont.Object.finish 98 + 99 + let show t = 100 + Printf.sprintf "emoji=%S, chinese=%S, rtl=%S" t.emoji t.chinese t.rtl 101 + end in 102 + let yaml = read_file file in 103 + let json = read_file (file ^ ".json") in 104 + let json_result = Jsont_bytesrw.decode_string M.text_codec json in 105 + let yaml_result = Yamlt.decode M.text_codec (Bytes.Reader.of_string yaml) in 106 + 107 + show_result_both "unicode" 108 + (Result.map M.show json_result) 109 + (Result.map M.show yaml_result) 110 + 111 + (* Test: Empty collections *) 112 + let test_empty_collections file = 113 + let module M = struct 114 + type data = { empty_array : int array; empty_object_array : unit array } 115 + 116 + let data_codec = 117 + Jsont.Object.map ~kind:"Data" (fun empty_array empty_object_array -> 118 + { empty_array; empty_object_array }) 119 + |> Jsont.Object.mem "empty_array" (Jsont.array Jsont.int) ~enc:(fun d -> 120 + d.empty_array) 121 + |> Jsont.Object.mem "empty_object_array" 122 + (Jsont.array (Jsont.null ())) 123 + ~enc:(fun d -> d.empty_object_array) 124 + |> Jsont.Object.finish 125 + 126 + let show d = 127 + Printf.sprintf "empty_array_len=%d, empty_object_array_len=%d" 128 + (Stdlib.Array.length d.empty_array) 129 + (Stdlib.Array.length d.empty_object_array) 130 + end in 131 + let yaml = read_file file in 132 + let json = read_file (file ^ ".json") in 133 + let json_result = Jsont_bytesrw.decode_string M.data_codec json in 134 + let yaml_result = Yamlt.decode M.data_codec (Bytes.Reader.of_string yaml) in 135 + 136 + show_result_both "empty_collections" 137 + (Result.map M.show json_result) 138 + (Result.map M.show yaml_result) 139 + 140 + (* Test: Key names with special characters *) 141 + let test_special_keys file = 142 + let module M = struct 143 + let show j = 144 + match Jsont.Json.decode (Jsont.any ()) j with 145 + | Ok (Jsont.Object _) -> "valid_object" 146 + | Ok _ -> "not_object" 147 + | Error _ -> "decode_error" 148 + end in 149 + let yaml = read_file file in 150 + let json = read_file (file ^ ".json") in 151 + let json_result = Jsont_bytesrw.decode_string (Jsont.any ()) json in 152 + let yaml_result = Yamlt.decode (Jsont.any ()) (Bytes.Reader.of_string yaml) in 153 + 154 + show_result_both "special_keys" 155 + (Result.map M.show json_result) 156 + (Result.map M.show yaml_result) 157 + 158 + (* Test: Single-element arrays *) 159 + let test_single_element file = 160 + let module M = struct 161 + type data = { single : int array } 162 + 163 + let data_codec = 164 + Jsont.Object.map ~kind:"Data" (fun single -> { single }) 165 + |> Jsont.Object.mem "single" (Jsont.array Jsont.int) ~enc:(fun d -> 166 + d.single) 167 + |> Jsont.Object.finish 168 + 169 + let show d = 170 + Printf.sprintf "length=%d, value=%d" 171 + (Stdlib.Array.length d.single) 172 + (if Stdlib.Array.length d.single > 0 then d.single.(0) else 0) 173 + end in 174 + let yaml = read_file file in 175 + let json = read_file (file ^ ".json") in 176 + let json_result = Jsont_bytesrw.decode_string M.data_codec json in 177 + let yaml_result = Yamlt.decode M.data_codec (Bytes.Reader.of_string yaml) in 178 + 179 + show_result_both "single_element" 180 + (Result.map M.show json_result) 181 + (Result.map M.show yaml_result) 182 + 183 + let () = 184 + let usage = "Usage: test_edge <command> [args...]" in 185 + 186 + if Stdlib.Array.length Sys.argv < 2 then begin 187 + prerr_endline usage; 188 + exit 1 189 + end; 190 + 191 + match Sys.argv.(1) with 192 + | "large-numbers" when Stdlib.Array.length Sys.argv = 3 -> 193 + test_large_numbers Sys.argv.(2) 194 + | "special-chars" when Stdlib.Array.length Sys.argv = 3 -> 195 + test_special_chars Sys.argv.(2) 196 + | "unicode" when Stdlib.Array.length Sys.argv = 3 -> test_unicode Sys.argv.(2) 197 + | "empty-collections" when Stdlib.Array.length Sys.argv = 3 -> 198 + test_empty_collections Sys.argv.(2) 199 + | "special-keys" when Stdlib.Array.length Sys.argv = 3 -> 200 + test_special_keys Sys.argv.(2) 201 + | "single-element" when Stdlib.Array.length Sys.argv = 3 -> 202 + test_single_element Sys.argv.(2) 203 + | _ -> 204 + prerr_endline usage; 205 + prerr_endline "Commands:"; 206 + prerr_endline " large-numbers <file> - Test very large numbers"; 207 + prerr_endline 208 + " special-chars <file> - Test special characters in strings"; 209 + prerr_endline " unicode <file> - Test Unicode strings"; 210 + prerr_endline " empty-collections <file> - Test empty collections"; 211 + prerr_endline 212 + " special-keys <file> - Test special characters in keys"; 213 + prerr_endline " single-element <file> - Test single-element arrays"; 214 + exit 1
+21
vendor/opam/yamlt/tests/bin/test_flow_newline.ml
··· 1 + open Bytesrw 2 + 3 + let () = 4 + let encode_codec = 5 + Jsont.Object.map ~kind:"Test" (fun name values -> (name, values)) 6 + |> Jsont.Object.mem "name" Jsont.string ~enc:fst 7 + |> Jsont.Object.mem "values" (Jsont.array Jsont.number) ~enc:snd 8 + |> Jsont.Object.finish 9 + in 10 + 11 + let b = Buffer.create 256 in 12 + let writer = Bytes.Writer.of_buffer b in 13 + match 14 + Yamlt.encode ~format:Flow encode_codec ("test", [| 1.; 2.; 3. |]) ~eod:true writer 15 + with 16 + | Ok () -> 17 + let yaml_flow = Buffer.contents b in 18 + Printf.printf "Length: %d\n" (String.length yaml_flow); 19 + Printf.printf "Repr: %S\n" yaml_flow; 20 + Printf.printf "Output:\n%s" yaml_flow 21 + | Error e -> Printf.printf "Error: %s\n" e
+248
vendor/opam/yamlt/tests/bin/test_formats.ml
··· 1 + (*--------------------------------------------------------------------------- 2 + Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org>. All rights reserved. 3 + SPDX-License-Identifier: ISC 4 + ---------------------------------------------------------------------------*) 5 + 6 + (** Test format-specific features with Yamlt *) 7 + 8 + open Bytesrw 9 + 10 + (* Helper to read file *) 11 + let read_file path = 12 + let ic = open_in path in 13 + let len = in_channel_length ic in 14 + let s = really_input_string ic len in 15 + close_in ic; 16 + s 17 + 18 + (* Helper to show results *) 19 + let show_result label = function 20 + | Ok v -> Printf.printf "%s: %s\n" label v 21 + | Error e -> Printf.printf "%s: ERROR: %s\n" label e 22 + 23 + let show_result_both label json_result yaml_result = 24 + Printf.printf "JSON: "; 25 + show_result label json_result; 26 + Printf.printf "YAML: "; 27 + show_result label yaml_result 28 + 29 + (* Test: Multi-line strings - literal style *) 30 + let test_literal_string file = 31 + let module M = struct 32 + type text = { content : string } 33 + 34 + let text_codec = 35 + Jsont.Object.map ~kind:"Text" (fun content -> { content }) 36 + |> Jsont.Object.mem "content" Jsont.string ~enc:(fun t -> t.content) 37 + |> Jsont.Object.finish 38 + 39 + let show t = 40 + Printf.sprintf "lines=%d, length=%d" 41 + (List.length (String.split_on_char '\n' t.content)) 42 + (String.length t.content) 43 + end in 44 + let yaml = read_file file in 45 + let json = read_file (file ^ ".json") in 46 + let json_result = Jsont_bytesrw.decode_string M.text_codec json in 47 + let yaml_result = Yamlt.decode M.text_codec (Bytes.Reader.of_string yaml) in 48 + 49 + show_result_both "literal_string" 50 + (Result.map M.show json_result) 51 + (Result.map M.show yaml_result) 52 + 53 + (* Test: Multi-line strings - folded style *) 54 + let test_folded_string file = 55 + let module M = struct 56 + type text = { content : string } 57 + 58 + let text_codec = 59 + Jsont.Object.map ~kind:"Text" (fun content -> { content }) 60 + |> Jsont.Object.mem "content" Jsont.string ~enc:(fun t -> t.content) 61 + |> Jsont.Object.finish 62 + 63 + let show t = 64 + Printf.sprintf "length=%d, newlines=%d" (String.length t.content) 65 + (List.length 66 + (List.filter 67 + (fun c -> c = '\n') 68 + (List.init (String.length t.content) (String.get t.content)))) 69 + end in 70 + let yaml = read_file file in 71 + let json = read_file (file ^ ".json") in 72 + let json_result = Jsont_bytesrw.decode_string M.text_codec json in 73 + let yaml_result = Yamlt.decode M.text_codec (Bytes.Reader.of_string yaml) in 74 + 75 + show_result_both "folded_string" 76 + (Result.map M.show json_result) 77 + (Result.map M.show yaml_result) 78 + 79 + (* Test: Number formats - hex, octal, binary *) 80 + let test_number_formats file = 81 + let module M = struct 82 + type numbers = { hex : float; octal : float; binary : float } 83 + 84 + let numbers_codec = 85 + Jsont.Object.map ~kind:"Numbers" (fun hex octal binary -> 86 + { hex; octal; binary }) 87 + |> Jsont.Object.mem "hex" Jsont.number ~enc:(fun n -> n.hex) 88 + |> Jsont.Object.mem "octal" Jsont.number ~enc:(fun n -> n.octal) 89 + |> Jsont.Object.mem "binary" Jsont.number ~enc:(fun n -> n.binary) 90 + |> Jsont.Object.finish 91 + 92 + let show n = 93 + Printf.sprintf "hex=%.0f, octal=%.0f, binary=%.0f" n.hex n.octal n.binary 94 + end in 95 + let yaml = read_file file in 96 + let json = read_file (file ^ ".json") in 97 + let json_result = Jsont_bytesrw.decode_string M.numbers_codec json in 98 + let yaml_result = Yamlt.decode M.numbers_codec (Bytes.Reader.of_string yaml) in 99 + 100 + show_result_both "number_formats" 101 + (Result.map M.show json_result) 102 + (Result.map M.show yaml_result) 103 + 104 + (* Test: Block vs Flow style encoding *) 105 + let test_encode_styles () = 106 + let module M = struct 107 + type data = { name : string; values : int array; nested : nested_data } 108 + and nested_data = { enabled : bool; count : int } 109 + 110 + let nested_codec = 111 + Jsont.Object.map ~kind:"Nested" (fun enabled count -> { enabled; count }) 112 + |> Jsont.Object.mem "enabled" Jsont.bool ~enc:(fun n -> n.enabled) 113 + |> Jsont.Object.mem "count" Jsont.int ~enc:(fun n -> n.count) 114 + |> Jsont.Object.finish 115 + 116 + let data_codec = 117 + Jsont.Object.map ~kind:"Data" (fun name values nested -> 118 + { name; values; nested }) 119 + |> Jsont.Object.mem "name" Jsont.string ~enc:(fun d -> d.name) 120 + |> Jsont.Object.mem "values" (Jsont.array Jsont.int) ~enc:(fun d -> 121 + d.values) 122 + |> Jsont.Object.mem "nested" nested_codec ~enc:(fun d -> d.nested) 123 + |> Jsont.Object.finish 124 + end in 125 + let data = 126 + { 127 + M.name = "test"; 128 + values = [| 1; 2; 3 |]; 129 + nested = { enabled = true; count = 5 }; 130 + } 131 + in 132 + 133 + (* Encode to YAML Block style *) 134 + (let b = Buffer.create 256 in 135 + let writer = Bytes.Writer.of_buffer b in 136 + match Yamlt.encode ~format:Yamlt.Block M.data_codec data ~eod:true writer with 137 + | Ok () -> Printf.printf "YAML Block:\n%s\n" (Buffer.contents b) 138 + | Error e -> Printf.printf "YAML Block ERROR: %s\n" e); 139 + 140 + (* Encode to YAML Flow style *) 141 + let b = Buffer.create 256 in 142 + let writer = Bytes.Writer.of_buffer b in 143 + match Yamlt.encode ~format:Yamlt.Flow M.data_codec data ~eod:true writer with 144 + | Ok () -> Printf.printf "YAML Flow:\n%s\n" (Buffer.contents b) 145 + | Error e -> Printf.printf "YAML Flow ERROR: %s\n" e 146 + 147 + (* Test: Comments in YAML (should be ignored) *) 148 + let test_comments file = 149 + let module M = struct 150 + type config = { host : string; port : int; debug : bool } 151 + 152 + let config_codec = 153 + Jsont.Object.map ~kind:"Config" (fun host port debug -> 154 + { host; port; debug }) 155 + |> Jsont.Object.mem "host" Jsont.string ~enc:(fun c -> c.host) 156 + |> Jsont.Object.mem "port" Jsont.int ~enc:(fun c -> c.port) 157 + |> Jsont.Object.mem "debug" Jsont.bool ~enc:(fun c -> c.debug) 158 + |> Jsont.Object.finish 159 + 160 + let show c = 161 + Printf.sprintf "host=%S, port=%d, debug=%b" c.host c.port c.debug 162 + end in 163 + let yaml = read_file file in 164 + let yaml_result = Yamlt.decode M.config_codec (Bytes.Reader.of_string yaml) in 165 + 166 + match yaml_result with 167 + | Ok v -> Printf.printf "YAML (with comments): %s\n" (M.show v) 168 + | Error e -> Printf.printf "YAML ERROR: %s\n" e 169 + 170 + (* Test: Empty documents and null documents *) 171 + let test_empty_document file = 172 + let module M = struct 173 + type wrapper = { value : string option } 174 + 175 + let wrapper_codec = 176 + Jsont.Object.map ~kind:"Wrapper" (fun value -> { value }) 177 + |> Jsont.Object.mem "value" (Jsont.some Jsont.string) ~enc:(fun w -> 178 + w.value) 179 + |> Jsont.Object.finish 180 + 181 + let show w = 182 + match w.value with 183 + | None -> "value=None" 184 + | Some s -> Printf.sprintf "value=Some(%S)" s 185 + end in 186 + let yaml = read_file file in 187 + let json = read_file (file ^ ".json") in 188 + let json_result = Jsont_bytesrw.decode_string M.wrapper_codec json in 189 + let yaml_result = Yamlt.decode M.wrapper_codec (Bytes.Reader.of_string yaml) in 190 + 191 + show_result_both "empty_document" 192 + (Result.map M.show json_result) 193 + (Result.map M.show yaml_result) 194 + 195 + (* Test: Explicit typing with tags (if supported) *) 196 + let test_explicit_tags file = 197 + let module M = struct 198 + type value_holder = { data : string } 199 + 200 + let value_codec = 201 + Jsont.Object.map ~kind:"ValueHolder" (fun data -> { data }) 202 + |> Jsont.Object.mem "data" Jsont.string ~enc:(fun v -> v.data) 203 + |> Jsont.Object.finish 204 + 205 + let show v = Printf.sprintf "data=%S" v.data 206 + end in 207 + let yaml = read_file file in 208 + let yaml_result = Yamlt.decode M.value_codec (Bytes.Reader.of_string yaml) in 209 + 210 + match yaml_result with 211 + | Ok v -> Printf.printf "YAML (with tags): %s\n" (M.show v) 212 + | Error e -> Printf.printf "YAML ERROR: %s\n" e 213 + 214 + let () = 215 + let usage = "Usage: test_formats <command> [args...]" in 216 + 217 + if Stdlib.Array.length Sys.argv < 2 then begin 218 + prerr_endline usage; 219 + exit 1 220 + end; 221 + 222 + match Sys.argv.(1) with 223 + | "literal" when Stdlib.Array.length Sys.argv = 3 -> 224 + test_literal_string Sys.argv.(2) 225 + | "folded" when Stdlib.Array.length Sys.argv = 3 -> 226 + test_folded_string Sys.argv.(2) 227 + | "number-formats" when Stdlib.Array.length Sys.argv = 3 -> 228 + test_number_formats Sys.argv.(2) 229 + | "encode-styles" when Stdlib.Array.length Sys.argv = 2 -> 230 + test_encode_styles () 231 + | "comments" when Stdlib.Array.length Sys.argv = 3 -> 232 + test_comments Sys.argv.(2) 233 + | "empty-doc" when Stdlib.Array.length Sys.argv = 3 -> 234 + test_empty_document Sys.argv.(2) 235 + | "explicit-tags" when Stdlib.Array.length Sys.argv = 3 -> 236 + test_explicit_tags Sys.argv.(2) 237 + | _ -> 238 + prerr_endline usage; 239 + prerr_endline "Commands:"; 240 + prerr_endline " literal <file> - Test literal multi-line strings"; 241 + prerr_endline " folded <file> - Test folded multi-line strings"; 242 + prerr_endline 243 + " number-formats <file> - Test hex/octal/binary number formats"; 244 + prerr_endline " encode-styles - Test block vs flow encoding"; 245 + prerr_endline " comments <file> - Test YAML with comments"; 246 + prerr_endline " empty-doc <file> - Test empty documents"; 247 + prerr_endline " explicit-tags <file> - Test explicit type tags"; 248 + exit 1
+270
vendor/opam/yamlt/tests/bin/test_locations.ml
··· 1 + (*--------------------------------------------------------------------------- 2 + Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org>. All rights reserved. 3 + SPDX-License-Identifier: ISC 4 + ---------------------------------------------------------------------------*) 5 + 6 + (** Test location and layout preservation options with Yamlt codec *) 7 + 8 + (* Helper to read file *) 9 + open Bytesrw 10 + 11 + let read_file path = 12 + let ic = open_in path in 13 + let len = in_channel_length ic in 14 + let s = really_input_string ic len in 15 + close_in ic; 16 + s 17 + 18 + (* Helper to show results *) 19 + let show_result label = function 20 + | Ok _ -> Printf.printf "%s: OK\n" label 21 + | Error e -> Printf.printf "%s:\n%s\n" label e 22 + 23 + (* Test: Compare error messages with and without locs *) 24 + let test_error_precision file = 25 + let yaml = read_file file in 26 + 27 + (* Define a codec that will fail on type mismatch *) 28 + let codec = 29 + Jsont.Object.map ~kind:"Person" (fun name age -> (name, age)) 30 + |> Jsont.Object.mem "name" Jsont.string ~enc:fst 31 + |> Jsont.Object.mem "age" Jsont.int ~enc:snd 32 + |> Jsont.Object.finish 33 + in 34 + 35 + Printf.printf "=== Without locs (default) ===\n"; 36 + let result_no_locs = Yamlt.decode codec (Bytes.Reader.of_string yaml) ~locs:false in 37 + show_result "Error message" result_no_locs; 38 + 39 + Printf.printf "\n=== With locs=true ===\n"; 40 + let result_with_locs = Yamlt.decode codec (Bytes.Reader.of_string yaml) ~locs:true in 41 + show_result "Error message" result_with_locs 42 + 43 + (* Test: Show error locations for nested structures *) 44 + let test_nested_error file = 45 + let yaml = read_file file in 46 + 47 + (* Nested object codec *) 48 + let address_codec = 49 + Jsont.Object.map ~kind:"Address" (fun street city zip -> 50 + (street, city, zip)) 51 + |> Jsont.Object.mem "street" Jsont.string ~enc:(fun (s, _, _) -> s) 52 + |> Jsont.Object.mem "city" Jsont.string ~enc:(fun (_, c, _) -> c) 53 + |> Jsont.Object.mem "zip" Jsont.int ~enc:(fun (_, _, z) -> z) 54 + |> Jsont.Object.finish 55 + in 56 + 57 + let codec = 58 + Jsont.Object.map ~kind:"Employee" (fun name address -> (name, address)) 59 + |> Jsont.Object.mem "name" Jsont.string ~enc:fst 60 + |> Jsont.Object.mem "address" address_codec ~enc:snd 61 + |> Jsont.Object.finish 62 + in 63 + 64 + Printf.printf "=== Without locs (default) ===\n"; 65 + let result_no_locs = Yamlt.decode codec (Bytes.Reader.of_string yaml) ~locs:false in 66 + show_result "Nested error" result_no_locs; 67 + 68 + Printf.printf "\n=== With locs=true ===\n"; 69 + let result_with_locs = Yamlt.decode codec (Bytes.Reader.of_string yaml) ~locs:true in 70 + show_result "Nested error" result_with_locs 71 + 72 + (* Test: Array element error locations *) 73 + let test_array_error file = 74 + let yaml = read_file file in 75 + 76 + (* Array codec *) 77 + let codec = 78 + Jsont.Object.map ~kind:"Numbers" (fun nums -> nums) 79 + |> Jsont.Object.mem "values" (Jsont.array Jsont.int) ~enc:(fun n -> n) 80 + |> Jsont.Object.finish 81 + in 82 + 83 + Printf.printf "=== Without locs (default) ===\n"; 84 + let result_no_locs = Yamlt.decode codec (Bytes.Reader.of_string yaml) ~locs:false in 85 + show_result "Array error" result_no_locs; 86 + 87 + Printf.printf "\n=== With locs=true ===\n"; 88 + let result_with_locs = Yamlt.decode codec (Bytes.Reader.of_string yaml) ~locs:true in 89 + show_result "Array error" result_with_locs 90 + 91 + (* Test: Layout preservation - check if we can decode with layout info *) 92 + let test_layout_preservation file = 93 + let yaml = read_file file in 94 + 95 + let codec = 96 + Jsont.Object.map ~kind:"Config" (fun host port -> (host, port)) 97 + |> Jsont.Object.mem "host" Jsont.string ~enc:fst 98 + |> Jsont.Object.mem "port" Jsont.int ~enc:snd 99 + |> Jsont.Object.finish 100 + in 101 + 102 + Printf.printf "=== Without layout (default) ===\n"; 103 + (match Yamlt.decode codec (Bytes.Reader.of_string yaml) ~layout:false with 104 + | Ok (host, port) -> 105 + Printf.printf "Decoded: host=%s, port=%d\n" host port; 106 + Printf.printf "Meta preserved: no\n" 107 + | Error e -> Printf.printf "Error: %s\n" e); 108 + 109 + Printf.printf "\n=== With layout=true ===\n"; 110 + match Yamlt.decode codec (Bytes.Reader.of_string yaml) ~layout:true with 111 + | Ok (host, port) -> 112 + Printf.printf "Decoded: host=%s, port=%d\n" host port; 113 + Printf.printf 114 + "Meta preserved: yes (style info available for round-tripping)\n" 115 + | Error e -> Printf.printf "Error: %s\n" e 116 + 117 + (* Test: Round-trip with layout preservation *) 118 + let test_roundtrip_layout file = 119 + let yaml = read_file file in 120 + 121 + let codec = 122 + Jsont.Object.map ~kind:"Data" (fun items -> items) 123 + |> Jsont.Object.mem "items" (Jsont.array Jsont.string) ~enc:(fun x -> x) 124 + |> Jsont.Object.finish 125 + in 126 + 127 + Printf.printf "=== Original YAML ===\n"; 128 + Printf.printf "%s\n" (String.trim yaml); 129 + 130 + Printf.printf "\n=== Decode without layout, re-encode ===\n"; 131 + (match Yamlt.decode codec (Bytes.Reader.of_string yaml) ~layout:false with 132 + | Ok items -> ( 133 + let b = Buffer.create 256 in 134 + let writer = Bytes.Writer.of_buffer b in 135 + match Yamlt.encode ~format:Yamlt.Block codec items ~eod:true writer with 136 + | Ok () -> Printf.printf "%s" (Buffer.contents b) 137 + | Error e -> Printf.printf "Encode error: %s\n" e) 138 + | Error e -> Printf.printf "Decode error: %s\n" e); 139 + 140 + Printf.printf 141 + "\n=== Decode with layout=true, re-encode with Layout format ===\n"; 142 + match Yamlt.decode codec (Bytes.Reader.of_string yaml) ~layout:true with 143 + | Ok items -> ( 144 + let b = Buffer.create 256 in 145 + let writer = Bytes.Writer.of_buffer b in 146 + match Yamlt.encode ~format:Yamlt.Layout codec items ~eod:true writer with 147 + | Ok () -> Printf.printf "%s" (Buffer.contents b) 148 + | Error e -> Printf.printf "Encode error: %s\n" e) 149 + | Error e -> Printf.printf "Decode error: %s\n" e 150 + 151 + (* Test: File path in error messages *) 152 + let test_file_path () = 153 + let yaml = "name: Alice\nage: not-a-number\n" in 154 + 155 + let codec = 156 + Jsont.Object.map ~kind:"Person" (fun name age -> (name, age)) 157 + |> Jsont.Object.mem "name" Jsont.string ~enc:fst 158 + |> Jsont.Object.mem "age" Jsont.int ~enc:snd 159 + |> Jsont.Object.finish 160 + in 161 + 162 + Printf.printf "=== Without file path ===\n"; 163 + let result1 = Yamlt.decode codec (Bytes.Reader.of_string yaml) ~locs:true in 164 + show_result "Error" result1; 165 + 166 + Printf.printf "\n=== With file path ===\n"; 167 + let result2 = Yamlt.decode codec (Bytes.Reader.of_string yaml) ~locs:true ~file:"test.yml" in 168 + show_result "Error" result2 169 + 170 + (* Test: Missing field error with locs *) 171 + let test_missing_field file = 172 + let yaml = read_file file in 173 + 174 + let codec = 175 + Jsont.Object.map ~kind:"Complete" (fun a b c -> (a, b, c)) 176 + |> Jsont.Object.mem "field_a" Jsont.string ~enc:(fun (a, _, _) -> a) 177 + |> Jsont.Object.mem "field_b" Jsont.int ~enc:(fun (_, b, _) -> b) 178 + |> Jsont.Object.mem "field_c" Jsont.bool ~enc:(fun (_, _, c) -> c) 179 + |> Jsont.Object.finish 180 + in 181 + 182 + Printf.printf "=== Without locs ===\n"; 183 + let result_no_locs = Yamlt.decode codec (Bytes.Reader.of_string yaml) ~locs:false in 184 + show_result "Missing field" result_no_locs; 185 + 186 + Printf.printf "\n=== With locs=true ===\n"; 187 + let result_with_locs = Yamlt.decode codec (Bytes.Reader.of_string yaml) ~locs:true in 188 + show_result "Missing field" result_with_locs 189 + 190 + (* Test: Both locs and layout together *) 191 + let test_combined_options file = 192 + let yaml = read_file file in 193 + 194 + let codec = 195 + Jsont.Object.map ~kind:"Settings" (fun timeout retries -> 196 + (timeout, retries)) 197 + |> Jsont.Object.mem "timeout" Jsont.int ~enc:fst 198 + |> Jsont.Object.mem "retries" Jsont.int ~enc:snd 199 + |> Jsont.Object.finish 200 + in 201 + 202 + Printf.printf "=== locs=false, layout=false (defaults) ===\n"; 203 + (match Yamlt.decode codec (Bytes.Reader.of_string yaml) ~locs:false ~layout:false with 204 + | Ok (timeout, retries) -> 205 + Printf.printf "OK: timeout=%d, retries=%d\n" timeout retries 206 + | Error e -> Printf.printf "Error: %s\n" e); 207 + 208 + Printf.printf "\n=== locs=true, layout=false ===\n"; 209 + (match Yamlt.decode codec (Bytes.Reader.of_string yaml) ~locs:true ~layout:false with 210 + | Ok (timeout, retries) -> 211 + Printf.printf "OK: timeout=%d, retries=%d (with precise locations)\n" 212 + timeout retries 213 + | Error e -> Printf.printf "Error: %s\n" e); 214 + 215 + Printf.printf "\n=== locs=false, layout=true ===\n"; 216 + (match Yamlt.decode codec (Bytes.Reader.of_string yaml) ~locs:false ~layout:true with 217 + | Ok (timeout, retries) -> 218 + Printf.printf "OK: timeout=%d, retries=%d (with layout metadata)\n" 219 + timeout retries 220 + | Error e -> Printf.printf "Error: %s\n" e); 221 + 222 + Printf.printf "\n=== locs=true, layout=true (both enabled) ===\n"; 223 + match Yamlt.decode codec (Bytes.Reader.of_string yaml) ~locs:true ~layout:true with 224 + | Ok (timeout, retries) -> 225 + Printf.printf "OK: timeout=%d, retries=%d (with locations and layout)\n" 226 + timeout retries 227 + | Error e -> Printf.printf "Error: %s\n" e 228 + 229 + let () = 230 + let usage = "Usage: test_locations <command> [args...]" in 231 + 232 + if Stdlib.Array.length Sys.argv < 2 then begin 233 + prerr_endline usage; 234 + exit 1 235 + end; 236 + 237 + match Sys.argv.(1) with 238 + | "error-precision" when Array.length Sys.argv = 3 -> 239 + test_error_precision Sys.argv.(2) 240 + | "nested-error" when Array.length Sys.argv = 3 -> 241 + test_nested_error Sys.argv.(2) 242 + | "array-error" when Array.length Sys.argv = 3 -> 243 + test_array_error Sys.argv.(2) 244 + | "layout" when Array.length Sys.argv = 3 -> 245 + test_layout_preservation Sys.argv.(2) 246 + | "roundtrip" when Array.length Sys.argv = 3 -> 247 + test_roundtrip_layout Sys.argv.(2) 248 + | "file-path" -> test_file_path () 249 + | "missing-field" when Array.length Sys.argv = 3 -> 250 + test_missing_field Sys.argv.(2) 251 + | "combined" when Array.length Sys.argv = 3 -> 252 + test_combined_options Sys.argv.(2) 253 + | _ -> 254 + prerr_endline usage; 255 + prerr_endline "Commands:"; 256 + prerr_endline 257 + " error-precision <file> - Compare error messages with/without locs"; 258 + prerr_endline 259 + " nested-error <file> - Test error locations in nested objects"; 260 + prerr_endline 261 + " array-error <file> - Test error locations in arrays"; 262 + prerr_endline " layout <file> - Test layout preservation"; 263 + prerr_endline 264 + " roundtrip <file> - Test round-tripping with layout"; 265 + prerr_endline 266 + " file-path - Test file path in error messages"; 267 + prerr_endline 268 + " missing-field <file> - Test missing field errors with locs"; 269 + prerr_endline " combined <file> - Test locs and layout together"; 270 + exit 1
+240
vendor/opam/yamlt/tests/bin/test_multidoc.ml
··· 1 + (*--------------------------------------------------------------------------- 2 + Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org>. All rights reserved. 3 + SPDX-License-Identifier: ISC 4 + ---------------------------------------------------------------------------*) 5 + 6 + (** Test multi-document YAML streams with decode_all *) 7 + 8 + open Bytesrw 9 + 10 + (* Helper to read file *) 11 + let read_file path = 12 + let ic = open_in path in 13 + let len = in_channel_length ic in 14 + let s = really_input_string ic len in 15 + close_in ic; 16 + s 17 + 18 + (* Helper to show results *) 19 + let show_result label = function 20 + | Ok v -> Printf.printf "%s: %s\n" label v 21 + | Error e -> Printf.printf "%s: ERROR: %s\n" label e 22 + 23 + (* Test: Simple multi-document stream *) 24 + let test_simple file = 25 + let module M = struct 26 + type person = { name : string; age : int } 27 + 28 + let person_codec = 29 + Jsont.Object.map ~kind:"Person" (fun name age -> { name; age }) 30 + |> Jsont.Object.mem "name" Jsont.string ~enc:(fun p -> p.name) 31 + |> Jsont.Object.mem "age" Jsont.int ~enc:(fun p -> p.age) 32 + |> Jsont.Object.finish 33 + 34 + let show p = Printf.sprintf "%s (age %d)" p.name p.age 35 + end in 36 + let yaml = read_file file in 37 + let reader = Bytes.Reader.of_string yaml in 38 + let seq = Yamlt.decode_all M.person_codec reader in 39 + Printf.printf "Documents:\n"; 40 + seq |> Seq.iteri (fun i result -> 41 + Printf.printf " [%d] " i; 42 + show_result "" (Result.map M.show result) 43 + ) 44 + 45 + (* Test: Count documents *) 46 + let test_count file = 47 + let yaml = read_file file in 48 + let reader = Bytes.Reader.of_string yaml in 49 + let seq = Yamlt.decode_all Jsont.json reader in 50 + let count = Seq.fold_left (fun acc _ -> acc + 1) 0 seq in 51 + Printf.printf "Document count: %d\n" count 52 + 53 + (* Test: Error tracking - show which documents succeed and which fail *) 54 + let test_errors file = 55 + let module M = struct 56 + type person = { name : string; age : int } 57 + 58 + let person_codec = 59 + Jsont.Object.map ~kind:"Person" (fun name age -> { name; age }) 60 + |> Jsont.Object.mem "name" Jsont.string ~enc:(fun p -> p.name) 61 + |> Jsont.Object.mem "age" Jsont.int ~enc:(fun p -> p.age) 62 + |> Jsont.Object.finish 63 + 64 + let show p = Printf.sprintf "%s (age %d)" p.name p.age 65 + end in 66 + let yaml = read_file file in 67 + let reader = Bytes.Reader.of_string yaml in 68 + let seq = Yamlt.decode_all M.person_codec reader in 69 + Printf.printf "Document results:\n"; 70 + seq |> Seq.iteri (fun i result -> 71 + match result with 72 + | Ok p -> Printf.printf " [%d] OK: %s\n" i (M.show p) 73 + | Error e -> Printf.printf " [%d] ERROR: %s\n" i (String.trim e) 74 + ) 75 + 76 + (* Test: Location tracking with locs=true *) 77 + let test_locations file = 78 + let module M = struct 79 + type person = { name : string; age : int } 80 + 81 + let person_codec = 82 + Jsont.Object.map ~kind:"Person" (fun name age -> { name; age }) 83 + |> Jsont.Object.mem "name" Jsont.string ~enc:(fun p -> p.name) 84 + |> Jsont.Object.mem "age" Jsont.int ~enc:(fun p -> p.age) 85 + |> Jsont.Object.finish 86 + end in 87 + let yaml = read_file file in 88 + 89 + Printf.printf "=== Without locs (default) ===\n"; 90 + let reader = Bytes.Reader.of_string yaml in 91 + let seq = Yamlt.decode_all ~locs:false M.person_codec reader in 92 + seq |> Seq.iteri (fun i result -> 93 + match result with 94 + | Ok _ -> Printf.printf " [%d] OK\n" i 95 + | Error e -> Printf.printf " [%d] ERROR:\n%s\n" i (String.trim e) 96 + ); 97 + 98 + Printf.printf "\n=== With locs=true ===\n"; 99 + let reader = Bytes.Reader.of_string yaml in 100 + let seq = Yamlt.decode_all ~locs:true ~file:"test.yml" M.person_codec reader in 101 + seq |> Seq.iteri (fun i result -> 102 + match result with 103 + | Ok _ -> Printf.printf " [%d] OK\n" i 104 + | Error e -> Printf.printf " [%d] ERROR:\n%s\n" i (String.trim e) 105 + ) 106 + 107 + (* Test: Roundtrip to JSON - decode YAML multidoc, encode each to JSON *) 108 + let test_json_roundtrip file = 109 + let yaml = read_file file in 110 + let reader = Bytes.Reader.of_string yaml in 111 + let seq = Yamlt.decode_all Jsont.json reader in 112 + Printf.printf "JSON outputs:\n"; 113 + seq |> Seq.iteri (fun i result -> 114 + match result with 115 + | Ok json_val -> 116 + (match Jsont_bytesrw.encode_string Jsont.json json_val with 117 + | Ok json_str -> Printf.printf " [%d] %s\n" i (String.trim json_str) 118 + | Error e -> Printf.printf " [%d] ENCODE ERROR: %s\n" i e) 119 + | Error e -> Printf.printf " [%d] DECODE ERROR: %s\n" i (String.trim e) 120 + ) 121 + 122 + (* Test: Nested objects in multidoc *) 123 + let test_nested file = 124 + let module M = struct 125 + type address = { street : string; city : string } 126 + type person = { name : string; age : int; address : address } 127 + 128 + let address_codec = 129 + Jsont.Object.map ~kind:"Address" (fun street city -> { street; city }) 130 + |> Jsont.Object.mem "street" Jsont.string ~enc:(fun a -> a.street) 131 + |> Jsont.Object.mem "city" Jsont.string ~enc:(fun a -> a.city) 132 + |> Jsont.Object.finish 133 + 134 + let person_codec = 135 + Jsont.Object.map ~kind:"Person" (fun name age address -> 136 + { name; age; address }) 137 + |> Jsont.Object.mem "name" Jsont.string ~enc:(fun p -> p.name) 138 + |> Jsont.Object.mem "age" Jsont.int ~enc:(fun p -> p.age) 139 + |> Jsont.Object.mem "address" address_codec ~enc:(fun p -> p.address) 140 + |> Jsont.Object.finish 141 + 142 + let show p = 143 + Printf.sprintf "%s (age %d) from %s, %s" p.name p.age p.address.street 144 + p.address.city 145 + end in 146 + let yaml = read_file file in 147 + let reader = Bytes.Reader.of_string yaml in 148 + let seq = Yamlt.decode_all M.person_codec reader in 149 + Printf.printf "Nested documents:\n"; 150 + seq |> Seq.iteri (fun i result -> 151 + Printf.printf " [%d] " i; 152 + show_result "" (Result.map M.show result) 153 + ) 154 + 155 + (* Test: Arrays in multidoc *) 156 + let test_arrays file = 157 + let yaml = read_file file in 158 + let reader = Bytes.Reader.of_string yaml in 159 + let seq = Yamlt.decode_all Jsont.json reader in 160 + Printf.printf "Array documents:\n"; 161 + seq |> Seq.iteri (fun i result -> 162 + match result with 163 + | Ok json_val -> 164 + (match Jsont_bytesrw.encode_string Jsont.json json_val with 165 + | Ok json_str -> Printf.printf " [%d] %s\n" i (String.trim json_str) 166 + | Error e -> Printf.printf " [%d] ERROR: %s\n" i e) 167 + | Error e -> Printf.printf " [%d] ERROR: %s\n" i (String.trim e) 168 + ) 169 + 170 + (* Test: Scalars in multidoc *) 171 + let test_scalars file = 172 + let yaml = read_file file in 173 + let reader = Bytes.Reader.of_string yaml in 174 + let seq = Yamlt.decode_all Jsont.json reader in 175 + Printf.printf "Scalar documents:\n"; 176 + seq |> Seq.iteri (fun i result -> 177 + match result with 178 + | Ok json_val -> 179 + (match Jsont_bytesrw.encode_string Jsont.json json_val with 180 + | Ok json_str -> Printf.printf " [%d] %s\n" i (String.trim json_str) 181 + | Error e -> Printf.printf " [%d] ERROR: %s\n" i e) 182 + | Error e -> Printf.printf " [%d] ERROR: %s\n" i (String.trim e) 183 + ) 184 + 185 + (* Test: Summary stats - count successes vs failures *) 186 + let test_summary file = 187 + let module M = struct 188 + type person = { name : string; age : int } 189 + 190 + let person_codec = 191 + Jsont.Object.map ~kind:"Person" (fun name age -> { name; age }) 192 + |> Jsont.Object.mem "name" Jsont.string ~enc:(fun p -> p.name) 193 + |> Jsont.Object.mem "age" Jsont.int ~enc:(fun p -> p.age) 194 + |> Jsont.Object.finish 195 + end in 196 + let yaml = read_file file in 197 + let reader = Bytes.Reader.of_string yaml in 198 + let seq = Yamlt.decode_all M.person_codec reader in 199 + let success = ref 0 in 200 + let failure = ref 0 in 201 + seq |> Seq.iter (fun result -> 202 + match result with 203 + | Ok _ -> incr success 204 + | Error _ -> incr failure 205 + ); 206 + Printf.printf "Summary: %d documents (%d ok, %d error)\n" 207 + (!success + !failure) !success !failure 208 + 209 + let () = 210 + let usage = "Usage: test_multidoc <command> <file>" in 211 + if Array.length Sys.argv < 3 then begin 212 + prerr_endline usage; 213 + exit 1 214 + end; 215 + 216 + let test = Sys.argv.(1) in 217 + let file = Sys.argv.(2) in 218 + match test with 219 + | "simple" -> test_simple file 220 + | "count" -> test_count file 221 + | "errors" -> test_errors file 222 + | "locations" -> test_locations file 223 + | "json" -> test_json_roundtrip file 224 + | "nested" -> test_nested file 225 + | "arrays" -> test_arrays file 226 + | "scalars" -> test_scalars file 227 + | "summary" -> test_summary file 228 + | _ -> 229 + prerr_endline usage; 230 + prerr_endline "Commands:"; 231 + prerr_endline " simple <file> - Decode person documents"; 232 + prerr_endline " count <file> - Count documents"; 233 + prerr_endline " errors <file> - Show success/error for each document"; 234 + prerr_endline " locations <file> - Test location tracking with locs=true"; 235 + prerr_endline " json <file> - Roundtrip to JSON"; 236 + prerr_endline " nested <file> - Decode nested objects"; 237 + prerr_endline " arrays <file> - Decode arrays"; 238 + prerr_endline " scalars <file> - Decode scalars"; 239 + prerr_endline " summary <file> - Show success/failure summary"; 240 + exit 1
+89
vendor/opam/yamlt/tests/bin/test_null_collections.ml
··· 1 + open Bytesrw 2 + 3 + let () = 4 + Printf.printf "=== Test 1: Explicit null as empty array ===\n"; 5 + let yaml1 = "values: null" in 6 + let codec1 = 7 + let open Jsont in 8 + Object.map ~kind:"Test" (fun v -> v) 9 + |> Object.mem "values" (list int) ~dec_absent:[] ~enc:(fun v -> v) 10 + |> Object.finish 11 + in 12 + (match Yamlt.decode codec1 (Bytes.Reader.of_string yaml1) with 13 + | Ok v -> 14 + Printf.printf "Result: [%s]\n" 15 + (String.concat "; " (List.map string_of_int v)) 16 + | Error e -> Printf.printf "Error: %s\n" e); 17 + 18 + Printf.printf "\n=== Test 2: Tilde as empty array ===\n"; 19 + let yaml2 = "values: ~" in 20 + (match Yamlt.decode codec1 (Bytes.Reader.of_string yaml2) with 21 + | Ok v -> 22 + Printf.printf "Result: [%s]\n" 23 + (String.concat "; " (List.map string_of_int v)) 24 + | Error e -> Printf.printf "Error: %s\n" e); 25 + 26 + Printf.printf "\n=== Test 3: Empty array syntax ===\n"; 27 + let yaml3 = "values: []" in 28 + (match Yamlt.decode codec1 (Bytes.Reader.of_string yaml3) with 29 + | Ok v -> 30 + Printf.printf "Result: [%s]\n" 31 + (String.concat "; " (List.map string_of_int v)) 32 + | Error e -> Printf.printf "Error: %s\n" e); 33 + 34 + Printf.printf "\n=== Test 4: Array with values ===\n"; 35 + let yaml4 = "values: [1, 2, 3]" in 36 + (match Yamlt.decode codec1 (Bytes.Reader.of_string yaml4) with 37 + | Ok v -> 38 + Printf.printf "Result: [%s]\n" 39 + (String.concat "; " (List.map string_of_int v)) 40 + | Error e -> Printf.printf "Error: %s\n" e); 41 + 42 + Printf.printf "\n=== Test 5: Explicit null as empty object ===\n"; 43 + let yaml5 = "config: null" in 44 + let codec2 = 45 + let open Jsont in 46 + let config_codec = 47 + Object.map ~kind:"Config" (fun timeout retries -> (timeout, retries)) 48 + |> Object.mem "timeout" int ~dec_absent:30 ~enc:fst 49 + |> Object.mem "retries" int ~dec_absent:3 ~enc:snd 50 + |> Object.finish 51 + in 52 + Object.map ~kind:"Test" (fun c -> c) 53 + |> Object.mem "config" config_codec ~dec_absent:(30, 3) ~enc:(fun c -> c) 54 + |> Object.finish 55 + in 56 + (match Yamlt.decode codec2 (Bytes.Reader.of_string yaml5) with 57 + | Ok (timeout, retries) -> 58 + Printf.printf "Result: {timeout=%d; retries=%d}\n" timeout retries 59 + | Error e -> Printf.printf "Error: %s\n" e); 60 + 61 + Printf.printf "\n=== Test 6: Empty object syntax ===\n"; 62 + let yaml6 = "config: {}" in 63 + (match Yamlt.decode codec2 (Bytes.Reader.of_string yaml6) with 64 + | Ok (timeout, retries) -> 65 + Printf.printf "Result: {timeout=%d; retries=%d}\n" timeout retries 66 + | Error e -> Printf.printf "Error: %s\n" e); 67 + 68 + Printf.printf "\n=== Test 7: Object with values ===\n"; 69 + let yaml7 = "config:\n timeout: 60\n retries: 5" in 70 + (match Yamlt.decode codec2 (Bytes.Reader.of_string yaml7) with 71 + | Ok (timeout, retries) -> 72 + Printf.printf "Result: {timeout=%d; retries=%d}\n" timeout retries 73 + | Error e -> Printf.printf "Error: %s\n" e); 74 + 75 + Printf.printf "\n=== Test 8: Nested null arrays ===\n"; 76 + let yaml8 = "name: test\nitems: null\ntags: ~" in 77 + let codec3 = 78 + let open Jsont in 79 + Object.map ~kind:"Nested" (fun name items tags -> (name, items, tags)) 80 + |> Object.mem "name" string ~enc:(fun (n, _, _) -> n) 81 + |> Object.mem "items" (list int) ~dec_absent:[] ~enc:(fun (_, i, _) -> i) 82 + |> Object.mem "tags" (list string) ~dec_absent:[] ~enc:(fun (_, _, t) -> t) 83 + |> Object.finish 84 + in 85 + match Yamlt.decode codec3 (Bytes.Reader.of_string yaml8) with 86 + | Ok (name, items, tags) -> 87 + Printf.printf "Result: {name=%s; items_count=%d; tags_count=%d}\n" 88 + name (List.length items) (List.length tags) 89 + | Error e -> Printf.printf "Error: %s\n" e
+39
vendor/opam/yamlt/tests/bin/test_null_complete.ml
··· 1 + open Bytesrw 2 + 3 + let () = 4 + Printf.printf "=== Test 1: Jsont.option with YAML null ===\n"; 5 + let yaml1 = "value: null" in 6 + let codec1 = 7 + let open Jsont in 8 + Object.map ~kind:"Test" (fun v -> v) 9 + |> Object.mem "value" (option string) ~enc:(fun v -> v) 10 + |> Object.finish 11 + in 12 + (match Yamlt.decode codec1 (Bytes.Reader.of_string yaml1) with 13 + | Ok v -> 14 + Printf.printf "Result: %s\n" 15 + (match v with None -> "None" | Some s -> "Some(" ^ s ^ ")") 16 + | Error e -> Printf.printf "Error: %s\n" e); 17 + 18 + Printf.printf "\n=== Test 2: Jsont.option with YAML string ===\n"; 19 + (match Yamlt.decode codec1 (Bytes.Reader.of_string "value: hello") with 20 + | Ok v -> 21 + Printf.printf "Result: %s\n" 22 + (match v with None -> "None" | Some s -> "Some(" ^ s ^ ")") 23 + | Error e -> Printf.printf "Error: %s\n" e); 24 + 25 + Printf.printf "\n=== Test 3: Jsont.string with YAML null (should error) ===\n"; 26 + let codec2 = 27 + let open Jsont in 28 + Object.map ~kind:"Test" (fun v -> v) 29 + |> Object.mem "value" string ~enc:(fun v -> v) 30 + |> Object.finish 31 + in 32 + (match Yamlt.decode codec2 (Bytes.Reader.of_string "value: null") with 33 + | Ok v -> Printf.printf "Result: %s\n" v 34 + | Error e -> Printf.printf "Error (expected): %s\n" e); 35 + 36 + Printf.printf "\n=== Test 4: Jsont.string with YAML string ===\n"; 37 + match Yamlt.decode codec2 (Bytes.Reader.of_string "value: hello") with 38 + | Ok v -> Printf.printf "Result: %s\n" v 39 + | Error e -> Printf.printf "Error: %s\n" e
+31
vendor/opam/yamlt/tests/bin/test_null_fix.ml
··· 1 + open Bytesrw 2 + 3 + let () = 4 + let module M = struct 5 + type data = { value : string option } 6 + 7 + let data_codec = 8 + Jsont.Object.map ~kind:"Data" (fun value -> { value }) 9 + |> Jsont.Object.mem "value" (Jsont.option Jsont.string) ~enc:(fun d -> 10 + d.value) 11 + |> Jsont.Object.finish 12 + end in 13 + let yaml_null = "value: null" in 14 + 15 + Printf.printf "Testing YAML null handling with Jsont.option Jsont.string:\n\n"; 16 + 17 + match Yamlt.decode M.data_codec (Bytes.Reader.of_string yaml_null) with 18 + | Ok data -> ( 19 + match data.M.value with 20 + | None -> Printf.printf "YAML: value=None (CORRECT)\n" 21 + | Some s -> Printf.printf "YAML: value=Some(%S) (BUG!)\n" s) 22 + | Error e -> ( 23 + Printf.printf "YAML ERROR: %s\n" e; 24 + 25 + let json_null = "{\"value\": null}" in 26 + match Jsont_bytesrw.decode_string M.data_codec json_null with 27 + | Ok data -> ( 28 + match data.M.value with 29 + | None -> Printf.printf "JSON: value=None (CORRECT)\n" 30 + | Some s -> Printf.printf "JSON: value=Some(%S) (BUG!)\n" s) 31 + | Error e -> Printf.printf "JSON ERROR: %s\n" e)
+297
vendor/opam/yamlt/tests/bin/test_objects.ml
··· 1 + (*--------------------------------------------------------------------------- 2 + Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org>. All rights reserved. 3 + SPDX-License-Identifier: ISC 4 + ---------------------------------------------------------------------------*) 5 + 6 + (** Test object codec functionality with Yamlt *) 7 + 8 + open Bytesrw 9 + 10 + (* Helper to read file *) 11 + let read_file path = 12 + let ic = open_in path in 13 + let len = in_channel_length ic in 14 + let s = really_input_string ic len in 15 + close_in ic; 16 + s 17 + 18 + (* Helper to show results *) 19 + let show_result label = function 20 + | Ok v -> Printf.printf "%s: %s\n" label v 21 + | Error e -> Printf.printf "%s: ERROR: %s\n" label e 22 + 23 + let show_result_both label json_result yaml_result = 24 + Printf.printf "JSON: "; 25 + show_result label json_result; 26 + Printf.printf "YAML: "; 27 + show_result label yaml_result 28 + 29 + (* Test: Simple object with required fields *) 30 + let test_simple_object file = 31 + let module M = struct 32 + type person = { name : string; age : int } 33 + 34 + let person_codec = 35 + Jsont.Object.map ~kind:"Person" (fun name age -> { name; age }) 36 + |> Jsont.Object.mem "name" Jsont.string ~enc:(fun p -> p.name) 37 + |> Jsont.Object.mem "age" Jsont.int ~enc:(fun p -> p.age) 38 + |> Jsont.Object.finish 39 + 40 + let show p = Printf.sprintf "{name=%S; age=%d}" p.name p.age 41 + end in 42 + let yaml = read_file file in 43 + let json = read_file (file ^ ".json") in 44 + let json_result = Jsont_bytesrw.decode_string M.person_codec json in 45 + let yaml_result = Yamlt.decode M.person_codec (Bytes.Reader.of_string yaml) in 46 + 47 + show_result_both "person" 48 + (Result.map M.show json_result) 49 + (Result.map M.show yaml_result) 50 + 51 + (* Test: Object with optional fields *) 52 + let test_optional_fields file = 53 + let module M = struct 54 + type config = { host : string; port : int option; debug : bool option } 55 + 56 + let config_codec = 57 + Jsont.Object.map ~kind:"Config" (fun host port debug -> 58 + { host; port; debug }) 59 + |> Jsont.Object.mem "host" Jsont.string ~enc:(fun c -> c.host) 60 + |> Jsont.Object.opt_mem "port" Jsont.int ~enc:(fun c -> c.port) 61 + |> Jsont.Object.opt_mem "debug" Jsont.bool ~enc:(fun c -> c.debug) 62 + |> Jsont.Object.finish 63 + 64 + let show c = 65 + Printf.sprintf "{host=%S; port=%s; debug=%s}" c.host 66 + (match c.port with 67 + | None -> "None" 68 + | Some p -> Printf.sprintf "Some %d" p) 69 + (match c.debug with 70 + | None -> "None" 71 + | Some b -> Printf.sprintf "Some %b" b) 72 + end in 73 + let yaml = read_file file in 74 + let json = read_file (file ^ ".json") in 75 + let json_result = Jsont_bytesrw.decode_string M.config_codec json in 76 + let yaml_result = Yamlt.decode M.config_codec (Bytes.Reader.of_string yaml) in 77 + 78 + show_result_both "config" 79 + (Result.map M.show json_result) 80 + (Result.map M.show yaml_result) 81 + 82 + (* Test: Object with default values *) 83 + let test_default_values file = 84 + let module M = struct 85 + type settings = { timeout : int; retries : int; verbose : bool } 86 + 87 + let settings_codec = 88 + Jsont.Object.map ~kind:"Settings" (fun timeout retries verbose -> 89 + { timeout; retries; verbose }) 90 + |> Jsont.Object.mem "timeout" Jsont.int 91 + ~enc:(fun s -> s.timeout) 92 + ~dec_absent:30 93 + |> Jsont.Object.mem "retries" Jsont.int 94 + ~enc:(fun s -> s.retries) 95 + ~dec_absent:3 96 + |> Jsont.Object.mem "verbose" Jsont.bool 97 + ~enc:(fun s -> s.verbose) 98 + ~dec_absent:false 99 + |> Jsont.Object.finish 100 + 101 + let show s = 102 + Printf.sprintf "{timeout=%d; retries=%d; verbose=%b}" s.timeout s.retries 103 + s.verbose 104 + end in 105 + let yaml = read_file file in 106 + let json = read_file (file ^ ".json") in 107 + let json_result = Jsont_bytesrw.decode_string M.settings_codec json in 108 + let yaml_result = Yamlt.decode M.settings_codec (Bytes.Reader.of_string yaml) in 109 + 110 + show_result_both "settings" 111 + (Result.map M.show json_result) 112 + (Result.map M.show yaml_result) 113 + 114 + (* Test: Nested objects *) 115 + let test_nested_objects file = 116 + let module M = struct 117 + type address = { street : string; city : string; zip : string } 118 + type employee = { name : string; address : address } 119 + 120 + let address_codec = 121 + Jsont.Object.map ~kind:"Address" (fun street city zip -> 122 + { street; city; zip }) 123 + |> Jsont.Object.mem "street" Jsont.string ~enc:(fun a -> a.street) 124 + |> Jsont.Object.mem "city" Jsont.string ~enc:(fun a -> a.city) 125 + |> Jsont.Object.mem "zip" Jsont.string ~enc:(fun a -> a.zip) 126 + |> Jsont.Object.finish 127 + 128 + let employee_codec = 129 + Jsont.Object.map ~kind:"Employee" (fun name address -> { name; address }) 130 + |> Jsont.Object.mem "name" Jsont.string ~enc:(fun e -> e.name) 131 + |> Jsont.Object.mem "address" address_codec ~enc:(fun e -> e.address) 132 + |> Jsont.Object.finish 133 + 134 + let show e = 135 + Printf.sprintf "{name=%S; address={street=%S; city=%S; zip=%S}}" e.name 136 + e.address.street e.address.city e.address.zip 137 + end in 138 + let yaml = read_file file in 139 + let json = read_file (file ^ ".json") in 140 + let json_result = Jsont_bytesrw.decode_string M.employee_codec json in 141 + let yaml_result = Yamlt.decode M.employee_codec (Bytes.Reader.of_string yaml) in 142 + 143 + show_result_both "employee" 144 + (Result.map M.show json_result) 145 + (Result.map M.show yaml_result) 146 + 147 + (* Test: Unknown member handling - error *) 148 + let test_unknown_members_error file = 149 + let module M = struct 150 + type strict = { name : string } 151 + 152 + let strict_codec = 153 + Jsont.Object.map ~kind:"Strict" (fun name -> { name }) 154 + |> Jsont.Object.mem "name" Jsont.string ~enc:(fun s -> s.name) 155 + |> Jsont.Object.finish 156 + end in 157 + let yaml = read_file file in 158 + let result = Yamlt.decode M.strict_codec (Bytes.Reader.of_string yaml) in 159 + match result with 160 + | Ok _ -> Printf.printf "Unexpected success\n" 161 + | Error e -> Printf.printf "Expected error: %s\n" e 162 + 163 + (* Test: Unknown member handling - keep *) 164 + let test_unknown_members_keep file = 165 + let module M = struct 166 + type flexible = { name : string; extra : Jsont.json } 167 + 168 + let flexible_codec = 169 + Jsont.Object.map ~kind:"Flexible" (fun name extra -> { name; extra }) 170 + |> Jsont.Object.mem "name" Jsont.string ~enc:(fun f -> f.name) 171 + |> Jsont.Object.keep_unknown Jsont.json_mems ~enc:(fun f -> f.extra) 172 + |> Jsont.Object.finish 173 + 174 + let show f = Printf.sprintf "{name=%S; has_extra=true}" f.name 175 + end in 176 + let yaml = read_file file in 177 + let json = read_file (file ^ ".json") in 178 + let json_result = Jsont_bytesrw.decode_string M.flexible_codec json in 179 + let yaml_result = Yamlt.decode M.flexible_codec (Bytes.Reader.of_string yaml) in 180 + 181 + show_result_both "flexible" 182 + (Result.map M.show json_result) 183 + (Result.map M.show yaml_result) 184 + 185 + (* Test: Object cases (discriminated unions) - simplified version *) 186 + let test_object_cases file = 187 + let module M = struct 188 + type circle = { type_ : string; radius : float } 189 + 190 + let circle_codec = 191 + Jsont.Object.map ~kind:"Circle" (fun type_ radius -> { type_; radius }) 192 + |> Jsont.Object.mem "type" Jsont.string ~enc:(fun c -> c.type_) 193 + |> Jsont.Object.mem "radius" Jsont.number ~enc:(fun c -> c.radius) 194 + |> Jsont.Object.finish 195 + 196 + let show c = Printf.sprintf "Circle{radius=%.2f}" c.radius 197 + end in 198 + let yaml = read_file file in 199 + let json = read_file (file ^ ".json") in 200 + let json_result = Jsont_bytesrw.decode_string M.circle_codec json in 201 + let yaml_result = Yamlt.decode M.circle_codec (Bytes.Reader.of_string yaml) in 202 + 203 + show_result_both "shape" 204 + (Result.map M.show json_result) 205 + (Result.map M.show yaml_result) 206 + 207 + (* Test: Missing required field error *) 208 + let test_missing_required file = 209 + let module M = struct 210 + type required = { name : string; age : int } 211 + 212 + let required_codec = 213 + Jsont.Object.map ~kind:"Required" (fun name age -> { name; age }) 214 + |> Jsont.Object.mem "name" Jsont.string ~enc:(fun r -> r.name) 215 + |> Jsont.Object.mem "age" Jsont.int ~enc:(fun r -> r.age) 216 + |> Jsont.Object.finish 217 + end in 218 + let yaml = read_file file in 219 + let result = Yamlt.decode M.required_codec (Bytes.Reader.of_string yaml) in 220 + match result with 221 + | Ok _ -> Printf.printf "Unexpected success\n" 222 + | Error e -> Printf.printf "Expected error: %s\n" e 223 + 224 + (* Test: Encoding objects to different formats *) 225 + let test_encode_object () = 226 + let module M = struct 227 + type person = { name : string; age : int; active : bool } 228 + 229 + let person_codec = 230 + Jsont.Object.map ~kind:"Person" (fun name age active -> 231 + { name; age; active }) 232 + |> Jsont.Object.mem "name" Jsont.string ~enc:(fun p -> p.name) 233 + |> Jsont.Object.mem "age" Jsont.int ~enc:(fun p -> p.age) 234 + |> Jsont.Object.mem "active" Jsont.bool ~enc:(fun p -> p.active) 235 + |> Jsont.Object.finish 236 + end in 237 + let person = M.{ name = "Alice"; age = 30; active = true } in 238 + 239 + (* Encode to JSON *) 240 + (match Jsont_bytesrw.encode_string M.person_codec person with 241 + | Ok s -> Printf.printf "JSON: %s\n" (String.trim s) 242 + | Error e -> Printf.printf "JSON ERROR: %s\n" e); 243 + 244 + (* Encode to YAML Block *) 245 + (let b = Buffer.create 256 in 246 + let writer = Bytes.Writer.of_buffer b in 247 + match Yamlt.encode ~format:Yamlt.Block M.person_codec person ~eod:true writer with 248 + | Ok () -> Printf.printf "YAML Block:\n%s" (Buffer.contents b) 249 + | Error e -> Printf.printf "YAML Block ERROR: %s\n" e); 250 + 251 + (* Encode to YAML Flow *) 252 + let b = Buffer.create 256 in 253 + let writer = Bytes.Writer.of_buffer b in 254 + match Yamlt.encode ~format:Yamlt.Flow M.person_codec person ~eod:true writer with 255 + | Ok () -> Printf.printf "YAML Flow: %s" (Buffer.contents b) 256 + | Error e -> Printf.printf "YAML Flow ERROR: %s\n" e 257 + 258 + let () = 259 + let usage = "Usage: test_objects <command> [args...]" in 260 + 261 + if Stdlib.Array.length Sys.argv < 2 then begin 262 + prerr_endline usage; 263 + exit 1 264 + end; 265 + 266 + match Sys.argv.(1) with 267 + | "simple" when Stdlib.Array.length Sys.argv = 3 -> 268 + test_simple_object Sys.argv.(2) 269 + | "optional" when Stdlib.Array.length Sys.argv = 3 -> 270 + test_optional_fields Sys.argv.(2) 271 + | "defaults" when Stdlib.Array.length Sys.argv = 3 -> 272 + test_default_values Sys.argv.(2) 273 + | "nested" when Stdlib.Array.length Sys.argv = 3 -> 274 + test_nested_objects Sys.argv.(2) 275 + | "unknown-error" when Stdlib.Array.length Sys.argv = 3 -> 276 + test_unknown_members_error Sys.argv.(2) 277 + | "unknown-keep" when Stdlib.Array.length Sys.argv = 3 -> 278 + test_unknown_members_keep Sys.argv.(2) 279 + | "cases" when Stdlib.Array.length Sys.argv = 3 -> 280 + test_object_cases Sys.argv.(2) 281 + | "missing-required" when Stdlib.Array.length Sys.argv = 3 -> 282 + test_missing_required Sys.argv.(2) 283 + | "encode" when Stdlib.Array.length Sys.argv = 2 -> test_encode_object () 284 + | _ -> 285 + prerr_endline usage; 286 + prerr_endline "Commands:"; 287 + prerr_endline " simple <file> - Test simple object"; 288 + prerr_endline " optional <file> - Test optional fields"; 289 + prerr_endline " defaults <file> - Test default values"; 290 + prerr_endline " nested <file> - Test nested objects"; 291 + prerr_endline " unknown-error <file> - Test unknown member error"; 292 + prerr_endline " unknown-keep <file> - Test keeping unknown members"; 293 + prerr_endline " cases <file> - Test object cases (unions)"; 294 + prerr_endline 295 + " missing-required <file> - Test missing required field error"; 296 + prerr_endline " encode - Test encoding objects"; 297 + exit 1
+19
vendor/opam/yamlt/tests/bin/test_opt_array.ml
··· 1 + open Bytesrw 2 + 3 + let () = 4 + let codec = 5 + Jsont.Object.map ~kind:"Test" (fun arr -> arr) 6 + |> Jsont.Object.opt_mem "values" (Jsont.array Jsont.string) ~enc:(fun arr -> 7 + arr) 8 + |> Jsont.Object.finish 9 + in 10 + 11 + let yaml = "values: [a, b, c]" in 12 + 13 + Printf.printf "Testing optional array field:\n"; 14 + match Yamlt.decode codec (Bytes.Reader.of_string yaml) with 15 + | Ok arr -> ( 16 + match arr with 17 + | None -> Printf.printf "Result: None\n" 18 + | Some a -> Printf.printf "Result: Some([%d items])\n" (Array.length a)) 19 + | Error e -> Printf.printf "Error: %s\n" e
+267
vendor/opam/yamlt/tests/bin/test_roundtrip.ml
··· 1 + (*--------------------------------------------------------------------------- 2 + Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org>. All rights reserved. 3 + SPDX-License-Identifier: ISC 4 + ---------------------------------------------------------------------------*) 5 + 6 + (** Test roundtrip encoding/decoding with Yamlt *) 7 + 8 + open Bytesrw 9 + 10 + (* Test: Roundtrip scalars *) 11 + let test_scalar_roundtrip () = 12 + let module M = struct 13 + type data = { s : string; n : float; b : bool; nul : unit } 14 + 15 + let data_codec = 16 + Jsont.Object.map ~kind:"Data" (fun s n b nul -> { s; n; b; nul }) 17 + |> Jsont.Object.mem "s" Jsont.string ~enc:(fun d -> d.s) 18 + |> Jsont.Object.mem "n" Jsont.number ~enc:(fun d -> d.n) 19 + |> Jsont.Object.mem "b" Jsont.bool ~enc:(fun d -> d.b) 20 + |> Jsont.Object.mem "nul" (Jsont.null ()) ~enc:(fun d -> d.nul) 21 + |> Jsont.Object.finish 22 + 23 + let equal d1 d2 = 24 + d1.s = d2.s && d1.n = d2.n && d1.b = d2.b && d1.nul = d2.nul 25 + end in 26 + let original = { M.s = "hello"; n = 42.5; b = true; nul = () } in 27 + 28 + (* JSON roundtrip *) 29 + let json_encoded = Jsont_bytesrw.encode_string M.data_codec original in 30 + let json_decoded = 31 + Result.bind json_encoded (Jsont_bytesrw.decode_string M.data_codec) 32 + in 33 + (match json_decoded with 34 + | Ok decoded when M.equal original decoded -> 35 + Printf.printf "JSON roundtrip: PASS\n" 36 + | Ok _ -> Printf.printf "JSON roundtrip: FAIL (data mismatch)\n" 37 + | Error e -> Printf.printf "JSON roundtrip: FAIL (%s)\n" e); 38 + 39 + (* YAML Block roundtrip *) 40 + let yaml_block_encoded = 41 + let b = Buffer.create 256 in 42 + let writer = Bytes.Writer.of_buffer b in 43 + match Yamlt.encode ~format:Yamlt.Block M.data_codec original ~eod:true writer with 44 + | Ok () -> Ok (Buffer.contents b) 45 + | Error e -> Error e 46 + in 47 + let yaml_block_decoded = 48 + Result.bind yaml_block_encoded (fun yaml -> 49 + Yamlt.decode M.data_codec (Bytes.Reader.of_string yaml)) 50 + in 51 + (match yaml_block_decoded with 52 + | Ok decoded when M.equal original decoded -> 53 + Printf.printf "YAML Block roundtrip: PASS\n" 54 + | Ok _ -> Printf.printf "YAML Block roundtrip: FAIL (data mismatch)\n" 55 + | Error e -> Printf.printf "YAML Block roundtrip: FAIL (%s)\n" e); 56 + 57 + (* YAML Flow roundtrip *) 58 + let yaml_flow_encoded = 59 + let b = Buffer.create 256 in 60 + let writer = Bytes.Writer.of_buffer b in 61 + match Yamlt.encode ~format:Yamlt.Flow M.data_codec original ~eod:true writer with 62 + | Ok () -> Ok (Buffer.contents b) 63 + | Error e -> Error e 64 + in 65 + let yaml_flow_decoded = 66 + Result.bind yaml_flow_encoded (fun yaml -> 67 + Yamlt.decode M.data_codec (Bytes.Reader.of_string yaml)) 68 + in 69 + match yaml_flow_decoded with 70 + | Ok decoded when M.equal original decoded -> 71 + Printf.printf "YAML Flow roundtrip: PASS\n" 72 + | Ok _ -> Printf.printf "YAML Flow roundtrip: FAIL (data mismatch)\n" 73 + | Error e -> Printf.printf "YAML Flow roundtrip: FAIL (%s)\n" e 74 + 75 + (* Test: Roundtrip arrays *) 76 + let test_array_roundtrip () = 77 + let module M = struct 78 + type data = { items : int array; nested : float array array } 79 + 80 + let data_codec = 81 + Jsont.Object.map ~kind:"Data" (fun items nested -> { items; nested }) 82 + |> Jsont.Object.mem "items" (Jsont.array Jsont.int) ~enc:(fun d -> 83 + d.items) 84 + |> Jsont.Object.mem "nested" 85 + (Jsont.array (Jsont.array Jsont.number)) 86 + ~enc:(fun d -> d.nested) 87 + |> Jsont.Object.finish 88 + 89 + let equal d1 d2 = d1.items = d2.items && d1.nested = d2.nested 90 + end in 91 + let original = 92 + { 93 + M.items = [| 1; 2; 3; 4; 5 |]; 94 + nested = [| [| 1.0; 2.0 |]; [| 3.0; 4.0 |] |]; 95 + } 96 + in 97 + 98 + (* JSON roundtrip *) 99 + let json_result = 100 + Result.bind 101 + (Jsont_bytesrw.encode_string M.data_codec original) 102 + (Jsont_bytesrw.decode_string M.data_codec) 103 + in 104 + (match json_result with 105 + | Ok decoded when M.equal original decoded -> 106 + Printf.printf "JSON array roundtrip: PASS\n" 107 + | Ok _ -> Printf.printf "JSON array roundtrip: FAIL (data mismatch)\n" 108 + | Error e -> Printf.printf "JSON array roundtrip: FAIL (%s)\n" e); 109 + 110 + (* YAML roundtrip *) 111 + let yaml_result = 112 + let b = Buffer.create 256 in 113 + let writer = Bytes.Writer.of_buffer b in 114 + match Yamlt.encode M.data_codec original ~eod:true writer with 115 + | Ok () -> 116 + let yaml = Buffer.contents b in 117 + Yamlt.decode M.data_codec (Bytes.Reader.of_string yaml) 118 + | Error e -> Error e 119 + in 120 + match yaml_result with 121 + | Ok decoded when M.equal original decoded -> 122 + Printf.printf "YAML array roundtrip: PASS\n" 123 + | Ok _ -> Printf.printf "YAML array roundtrip: FAIL (data mismatch)\n" 124 + | Error e -> Printf.printf "YAML array roundtrip: FAIL (%s)\n" e 125 + 126 + (* Test: Roundtrip objects *) 127 + let test_object_roundtrip () = 128 + let module M = struct 129 + type person = { p_name : string; age : int; active : bool } 130 + type company = { c_name : string; employees : person array } 131 + 132 + let person_codec = 133 + Jsont.Object.map ~kind:"Person" (fun p_name age active -> 134 + { p_name; age; active }) 135 + |> Jsont.Object.mem "name" Jsont.string ~enc:(fun p -> p.p_name) 136 + |> Jsont.Object.mem "age" Jsont.int ~enc:(fun p -> p.age) 137 + |> Jsont.Object.mem "active" Jsont.bool ~enc:(fun p -> p.active) 138 + |> Jsont.Object.finish 139 + 140 + let company_codec = 141 + Jsont.Object.map ~kind:"Company" (fun c_name employees -> 142 + { c_name; employees }) 143 + |> Jsont.Object.mem "name" Jsont.string ~enc:(fun c -> c.c_name) 144 + |> Jsont.Object.mem "employees" (Jsont.array person_codec) ~enc:(fun c -> 145 + c.employees) 146 + |> Jsont.Object.finish 147 + 148 + let person_equal p1 p2 = 149 + p1.p_name = p2.p_name && p1.age = p2.age && p1.active = p2.active 150 + 151 + let equal c1 c2 = 152 + c1.c_name = c2.c_name 153 + && Stdlib.Array.length c1.employees = Stdlib.Array.length c2.employees 154 + && Stdlib.Array.for_all2 person_equal c1.employees c2.employees 155 + end in 156 + let original = 157 + { 158 + M.c_name = "Acme Corp"; 159 + employees = 160 + [| 161 + { p_name = "Alice"; age = 30; active = true }; 162 + { p_name = "Bob"; age = 25; active = false }; 163 + |]; 164 + } 165 + in 166 + 167 + (* JSON roundtrip *) 168 + let json_result = 169 + Result.bind 170 + (Jsont_bytesrw.encode_string M.company_codec original) 171 + (Jsont_bytesrw.decode_string M.company_codec) 172 + in 173 + (match json_result with 174 + | Ok decoded when M.equal original decoded -> 175 + Printf.printf "JSON object roundtrip: PASS\n" 176 + | Ok _ -> Printf.printf "JSON object roundtrip: FAIL (data mismatch)\n" 177 + | Error e -> Printf.printf "JSON object roundtrip: FAIL (%s)\n" e); 178 + 179 + (* YAML roundtrip *) 180 + let yaml_result = 181 + let b = Buffer.create 256 in 182 + let writer = Bytes.Writer.of_buffer b in 183 + match Yamlt.encode M.company_codec original ~eod:true writer with 184 + | Ok () -> 185 + let yaml = Buffer.contents b in 186 + Yamlt.decode M.company_codec (Bytes.Reader.of_string yaml) 187 + | Error e -> Error e 188 + in 189 + match yaml_result with 190 + | Ok decoded when M.equal original decoded -> 191 + Printf.printf "YAML object roundtrip: PASS\n" 192 + | Ok _ -> Printf.printf "YAML object roundtrip: FAIL (data mismatch)\n" 193 + | Error e -> Printf.printf "YAML object roundtrip: FAIL (%s)\n" e 194 + 195 + (* Test: Roundtrip with optionals *) 196 + let test_optional_roundtrip () = 197 + let module M = struct 198 + type data = { 199 + required : string; 200 + optional : int option; 201 + nullable : string option; 202 + } 203 + 204 + let data_codec = 205 + Jsont.Object.map ~kind:"Data" (fun required optional nullable -> 206 + { required; optional; nullable }) 207 + |> Jsont.Object.mem "required" Jsont.string ~enc:(fun d -> d.required) 208 + |> Jsont.Object.opt_mem "optional" Jsont.int ~enc:(fun d -> d.optional) 209 + |> Jsont.Object.mem "nullable" (Jsont.some Jsont.string) ~enc:(fun d -> 210 + d.nullable) 211 + |> Jsont.Object.finish 212 + 213 + let equal d1 d2 = 214 + d1.required = d2.required && d1.optional = d2.optional 215 + && d1.nullable = d2.nullable 216 + end in 217 + let original = { M.required = "test"; optional = Some 42; nullable = None } in 218 + 219 + (* JSON roundtrip *) 220 + let json_result = 221 + Result.bind 222 + (Jsont_bytesrw.encode_string M.data_codec original) 223 + (Jsont_bytesrw.decode_string M.data_codec) 224 + in 225 + (match json_result with 226 + | Ok decoded when M.equal original decoded -> 227 + Printf.printf "JSON optional roundtrip: PASS\n" 228 + | Ok _ -> Printf.printf "JSON optional roundtrip: FAIL (data mismatch)\n" 229 + | Error e -> Printf.printf "JSON optional roundtrip: FAIL (%s)\n" e); 230 + 231 + (* YAML roundtrip *) 232 + let yaml_result = 233 + let b = Buffer.create 256 in 234 + let writer = Bytes.Writer.of_buffer b in 235 + match Yamlt.encode M.data_codec original ~eod:true writer with 236 + | Ok () -> 237 + let yaml = Buffer.contents b in 238 + Yamlt.decode M.data_codec (Bytes.Reader.of_string yaml) 239 + | Error e -> Error e 240 + in 241 + match yaml_result with 242 + | Ok decoded when M.equal original decoded -> 243 + Printf.printf "YAML optional roundtrip: PASS\n" 244 + | Ok _ -> Printf.printf "YAML optional roundtrip: FAIL (data mismatch)\n" 245 + | Error e -> Printf.printf "YAML optional roundtrip: FAIL (%s)\n" e 246 + 247 + let () = 248 + let usage = "Usage: test_roundtrip <command>" in 249 + 250 + if Stdlib.Array.length Sys.argv < 2 then begin 251 + prerr_endline usage; 252 + exit 1 253 + end; 254 + 255 + match Sys.argv.(1) with 256 + | "scalar" -> test_scalar_roundtrip () 257 + | "array" -> test_array_roundtrip () 258 + | "object" -> test_object_roundtrip () 259 + | "optional" -> test_optional_roundtrip () 260 + | _ -> 261 + prerr_endline usage; 262 + prerr_endline "Commands:"; 263 + prerr_endline " scalar - Test scalar roundtrip"; 264 + prerr_endline " array - Test array roundtrip"; 265 + prerr_endline " object - Test object roundtrip"; 266 + prerr_endline " optional - Test optional fields roundtrip"; 267 + exit 1
+309
vendor/opam/yamlt/tests/bin/test_scalars.ml
··· 1 + (*--------------------------------------------------------------------------- 2 + Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org>. All rights reserved. 3 + SPDX-License-Identifier: ISC 4 + ---------------------------------------------------------------------------*) 5 + 6 + (** Test scalar type resolution with Yamlt codec *) 7 + 8 + open Bytesrw 9 + 10 + (* Helper to read file *) 11 + let read_file path = 12 + let ic = open_in path in 13 + let len = in_channel_length ic in 14 + let s = really_input_string ic len in 15 + close_in ic; 16 + s 17 + 18 + (* Helper to show results *) 19 + let show_result label = function 20 + | Ok v -> Printf.printf "%s: %s\n" label v 21 + | Error e -> Printf.printf "%s: ERROR: %s\n" label e 22 + 23 + let show_result_json label json_result yaml_result = 24 + Printf.printf "JSON %s\n" label; 25 + show_result " decode" json_result; 26 + Printf.printf "YAML %s\n" label; 27 + show_result " decode" yaml_result 28 + 29 + (* Test: Decode null values with different type expectations *) 30 + let test_null_resolution file = 31 + let yaml = read_file file in 32 + 33 + (* Define a simple object codec with nullable field *) 34 + let null_codec = 35 + Jsont.Object.map ~kind:"NullTest" (fun n -> n) 36 + |> Jsont.Object.mem "value" (Jsont.null ()) ~enc:(fun n -> n) 37 + |> Jsont.Object.finish 38 + in 39 + 40 + (* Try decoding as null *) 41 + let result = Yamlt.decode null_codec (Bytes.Reader.of_string yaml) in 42 + show_result "null_codec" (Result.map (fun () -> "null") result) 43 + 44 + (* Test: Boolean type-directed resolution *) 45 + let test_bool_resolution file = 46 + let yaml = read_file file in 47 + let json = read_file (file ^ ".json") in 48 + 49 + (* Codec expecting bool *) 50 + let bool_codec = 51 + Jsont.Object.map ~kind:"BoolTest" (fun b -> b) 52 + |> Jsont.Object.mem "value" Jsont.bool ~enc:(fun b -> b) 53 + |> Jsont.Object.finish 54 + in 55 + 56 + (* Codec expecting string *) 57 + let string_codec = 58 + Jsont.Object.map ~kind:"StringTest" (fun s -> s) 59 + |> Jsont.Object.mem "value" Jsont.string ~enc:(fun s -> s) 60 + |> Jsont.Object.finish 61 + in 62 + 63 + Printf.printf "=== Bool Codec ===\n"; 64 + let json_result = Jsont_bytesrw.decode_string bool_codec json in 65 + let yaml_result = Yamlt.decode bool_codec (Bytes.Reader.of_string yaml) in 66 + show_result_json "bool_codec" 67 + (Result.map (Printf.sprintf "%b") json_result) 68 + (Result.map (Printf.sprintf "%b") yaml_result); 69 + 70 + Printf.printf "\n=== String Codec ===\n"; 71 + let json_result = Jsont_bytesrw.decode_string string_codec json in 72 + let yaml_result = Yamlt.decode string_codec (Bytes.Reader.of_string yaml) in 73 + show_result_json "string_codec" 74 + (Result.map (Printf.sprintf "%S") json_result) 75 + (Result.map (Printf.sprintf "%S") yaml_result) 76 + 77 + (* Test: Number resolution *) 78 + let test_number_resolution file = 79 + let yaml = read_file file in 80 + let json = read_file (file ^ ".json") in 81 + 82 + let number_codec = 83 + Jsont.Object.map ~kind:"NumberTest" (fun n -> n) 84 + |> Jsont.Object.mem "value" Jsont.number ~enc:(fun n -> n) 85 + |> Jsont.Object.finish 86 + in 87 + 88 + let json_result = Jsont_bytesrw.decode_string number_codec json in 89 + let yaml_result = Yamlt.decode number_codec (Bytes.Reader.of_string yaml) in 90 + 91 + show_result_json "number_codec" 92 + (Result.map (Printf.sprintf "%.17g") json_result) 93 + (Result.map (Printf.sprintf "%.17g") yaml_result) 94 + 95 + (* Test: String resolution preserves everything *) 96 + let test_string_resolution file = 97 + let yaml = read_file file in 98 + let json = read_file (file ^ ".json") in 99 + 100 + let string_codec = 101 + Jsont.Object.map ~kind:"StringTest" (fun s -> s) 102 + |> Jsont.Object.mem "value" Jsont.string ~enc:(fun s -> s) 103 + |> Jsont.Object.finish 104 + in 105 + 106 + let json_result = Jsont_bytesrw.decode_string string_codec json in 107 + let yaml_result = Yamlt.decode string_codec (Bytes.Reader.of_string yaml) in 108 + 109 + show_result_json "string_codec" 110 + (Result.map (Printf.sprintf "%S") json_result) 111 + (Result.map (Printf.sprintf "%S") yaml_result) 112 + 113 + (* Test: Special float values *) 114 + let test_special_floats file = 115 + let yaml = read_file file in 116 + 117 + let number_codec = 118 + Jsont.Object.map ~kind:"SpecialFloat" (fun n -> n) 119 + |> Jsont.Object.mem "value" Jsont.number ~enc:(fun n -> n) 120 + |> Jsont.Object.finish 121 + in 122 + 123 + let result = Yamlt.decode number_codec (Bytes.Reader.of_string yaml) in 124 + match result with 125 + | Ok f -> 126 + if Float.is_nan f then Printf.printf "value: NaN\n" 127 + else if f = Float.infinity then Printf.printf "value: +Infinity\n" 128 + else if f = Float.neg_infinity then Printf.printf "value: -Infinity\n" 129 + else Printf.printf "value: %.17g\n" f 130 + | Error e -> Printf.printf "ERROR: %s\n" e 131 + 132 + (* Test: Type mismatch errors *) 133 + let test_type_mismatch file expected_type = 134 + let yaml = read_file file in 135 + 136 + match expected_type with 137 + | "bool" -> ( 138 + let codec = 139 + Jsont.Object.map ~kind:"BoolTest" (fun b -> b) 140 + |> Jsont.Object.mem "value" Jsont.bool ~enc:(fun b -> b) 141 + |> Jsont.Object.finish 142 + in 143 + let result = Yamlt.decode codec (Bytes.Reader.of_string yaml) in 144 + match result with 145 + | Ok _ -> Printf.printf "Unexpected success\n" 146 + | Error e -> Printf.printf "Expected error: %s\n" e) 147 + | "number" -> ( 148 + let codec = 149 + Jsont.Object.map ~kind:"NumberTest" (fun n -> n) 150 + |> Jsont.Object.mem "value" Jsont.number ~enc:(fun n -> n) 151 + |> Jsont.Object.finish 152 + in 153 + let result = Yamlt.decode codec (Bytes.Reader.of_string yaml) in 154 + match result with 155 + | Ok _ -> Printf.printf "Unexpected success\n" 156 + | Error e -> Printf.printf "Expected error: %s\n" e) 157 + | "null" -> ( 158 + let codec = 159 + Jsont.Object.map ~kind:"NullTest" (fun n -> n) 160 + |> Jsont.Object.mem "value" (Jsont.null ()) ~enc:(fun n -> n) 161 + |> Jsont.Object.finish 162 + in 163 + let result = Yamlt.decode codec (Bytes.Reader.of_string yaml) in 164 + match result with 165 + | Ok _ -> Printf.printf "Unexpected success\n" 166 + | Error e -> Printf.printf "Expected error: %s\n" e) 167 + | _ -> failwith "unknown type" 168 + 169 + (* Test: Decode with Jsont.json to see auto-resolution *) 170 + let test_any_resolution file = 171 + let yaml = read_file file in 172 + let json = read_file (file ^ ".json") in 173 + 174 + let any_codec = 175 + Jsont.Object.map ~kind:"AnyTest" (fun v -> v) 176 + |> Jsont.Object.mem "value" Jsont.json ~enc:(fun v -> v) 177 + |> Jsont.Object.finish 178 + in 179 + 180 + let json_result = Jsont_bytesrw.decode_string any_codec json in 181 + let yaml_result = Yamlt.decode any_codec (Bytes.Reader.of_string yaml) in 182 + 183 + (* Just show that it decoded successfully *) 184 + show_result_json "any_codec" 185 + (Result.map (fun _ -> "decoded") json_result) 186 + (Result.map (fun _ -> "decoded") yaml_result) 187 + 188 + (* Test: Encoding to different formats *) 189 + let test_encode_formats value_type value = 190 + match value_type with 191 + | "bool" -> ( 192 + let codec = 193 + Jsont.Object.map ~kind:"BoolTest" (fun b -> b) 194 + |> Jsont.Object.mem "value" Jsont.bool ~enc:(fun b -> b) 195 + |> Jsont.Object.finish 196 + in 197 + let v = bool_of_string value in 198 + (match Jsont_bytesrw.encode_string codec v with 199 + | Ok s -> Printf.printf "JSON: %s\n" (String.trim s) 200 + | Error e -> Printf.printf "JSON ERROR: %s\n" e); 201 + (let b = Buffer.create 256 in 202 + let writer = Bytes.Writer.of_buffer b in 203 + match Yamlt.encode ~format:Yamlt.Block codec v ~eod:true writer with 204 + | Ok () -> Printf.printf "YAML Block:\n%s" (Buffer.contents b) 205 + | Error e -> Printf.printf "YAML Block ERROR: %s\n" e); 206 + let b = Buffer.create 256 in 207 + let writer = Bytes.Writer.of_buffer b in 208 + match Yamlt.encode ~format:Yamlt.Flow codec v ~eod:true writer with 209 + | Ok () -> Printf.printf "YAML Flow: %s" (Buffer.contents b) 210 + | Error e -> Printf.printf "YAML Flow ERROR: %s\n" e) 211 + | "number" -> ( 212 + let codec = 213 + Jsont.Object.map ~kind:"NumberTest" (fun n -> n) 214 + |> Jsont.Object.mem "value" Jsont.number ~enc:(fun n -> n) 215 + |> Jsont.Object.finish 216 + in 217 + let v = float_of_string value in 218 + (match Jsont_bytesrw.encode_string codec v with 219 + | Ok s -> Printf.printf "JSON: %s\n" (String.trim s) 220 + | Error e -> Printf.printf "JSON ERROR: %s\n" e); 221 + (let b = Buffer.create 256 in 222 + let writer = Bytes.Writer.of_buffer b in 223 + match Yamlt.encode ~format:Yamlt.Block codec v ~eod:true writer with 224 + | Ok () -> Printf.printf "YAML Block:\n%s" (Buffer.contents b) 225 + | Error e -> Printf.printf "YAML Block ERROR: %s\n" e); 226 + let b = Buffer.create 256 in 227 + let writer = Bytes.Writer.of_buffer b in 228 + match Yamlt.encode ~format:Yamlt.Flow codec v ~eod:true writer with 229 + | Ok () -> Printf.printf "YAML Flow: %s" (Buffer.contents b) 230 + | Error e -> Printf.printf "YAML Flow ERROR: %s\n" e) 231 + | "string" -> ( 232 + let codec = 233 + Jsont.Object.map ~kind:"StringTest" (fun s -> s) 234 + |> Jsont.Object.mem "value" Jsont.string ~enc:(fun s -> s) 235 + |> Jsont.Object.finish 236 + in 237 + let v = value in 238 + (match Jsont_bytesrw.encode_string codec v with 239 + | Ok s -> Printf.printf "JSON: %s\n" (String.trim s) 240 + | Error e -> Printf.printf "JSON ERROR: %s\n" e); 241 + (let b = Buffer.create 256 in 242 + let writer = Bytes.Writer.of_buffer b in 243 + match Yamlt.encode ~format:Yamlt.Block codec v ~eod:true writer with 244 + | Ok () -> Printf.printf "YAML Block:\n%s" (Buffer.contents b) 245 + | Error e -> Printf.printf "YAML Block ERROR: %s\n" e); 246 + let b = Buffer.create 256 in 247 + let writer = Bytes.Writer.of_buffer b in 248 + match Yamlt.encode ~format:Yamlt.Flow codec v ~eod:true writer with 249 + | Ok () -> Printf.printf "YAML Flow: %s" (Buffer.contents b) 250 + | Error e -> Printf.printf "YAML Flow ERROR: %s\n" e) 251 + | "null" -> ( 252 + let codec = 253 + Jsont.Object.map ~kind:"NullTest" (fun n -> n) 254 + |> Jsont.Object.mem "value" (Jsont.null ()) ~enc:(fun n -> n) 255 + |> Jsont.Object.finish 256 + in 257 + let v = () in 258 + (match Jsont_bytesrw.encode_string codec v with 259 + | Ok s -> Printf.printf "JSON: %s\n" (String.trim s) 260 + | Error e -> Printf.printf "JSON ERROR: %s\n" e); 261 + (let b = Buffer.create 256 in 262 + let writer = Bytes.Writer.of_buffer b in 263 + match Yamlt.encode ~format:Yamlt.Block codec v ~eod:true writer with 264 + | Ok () -> Printf.printf "YAML Block:\n%s" (Buffer.contents b) 265 + | Error e -> Printf.printf "YAML Block ERROR: %s\n" e); 266 + let b = Buffer.create 256 in 267 + let writer = Bytes.Writer.of_buffer b in 268 + match Yamlt.encode ~format:Yamlt.Flow codec v ~eod:true writer with 269 + | Ok () -> Printf.printf "YAML Flow: %s" (Buffer.contents b) 270 + | Error e -> Printf.printf "YAML Flow ERROR: %s\n" e) 271 + | _ -> failwith "unknown type" 272 + 273 + let () = 274 + let usage = "Usage: test_scalars <command> [args...]" in 275 + 276 + if Stdlib.Array.length Sys.argv < 2 then begin 277 + prerr_endline usage; 278 + exit 1 279 + end; 280 + 281 + match Sys.argv.(1) with 282 + | "null" when Array.length Sys.argv = 3 -> test_null_resolution Sys.argv.(2) 283 + | "bool" when Array.length Sys.argv = 3 -> test_bool_resolution Sys.argv.(2) 284 + | "number" when Array.length Sys.argv = 3 -> 285 + test_number_resolution Sys.argv.(2) 286 + | "string" when Array.length Sys.argv = 3 -> 287 + test_string_resolution Sys.argv.(2) 288 + | "special-float" when Array.length Sys.argv = 3 -> 289 + test_special_floats Sys.argv.(2) 290 + | "type-mismatch" when Array.length Sys.argv = 4 -> 291 + test_type_mismatch Sys.argv.(2) Sys.argv.(3) 292 + | "any" when Array.length Sys.argv = 3 -> test_any_resolution Sys.argv.(2) 293 + | "encode" when Array.length Sys.argv = 4 -> 294 + test_encode_formats Sys.argv.(2) Sys.argv.(3) 295 + | _ -> 296 + prerr_endline usage; 297 + prerr_endline "Commands:"; 298 + prerr_endline " null <file> - Test null resolution"; 299 + prerr_endline 300 + " bool <file> - Test bool vs string resolution"; 301 + prerr_endline " number <file> - Test number resolution"; 302 + prerr_endline " string <file> - Test string resolution"; 303 + prerr_endline " special-float <file> - Test .inf, .nan, etc."; 304 + prerr_endline 305 + " type-mismatch <file> <type> - Test error on type mismatch"; 306 + prerr_endline 307 + " any <file> - Test Jsont.any auto-resolution"; 308 + prerr_endline " encode <type> <value> - Test encoding to JSON/YAML"; 309 + exit 1
+38
vendor/opam/yamlt/tests/bin/test_some_vs_option.ml
··· 1 + open Bytesrw 2 + 3 + let () = 4 + (* Using Jsont.some like opt_mem does *) 5 + let codec1 = 6 + Jsont.Object.map ~kind:"Test" (fun arr -> arr) 7 + |> Jsont.Object.mem "values" 8 + (Jsont.some (Jsont.array Jsont.string)) 9 + ~enc:(fun arr -> arr) 10 + |> Jsont.Object.finish 11 + in 12 + 13 + let yaml = "values: [a, b, c]" in 14 + 15 + Printf.printf "Test 1: Jsont.some (Jsont.array) - like opt_mem:\n"; 16 + (match Yamlt.decode codec1 (Bytes.Reader.of_string yaml) with 17 + | Ok arr -> ( 18 + match arr with 19 + | None -> Printf.printf "Result: None\n" 20 + | Some a -> Printf.printf "Result: Some([%d items])\n" (Array.length a)) 21 + | Error e -> Printf.printf "Error: %s\n" e); 22 + 23 + (* Using Jsont.option *) 24 + let codec2 = 25 + Jsont.Object.map ~kind:"Test" (fun arr -> arr) 26 + |> Jsont.Object.mem "values" 27 + (Jsont.option (Jsont.array Jsont.string)) 28 + ~enc:(fun arr -> arr) 29 + |> Jsont.Object.finish 30 + in 31 + 32 + Printf.printf "\nTest 2: Jsont.option (Jsont.array):\n"; 33 + match Yamlt.decode codec2 (Bytes.Reader.of_string yaml) with 34 + | Ok arr -> ( 35 + match arr with 36 + | None -> Printf.printf "Result: None\n" 37 + | Some a -> Printf.printf "Result: Some([%d items])\n" (Array.length a)) 38 + | Error e -> Printf.printf "Error: %s\n" e
+148
vendor/opam/yamlt/tests/cram/arrays_codec.t
··· 1 + Array Codec Tests with Yamlt 2 + =============================== 3 + 4 + This test suite validates array encoding/decoding with Jsont codecs in YAML, 5 + including homogeneous type checking and nested structures. 6 + 7 + Setup 8 + ----- 9 + 10 + ================================================================================ 11 + HOMOGENEOUS ARRAYS 12 + ================================================================================ 13 + 14 + Integer arrays 15 + 16 + $ test_arrays int ../data/arrays/int_array.yml 17 + JSON: int_array: [1; 2; 3; 4; 5] 18 + YAML: int_array: [1; 2; 3; 4; 5] 19 + 20 + String arrays 21 + 22 + $ test_arrays string ../data/arrays/string_array.yml 23 + JSON: string_array: ["apple"; "banana"; "cherry"] 24 + YAML: string_array: ["apple"; "banana"; "cherry"] 25 + 26 + Float/Number arrays 27 + 28 + $ test_arrays float ../data/arrays/float_array.yml 29 + JSON: float_array: [1.50; 2.70; 3.14; 0.50] 30 + YAML: float_array: [1.50; 2.70; 3.14; 0.50] 31 + 32 + Boolean arrays 33 + 34 + $ test_arrays bool ../data/arrays/bool_array.yml 35 + JSON: bool_array: [true; false; true; true; false] 36 + YAML: bool_array: [true; false; true; true; false] 37 + 38 + ================================================================================ 39 + EMPTY ARRAYS 40 + ================================================================================ 41 + 42 + Empty arrays work correctly 43 + 44 + $ test_arrays empty ../data/arrays/empty_array.yml 45 + JSON: empty_array: length=0 46 + YAML: empty_array: length=0 47 + 48 + ================================================================================ 49 + ARRAYS OF OBJECTS 50 + ================================================================================ 51 + 52 + Arrays containing objects 53 + 54 + $ test_arrays objects ../data/arrays/object_array.yml 55 + JSON: object_array: [{Alice,30}; {Bob,25}; {Charlie,35}] 56 + YAML: object_array: [{Alice,30}; {Bob,25}; {Charlie,35}] 57 + 58 + ================================================================================ 59 + NESTED ARRAYS 60 + ================================================================================ 61 + 62 + Arrays containing arrays (matrices) 63 + 64 + $ test_arrays nested ../data/arrays/nested_array.yml 65 + JSON: nested_arrays: [[1; 2; 3]; [4; 5; 6]; [7; 8; 9]] 66 + YAML: nested_arrays: [[1; 2; 3]; [4; 5; 6]; [7; 8; 9]] 67 + 68 + ================================================================================ 69 + NULLABLE ARRAYS 70 + ================================================================================ 71 + 72 + Arrays with null elements 73 + 74 + $ test_arrays nullable ../data/arrays/nullable_array.yml 75 + JSON: nullable_array: ERROR: Expected string but found null 76 + File "-", line 1, characters 21-22: 77 + File "-", line 1, characters 21-22: at index 1 of 78 + File "-", line 1, characters 11-22: array<string> 79 + File "-": in member values of 80 + File "-", line 1, characters 0-22: Nullable object 81 + YAML: nullable_array: ERROR: Expected string but found null 82 + File "-": 83 + at index 1 of 84 + File "-": array<string> 85 + File "-": in member values of 86 + File "-": Nullable object 87 + 88 + ================================================================================ 89 + ERROR HANDLING 90 + ================================================================================ 91 + 92 + Type mismatch in array element 93 + 94 + $ test_arrays type-mismatch ../data/arrays/type_mismatch.yml 95 + Expected error: String "not-a-number" does not parse to OCaml int value 96 + File "-": 97 + at index 2 of 98 + File "-": array<OCaml int> 99 + File "-": in member values of 100 + File "-": Numbers object 101 + 102 + ================================================================================ 103 + ENCODING ARRAYS 104 + ================================================================================ 105 + 106 + Encode arrays to JSON and YAML formats 107 + 108 + $ test_arrays encode 109 + JSON: {"numbers":[1,2,3,4,5],"strings":["hello","world"]} 110 + YAML Block: 111 + numbers: 112 + - 1 113 + - 2 114 + - 3 115 + - 4 116 + - 5 117 + strings: 118 + - hello 119 + - world 120 + YAML Flow: {numbers: [1, 2, 3, 4, 5], strings: [hello, world]} 121 + 122 + ================================================================================ 123 + NEGATIVE TESTS - Wrong File Types 124 + ================================================================================ 125 + 126 + Attempting to decode an object file with an array codec should fail 127 + 128 + $ test_arrays int ../data/objects/simple.yml 129 + JSON: int_array: ERROR: Missing member values in Numbers object 130 + File "-", line 1, characters 0-28: 131 + YAML: int_array: ERROR: Missing member values in Numbers object 132 + File "-": 133 + 134 + Attempting to decode a scalar file with an array codec should fail 135 + 136 + $ test_arrays string ../data/scalars/string_plain.yml 137 + JSON: string_array: ERROR: Missing member items in Tags object 138 + File "-", line 1, characters 0-24: 139 + YAML: string_array: ERROR: Missing member items in Tags object 140 + File "-": 141 + 142 + Attempting to decode int array with string array codec should fail 143 + 144 + $ test_arrays string ../data/arrays/int_array.yml 145 + JSON: string_array: ERROR: Missing member items in Tags object 146 + File "-", line 1, characters 0-27: 147 + YAML: string_array: ERROR: Missing member items in Tags object 148 + File "-":
+71
vendor/opam/yamlt/tests/cram/complex_codec.t
··· 1 + Complex Nested Types Tests with Yamlt 2 + ====================================== 3 + 4 + This test suite validates complex nested structures combining objects, arrays, 5 + and various levels of nesting. 6 + 7 + ================================================================================ 8 + DEEPLY NESTED OBJECTS 9 + ================================================================================ 10 + 11 + Handle deeply nested object structures 12 + 13 + $ test_complex deep-nesting ../data/complex/deep_nesting.yml 14 + JSON: deep_nesting: depth=4, value=42 15 + YAML: deep_nesting: depth=4, value=42 16 + 17 + ================================================================================ 18 + MIXED STRUCTURES 19 + ================================================================================ 20 + 21 + Arrays of objects containing arrays 22 + 23 + $ test_complex mixed-structure ../data/complex/mixed_structure.yml 24 + JSON: mixed_structure: name="products", items=3, total_tags=6 25 + YAML: mixed_structure: name="products", items=3, total_tags=6 26 + 27 + ================================================================================ 28 + COMPLEX OPTIONAL COMBINATIONS 29 + ================================================================================ 30 + 31 + Multiple optional fields with different combinations 32 + 33 + $ test_complex complex-optional ../data/complex/complex_optional.yml 34 + JSON: complex_optional: host="example.com", port=443, ssl=true, fallbacks=2 35 + YAML: complex_optional: host="example.com", port=443, ssl=true, fallbacks=2 36 + 37 + ================================================================================ 38 + HETEROGENEOUS DATA 39 + ================================================================================ 40 + 41 + Mixed types in arrays using any type 42 + 43 + $ test_complex heterogeneous ../data/complex/heterogeneous.yml 44 + JSON: heterogeneous: ERROR: Expected one of but found number 45 + File "-", line 1, characters 11-12: 46 + File "-", line 1, characters 11-12: at index 0 of 47 + File "-", line 1, characters 10-12: array<one of > 48 + File "-": in member mixed of 49 + File "-", line 1, characters 0-12: Data object 50 + YAML: heterogeneous: ERROR: Expected one of but found number 51 + File "-": 52 + at index 0 of 53 + File "-": array<one of > 54 + File "-": in member mixed of 55 + File "-": Data object 56 + 57 + ================================================================================ 58 + NEGATIVE TESTS - Structure Mismatch 59 + ================================================================================ 60 + 61 + Using deeply nested data with flat codec should fail 62 + 63 + $ test_complex mixed-structure ../data/complex/deep_nesting.yml 64 + JSON: mixed_structure: ERROR: Missing members in Collection object: 65 + items 66 + name 67 + File "-", line 1, characters 0-44: 68 + YAML: mixed_structure: ERROR: Missing members in Collection object: 69 + items 70 + name 71 + File "-":
+17
vendor/opam/yamlt/tests/cram/dune
··· 1 + (cram 2 + (deps 3 + (package yamlt) 4 + (glob_files ../data/scalars/*.yml) 5 + (glob_files ../data/scalars/*.json) 6 + (glob_files ../data/objects/*.yml) 7 + (glob_files ../data/objects/*.json) 8 + (glob_files ../data/arrays/*.yml) 9 + (glob_files ../data/arrays/*.json) 10 + (glob_files ../data/formats/*.yml) 11 + (glob_files ../data/formats/*.json) 12 + (glob_files ../data/complex/*.yml) 13 + (glob_files ../data/complex/*.json) 14 + (glob_files ../data/edge/*.yml) 15 + (glob_files ../data/edge/*.json) 16 + (glob_files ../data/multidoc/*.yml) 17 + (glob_files ../data/locations/*.yml)))
+85
vendor/opam/yamlt/tests/cram/edge_codec.t
··· 1 + Edge Cases Tests with Yamlt 2 + ============================ 3 + 4 + This test suite validates edge cases including large numbers, special characters, 5 + unicode, and boundary conditions. 6 + 7 + ================================================================================ 8 + LARGE NUMBERS 9 + ================================================================================ 10 + 11 + Very large and very small floating point numbers 12 + 13 + $ test_edge large-numbers ../data/edge/large_numbers.yml 14 + JSON: large_numbers: large_int=9007199254740991, large_float=1.797693e+308, small_float=2.225074e-308 15 + YAML: large_numbers: large_int=9007199254740991, large_float=1.797693e+308, small_float=2.225074e-308 16 + 17 + ================================================================================ 18 + SPECIAL CHARACTERS 19 + ================================================================================ 20 + 21 + Strings containing newlines, tabs, and other special characters 22 + 23 + $ test_edge special-chars ../data/edge/special_chars.yml 24 + JSON: special_chars: length=34, contains_newline=true, contains_tab=true 25 + YAML: special_chars: length=34, contains_newline=true, contains_tab=true 26 + 27 + ================================================================================ 28 + UNICODE STRINGS 29 + ================================================================================ 30 + 31 + Emoji, Chinese, and RTL text 32 + 33 + $ test_edge unicode ../data/edge/unicode.yml 34 + JSON: unicode: emoji="\240\159\142\137\240\159\154\128\226\156\168", chinese="\228\189\160\229\165\189\228\184\150\231\149\140", rtl="\217\133\216\177\216\173\216\168\216\167" 35 + YAML: unicode: emoji="\240\159\142\137\240\159\154\128\226\156\168", chinese="\228\189\160\229\165\189\228\184\150\231\149\140", rtl="\217\133\216\177\216\173\216\168\216\167" 36 + 37 + ================================================================================ 38 + EMPTY COLLECTIONS 39 + ================================================================================ 40 + 41 + Empty arrays and objects 42 + 43 + $ test_edge empty-collections ../data/edge/empty_collections.yml 44 + JSON: empty_collections: empty_array_len=0, empty_object_array_len=0 45 + YAML: empty_collections: empty_array_len=0, empty_object_array_len=0 46 + 47 + ================================================================================ 48 + SPECIAL KEY NAMES 49 + ================================================================================ 50 + 51 + Keys with dots, dashes, colons 52 + 53 + $ test_edge special-keys ../data/edge/special_keys.yml 54 + JSON: special_keys: ERROR: Expected one of but found object 55 + File "-", line 1, characters 0-1: 56 + YAML: special_keys: ERROR: Expected one of but found object 57 + File "-": 58 + 59 + ================================================================================ 60 + SINGLE-ELEMENT ARRAYS 61 + ================================================================================ 62 + 63 + Arrays with exactly one element 64 + 65 + $ test_edge single-element ../data/edge/single_element.yml 66 + JSON: single_element: length=1, value=42 67 + YAML: single_element: length=1, value=42 68 + 69 + ================================================================================ 70 + NEGATIVE TESTS - Boundary Violations 71 + ================================================================================ 72 + 73 + Using unicode data with number codec should fail 74 + 75 + $ test_edge large-numbers ../data/edge/unicode.yml 76 + JSON: large_numbers: ERROR: Missing members in Numbers object: 77 + large_float 78 + large_int 79 + small_float 80 + File "-", line 1, characters 0-72: 81 + YAML: large_numbers: ERROR: Missing members in Numbers object: 82 + large_float 83 + large_int 84 + small_float 85 + File "-":
+107
vendor/opam/yamlt/tests/cram/formats_codec.t
··· 1 + Format-Specific Features Tests with Yamlt 2 + ========================================== 3 + 4 + This test suite validates YAML-specific format features and compares with JSON behavior. 5 + 6 + ================================================================================ 7 + MULTI-LINE STRINGS - LITERAL STYLE 8 + ================================================================================ 9 + 10 + Literal style (|) preserves newlines 11 + 12 + $ test_formats literal ../data/formats/literal_string.yml 13 + JSON: literal_string: lines=5, length=81 14 + YAML: literal_string: lines=5, length=81 15 + 16 + ================================================================================ 17 + MULTI-LINE STRINGS - FOLDED STYLE 18 + ================================================================================ 19 + 20 + Folded style (>) folds lines into single line 21 + 22 + $ test_formats folded ../data/formats/folded_string.yml 23 + JSON: folded_string: length=114, newlines=1 24 + YAML: folded_string: length=114, newlines=1 25 + 26 + ================================================================================ 27 + NUMBER FORMATS 28 + ================================================================================ 29 + 30 + YAML supports hex, octal, and binary number formats 31 + 32 + $ test_formats number-formats ../data/formats/number_formats.yml 33 + JSON: number_formats: hex=255, octal=63, binary=10 34 + YAML: number_formats: hex=255, octal=63, binary=10 35 + 36 + ================================================================================ 37 + COMMENTS 38 + ================================================================================ 39 + 40 + YAML comments are ignored during parsing 41 + 42 + $ test_formats comments ../data/formats/comments.yml 43 + YAML (with comments): host="localhost", port=8080, debug=true 44 + 45 + ================================================================================ 46 + EMPTY DOCUMENTS 47 + ================================================================================ 48 + 49 + Empty or null documents handled correctly 50 + 51 + $ test_formats empty-doc ../data/formats/empty_doc.yml 52 + JSON: empty_document: ERROR: Expected string but found null 53 + File "-", line 1, characters 10-11: 54 + File "-": in member value of 55 + File "-", line 1, characters 0-11: Wrapper object 56 + YAML: empty_document: ERROR: Expected string but found null 57 + File "-": 58 + File "-": in member value of 59 + File "-": Wrapper object 60 + 61 + ================================================================================ 62 + EXPLICIT TYPE TAGS 63 + ================================================================================ 64 + 65 + Explicit YAML type tags (!!str, !!int, etc.) 66 + 67 + $ test_formats explicit-tags ../data/formats/explicit_tags.yml 68 + YAML (with tags): data="123" 69 + 70 + ================================================================================ 71 + ENCODING STYLES 72 + ================================================================================ 73 + 74 + Compare Block vs Flow encoding styles 75 + 76 + $ test_formats encode-styles 77 + YAML Block: 78 + name: test 79 + values: 80 + - 1 81 + - 2 82 + - 3 83 + nested: 84 + enabled: true 85 + count: 5 86 + 87 + YAML Flow: 88 + {name: test, values: [1, 2, 3], nested: {enabled: true, count: 5}} 89 + 90 + 91 + ================================================================================ 92 + NEGATIVE TESTS - Format Compatibility 93 + ================================================================================ 94 + 95 + Using literal string test with number codec should fail 96 + 97 + $ test_formats number-formats ../data/formats/literal_string.yml 98 + JSON: number_formats: ERROR: Missing members in Numbers object: 99 + binary 100 + hex 101 + octal 102 + File "-", line 1, characters 0-100: 103 + YAML: number_formats: ERROR: Missing members in Numbers object: 104 + binary 105 + hex 106 + octal 107 + File "-":
+217
vendor/opam/yamlt/tests/cram/locations.t
··· 1 + Location and Layout Preservation Tests with Yamlt 2 + ================================================== 3 + 4 + This test suite validates the `locs` and `layout` options in the Yamlt decoder, 5 + demonstrating how they affect error messages and metadata preservation. 6 + 7 + ================================================================================ 8 + ERROR MESSAGE PRECISION - locs option 9 + ================================================================================ 10 + 11 + The `locs` option controls whether source locations are preserved in error messages. 12 + When `locs=false` (default), errors show basic location info. 13 + When `locs=true`, errors show precise character positions. 14 + 15 + Basic type error with and without locs 16 + 17 + $ test_locations error-precision ../data/locations/type_error.yml 18 + === Without locs (default) === 19 + Error message: 20 + String "not-a-number" does not parse to OCaml int value 21 + File "-": 22 + File "-": in member age of 23 + File "-": Person object 24 + 25 + === With locs=true === 26 + Error message: 27 + String "not-a-number" does not parse to OCaml int value 28 + File "-", line 2, characters 5-18: 29 + File "-", line 2, characters 0-3: in member age of 30 + File "-", line 1, characters 0-1: Person object 31 + 32 + ================================================================================ 33 + NESTED ERROR LOCATIONS 34 + ================================================================================ 35 + 36 + The `locs` option is especially useful for nested structures, 37 + showing exactly where deep errors occur. 38 + 39 + Error in nested object field 40 + 41 + $ test_locations nested-error ../data/locations/nested_error.yml 42 + === Without locs (default) === 43 + Nested error: 44 + String "invalid-zip" does not parse to OCaml int value 45 + File "-": 46 + File "-": in member zip of 47 + File "-": Address object 48 + File "-": in member address of 49 + File "-": Employee object 50 + 51 + === With locs=true === 52 + Nested error: 53 + String "invalid-zip" does not parse to OCaml int value 54 + File "-", line 5, characters 7-19: 55 + File "-", line 5, characters 2-5: in member zip of 56 + File "-", line 3, characters 2-3: Address object 57 + File "-", line 2, characters 0-7: in member address of 58 + File "-", line 1, characters 0-1: Employee object 59 + 60 + ================================================================================ 61 + ARRAY ELEMENT ERROR LOCATIONS 62 + ================================================================================ 63 + 64 + The `locs` option pinpoints which array element caused an error. 65 + 66 + Error at specific array index 67 + 68 + $ test_locations array-error ../data/locations/array_error.yml 69 + === Without locs (default) === 70 + Array error: 71 + String "not-a-number" does not parse to OCaml int value 72 + File "-": 73 + at index 2 of 74 + File "-": array<OCaml int> 75 + File "-": in member values of 76 + File "-": Numbers object 77 + 78 + === With locs=true === 79 + Array error: 80 + String "not-a-number" does not parse to OCaml int value 81 + File "-", lines 4-5, characters 4-2: 82 + at index 2 of 83 + File "-", line 2, characters 2-3: array<OCaml int> 84 + File "-", line 1, characters 0-6: in member values of 85 + File "-", line 1, characters 0-1: Numbers object 86 + 87 + ================================================================================ 88 + FILE PATH IN ERROR MESSAGES 89 + ================================================================================ 90 + 91 + The `file` parameter sets the file path shown in error messages. 92 + 93 + $ test_locations file-path 94 + === Without file path === 95 + Error: 96 + String "not-a-number" does not parse to OCaml int value 97 + File "-", line 2, characters 5-18: 98 + File "-", line 2, characters 0-3: in member age of 99 + File "-", line 1, characters 0-1: Person object 100 + 101 + === With file path === 102 + Error: 103 + String "not-a-number" does not parse to OCaml int value 104 + File "test.yml", line 2, characters 5-18: 105 + File "test.yml", line 2, characters 0-3: in member age of 106 + File "test.yml", line 1, characters 0-1: Person object 107 + 108 + ================================================================================ 109 + MISSING FIELD ERROR LOCATIONS 110 + ================================================================================ 111 + 112 + The `locs` option helps identify where fields are missing. 113 + 114 + $ test_locations missing-field ../data/locations/missing_field.yml 115 + === Without locs === 116 + Missing field: 117 + Missing member field_c in Complete object 118 + File "-": 119 + 120 + === With locs=true === 121 + Missing field: 122 + Missing member field_c in Complete object 123 + File "-", line 1, characters 0-1: 124 + 125 + ================================================================================ 126 + LAYOUT PRESERVATION - layout option 127 + ================================================================================ 128 + 129 + The `layout` option controls whether style information (block vs flow) 130 + is preserved in metadata for potential round-tripping. 131 + 132 + Basic layout preservation 133 + 134 + $ test_locations layout ../data/locations/simple.yml 135 + === Without layout (default) === 136 + Decoded: host=localhost, port=8080 137 + Meta preserved: no 138 + 139 + === With layout=true === 140 + Decoded: host=localhost, port=8080 141 + Meta preserved: yes (style info available for round-tripping) 142 + 143 + ================================================================================ 144 + ROUND-TRIPPING WITH LAYOUT 145 + ================================================================================ 146 + 147 + With `layout=true` during decode and `format:Layout` during encode, 148 + the original YAML style can be preserved. 149 + 150 + Flow style preservation 151 + 152 + $ test_locations roundtrip ../data/locations/flow_style.yml 153 + === Original YAML === 154 + items: [apple, banana, cherry] 155 + 156 + === Decode without layout, re-encode === 157 + items: 158 + - apple 159 + - banana 160 + - cherry 161 + 162 + === Decode with layout=true, re-encode with Layout format === 163 + items: 164 + - apple 165 + - banana 166 + - cherry 167 + 168 + Block style preservation 169 + 170 + $ test_locations roundtrip ../data/locations/block_style.yml 171 + === Original YAML === 172 + items: 173 + - apple 174 + - banana 175 + - cherry 176 + 177 + === Decode without layout, re-encode === 178 + items: 179 + - apple 180 + - banana 181 + - cherry 182 + 183 + === Decode with layout=true, re-encode with Layout format === 184 + items: 185 + - apple 186 + - banana 187 + - cherry 188 + 189 + ================================================================================ 190 + COMBINED OPTIONS - locs and layout together 191 + ================================================================================ 192 + 193 + Both options can be used simultaneously for maximum information. 194 + 195 + $ test_locations combined ../data/locations/valid_settings.yml 196 + === locs=false, layout=false (defaults) === 197 + OK: timeout=30, retries=3 198 + 199 + === locs=true, layout=false === 200 + OK: timeout=30, retries=3 (with precise locations) 201 + 202 + === locs=false, layout=true === 203 + OK: timeout=30, retries=3 (with layout metadata) 204 + 205 + === locs=true, layout=true (both enabled) === 206 + OK: timeout=30, retries=3 (with locations and layout) 207 + 208 + ================================================================================ 209 + SUMMARY OF OPTIONS 210 + ================================================================================ 211 + 212 + locs option: 213 + 214 + layout option: 215 + 216 + Both options add metadata overhead, so only enable when needed. 217 + For production parsing where you only need the data, use defaults (both false).
+220
vendor/opam/yamlt/tests/cram/multidoc.t
··· 1 + Multi-Document YAML Streams with Yamlt 2 + ======================================== 3 + 4 + This test suite validates multi-document YAML stream decoding using decode_all, 5 + including error handling, location tracking, and JSON roundtripping. 6 + 7 + ================================================================================ 8 + BASIC MULTIDOC DECODING 9 + ================================================================================ 10 + 11 + Simple multi-document stream with person objects 12 + 13 + $ test_multidoc simple ../data/multidoc/simple.yml 14 + Documents: 15 + [0] : Alice (age 30) 16 + [1] : Bob (age 25) 17 + [2] : Charlie (age 35) 18 + 19 + Count documents in a stream 20 + 21 + $ test_multidoc count ../data/multidoc/simple.yml 22 + Document count: 3 23 + 24 + ================================================================================ 25 + ERROR HANDLING - MIXED VALID AND INVALID DOCUMENTS 26 + ================================================================================ 27 + 28 + When some documents succeed and others fail, decode_all continues processing 29 + and returns results for each document individually. 30 + 31 + Stream with one error in the middle 32 + 33 + $ test_multidoc errors ../data/multidoc/mixed_errors.yml 34 + Document results: 35 + [0] OK: Alice (age 30) 36 + [1] ERROR: String "not-a-number" does not parse to OCaml int value 37 + File "-": 38 + File "-": in member age of 39 + File "-": Person object 40 + [2] OK: Charlie (age 35) 41 + 42 + Summary statistics for mixed documents 43 + 44 + $ test_multidoc summary ../data/multidoc/mixed_errors.yml 45 + Summary: 3 documents (2 ok, 1 error) 46 + 47 + Stream where all documents fail 48 + 49 + $ test_multidoc errors ../data/multidoc/all_errors.yml 50 + Document results: 51 + [0] ERROR: String "invalid1" does not parse to OCaml int value 52 + File "-": 53 + File "-": in member age of 54 + File "-": Person object 55 + [1] ERROR: String "invalid2" does not parse to OCaml int value 56 + File "-": 57 + File "-": in member age of 58 + File "-": Person object 59 + [2] ERROR: String "invalid3" does not parse to OCaml int value 60 + File "-": 61 + File "-": in member age of 62 + File "-": Person object 63 + 64 + Summary for all-error stream 65 + 66 + $ test_multidoc summary ../data/multidoc/all_errors.yml 67 + Summary: 3 documents (0 ok, 3 error) 68 + 69 + ================================================================================ 70 + LOCATION TRACKING WITH locs=true 71 + ================================================================================ 72 + 73 + Location tracking helps identify exactly where errors occur in each document 74 + of a multi-document stream. 75 + 76 + Without locs (default) - basic error information 77 + 78 + $ test_multidoc locations ../data/multidoc/mixed_errors.yml 79 + === Without locs (default) === 80 + [0] OK 81 + [1] ERROR: 82 + String "not-a-number" does not parse to OCaml int value 83 + File "-": 84 + File "-": in member age of 85 + File "-": Person object 86 + [2] OK 87 + 88 + === With locs=true === 89 + [0] OK 90 + [1] ERROR: 91 + String "not-a-number" does not parse to OCaml int value 92 + File "test.yml", line 6, characters 5-18: 93 + File "test.yml", line 6, characters 0-3: in member age of 94 + File "test.yml", line 5, characters 0-1: Person object 95 + [2] OK 96 + 97 + ================================================================================ 98 + MISSING FIELDS IN MULTIDOC 99 + ================================================================================ 100 + 101 + Documents with missing required fields generate errors but don't stop 102 + processing of subsequent documents. 103 + 104 + $ test_multidoc errors ../data/multidoc/missing_fields.yml 105 + Document results: 106 + [0] OK: Alice (age 30) 107 + [1] ERROR: Missing member age in Person object 108 + File "-": 109 + [2] OK: Charlie (age 35) 110 + 111 + Summary of missing fields test 112 + 113 + $ test_multidoc summary ../data/multidoc/missing_fields.yml 114 + Summary: 3 documents (2 ok, 1 error) 115 + 116 + ================================================================================ 117 + JSON ROUNDTRIPPING 118 + ================================================================================ 119 + 120 + Decode YAML multi-document streams and encode each document as JSON. 121 + This validates that the data model conversion is correct. 122 + 123 + Simple documents to JSON 124 + 125 + $ test_multidoc json ../data/multidoc/simple.yml 126 + JSON outputs: 127 + [0] {"name":"Alice","age":30} 128 + [1] {"name":"Bob","age":25} 129 + [2] {"name":"Charlie","age":35} 130 + 131 + Nested objects to JSON 132 + 133 + $ test_multidoc json ../data/multidoc/nested.yml 134 + JSON outputs: 135 + [0] {"name":"Alice","age":30,"address":{"street":"123 Main St","city":"Boston"}} 136 + [1] {"name":"Bob","age":25,"address":{"street":"456 Oak Ave","city":"Seattle"}} 137 + [2] {"name":"Charlie","age":35,"address":{"street":"789 Pine Rd","city":"Portland"}} 138 + 139 + Arrays to JSON 140 + 141 + $ test_multidoc json ../data/multidoc/arrays.yml 142 + JSON outputs: 143 + [0] [1,2,3] 144 + [1] ["apple","banana","cherry"] 145 + [2] [true,false,true] 146 + 147 + Scalar values to JSON 148 + 149 + $ test_multidoc json ../data/multidoc/scalars.yml 150 + JSON outputs: 151 + [0] "hello world" 152 + [1] 42 153 + [2] true 154 + [3] null 155 + 156 + ================================================================================ 157 + NESTED OBJECTS IN MULTIDOC 158 + ================================================================================ 159 + 160 + Test decoding complex nested structures across multiple documents. 161 + 162 + $ test_multidoc nested ../data/multidoc/nested.yml 163 + Nested documents: 164 + [0] : Alice (age 30) from 123 Main St, Boston 165 + [1] : Bob (age 25) from 456 Oak Ave, Seattle 166 + [2] : Charlie (age 35) from 789 Pine Rd, Portland 167 + 168 + ================================================================================ 169 + ARRAYS IN MULTIDOC 170 + ================================================================================ 171 + 172 + Test decoding different array types across documents. 173 + 174 + $ test_multidoc arrays ../data/multidoc/arrays.yml 175 + Array documents: 176 + [0] [1,2,3] 177 + [1] ["apple","banana","cherry"] 178 + [2] [true,false,true] 179 + 180 + ================================================================================ 181 + SCALARS IN MULTIDOC 182 + ================================================================================ 183 + 184 + Test decoding bare scalar values as documents. 185 + 186 + $ test_multidoc scalars ../data/multidoc/scalars.yml 187 + Scalar documents: 188 + [0] "hello world" 189 + [1] 42 190 + [2] true 191 + [3] null 192 + 193 + ================================================================================ 194 + EMPTY DOCUMENTS 195 + ================================================================================ 196 + 197 + Empty or null documents in a stream are handled correctly. 198 + 199 + $ test_multidoc json ../data/multidoc/empty_docs.yml 200 + JSON outputs: 201 + [0] {"name":"Alice","age":30} 202 + [1] null 203 + [2] {"name":"Charlie","age":35} 204 + 205 + Count including empty documents 206 + 207 + $ test_multidoc count ../data/multidoc/empty_docs.yml 208 + Document count: 3 209 + 210 + ================================================================================ 211 + SUMMARY 212 + ================================================================================ 213 + 214 + The decode_all function: 215 + - Processes all documents in a stream, not stopping on errors 216 + - Returns a sequence of Result values (Ok/Error for each document) 217 + - Supports all decode options: locs, layout, file, max_depth, max_nodes 218 + - Correctly handles document boundaries even when errors occur 219 + - Works with any Jsont codec (objects, arrays, scalars, etc.) 220 + - Can be used for JSON roundtripping and format conversion
+37
vendor/opam/yamlt/tests/cram/null_collections.t
··· 1 + Null to Empty Collection Tests 2 + ================================ 3 + 4 + This test suite validates that yamlt treats null values as empty collections 5 + when decoding into Array or Object types, providing a more user-friendly 6 + YAML experience. 7 + 8 + ================================================================================ 9 + NULL AS EMPTY COLLECTION 10 + ================================================================================ 11 + 12 + Test various forms of null decoding as empty arrays and objects 13 + 14 + $ test_null_collections 15 + === Test 1: Explicit null as empty array === 16 + Result: [] 17 + 18 + === Test 2: Tilde as empty array === 19 + Result: [] 20 + 21 + === Test 3: Empty array syntax === 22 + Result: [] 23 + 24 + === Test 4: Array with values === 25 + Result: [1; 2; 3] 26 + 27 + === Test 5: Explicit null as empty object === 28 + Result: {timeout=30; retries=3} 29 + 30 + === Test 6: Empty object syntax === 31 + Result: {timeout=30; retries=3} 32 + 33 + === Test 7: Object with values === 34 + Result: {timeout=60; retries=5} 35 + 36 + === Test 8: Nested null arrays === 37 + Result: {name=test; items_count=0; tags_count=0}
+160
vendor/opam/yamlt/tests/cram/objects_codec.t
··· 1 + Object Codec Tests with Yamlt 2 + ================================ 3 + 4 + This test suite validates object encoding/decoding with Jsont codecs in YAML, 5 + and compares behavior with JSON. 6 + 7 + Setup 8 + ----- 9 + 10 + 11 + ================================================================================ 12 + SIMPLE OBJECTS 13 + ================================================================================ 14 + 15 + Decode simple object with required fields 16 + 17 + $ test_objects simple ../data/objects/simple.yml 18 + JSON: person: {name="Alice"; age=30} 19 + YAML: person: {name="Alice"; age=30} 20 + 21 + ================================================================================ 22 + OPTIONAL FIELDS 23 + ================================================================================ 24 + 25 + Object with all optional fields present 26 + 27 + $ test_objects optional ../data/objects/optional_all.yml 28 + JSON: config: {host="localhost"; port=Some 8080; debug=Some true} 29 + YAML: config: {host="localhost"; port=Some 8080; debug=Some true} 30 + 31 + Object with some optional fields missing 32 + 33 + $ test_objects optional ../data/objects/optional_partial.yml 34 + JSON: config: {host="example.com"; port=Some 3000; debug=None} 35 + YAML: config: {host="example.com"; port=Some 3000; debug=None} 36 + 37 + Object with only required field 38 + 39 + $ test_objects optional ../data/objects/optional_minimal.yml 40 + JSON: config: {host="minimal.com"; port=None; debug=None} 41 + YAML: config: {host="minimal.com"; port=None; debug=None} 42 + 43 + ================================================================================ 44 + DEFAULT VALUES 45 + ================================================================================ 46 + 47 + Empty object uses all defaults 48 + 49 + $ test_objects defaults ../data/objects/defaults_empty.yml 50 + JSON: settings: {timeout=30; retries=3; verbose=false} 51 + YAML: settings: {timeout=30; retries=3; verbose=false} 52 + 53 + Object with partial fields uses defaults for missing ones 54 + 55 + $ test_objects defaults ../data/objects/defaults_partial.yml 56 + JSON: settings: {timeout=60; retries=3; verbose=false} 57 + YAML: settings: {timeout=60; retries=3; verbose=false} 58 + 59 + ================================================================================ 60 + NESTED OBJECTS 61 + ================================================================================ 62 + 63 + Objects containing other objects 64 + 65 + $ test_objects nested ../data/objects/nested.yml 66 + JSON: employee: {name="Bob"; address={street="123 Main St"; city="Springfield"; zip="12345"}} 67 + YAML: employee: {name="Bob"; address={street="123 Main St"; city="Springfield"; zip="12345"}} 68 + 69 + ================================================================================ 70 + UNKNOWN MEMBER HANDLING 71 + ================================================================================ 72 + 73 + Unknown members cause error by default 74 + 75 + $ test_objects unknown-error ../data/objects/unknown_members.yml 76 + Unexpected success 77 + 78 + Unknown members can be kept 79 + 80 + $ test_objects unknown-keep ../data/objects/unknown_keep.yml 81 + JSON: flexible: {name="Charlie"; has_extra=true} 82 + YAML: flexible: {name="Charlie"; has_extra=true} 83 + 84 + ================================================================================ 85 + OBJECT CASES (DISCRIMINATED UNIONS) 86 + ================================================================================ 87 + 88 + Decode circle variant 89 + 90 + $ test_objects cases ../data/objects/case_circle.yml 91 + JSON: shape: Circle{radius=5.50} 92 + YAML: shape: Circle{radius=5.50} 93 + 94 + Decode rectangle variant 95 + 96 + $ test_objects cases ../data/objects/case_rectangle.yml 97 + JSON: shape: ERROR: Missing member radius in Circle object 98 + File "-", line 1, characters 0-52: 99 + YAML: shape: ERROR: Missing member radius in Circle object 100 + File "-": 101 + 102 + ================================================================================ 103 + ERROR HANDLING 104 + ================================================================================ 105 + 106 + Missing required field produces error 107 + 108 + $ test_objects missing-required ../data/objects/missing_required.yml 109 + Expected error: Missing member age in Required object 110 + File "-": 111 + 112 + ================================================================================ 113 + ENCODING OBJECTS 114 + ================================================================================ 115 + 116 + Encode objects to JSON and YAML formats 117 + 118 + $ test_objects encode 119 + JSON: {"name":"Alice","age":30,"active":true} 120 + YAML Block: 121 + name: Alice 122 + age: 30 123 + active: true 124 + YAML Flow: {name: Alice, age: 30, active: true} 125 + 126 + ================================================================================ 127 + NEGATIVE TESTS - Wrong File Types 128 + ================================================================================ 129 + 130 + Attempting to decode an array file with an object codec should fail 131 + 132 + $ test_objects simple ../data/arrays/int_array.yml 133 + JSON: person: ERROR: Missing members in Person object: 134 + age 135 + name 136 + File "-", line 1, characters 0-27: 137 + YAML: person: ERROR: Missing members in Person object: 138 + age 139 + name 140 + File "-": 141 + 142 + Attempting to decode a scalar file with an object codec should fail 143 + 144 + $ test_objects simple ../data/scalars/string_plain.yml 145 + JSON: person: ERROR: Missing members in Person object: 146 + age 147 + name 148 + File "-", line 1, characters 0-24: 149 + YAML: person: ERROR: Missing members in Person object: 150 + age 151 + name 152 + File "-": 153 + 154 + Attempting to decode wrong object type (nested when expecting simple) should fail 155 + 156 + $ test_objects simple ../data/objects/nested.yml 157 + JSON: person: ERROR: Missing member age in Person object 158 + File "-", line 1, characters 0-92: 159 + YAML: person: ERROR: Missing member age in Person object 160 + File "-":
+46
vendor/opam/yamlt/tests/cram/roundtrip_codec.t
··· 1 + Roundtrip Encoding/Decoding Tests with Yamlt 2 + ============================================= 3 + 4 + This test suite validates that data can be encoded and then decoded back 5 + to the original value, ensuring no data loss in the roundtrip process. 6 + 7 + ================================================================================ 8 + SCALAR ROUNDTRIP 9 + ================================================================================ 10 + 11 + Encode and decode scalar types 12 + 13 + $ test_roundtrip scalar 14 + JSON roundtrip: PASS 15 + YAML Block roundtrip: PASS 16 + YAML Flow roundtrip: PASS 17 + 18 + ================================================================================ 19 + ARRAY ROUNDTRIP 20 + ================================================================================ 21 + 22 + Encode and decode arrays including nested arrays 23 + 24 + $ test_roundtrip array 25 + JSON array roundtrip: PASS 26 + YAML array roundtrip: PASS 27 + 28 + ================================================================================ 29 + OBJECT ROUNDTRIP 30 + ================================================================================ 31 + 32 + Encode and decode complex objects with nested structures 33 + 34 + $ test_roundtrip object 35 + JSON object roundtrip: PASS 36 + YAML object roundtrip: PASS 37 + 38 + ================================================================================ 39 + OPTIONAL FIELDS ROUNDTRIP 40 + ================================================================================ 41 + 42 + Encode and decode optional and nullable fields 43 + 44 + $ test_roundtrip optional 45 + Fatal error: exception Invalid_argument("option is None") 46 + [2]
+339
vendor/opam/yamlt/tests/cram/scalars_codec.t
··· 1 + Scalar Type Resolution Tests with Yamlt Codec 2 + ================================================== 3 + 4 + This test suite validates how YAML scalars are resolved based on the expected 5 + Jsont type codec, and compares behavior with JSON decoding. 6 + 7 + ================================================================================ 8 + NULL RESOLUTION 9 + ================================================================================ 10 + 11 + Explicit null value 12 + 13 + $ test_scalars null ../data/scalars/null_explicit.yml 14 + null_codec: null 15 + 16 + Tilde as null 17 + 18 + $ test_scalars null ../data/scalars/null_tilde.yml 19 + null_codec: null 20 + 21 + Empty value as null 22 + 23 + $ test_scalars null ../data/scalars/null_empty.yml 24 + null_codec: null 25 + 26 + ================================================================================ 27 + BOOLEAN TYPE-DIRECTED RESOLUTION 28 + ================================================================================ 29 + 30 + Plain "true" resolves to bool(true) with bool codec, but string "true" with string codec 31 + 32 + $ test_scalars bool ../data/scalars/bool_true_plain.yml 33 + === Bool Codec === 34 + JSON bool_codec 35 + decode: true 36 + YAML bool_codec 37 + decode: true 38 + 39 + === String Codec === 40 + JSON string_codec 41 + decode: ERROR: Expected string but found bool 42 + File "-", line 1, characters 10-11: 43 + File "-": in member value of 44 + File "-", line 1, characters 0-11: StringTest object 45 + YAML string_codec 46 + decode: "true" 47 + 48 + Quoted "true" always resolves to string, even with bool codec 49 + 50 + $ test_scalars bool ../data/scalars/bool_true_quoted.yml 51 + === Bool Codec === 52 + JSON bool_codec 53 + decode: ERROR: Expected bool but found string 54 + File "-", line 1, characters 10-11: 55 + File "-": in member value of 56 + File "-", line 1, characters 0-11: BoolTest object 57 + YAML bool_codec 58 + decode: true 59 + 60 + === String Codec === 61 + JSON string_codec 62 + decode: "true" 63 + YAML string_codec 64 + decode: "true" 65 + 66 + YAML-specific bool: "yes" resolves to bool(true) 67 + 68 + $ test_scalars bool ../data/scalars/bool_yes.yml 69 + === Bool Codec === 70 + JSON bool_codec 71 + decode: true 72 + YAML bool_codec 73 + decode: true 74 + 75 + === String Codec === 76 + JSON string_codec 77 + decode: ERROR: Expected string but found bool 78 + File "-", line 1, characters 10-11: 79 + File "-": in member value of 80 + File "-", line 1, characters 0-11: StringTest object 81 + YAML string_codec 82 + decode: "yes" 83 + 84 + Plain "false" and "no" work similarly 85 + 86 + $ test_scalars bool ../data/scalars/bool_false.yml 87 + === Bool Codec === 88 + JSON bool_codec 89 + decode: false 90 + YAML bool_codec 91 + decode: false 92 + 93 + === String Codec === 94 + JSON string_codec 95 + decode: ERROR: Expected string but found bool 96 + File "-", line 1, characters 10-11: 97 + File "-": in member value of 98 + File "-", line 1, characters 0-11: StringTest object 99 + YAML string_codec 100 + decode: "false" 101 + 102 + $ test_scalars bool ../data/scalars/bool_no.yml 103 + === Bool Codec === 104 + JSON bool_codec 105 + decode: false 106 + YAML bool_codec 107 + decode: false 108 + 109 + === String Codec === 110 + JSON string_codec 111 + decode: ERROR: Expected string but found bool 112 + File "-", line 1, characters 10-11: 113 + File "-": in member value of 114 + File "-", line 1, characters 0-11: StringTest object 115 + YAML string_codec 116 + decode: "no" 117 + 118 + ================================================================================ 119 + NUMBER RESOLUTION 120 + ================================================================================ 121 + 122 + Integer values 123 + 124 + $ test_scalars number ../data/scalars/number_int.yml 125 + JSON number_codec 126 + decode: 42 127 + YAML number_codec 128 + decode: 42 129 + 130 + Float values 131 + 132 + $ test_scalars number ../data/scalars/number_float.yml 133 + JSON number_codec 134 + decode: 3.1415899999999999 135 + YAML number_codec 136 + decode: 3.1415899999999999 137 + 138 + Hexadecimal notation (YAML-specific) 139 + 140 + $ test_scalars number ../data/scalars/number_hex.yml 141 + JSON number_codec 142 + decode: 42 143 + YAML number_codec 144 + decode: 42 145 + 146 + Octal notation (YAML-specific) 147 + 148 + $ test_scalars number ../data/scalars/number_octal.yml 149 + JSON number_codec 150 + decode: 42 151 + YAML number_codec 152 + decode: 42 153 + 154 + Negative numbers 155 + 156 + $ test_scalars number ../data/scalars/number_negative.yml 157 + JSON number_codec 158 + decode: -273.14999999999998 159 + YAML number_codec 160 + decode: -273.14999999999998 161 + 162 + ================================================================================ 163 + SPECIAL FLOAT VALUES (YAML-specific) 164 + ================================================================================ 165 + 166 + Positive infinity 167 + 168 + $ test_scalars special-float ../data/scalars/special_inf.yml 169 + value: +Infinity 170 + 171 + Negative infinity 172 + 173 + $ test_scalars special-float ../data/scalars/special_neg_inf.yml 174 + value: -Infinity 175 + 176 + Not-a-Number (NaN) 177 + 178 + $ test_scalars special-float ../data/scalars/special_nan.yml 179 + value: NaN 180 + 181 + ================================================================================ 182 + STRING RESOLUTION 183 + ================================================================================ 184 + 185 + Plain strings 186 + 187 + $ test_scalars string ../data/scalars/string_plain.yml 188 + JSON string_codec 189 + decode: "hello world" 190 + YAML string_codec 191 + decode: "hello world" 192 + 193 + Quoted numeric strings stay as strings 194 + 195 + $ test_scalars string ../data/scalars/string_quoted.yml 196 + JSON string_codec 197 + decode: "42" 198 + YAML string_codec 199 + decode: "42" 200 + 201 + Empty strings 202 + 203 + $ test_scalars string ../data/scalars/string_empty.yml 204 + JSON string_codec 205 + decode: "" 206 + YAML string_codec 207 + decode: "" 208 + 209 + ================================================================================ 210 + TYPE MISMATCH ERRORS 211 + ================================================================================ 212 + 213 + String when bool expected 214 + 215 + $ test_scalars type-mismatch ../data/scalars/mismatch_string_as_bool.yml bool 216 + Expected error: Expected bool but found scalar hello 217 + File "-": 218 + File "-": in member value of 219 + File "-": BoolTest object 220 + 221 + String when number expected 222 + 223 + $ test_scalars type-mismatch ../data/scalars/mismatch_string_as_number.yml number 224 + Expected error: Expected number but found scalar not-a-number 225 + File "-": 226 + File "-": in member value of 227 + File "-": NumberTest object 228 + 229 + Number when null expected 230 + 231 + $ test_scalars type-mismatch ../data/scalars/mismatch_number_as_null.yml null 232 + Expected error: Expected null but found scalar 42 233 + File "-": 234 + File "-": in member value of 235 + File "-": NullTest object 236 + 237 + ================================================================================ 238 + JSONT.ANY AUTO-RESOLUTION 239 + ================================================================================ 240 + 241 + With Jsont.any, scalars are auto-resolved based on their content 242 + 243 + Null auto-resolves to null 244 + 245 + $ test_scalars any ../data/scalars/any_null.yml 246 + JSON any_codec 247 + decode: decoded 248 + YAML any_codec 249 + decode: decoded 250 + 251 + Plain bool auto-resolves to bool 252 + 253 + $ test_scalars any ../data/scalars/any_bool.yml 254 + JSON any_codec 255 + decode: decoded 256 + YAML any_codec 257 + decode: decoded 258 + 259 + Number auto-resolves to number 260 + 261 + $ test_scalars any ../data/scalars/any_number.yml 262 + JSON any_codec 263 + decode: decoded 264 + YAML any_codec 265 + decode: decoded 266 + 267 + Plain string auto-resolves to string 268 + 269 + $ test_scalars any ../data/scalars/any_string.yml 270 + JSON any_codec 271 + decode: decoded 272 + YAML any_codec 273 + decode: decoded 274 + 275 + ================================================================================ 276 + ENCODING SCALARS 277 + ================================================================================ 278 + 279 + Encoding bool values 280 + 281 + $ test_scalars encode bool true 282 + JSON: {"value":true} 283 + YAML Block: 284 + value: true 285 + YAML Flow: {value: true} 286 + 287 + $ test_scalars encode bool false 288 + JSON: {"value":false} 289 + YAML Block: 290 + value: false 291 + YAML Flow: {value: false} 292 + 293 + Encoding numbers 294 + 295 + $ test_scalars encode number 42.5 296 + JSON: {"value":42.5} 297 + YAML Block: 298 + value: 42.5 299 + YAML Flow: {value: 42.5} 300 + 301 + Encoding strings 302 + 303 + $ test_scalars encode string "hello world" 304 + JSON: {"value":"hello world"} 305 + YAML Block: 306 + value: hello world 307 + YAML Flow: {value: hello world} 308 + 309 + Encoding null 310 + 311 + $ test_scalars encode null "" 312 + JSON: {"value":null} 313 + YAML Block: 314 + value: null 315 + YAML Flow: {value: null} 316 + 317 + ================================================================================ 318 + NEGATIVE TESTS - Wrong File Types 319 + ================================================================================ 320 + 321 + Attempting to decode an object file with a scalar codec should fail 322 + 323 + $ test_scalars string ../data/objects/simple.yml 324 + JSON string_codec 325 + decode: ERROR: Missing member value in StringTest object 326 + File "-", line 1, characters 0-28: 327 + YAML string_codec 328 + decode: ERROR: Missing member value in StringTest object 329 + File "-": 330 + 331 + Attempting to decode an array file with a scalar codec should fail 332 + 333 + $ test_scalars number ../data/arrays/int_array.yml 334 + JSON number_codec 335 + decode: ERROR: Missing member value in NumberTest object 336 + File "-", line 1, characters 0-27: 337 + YAML number_codec 338 + decode: ERROR: Missing member value in NumberTest object 339 + File "-":
+6
vendor/opam/yamlt/tests/data/arrays/bool_array.yml
··· 1 + values: 2 + - true 3 + - false 4 + - true 5 + - true 6 + - false
+1
vendor/opam/yamlt/tests/data/arrays/bool_array.yml.json
··· 1 + {"values": [true, false, true, true, false]}
+1
vendor/opam/yamlt/tests/data/arrays/empty_array.yml
··· 1 + items: []
+1
vendor/opam/yamlt/tests/data/arrays/empty_array.yml.json
··· 1 + {"items": []}
+5
vendor/opam/yamlt/tests/data/arrays/float_array.yml
··· 1 + values: 2 + - 1.5 3 + - 2.7 4 + - 3.14 5 + - 0.5
+1
vendor/opam/yamlt/tests/data/arrays/float_array.yml.json
··· 1 + {"values": [1.5, 2.7, 3.14, 0.5]}
+6
vendor/opam/yamlt/tests/data/arrays/int_array.yml
··· 1 + values: 2 + - 1 3 + - 2 4 + - 3 5 + - 4 6 + - 5
+1
vendor/opam/yamlt/tests/data/arrays/int_array.yml.json
··· 1 + {"values": [1, 2, 3, 4, 5]}
+4
vendor/opam/yamlt/tests/data/arrays/nested_array.yml
··· 1 + data: 2 + - [1, 2, 3] 3 + - [4, 5, 6] 4 + - [7, 8, 9]
+1
vendor/opam/yamlt/tests/data/arrays/nested_array.yml.json
··· 1 + {"data": [[1, 2, 3], [4, 5, 6], [7, 8, 9]]}
+6
vendor/opam/yamlt/tests/data/arrays/nullable_array.yml
··· 1 + values: 2 + - hello 3 + - null 4 + - world 5 + - null 6 + - test
+1
vendor/opam/yamlt/tests/data/arrays/nullable_array.yml.json
··· 1 + {"values": ["hello", null, "world", null, "test"]}
+7
vendor/opam/yamlt/tests/data/arrays/object_array.yml
··· 1 + persons: 2 + - name: Alice 3 + age: 30 4 + - name: Bob 5 + age: 25 6 + - name: Charlie 7 + age: 35
+1
vendor/opam/yamlt/tests/data/arrays/object_array.yml.json
··· 1 + {"persons": [{"name": "Alice", "age": 30}, {"name": "Bob", "age": 25}, {"name": "Charlie", "age": 35}]}
+4
vendor/opam/yamlt/tests/data/arrays/string_array.yml
··· 1 + items: 2 + - apple 3 + - banana 4 + - cherry
+1
vendor/opam/yamlt/tests/data/arrays/string_array.yml.json
··· 1 + {"items": ["apple", "banana", "cherry"]}
+5
vendor/opam/yamlt/tests/data/arrays/type_mismatch.yml
··· 1 + values: 2 + - 1 3 + - 2 4 + - not-a-number 5 + - 4
+4
vendor/opam/yamlt/tests/data/complex/complex_optional.yml
··· 1 + host: example.com 2 + port: 443 3 + ssl: true 4 + fallback_hosts: [backup1.example.com, backup2.example.com]
+1
vendor/opam/yamlt/tests/data/complex/complex_optional.yml.json
··· 1 + {"host": "example.com", "port": 443, "ssl": true, "fallback_hosts": ["backup1.example.com", "backup2.example.com"]}
+4
vendor/opam/yamlt/tests/data/complex/deep_nesting.yml
··· 1 + top: 2 + nested: 3 + data: 4 + value: 42
+1
vendor/opam/yamlt/tests/data/complex/deep_nesting.yml.json
··· 1 + {"top": {"nested": {"data": {"value": 42}}}}
+1
vendor/opam/yamlt/tests/data/complex/heterogeneous.yml
··· 1 + mixed: [42, "hello", true, null, 3.14]
+1
vendor/opam/yamlt/tests/data/complex/heterogeneous.yml.json
··· 1 + {"mixed": [42, "hello", true, null, 3.14]}
+8
vendor/opam/yamlt/tests/data/complex/mixed_structure.yml
··· 1 + name: products 2 + items: 3 + - id: 1 4 + tags: [new, sale, featured] 5 + - id: 2 6 + tags: [clearance] 7 + - id: 3 8 + tags: [premium, exclusive]
+1
vendor/opam/yamlt/tests/data/complex/mixed_structure.yml.json
··· 1 + {"name": "products", "items": [{"id": 1, "tags": ["new", "sale", "featured"]}, {"id": 2, "tags": ["clearance"]}, {"id": 3, "tags": ["premium", "exclusive"]}]}
+2
vendor/opam/yamlt/tests/data/edge/empty_collections.yml
··· 1 + empty_array: [] 2 + empty_object_array: []
+1
vendor/opam/yamlt/tests/data/edge/empty_collections.yml.json
··· 1 + {"empty_array": [], "empty_object_array": []}
+3
vendor/opam/yamlt/tests/data/edge/large_numbers.yml
··· 1 + large_int: 9007199254740991 2 + large_float: 1.7976931348623157e+308 3 + small_float: 2.2250738585072014e-308
+1
vendor/opam/yamlt/tests/data/edge/large_numbers.yml.json
··· 1 + {"large_int": 9007199254740991, "large_float": 1.7976931348623157e+308, "small_float": 2.2250738585072014e-308}
+1
vendor/opam/yamlt/tests/data/edge/single_element.yml
··· 1 + single: [42]
+1
vendor/opam/yamlt/tests/data/edge/single_element.yml.json
··· 1 + {"single": [42]}
+1
vendor/opam/yamlt/tests/data/edge/special_chars.yml
··· 1 + content: "Line 1\nLine 2\tTabbed\r\nWindows line"
+1
vendor/opam/yamlt/tests/data/edge/special_chars.yml.json
··· 1 + {"content": "Line 1\nLine 2\tTabbed\r\nWindows line"}
+3
vendor/opam/yamlt/tests/data/edge/special_keys.yml
··· 1 + "key.with.dots": value1 2 + "key-with-dashes": value2 3 + "key:with:colons": value3
+1
vendor/opam/yamlt/tests/data/edge/special_keys.yml.json
··· 1 + {"key.with.dots": "value1", "key-with-dashes": "value2", "key:with:colons": "value3"}
+3
vendor/opam/yamlt/tests/data/edge/unicode.yml
··· 1 + emoji: "🎉🚀✨" 2 + chinese: "你好世界" 3 + rtl: "مرحبا"
+1
vendor/opam/yamlt/tests/data/edge/unicode.yml.json
··· 1 + {"emoji": "🎉🚀✨", "chinese": "你好世界", "rtl": "مرحبا"}
+5
vendor/opam/yamlt/tests/data/formats/comments.yml
··· 1 + # Configuration file with comments 2 + host: localhost # The server host 3 + port: 8080 # The server port 4 + # Enable debug mode for development 5 + debug: true
+1
vendor/opam/yamlt/tests/data/formats/empty_doc.yml
··· 1 + value: null
+1
vendor/opam/yamlt/tests/data/formats/empty_doc.yml.json
··· 1 + {"value": null}
+1
vendor/opam/yamlt/tests/data/formats/explicit_tags.yml
··· 1 + data: !!str 123
+5
vendor/opam/yamlt/tests/data/formats/folded_string.yml
··· 1 + content: > 2 + This is a folded string that 3 + spans multiple lines but will 4 + be folded into a single line 5 + with spaces between words
+1
vendor/opam/yamlt/tests/data/formats/folded_string.yml.json
··· 1 + {"content": "This is a folded string that spans multiple lines but will be folded into a single line with spaces between words\n"}
+5
vendor/opam/yamlt/tests/data/formats/literal_string.yml
··· 1 + content: | 2 + This is a literal string 3 + with multiple lines 4 + preserving newlines 5 + and indentation
+1
vendor/opam/yamlt/tests/data/formats/literal_string.yml.json
··· 1 + {"content": "This is a literal string\nwith multiple lines\npreserving newlines\nand indentation\n"}
+3
vendor/opam/yamlt/tests/data/formats/number_formats.yml
··· 1 + hex: 0xFF 2 + octal: 0o77 3 + binary: 0b1010
+1
vendor/opam/yamlt/tests/data/formats/number_formats.yml.json
··· 1 + {"hex": 255, "octal": 63, "binary": 10}
+6
vendor/opam/yamlt/tests/data/locations/array_error.yml
··· 1 + values: 2 + - 1 3 + - 2 4 + - not-a-number 5 + - 4 6 + - 5
+4
vendor/opam/yamlt/tests/data/locations/block_style.yml
··· 1 + items: 2 + - apple 3 + - banana 4 + - cherry
+1
vendor/opam/yamlt/tests/data/locations/flow_style.yml
··· 1 + items: [apple, banana, cherry]
+2
vendor/opam/yamlt/tests/data/locations/missing_field.yml
··· 1 + field_a: hello 2 + field_b: 42
+5
vendor/opam/yamlt/tests/data/locations/nested_error.yml
··· 1 + name: Bob 2 + address: 3 + street: 123 Main St 4 + city: Springfield 5 + zip: invalid-zip
+2
vendor/opam/yamlt/tests/data/locations/simple.yml
··· 1 + host: localhost 2 + port: 8080
+2
vendor/opam/yamlt/tests/data/locations/type_error.yml
··· 1 + name: Alice 2 + age: not-a-number
+2
vendor/opam/yamlt/tests/data/locations/valid_settings.yml
··· 1 + timeout: 30 2 + retries: 3
+9
vendor/opam/yamlt/tests/data/multidoc/all_errors.yml
··· 1 + --- 2 + name: Alice 3 + age: invalid1 4 + --- 5 + name: Bob 6 + age: invalid2 7 + --- 8 + name: Charlie 9 + age: invalid3
+12
vendor/opam/yamlt/tests/data/multidoc/arrays.yml
··· 1 + --- 2 + - 1 3 + - 2 4 + - 3 5 + --- 6 + - apple 7 + - banana 8 + - cherry 9 + --- 10 + - true 11 + - false 12 + - true
+7
vendor/opam/yamlt/tests/data/multidoc/empty_docs.yml
··· 1 + --- 2 + name: Alice 3 + age: 30 4 + --- 5 + --- 6 + name: Charlie 7 + age: 35
+9
vendor/opam/yamlt/tests/data/multidoc/missing_fields.yml
··· 1 + --- 2 + name: Alice 3 + age: 30 4 + --- 5 + name: Bob 6 + --- 7 + name: Charlie 8 + age: 35 9 + city: Springfield
+9
vendor/opam/yamlt/tests/data/multidoc/mixed_errors.yml
··· 1 + --- 2 + name: Alice 3 + age: 30 4 + --- 5 + name: Bob 6 + age: not-a-number 7 + --- 8 + name: Charlie 9 + age: 35
+18
vendor/opam/yamlt/tests/data/multidoc/nested.yml
··· 1 + --- 2 + name: Alice 3 + age: 30 4 + address: 5 + street: 123 Main St 6 + city: Boston 7 + --- 8 + name: Bob 9 + age: 25 10 + address: 11 + street: 456 Oak Ave 12 + city: Seattle 13 + --- 14 + name: Charlie 15 + age: 35 16 + address: 17 + street: 789 Pine Rd 18 + city: Portland
+8
vendor/opam/yamlt/tests/data/multidoc/scalars.yml
··· 1 + --- 2 + hello world 3 + --- 4 + 42 5 + --- 6 + true 7 + --- 8 + null
+9
vendor/opam/yamlt/tests/data/multidoc/simple.yml
··· 1 + --- 2 + name: Alice 3 + age: 30 4 + --- 5 + name: Bob 6 + age: 25 7 + --- 8 + name: Charlie 9 + age: 35
+2
vendor/opam/yamlt/tests/data/objects/case_circle.yml
··· 1 + type: circle 2 + radius: 5.5
+1
vendor/opam/yamlt/tests/data/objects/case_circle.yml.json
··· 1 + {"type": "circle", "radius": 5.5}
+3
vendor/opam/yamlt/tests/data/objects/case_rectangle.yml
··· 1 + type: rectangle 2 + width: 10.0 3 + height: 20.0
+1
vendor/opam/yamlt/tests/data/objects/case_rectangle.yml.json
··· 1 + {"type": "rectangle", "width": 10.0, "height": 20.0}
+1
vendor/opam/yamlt/tests/data/objects/defaults_empty.yml
··· 1 + {}
+1
vendor/opam/yamlt/tests/data/objects/defaults_empty.yml.json
··· 1 + {}
+1
vendor/opam/yamlt/tests/data/objects/defaults_partial.yml
··· 1 + timeout: 60
+1
vendor/opam/yamlt/tests/data/objects/defaults_partial.yml.json
··· 1 + {"timeout": 60}
+1
vendor/opam/yamlt/tests/data/objects/missing_required.yml
··· 1 + name: Incomplete
+5
vendor/opam/yamlt/tests/data/objects/nested.yml
··· 1 + name: Bob 2 + address: 3 + street: 123 Main St 4 + city: Springfield 5 + zip: "12345"
+1
vendor/opam/yamlt/tests/data/objects/nested.yml.json
··· 1 + {"name": "Bob", "address": {"street": "123 Main St", "city": "Springfield", "zip": "12345"}}
+3
vendor/opam/yamlt/tests/data/objects/optional_all.yml
··· 1 + host: localhost 2 + port: 8080 3 + debug: true
+1
vendor/opam/yamlt/tests/data/objects/optional_all.yml.json
··· 1 + {"host": "localhost", "port": 8080, "debug": true}
+1
vendor/opam/yamlt/tests/data/objects/optional_minimal.yml
··· 1 + host: minimal.com
+1
vendor/opam/yamlt/tests/data/objects/optional_minimal.yml.json
··· 1 + {"host": "minimal.com"}
+2
vendor/opam/yamlt/tests/data/objects/optional_partial.yml
··· 1 + host: example.com 2 + port: 3000
+1
vendor/opam/yamlt/tests/data/objects/optional_partial.yml.json
··· 1 + {"host": "example.com", "port": 3000}
+2
vendor/opam/yamlt/tests/data/objects/simple.yml
··· 1 + name: Alice 2 + age: 30
+1
vendor/opam/yamlt/tests/data/objects/simple.yml.json
··· 1 + {"name": "Alice", "age": 30}
+3
vendor/opam/yamlt/tests/data/objects/unknown_keep.yml
··· 1 + name: Charlie 2 + extra1: value1 3 + extra2: value2
+1
vendor/opam/yamlt/tests/data/objects/unknown_keep.yml.json
··· 1 + {"name": "Charlie", "extra1": "value1", "extra2": "value2"}
+3
vendor/opam/yamlt/tests/data/objects/unknown_members.yml
··· 1 + name: Alice 2 + age: 30 3 + extra: not_expected
+1
vendor/opam/yamlt/tests/data/scalars/any_bool.yml
··· 1 + value: true
+1
vendor/opam/yamlt/tests/data/scalars/any_bool.yml.json
··· 1 + {"value": true}
+1
vendor/opam/yamlt/tests/data/scalars/any_null.yml
··· 1 + value: null
+1
vendor/opam/yamlt/tests/data/scalars/any_null.yml.json
··· 1 + {"value": null}
+1
vendor/opam/yamlt/tests/data/scalars/any_number.yml
··· 1 + value: 123.45
+1
vendor/opam/yamlt/tests/data/scalars/any_number.yml.json
··· 1 + {"value": 123.45}
+1
vendor/opam/yamlt/tests/data/scalars/any_string.yml
··· 1 + value: hello
+1
vendor/opam/yamlt/tests/data/scalars/any_string.yml.json
··· 1 + {"value": "hello"}
+1
vendor/opam/yamlt/tests/data/scalars/bool_false.yml
··· 1 + value: false
+1
vendor/opam/yamlt/tests/data/scalars/bool_false.yml.json
··· 1 + {"value": false}
+1
vendor/opam/yamlt/tests/data/scalars/bool_no.yml
··· 1 + value: no
+1
vendor/opam/yamlt/tests/data/scalars/bool_no.yml.json
··· 1 + {"value": false}
+1
vendor/opam/yamlt/tests/data/scalars/bool_true_plain.yml
··· 1 + value: true
+1
vendor/opam/yamlt/tests/data/scalars/bool_true_plain.yml.json
··· 1 + {"value": true}
+1
vendor/opam/yamlt/tests/data/scalars/bool_true_quoted.yml
··· 1 + value: "true"
+1
vendor/opam/yamlt/tests/data/scalars/bool_true_quoted.yml.json
··· 1 + {"value": "true"}
+1
vendor/opam/yamlt/tests/data/scalars/bool_yes.yml
··· 1 + value: yes
+1
vendor/opam/yamlt/tests/data/scalars/bool_yes.yml.json
··· 1 + {"value": true}
+1
vendor/opam/yamlt/tests/data/scalars/mismatch_number_as_null.yml
··· 1 + value: 42
+1
vendor/opam/yamlt/tests/data/scalars/mismatch_string_as_bool.yml
··· 1 + value: hello
+1
vendor/opam/yamlt/tests/data/scalars/mismatch_string_as_number.yml
··· 1 + value: not-a-number
+1
vendor/opam/yamlt/tests/data/scalars/null_empty.yml
··· 1 + value:
+1
vendor/opam/yamlt/tests/data/scalars/null_explicit.yml
··· 1 + value: null
+1
vendor/opam/yamlt/tests/data/scalars/null_tilde.yml
··· 1 + value: ~
+1
vendor/opam/yamlt/tests/data/scalars/number_float.yml
··· 1 + value: 3.14159
+1
vendor/opam/yamlt/tests/data/scalars/number_float.yml.json
··· 1 + {"value": 3.14159}
+1
vendor/opam/yamlt/tests/data/scalars/number_hex.yml
··· 1 + value: 0x2A
+1
vendor/opam/yamlt/tests/data/scalars/number_hex.yml.json
··· 1 + {"value": 42}
+1
vendor/opam/yamlt/tests/data/scalars/number_int.yml
··· 1 + value: 42
+1
vendor/opam/yamlt/tests/data/scalars/number_int.yml.json
··· 1 + {"value": 42}
+1
vendor/opam/yamlt/tests/data/scalars/number_negative.yml
··· 1 + value: -273.15
+1
vendor/opam/yamlt/tests/data/scalars/number_negative.yml.json
··· 1 + {"value": -273.15}
+1
vendor/opam/yamlt/tests/data/scalars/number_octal.yml
··· 1 + value: 0o52
+1
vendor/opam/yamlt/tests/data/scalars/number_octal.yml.json
··· 1 + {"value": 42}
+1
vendor/opam/yamlt/tests/data/scalars/special_inf.yml
··· 1 + value: .inf
+1
vendor/opam/yamlt/tests/data/scalars/special_nan.yml
··· 1 + value: .nan
+1
vendor/opam/yamlt/tests/data/scalars/special_neg_inf.yml
··· 1 + value: -.inf
+1
vendor/opam/yamlt/tests/data/scalars/string_empty.yml
··· 1 + value: ""
+1
vendor/opam/yamlt/tests/data/scalars/string_empty.yml.json
··· 1 + {"value": ""}
+1
vendor/opam/yamlt/tests/data/scalars/string_plain.yml
··· 1 + value: hello world
+1
vendor/opam/yamlt/tests/data/scalars/string_plain.yml.json
··· 1 + {"value": "hello world"}
+1
vendor/opam/yamlt/tests/data/scalars/string_quoted.yml
··· 1 + value: "42"
+1
vendor/opam/yamlt/tests/data/scalars/string_quoted.yml.json
··· 1 + {"value": "42"}
+33
vendor/opam/yamlt/yamlt.opam
··· 1 + # This file is generated by dune, edit dune-project instead 2 + opam-version: "2.0" 3 + synopsis: "YAML codec using Jsont type descriptions" 4 + description: 5 + "Allows the same Jsont.t codec definitions to work for both JSON and YAML" 6 + maintainer: ["Anil Madhavapeddy <anil@recoil.org>"] 7 + authors: ["Anil Madhavapeddy"] 8 + license: "ISC" 9 + homepage: "https://tangled.org/@anil.recoil.org/ocaml-yamlt" 10 + bug-reports: "https://tangled.org/@anil.recoil.org/ocaml-yamlt/issues" 11 + depends: [ 12 + "dune" {>= "3.18"} 13 + "ocaml" {>= "4.14.0"} 14 + "yamlrw" 15 + "jsont" 16 + "bytesrw" 17 + "odoc" {with-doc} 18 + ] 19 + build: [ 20 + ["dune" "subst"] {dev} 21 + [ 22 + "dune" 23 + "build" 24 + "-p" 25 + name 26 + "-j" 27 + jobs 28 + "@install" 29 + "@runtest" {with-test} 30 + "@doc" {with-doc} 31 + ] 32 + ] 33 + x-maintenance-intent: ["(latest)"]