···33 SPDX-License-Identifier: ISC
44 ---------------------------------------------------------------------------*)
5566-open Bytesrw
76open Jsont.Repr
87open Yamlrw
98···6564 let first_line =
6665 (start.Position.line, start.Position.index - start.Position.column + 1)
6766 in
6767+ (* Handle case where stop is at the start of a new line (column 1)
6868+ This happens when the span includes a trailing newline.
6969+ The last_byte is on the previous line, so we need to calculate
7070+ the line start position based on last_byte, not stop. *)
6871 let last_line =
6969- (stop.Position.line, stop.Position.index - stop.Position.column + 1)
7272+ if stop.Position.column = 1 && stop.Position.line > start.Position.line then
7373+ (* last_byte is on the previous line (stop.line - 1)
7474+ We need to estimate where that line starts. Since we don't have
7575+ the full text, we can't calculate it exactly, but we can use:
7676+ last_byte - (estimated_column - 1)
7777+ For now, we'll use the same line as start if they're close,
7878+ or just report it as the previous line. *)
7979+ let last_line_num = stop.Position.line - 1 in
8080+ (* Estimate: assume last_byte is somewhere on the previous line.
8181+ We'll use the byte position minus a reasonable offset.
8282+ This is approximate but better than wrapping to the next line. *)
8383+ if last_line_num = start.Position.line then
8484+ (* Same line as start - use start's line position *)
8585+ first_line
8686+ else
8787+ (* Different line - estimate line start as last_byte minus some offset
8888+ Since we subtracted 1 from stop.index to get last_byte, and stop.column was 1,
8989+ last_byte should be the newline character on the previous line.
9090+ The line likely started much earlier, but we'll estimate conservatively. *)
9191+ (last_line_num, last_byte)
9292+ else
9393+ (stop.Position.line, stop.Position.index - stop.Position.column + 1)
7094 in
7195 let textloc =
7296 Jsont.Textloc.make ~file:d.file ~first_byte ~last_byte ~first_line
···656680 in
657681 loop ()
658682683683+(* Skip to the end of the current document after an error *)
684684+let skip_to_document_end d =
685685+ let rec loop depth =
686686+ match peek_event d with
687687+ | None -> ()
688688+ | Some { Event.event = Event.Stream_end; _ } -> ()
689689+ | Some { Event.event = Event.Document_end _; _ } ->
690690+ skip_event d;
691691+ if depth = 0 then () else loop (depth - 1)
692692+ | Some { Event.event = Event.Document_start _; _ } ->
693693+ skip_event d;
694694+ loop (depth + 1)
695695+ | Some _ ->
696696+ skip_event d;
697697+ loop depth
698698+ in
699699+ loop 0
700700+659701(* Public decode API *)
660702703703+(* Decode all documents from a multi-document YAML stream *)
704704+let decode_all' ?(layout = false) ?(locs = false) ?(file = "-")
705705+ ?(max_depth = 100) ?(max_nodes = 10_000_000) t reader =
706706+ let parser = Parser.of_reader reader in
707707+ let d = make_decoder ~layout ~locs ~file ~max_depth ~max_nodes parser in
708708+ let t' = Jsont.Repr.of_t t in
709709+ let rec next_doc () =
710710+ match peek_event d with
711711+ | None -> Seq.Nil
712712+ | Some { Event.event = Event.Stream_end; _ } ->
713713+ skip_event d;
714714+ Seq.Nil
715715+ | Some _ -> (
716716+ try
717717+ skip_to_content d;
718718+ (* Reset node count for each document *)
719719+ d.node_count <- 0;
720720+ let v = decode d ~nest:0 t' in
721721+ (* Skip document end marker if present *)
722722+ (match peek_event d with
723723+ | Some { Event.event = Event.Document_end _; _ } -> skip_event d
724724+ | _ -> ());
725725+ Seq.Cons (Ok v, next_doc)
726726+ with
727727+ | Jsont.Error e ->
728728+ skip_to_document_end d;
729729+ Seq.Cons (Error e, next_doc)
730730+ | Error.Yamlrw_error err ->
731731+ skip_to_document_end d;
732732+ let msg = Error.to_string err in
733733+ let e =
734734+ Jsont.Error.make_msg Jsont.Error.Context.empty Jsont.Meta.none msg
735735+ in
736736+ Seq.Cons (Error e, next_doc))
737737+ in
738738+ next_doc
739739+740740+let decode_all ?layout ?locs ?file ?max_depth ?max_nodes t reader =
741741+ decode_all' ?layout ?locs ?file ?max_depth ?max_nodes t reader
742742+ |> Seq.map (Result.map_error Jsont.Error.to_string)
743743+661744let decode' ?layout ?locs ?file ?max_depth ?max_nodes t reader =
662745 let parser = Parser.of_reader reader in
663746 let d = make_decoder ?layout ?locs ?file ?max_depth ?max_nodes parser in
···676759let decode ?layout ?locs ?file ?max_depth ?max_nodes t reader =
677760 Result.map_error Jsont.Error.to_string
678761 (decode' ?layout ?locs ?file ?max_depth ?max_nodes t reader)
679679-680680-let decode_string' ?layout ?locs ?file ?max_depth ?max_nodes t s =
681681- decode' ?layout ?locs ?file ?max_depth ?max_nodes t (Bytes.Reader.of_string s)
682682-683683-let decode_string ?layout ?locs ?file ?max_depth ?max_nodes t s =
684684- decode ?layout ?locs ?file ?max_depth ?max_nodes t (Bytes.Reader.of_string s)
685762686763(* Encoder *)
687764···908985 Result.map_error Jsont.Error.to_string
909986 (encode' ?buf ?format ?indent ?explicit_doc ?scalar_style t v ~eod writer)
910987911911-let encode_string' ?buf ?format ?indent ?explicit_doc ?scalar_style t v =
912912- let b = Buffer.create 256 in
913913- let writer = Bytes.Writer.of_buffer b in
914914- match
915915- encode' ?buf ?format ?indent ?explicit_doc ?scalar_style t v ~eod:true
916916- writer
917917- with
918918- | Ok () -> Ok (Buffer.contents b)
919919- | Error e -> Error e
920920-921921-let encode_string ?buf ?format ?indent ?explicit_doc ?scalar_style t v =
922922- Result.map_error Jsont.Error.to_string
923923- (encode_string' ?buf ?format ?indent ?explicit_doc ?scalar_style t v)
924924-925988(* Recode *)
926989927990let recode ?layout ?locs ?file ?max_depth ?max_nodes ?buf ?format ?indent
···936999 | Ok v ->
9371000 encode ?buf ?format ?indent ?explicit_doc ?scalar_style t v ~eod writer
9381001 | Error e -> Error (Jsont.Error.to_string e)
939939-940940-let recode_string ?layout ?locs ?file ?max_depth ?max_nodes ?buf ?format ?indent
941941- ?explicit_doc ?scalar_style t s =
942942- let format =
943943- match (layout, format) with Some true, None -> Some Layout | _, f -> f
944944- in
945945- let layout =
946946- match (layout, format) with None, Some Layout -> Some true | l, _ -> l
947947- in
948948- match decode_string' ?layout ?locs ?file ?max_depth ?max_nodes t s with
949949- | Ok v -> encode_string ?buf ?format ?indent ?explicit_doc ?scalar_style t v
950950- | Error e -> Error (Jsont.Error.to_string e)
+11-47
lib/yamlt.mli
···7171 ('a, Jsont.Error.t) result
7272(** [decode'] is like {!val-decode} but preserves the error structure. *)
73737474-val decode_string :
7474+val decode_all :
7575 ?layout:bool ->
7676 ?locs:bool ->
7777 ?file:Jsont.Textloc.fpath ->
7878 ?max_depth:int ->
7979 ?max_nodes:int ->
8080 'a Jsont.t ->
8181- string ->
8282- ('a, string) result
8383-(** [decode_string] is like {!val-decode} but decodes directly from a string. *)
8181+ Bytes.Reader.t ->
8282+ ('a, string) result Seq.t
8383+(** [decode_all t r] decodes all documents from a multi-document YAML stream.
8484+ Returns a sequence where each element is a result of decoding one document.
8585+ Parameters are as in {!val-decode}. Use this for YAML streams containing
8686+ multiple documents separated by [---]. *)
84878585-val decode_string' :
8888+val decode_all' :
8689 ?layout:bool ->
8790 ?locs:bool ->
8891 ?file:Jsont.Textloc.fpath ->
8992 ?max_depth:int ->
9093 ?max_nodes:int ->
9194 'a Jsont.t ->
9292- string ->
9393- ('a, Jsont.Error.t) result
9494-(** [decode_string'] is like {!val-decode'} but decodes directly from a string.
9595-*)
9595+ Bytes.Reader.t ->
9696+ ('a, Jsont.Error.t) result Seq.t
9797+(** [decode_all'] is like {!val-decode_all} but preserves the error structure. *)
96989799(** {1:encode Encode} *)
98100···138140 (unit, Jsont.Error.t) result
139141(** [encode'] is like {!val-encode} but preserves the error structure. *)
140142141141-val encode_string :
142142- ?buf:Stdlib.Bytes.t ->
143143- ?format:yaml_format ->
144144- ?indent:int ->
145145- ?explicit_doc:bool ->
146146- ?scalar_style:Yamlrw.Scalar_style.t ->
147147- 'a Jsont.t ->
148148- 'a ->
149149- (string, string) result
150150-(** [encode_string] is like {!val-encode} but writes to a string. *)
151151-152152-val encode_string' :
153153- ?buf:Stdlib.Bytes.t ->
154154- ?format:yaml_format ->
155155- ?indent:int ->
156156- ?explicit_doc:bool ->
157157- ?scalar_style:Yamlrw.Scalar_style.t ->
158158- 'a Jsont.t ->
159159- 'a ->
160160- (string, Jsont.Error.t) result
161161-(** [encode_string'] is like {!val-encode'} but writes to a string. *)
162162-163143(** {1:recode Recode}
164144165145 The defaults in these functions are those of {!val-decode} and
···183163 eod:bool ->
184164 (unit, string) result
185165(** [recode t r w] is {!val-decode} followed by {!val-encode}. *)
186186-187187-val recode_string :
188188- ?layout:bool ->
189189- ?locs:bool ->
190190- ?file:Jsont.Textloc.fpath ->
191191- ?max_depth:int ->
192192- ?max_nodes:int ->
193193- ?buf:Stdlib.Bytes.t ->
194194- ?format:yaml_format ->
195195- ?indent:int ->
196196- ?explicit_doc:bool ->
197197- ?scalar_style:Yamlrw.Scalar_style.t ->
198198- 'a Jsont.t ->
199199- string ->
200200- (string, string) result
201201-(** [recode_string] is like {!val-recode} but operates on strings. *)
202166203167(** {1:yaml_mapping YAML to JSON Mapping}
204168
···11+open Bytesrw
22+13let () =
24 let codec1 =
35 Jsont.Object.map ~kind:"Test" (fun arr -> arr)
···911 let yaml1 = "values: [a, b, c]" in
10121113 Printf.printf "Test 1: Non-optional array:\n";
1212- (match Yamlt.decode_string codec1 yaml1 with
1414+ (match Yamlt.decode codec1 (Bytes.Reader.of_string yaml1) with
1315 | Ok arr -> Printf.printf "Result: [%d items]\n" (Array.length arr)
1416 | Error e -> Printf.printf "Error: %s\n" e);
1517···2224 in
23252426 Printf.printf "\nTest 2: Jsont.option (Jsont.array):\n";
2525- match Yamlt.decode_string codec2 yaml1 with
2727+ match Yamlt.decode codec2 (Bytes.Reader.of_string yaml1) with
2628 | Ok arr -> (
2729 match arr with
2830 | None -> Printf.printf "Result: None\n"
+20-14
tests/bin/test_arrays.ml
···5566(** Test array codec functionality with Yamlt *)
7788+open Bytesrw
99+810(* Helper to read file *)
911let read_file path =
1012 let ic = open_in path in
···4244 let yaml = read_file file in
4345 let json = read_file (file ^ ".json") in
4446 let json_result = Jsont_bytesrw.decode_string M.numbers_codec json in
4545- let yaml_result = Yamlt.decode_string M.numbers_codec yaml in
4747+ let yaml_result = Yamlt.decode M.numbers_codec (Bytes.Reader.of_string yaml) in
46484749 show_result_both "int_array"
4850 (Result.map M.show json_result)
···6769 let yaml = read_file file in
6870 let json = read_file (file ^ ".json") in
6971 let json_result = Jsont_bytesrw.decode_string M.tags_codec json in
7070- let yaml_result = Yamlt.decode_string M.tags_codec yaml in
7272+ let yaml_result = Yamlt.decode M.tags_codec (Bytes.Reader.of_string yaml) in
71737274 show_result_both "string_array"
7375 (Result.map M.show json_result)
···9294 let yaml = read_file file in
9395 let json = read_file (file ^ ".json") in
9496 let json_result = Jsont_bytesrw.decode_string M.measurements_codec json in
9595- let yaml_result = Yamlt.decode_string M.measurements_codec yaml in
9797+ let yaml_result = Yamlt.decode M.measurements_codec (Bytes.Reader.of_string yaml) in
96989799 show_result_both "float_array"
98100 (Result.map M.show json_result)
···114116 let yaml = read_file file in
115117 let json = read_file (file ^ ".json") in
116118 let json_result = Jsont_bytesrw.decode_string M.empty_codec json in
117117- let yaml_result = Yamlt.decode_string M.empty_codec yaml in
119119+ let yaml_result = Yamlt.decode M.empty_codec (Bytes.Reader.of_string yaml) in
118120119121 show_result_both "empty_array"
120122 (Result.map M.show json_result)
···147149 let yaml = read_file file in
148150 let json = read_file (file ^ ".json") in
149151 let json_result = Jsont_bytesrw.decode_string M.people_codec json in
150150- let yaml_result = Yamlt.decode_string M.people_codec yaml in
152152+ let yaml_result = Yamlt.decode M.people_codec (Bytes.Reader.of_string yaml) in
151153152154 show_result_both "object_array"
153155 (Result.map M.show json_result)
···176178 let yaml = read_file file in
177179 let json = read_file (file ^ ".json") in
178180 let json_result = Jsont_bytesrw.decode_string M.matrix_codec json in
179179- let yaml_result = Yamlt.decode_string M.matrix_codec yaml in
181181+ let yaml_result = Yamlt.decode M.matrix_codec (Bytes.Reader.of_string yaml) in
180182181183 show_result_both "nested_arrays"
182184 (Result.map M.show json_result)
···194196 |> Jsont.Object.finish
195197 end in
196198 let yaml = read_file file in
197197- let result = Yamlt.decode_string M.numbers_codec yaml in
199199+ let result = Yamlt.decode M.numbers_codec (Bytes.Reader.of_string yaml) in
198200 match result with
199201 | Ok _ -> Printf.printf "Unexpected success\n"
200202 | Error e -> Printf.printf "Expected error: %s\n" e
···217219 let yaml = read_file file in
218220 let json = read_file (file ^ ".json") in
219221 let json_result = Jsont_bytesrw.decode_string M.flags_codec json in
220220- let yaml_result = Yamlt.decode_string M.flags_codec yaml in
222222+ let yaml_result = Yamlt.decode M.flags_codec (Bytes.Reader.of_string yaml) in
221223222224 show_result_both "bool_array"
223225 (Result.map M.show json_result)
···244246 let yaml = read_file file in
245247 let json = read_file (file ^ ".json") in
246248 let json_result = Jsont_bytesrw.decode_string M.nullable_codec json in
247247- let yaml_result = Yamlt.decode_string M.nullable_codec yaml in
249249+ let yaml_result = Yamlt.decode M.nullable_codec (Bytes.Reader.of_string yaml) in
248250249251 show_result_both "nullable_array"
250252 (Result.map M.show json_result)
···274276 | Error e -> Printf.printf "JSON ERROR: %s\n" e);
275277276278 (* Encode to YAML Block *)
277277- (match Yamlt.encode_string ~format:Yamlt.Block M.data_codec data with
278278- | Ok s -> Printf.printf "YAML Block:\n%s" s
279279- | Error e -> Printf.printf "YAML Block ERROR: %s\n" e);
279279+ (let b = Buffer.create 256 in
280280+ let writer = Bytes.Writer.of_buffer b in
281281+ match Yamlt.encode ~format:Yamlt.Block M.data_codec data ~eod:true writer with
282282+ | Ok () -> Printf.printf "YAML Block:\n%s" (Buffer.contents b)
283283+ | Error e -> Printf.printf "YAML Block ERROR: %s\n" e);
280284281285 (* Encode to YAML Flow *)
282282- match Yamlt.encode_string ~format:Yamlt.Flow M.data_codec data with
283283- | Ok s -> Printf.printf "YAML Flow: %s" s
286286+ let b = Buffer.create 256 in
287287+ let writer = Bytes.Writer.of_buffer b in
288288+ match Yamlt.encode ~format:Yamlt.Flow M.data_codec data ~eod:true writer with
289289+ | Ok () -> Printf.printf "YAML Flow: %s" (Buffer.contents b)
284290 | Error e -> Printf.printf "YAML Flow ERROR: %s\n" e
285291286292let () =
+6-4
tests/bin/test_complex.ml
···5566(** Test complex nested types with Yamlt *)
7788+open Bytesrw
99+810(* Helper to read file *)
911let read_file path =
1012 let ic = open_in path in
···5759 let yaml = read_file file in
5860 let json = read_file (file ^ ".json") in
5961 let json_result = Jsont_bytesrw.decode_string M.root_codec json in
6060- let yaml_result = Yamlt.decode_string M.root_codec yaml in
6262+ let yaml_result = Yamlt.decode M.root_codec (Bytes.Reader.of_string yaml) in
61636264 show_result_both "deep_nesting"
6365 (Result.map M.show json_result)
···9698 let yaml = read_file file in
9799 let json = read_file (file ^ ".json") in
98100 let json_result = Jsont_bytesrw.decode_string M.collection_codec json in
9999- let yaml_result = Yamlt.decode_string M.collection_codec yaml in
101101+ let yaml_result = Yamlt.decode M.collection_codec (Bytes.Reader.of_string yaml) in
100102101103 show_result_both "mixed_structure"
102104 (Result.map M.show json_result)
···144146 let yaml = read_file file in
145147 let json = read_file (file ^ ".json") in
146148 let json_result = Jsont_bytesrw.decode_string M.config_codec json in
147147- let yaml_result = Yamlt.decode_string M.config_codec yaml in
149149+ let yaml_result = Yamlt.decode M.config_codec (Bytes.Reader.of_string yaml) in
148150149151 show_result_both "complex_optional"
150152 (Result.map M.show json_result)
···167169 let yaml = read_file file in
168170 let json = read_file (file ^ ".json") in
169171 let json_result = Jsont_bytesrw.decode_string M.data_codec json in
170170- let yaml_result = Yamlt.decode_string M.data_codec yaml in
172172+ let yaml_result = Yamlt.decode M.data_codec (Bytes.Reader.of_string yaml) in
171173172174 show_result_both "heterogeneous"
173175 (Result.map M.show json_result)
+18-14
tests/bin/test_comprehensive.ml
···11+open Bytesrw
22+13let () =
24 (* Test 1: Null handling with option types *)
35 Printf.printf "=== NULL HANDLING ===\n";
···79 |> Jsont.Object.finish
810 in
9111010- (match Yamlt.decode_string opt_codec "value: null" with
1212+ (match Yamlt.decode opt_codec (Bytes.Reader.of_string "value: null") with
1113 | Ok None -> Printf.printf "✓ Plain 'null' with option codec: None\n"
1214 | _ -> Printf.printf "✗ FAIL\n");
13151414- (match Yamlt.decode_string opt_codec "value: hello" with
1616+ (match Yamlt.decode opt_codec (Bytes.Reader.of_string "value: hello") with
1517 | Ok (Some "hello") ->
1618 Printf.printf "✓ Plain 'hello' with option codec: Some(hello)\n"
1719 | _ -> Printf.printf "✗ FAIL\n");
···2224 |> Jsont.Object.finish
2325 in
24262525- (match Yamlt.decode_string string_codec "value: null" with
2727+ (match Yamlt.decode string_codec (Bytes.Reader.of_string "value: null") with
2628 | Error _ ->
2729 Printf.printf "✓ Plain 'null' with string codec: ERROR (expected)\n"
2830 | _ -> Printf.printf "✗ FAIL\n");
29313030- (match Yamlt.decode_string string_codec "value: \"\"" with
3232+ (match Yamlt.decode string_codec (Bytes.Reader.of_string "value: \"\"") with
3133 | Ok "" -> Printf.printf "✓ Quoted empty string: \"\"\n"
3234 | _ -> Printf.printf "✗ FAIL\n");
33353434- (match Yamlt.decode_string string_codec "value: \"null\"" with
3636+ (match Yamlt.decode string_codec (Bytes.Reader.of_string "value: \"null\"") with
3537 | Ok "null" -> Printf.printf "✓ Quoted 'null': \"null\"\n"
3638 | _ -> Printf.printf "✗ FAIL\n");
3739···4345 |> Jsont.Object.finish
4446 in
45474646- (match Yamlt.decode_string num_codec "value: 0xFF" with
4848+ (match Yamlt.decode num_codec (Bytes.Reader.of_string "value: 0xFF") with
4749 | Ok 255. -> Printf.printf "✓ Hex 0xFF: 255\n"
4850 | _ -> Printf.printf "✗ FAIL\n");
49515050- (match Yamlt.decode_string num_codec "value: 0o77" with
5252+ (match Yamlt.decode num_codec (Bytes.Reader.of_string "value: 0o77") with
5153 | Ok 63. -> Printf.printf "✓ Octal 0o77: 63\n"
5254 | _ -> Printf.printf "✗ FAIL\n");
53555454- (match Yamlt.decode_string num_codec "value: 0b1010" with
5656+ (match Yamlt.decode num_codec (Bytes.Reader.of_string "value: 0b1010") with
5557 | Ok 10. -> Printf.printf "✓ Binary 0b1010: 10\n"
5658 | _ -> Printf.printf "✗ FAIL\n");
5759···6466 |> Jsont.Object.finish
6567 in
66686767- (match Yamlt.decode_string opt_array_codec "values: [a, b, c]" with
6969+ (match Yamlt.decode opt_array_codec (Bytes.Reader.of_string "values: [a, b, c]") with
6870 | Ok (Some arr) when Array.length arr = 3 ->
6971 Printf.printf "✓ Optional array [a, b, c]: Some([3 items])\n"
7072 | _ -> Printf.printf "✗ FAIL\n");
71737272- (match Yamlt.decode_string opt_array_codec "{}" with
7474+ (match Yamlt.decode opt_array_codec (Bytes.Reader.of_string "{}") with
7375 | Ok None -> Printf.printf "✓ Missing optional array: None\n"
7476 | _ -> Printf.printf "✗ FAIL\n");
7577···8284 |> Jsont.Object.finish
8385 in
84868787+ let b = Buffer.create 256 in
8888+ let writer = Bytes.Writer.of_buffer b in
8589 match
8686- Yamlt.encode_string ~format:Flow encode_codec ("test", [| 1.; 2.; 3. |])
9090+ Yamlt.encode ~format:Flow encode_codec ("test", [| 1.; 2.; 3. |]) ~eod:true writer
8791 with
8888- | Ok yaml_flow
8989- when String.equal yaml_flow "{name: test, values: [1.0, 2.0, 3.0]}\n" ->
9292+ | Ok ()
9393+ when String.equal (Buffer.contents b) "{name: test, values: [1.0, 2.0, 3.0]}\n" ->
9094 Printf.printf "✓ Flow encoding with comma separator\n"
9191- | Ok yaml_flow -> Printf.printf "✗ FAIL: %S\n" yaml_flow
9595+ | Ok () -> Printf.printf "✗ FAIL: %S\n" (Buffer.contents b)
9296 | Error e -> Printf.printf "✗ ERROR: %s\n" e
+8-6
tests/bin/test_edge.ml
···5566(** Test edge cases with Yamlt *)
7788+open Bytesrw
99+810(* Helper to read file *)
911let read_file path =
1012 let ic = open_in path in
···5052 let yaml = read_file file in
5153 let json = read_file (file ^ ".json") in
5254 let json_result = Jsont_bytesrw.decode_string M.numbers_codec json in
5353- let yaml_result = Yamlt.decode_string M.numbers_codec yaml in
5555+ let yaml_result = Yamlt.decode M.numbers_codec (Bytes.Reader.of_string yaml) in
54565557 show_result_both "large_numbers"
5658 (Result.map M.show json_result)
···7577 let yaml = read_file file in
7678 let json = read_file (file ^ ".json") in
7779 let json_result = Jsont_bytesrw.decode_string M.text_codec json in
7878- let yaml_result = Yamlt.decode_string M.text_codec yaml in
8080+ let yaml_result = Yamlt.decode M.text_codec (Bytes.Reader.of_string yaml) in
79818082 show_result_both "special_chars"
8183 (Result.map M.show json_result)
···100102 let yaml = read_file file in
101103 let json = read_file (file ^ ".json") in
102104 let json_result = Jsont_bytesrw.decode_string M.text_codec json in
103103- let yaml_result = Yamlt.decode_string M.text_codec yaml in
105105+ let yaml_result = Yamlt.decode M.text_codec (Bytes.Reader.of_string yaml) in
104106105107 show_result_both "unicode"
106108 (Result.map M.show json_result)
···129131 let yaml = read_file file in
130132 let json = read_file (file ^ ".json") in
131133 let json_result = Jsont_bytesrw.decode_string M.data_codec json in
132132- let yaml_result = Yamlt.decode_string M.data_codec yaml in
134134+ let yaml_result = Yamlt.decode M.data_codec (Bytes.Reader.of_string yaml) in
133135134136 show_result_both "empty_collections"
135137 (Result.map M.show json_result)
···147149 let yaml = read_file file in
148150 let json = read_file (file ^ ".json") in
149151 let json_result = Jsont_bytesrw.decode_string (Jsont.any ()) json in
150150- let yaml_result = Yamlt.decode_string (Jsont.any ()) yaml in
152152+ let yaml_result = Yamlt.decode (Jsont.any ()) (Bytes.Reader.of_string yaml) in
151153152154 show_result_both "special_keys"
153155 (Result.map M.show json_result)
···172174 let yaml = read_file file in
173175 let json = read_file (file ^ ".json") in
174176 let json_result = Jsont_bytesrw.decode_string M.data_codec json in
175175- let yaml_result = Yamlt.decode_string M.data_codec yaml in
177177+ let yaml_result = Yamlt.decode M.data_codec (Bytes.Reader.of_string yaml) in
176178177179 show_result_both "single_element"
178180 (Result.map M.show json_result)
+7-2
tests/bin/test_flow_newline.ml
···11+open Bytesrw
22+13let () =
24 let encode_codec =
35 Jsont.Object.map ~kind:"Test" (fun name values -> (name, values))
···68 |> Jsont.Object.finish
79 in
8101111+ let b = Buffer.create 256 in
1212+ let writer = Bytes.Writer.of_buffer b in
913 match
1010- Yamlt.encode_string ~format:Flow encode_codec ("test", [| 1.; 2.; 3. |])
1414+ Yamlt.encode ~format:Flow encode_codec ("test", [| 1.; 2.; 3. |]) ~eod:true writer
1115 with
1212- | Ok yaml_flow ->
1616+ | Ok () ->
1717+ let yaml_flow = Buffer.contents b in
1318 Printf.printf "Length: %d\n" (String.length yaml_flow);
1419 Printf.printf "Repr: %S\n" yaml_flow;
1520 Printf.printf "Output:\n%s" yaml_flow
+17-11
tests/bin/test_formats.ml
···5566(** Test format-specific features with Yamlt *)
7788+open Bytesrw
99+810(* Helper to read file *)
911let read_file path =
1012 let ic = open_in path in
···4244 let yaml = read_file file in
4345 let json = read_file (file ^ ".json") in
4446 let json_result = Jsont_bytesrw.decode_string M.text_codec json in
4545- let yaml_result = Yamlt.decode_string M.text_codec yaml in
4747+ let yaml_result = Yamlt.decode M.text_codec (Bytes.Reader.of_string yaml) in
46484749 show_result_both "literal_string"
4850 (Result.map M.show json_result)
···6870 let yaml = read_file file in
6971 let json = read_file (file ^ ".json") in
7072 let json_result = Jsont_bytesrw.decode_string M.text_codec json in
7171- let yaml_result = Yamlt.decode_string M.text_codec yaml in
7373+ let yaml_result = Yamlt.decode M.text_codec (Bytes.Reader.of_string yaml) in
72747375 show_result_both "folded_string"
7476 (Result.map M.show json_result)
···9395 let yaml = read_file file in
9496 let json = read_file (file ^ ".json") in
9597 let json_result = Jsont_bytesrw.decode_string M.numbers_codec json in
9696- let yaml_result = Yamlt.decode_string M.numbers_codec yaml in
9898+ let yaml_result = Yamlt.decode M.numbers_codec (Bytes.Reader.of_string yaml) in
979998100 show_result_both "number_formats"
99101 (Result.map M.show json_result)
···129131 in
130132131133 (* Encode to YAML Block style *)
132132- (match Yamlt.encode_string ~format:Yamlt.Block M.data_codec data with
133133- | Ok s -> Printf.printf "YAML Block:\n%s\n" s
134134- | Error e -> Printf.printf "YAML Block ERROR: %s\n" e);
134134+ (let b = Buffer.create 256 in
135135+ let writer = Bytes.Writer.of_buffer b in
136136+ match Yamlt.encode ~format:Yamlt.Block M.data_codec data ~eod:true writer with
137137+ | Ok () -> Printf.printf "YAML Block:\n%s\n" (Buffer.contents b)
138138+ | Error e -> Printf.printf "YAML Block ERROR: %s\n" e);
135139136140 (* Encode to YAML Flow style *)
137137- match Yamlt.encode_string ~format:Yamlt.Flow M.data_codec data with
138138- | Ok s -> Printf.printf "YAML Flow:\n%s\n" s
141141+ let b = Buffer.create 256 in
142142+ let writer = Bytes.Writer.of_buffer b in
143143+ match Yamlt.encode ~format:Yamlt.Flow M.data_codec data ~eod:true writer with
144144+ | Ok () -> Printf.printf "YAML Flow:\n%s\n" (Buffer.contents b)
139145 | Error e -> Printf.printf "YAML Flow ERROR: %s\n" e
140146141147(* Test: Comments in YAML (should be ignored) *)
···155161 Printf.sprintf "host=%S, port=%d, debug=%b" c.host c.port c.debug
156162 end in
157163 let yaml = read_file file in
158158- let yaml_result = Yamlt.decode_string M.config_codec yaml in
164164+ let yaml_result = Yamlt.decode M.config_codec (Bytes.Reader.of_string yaml) in
159165160166 match yaml_result with
161167 | Ok v -> Printf.printf "YAML (with comments): %s\n" (M.show v)
···180186 let yaml = read_file file in
181187 let json = read_file (file ^ ".json") in
182188 let json_result = Jsont_bytesrw.decode_string M.wrapper_codec json in
183183- let yaml_result = Yamlt.decode_string M.wrapper_codec yaml in
189189+ let yaml_result = Yamlt.decode M.wrapper_codec (Bytes.Reader.of_string yaml) in
184190185191 show_result_both "empty_document"
186192 (Result.map M.show json_result)
···199205 let show v = Printf.sprintf "data=%S" v.data
200206 end in
201207 let yaml = read_file file in
202202- let yaml_result = Yamlt.decode_string M.value_codec yaml in
208208+ let yaml_result = Yamlt.decode M.value_codec (Bytes.Reader.of_string yaml) in
203209204210 match yaml_result with
205211 | Ok v -> Printf.printf "YAML (with tags): %s\n" (M.show v)
+28-22
tests/bin/test_locations.ml
···66(** Test location and layout preservation options with Yamlt codec *)
7788(* Helper to read file *)
99+open Bytesrw
1010+911let read_file path =
1012 let ic = open_in path in
1113 let len = in_channel_length ic in
···3133 in
32343335 Printf.printf "=== Without locs (default) ===\n";
3434- let result_no_locs = Yamlt.decode_string ~locs:false codec yaml in
3636+ let result_no_locs = Yamlt.decode codec (Bytes.Reader.of_string yaml) ~locs:false in
3537 show_result "Error message" result_no_locs;
36383739 Printf.printf "\n=== With locs=true ===\n";
3838- let result_with_locs = Yamlt.decode_string ~locs:true codec yaml in
4040+ let result_with_locs = Yamlt.decode codec (Bytes.Reader.of_string yaml) ~locs:true in
3941 show_result "Error message" result_with_locs
40424143(* Test: Show error locations for nested structures *)
···6062 in
61636264 Printf.printf "=== Without locs (default) ===\n";
6363- let result_no_locs = Yamlt.decode_string ~locs:false codec yaml in
6565+ let result_no_locs = Yamlt.decode codec (Bytes.Reader.of_string yaml) ~locs:false in
6466 show_result "Nested error" result_no_locs;
65676668 Printf.printf "\n=== With locs=true ===\n";
6767- let result_with_locs = Yamlt.decode_string ~locs:true codec yaml in
6969+ let result_with_locs = Yamlt.decode codec (Bytes.Reader.of_string yaml) ~locs:true in
6870 show_result "Nested error" result_with_locs
69717072(* Test: Array element error locations *)
···7981 in
80828183 Printf.printf "=== Without locs (default) ===\n";
8282- let result_no_locs = Yamlt.decode_string ~locs:false codec yaml in
8484+ let result_no_locs = Yamlt.decode codec (Bytes.Reader.of_string yaml) ~locs:false in
8385 show_result "Array error" result_no_locs;
84868587 Printf.printf "\n=== With locs=true ===\n";
8686- let result_with_locs = Yamlt.decode_string ~locs:true codec yaml in
8888+ let result_with_locs = Yamlt.decode codec (Bytes.Reader.of_string yaml) ~locs:true in
8789 show_result "Array error" result_with_locs
88908991(* Test: Layout preservation - check if we can decode with layout info *)
···98100 in
99101100102 Printf.printf "=== Without layout (default) ===\n";
101101- (match Yamlt.decode_string ~layout:false codec yaml with
103103+ (match Yamlt.decode codec (Bytes.Reader.of_string yaml) ~layout:false with
102104 | Ok (host, port) ->
103105 Printf.printf "Decoded: host=%s, port=%d\n" host port;
104106 Printf.printf "Meta preserved: no\n"
105107 | Error e -> Printf.printf "Error: %s\n" e);
106108107109 Printf.printf "\n=== With layout=true ===\n";
108108- match Yamlt.decode_string ~layout:true codec yaml with
110110+ match Yamlt.decode codec (Bytes.Reader.of_string yaml) ~layout:true with
109111 | Ok (host, port) ->
110112 Printf.printf "Decoded: host=%s, port=%d\n" host port;
111113 Printf.printf
···126128 Printf.printf "%s\n" (String.trim yaml);
127129128130 Printf.printf "\n=== Decode without layout, re-encode ===\n";
129129- (match Yamlt.decode_string ~layout:false codec yaml with
131131+ (match Yamlt.decode codec (Bytes.Reader.of_string yaml) ~layout:false with
130132 | Ok items -> (
131131- match Yamlt.encode_string ~format:Yamlt.Block codec items with
132132- | Ok yaml_out -> Printf.printf "%s" yaml_out
133133+ let b = Buffer.create 256 in
134134+ let writer = Bytes.Writer.of_buffer b in
135135+ match Yamlt.encode ~format:Yamlt.Block codec items ~eod:true writer with
136136+ | Ok () -> Printf.printf "%s" (Buffer.contents b)
133137 | Error e -> Printf.printf "Encode error: %s\n" e)
134138 | Error e -> Printf.printf "Decode error: %s\n" e);
135139136140 Printf.printf
137141 "\n=== Decode with layout=true, re-encode with Layout format ===\n";
138138- match Yamlt.decode_string ~layout:true codec yaml with
142142+ match Yamlt.decode codec (Bytes.Reader.of_string yaml) ~layout:true with
139143 | Ok items -> (
140140- match Yamlt.encode_string ~format:Yamlt.Layout codec items with
141141- | Ok yaml_out -> Printf.printf "%s" yaml_out
144144+ let b = Buffer.create 256 in
145145+ let writer = Bytes.Writer.of_buffer b in
146146+ match Yamlt.encode ~format:Yamlt.Layout codec items ~eod:true writer with
147147+ | Ok () -> Printf.printf "%s" (Buffer.contents b)
142148 | Error e -> Printf.printf "Encode error: %s\n" e)
143149 | Error e -> Printf.printf "Decode error: %s\n" e
144150···154160 in
155161156162 Printf.printf "=== Without file path ===\n";
157157- let result1 = Yamlt.decode_string ~locs:true codec yaml in
163163+ let result1 = Yamlt.decode codec (Bytes.Reader.of_string yaml) ~locs:true in
158164 show_result "Error" result1;
159165160166 Printf.printf "\n=== With file path ===\n";
161161- let result2 = Yamlt.decode_string ~locs:true ~file:"test.yml" codec yaml in
167167+ let result2 = Yamlt.decode codec (Bytes.Reader.of_string yaml) ~locs:true ~file:"test.yml" in
162168 show_result "Error" result2
163169164170(* Test: Missing field error with locs *)
···174180 in
175181176182 Printf.printf "=== Without locs ===\n";
177177- let result_no_locs = Yamlt.decode_string ~locs:false codec yaml in
183183+ let result_no_locs = Yamlt.decode codec (Bytes.Reader.of_string yaml) ~locs:false in
178184 show_result "Missing field" result_no_locs;
179185180186 Printf.printf "\n=== With locs=true ===\n";
181181- let result_with_locs = Yamlt.decode_string ~locs:true codec yaml in
187187+ let result_with_locs = Yamlt.decode codec (Bytes.Reader.of_string yaml) ~locs:true in
182188 show_result "Missing field" result_with_locs
183189184190(* Test: Both locs and layout together *)
···194200 in
195201196202 Printf.printf "=== locs=false, layout=false (defaults) ===\n";
197197- (match Yamlt.decode_string ~locs:false ~layout:false codec yaml with
203203+ (match Yamlt.decode codec (Bytes.Reader.of_string yaml) ~locs:false ~layout:false with
198204 | Ok (timeout, retries) ->
199205 Printf.printf "OK: timeout=%d, retries=%d\n" timeout retries
200206 | Error e -> Printf.printf "Error: %s\n" e);
201207202208 Printf.printf "\n=== locs=true, layout=false ===\n";
203203- (match Yamlt.decode_string ~locs:true ~layout:false codec yaml with
209209+ (match Yamlt.decode codec (Bytes.Reader.of_string yaml) ~locs:true ~layout:false with
204210 | Ok (timeout, retries) ->
205211 Printf.printf "OK: timeout=%d, retries=%d (with precise locations)\n"
206212 timeout retries
207213 | Error e -> Printf.printf "Error: %s\n" e);
208214209215 Printf.printf "\n=== locs=false, layout=true ===\n";
210210- (match Yamlt.decode_string ~locs:false ~layout:true codec yaml with
216216+ (match Yamlt.decode codec (Bytes.Reader.of_string yaml) ~locs:false ~layout:true with
211217 | Ok (timeout, retries) ->
212218 Printf.printf "OK: timeout=%d, retries=%d (with layout metadata)\n"
213219 timeout retries
214220 | Error e -> Printf.printf "Error: %s\n" e);
215221216222 Printf.printf "\n=== locs=true, layout=true (both enabled) ===\n";
217217- match Yamlt.decode_string ~locs:true ~layout:true codec yaml with
223223+ match Yamlt.decode codec (Bytes.Reader.of_string yaml) ~locs:true ~layout:true with
218224 | Ok (timeout, retries) ->
219225 Printf.printf "OK: timeout=%d, retries=%d (with locations and layout)\n"
220226 timeout retries
+240
tests/bin/test_multidoc.ml
···11+(*---------------------------------------------------------------------------
22+ Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org>. All rights reserved.
33+ SPDX-License-Identifier: ISC
44+---------------------------------------------------------------------------*)
55+66+(** Test multi-document YAML streams with decode_all *)
77+88+open Bytesrw
99+1010+(* Helper to read file *)
1111+let read_file path =
1212+ let ic = open_in path in
1313+ let len = in_channel_length ic in
1414+ let s = really_input_string ic len in
1515+ close_in ic;
1616+ s
1717+1818+(* Helper to show results *)
1919+let show_result label = function
2020+ | Ok v -> Printf.printf "%s: %s\n" label v
2121+ | Error e -> Printf.printf "%s: ERROR: %s\n" label e
2222+2323+(* Test: Simple multi-document stream *)
2424+let test_simple file =
2525+ let module M = struct
2626+ type person = { name : string; age : int }
2727+2828+ let person_codec =
2929+ Jsont.Object.map ~kind:"Person" (fun name age -> { name; age })
3030+ |> Jsont.Object.mem "name" Jsont.string ~enc:(fun p -> p.name)
3131+ |> Jsont.Object.mem "age" Jsont.int ~enc:(fun p -> p.age)
3232+ |> Jsont.Object.finish
3333+3434+ let show p = Printf.sprintf "%s (age %d)" p.name p.age
3535+ end in
3636+ let yaml = read_file file in
3737+ let reader = Bytes.Reader.of_string yaml in
3838+ let seq = Yamlt.decode_all M.person_codec reader in
3939+ Printf.printf "Documents:\n";
4040+ seq |> Seq.iteri (fun i result ->
4141+ Printf.printf " [%d] " i;
4242+ show_result "" (Result.map M.show result)
4343+ )
4444+4545+(* Test: Count documents *)
4646+let test_count file =
4747+ let yaml = read_file file in
4848+ let reader = Bytes.Reader.of_string yaml in
4949+ let seq = Yamlt.decode_all Jsont.json reader in
5050+ let count = Seq.fold_left (fun acc _ -> acc + 1) 0 seq in
5151+ Printf.printf "Document count: %d\n" count
5252+5353+(* Test: Error tracking - show which documents succeed and which fail *)
5454+let test_errors file =
5555+ let module M = struct
5656+ type person = { name : string; age : int }
5757+5858+ let person_codec =
5959+ Jsont.Object.map ~kind:"Person" (fun name age -> { name; age })
6060+ |> Jsont.Object.mem "name" Jsont.string ~enc:(fun p -> p.name)
6161+ |> Jsont.Object.mem "age" Jsont.int ~enc:(fun p -> p.age)
6262+ |> Jsont.Object.finish
6363+6464+ let show p = Printf.sprintf "%s (age %d)" p.name p.age
6565+ end in
6666+ let yaml = read_file file in
6767+ let reader = Bytes.Reader.of_string yaml in
6868+ let seq = Yamlt.decode_all M.person_codec reader in
6969+ Printf.printf "Document results:\n";
7070+ seq |> Seq.iteri (fun i result ->
7171+ match result with
7272+ | Ok p -> Printf.printf " [%d] OK: %s\n" i (M.show p)
7373+ | Error e -> Printf.printf " [%d] ERROR: %s\n" i (String.trim e)
7474+ )
7575+7676+(* Test: Location tracking with locs=true *)
7777+let test_locations file =
7878+ let module M = struct
7979+ type person = { name : string; age : int }
8080+8181+ let person_codec =
8282+ Jsont.Object.map ~kind:"Person" (fun name age -> { name; age })
8383+ |> Jsont.Object.mem "name" Jsont.string ~enc:(fun p -> p.name)
8484+ |> Jsont.Object.mem "age" Jsont.int ~enc:(fun p -> p.age)
8585+ |> Jsont.Object.finish
8686+ end in
8787+ let yaml = read_file file in
8888+8989+ Printf.printf "=== Without locs (default) ===\n";
9090+ let reader = Bytes.Reader.of_string yaml in
9191+ let seq = Yamlt.decode_all ~locs:false M.person_codec reader in
9292+ seq |> Seq.iteri (fun i result ->
9393+ match result with
9494+ | Ok _ -> Printf.printf " [%d] OK\n" i
9595+ | Error e -> Printf.printf " [%d] ERROR:\n%s\n" i (String.trim e)
9696+ );
9797+9898+ Printf.printf "\n=== With locs=true ===\n";
9999+ let reader = Bytes.Reader.of_string yaml in
100100+ let seq = Yamlt.decode_all ~locs:true ~file:"test.yml" M.person_codec reader in
101101+ seq |> Seq.iteri (fun i result ->
102102+ match result with
103103+ | Ok _ -> Printf.printf " [%d] OK\n" i
104104+ | Error e -> Printf.printf " [%d] ERROR:\n%s\n" i (String.trim e)
105105+ )
106106+107107+(* Test: Roundtrip to JSON - decode YAML multidoc, encode each to JSON *)
108108+let test_json_roundtrip file =
109109+ let yaml = read_file file in
110110+ let reader = Bytes.Reader.of_string yaml in
111111+ let seq = Yamlt.decode_all Jsont.json reader in
112112+ Printf.printf "JSON outputs:\n";
113113+ seq |> Seq.iteri (fun i result ->
114114+ match result with
115115+ | Ok json_val ->
116116+ (match Jsont_bytesrw.encode_string Jsont.json json_val with
117117+ | Ok json_str -> Printf.printf " [%d] %s\n" i (String.trim json_str)
118118+ | Error e -> Printf.printf " [%d] ENCODE ERROR: %s\n" i e)
119119+ | Error e -> Printf.printf " [%d] DECODE ERROR: %s\n" i (String.trim e)
120120+ )
121121+122122+(* Test: Nested objects in multidoc *)
123123+let test_nested file =
124124+ let module M = struct
125125+ type address = { street : string; city : string }
126126+ type person = { name : string; age : int; address : address }
127127+128128+ let address_codec =
129129+ Jsont.Object.map ~kind:"Address" (fun street city -> { street; city })
130130+ |> Jsont.Object.mem "street" Jsont.string ~enc:(fun a -> a.street)
131131+ |> Jsont.Object.mem "city" Jsont.string ~enc:(fun a -> a.city)
132132+ |> Jsont.Object.finish
133133+134134+ let person_codec =
135135+ Jsont.Object.map ~kind:"Person" (fun name age address ->
136136+ { name; age; address })
137137+ |> Jsont.Object.mem "name" Jsont.string ~enc:(fun p -> p.name)
138138+ |> Jsont.Object.mem "age" Jsont.int ~enc:(fun p -> p.age)
139139+ |> Jsont.Object.mem "address" address_codec ~enc:(fun p -> p.address)
140140+ |> Jsont.Object.finish
141141+142142+ let show p =
143143+ Printf.sprintf "%s (age %d) from %s, %s" p.name p.age p.address.street
144144+ p.address.city
145145+ end in
146146+ let yaml = read_file file in
147147+ let reader = Bytes.Reader.of_string yaml in
148148+ let seq = Yamlt.decode_all M.person_codec reader in
149149+ Printf.printf "Nested documents:\n";
150150+ seq |> Seq.iteri (fun i result ->
151151+ Printf.printf " [%d] " i;
152152+ show_result "" (Result.map M.show result)
153153+ )
154154+155155+(* Test: Arrays in multidoc *)
156156+let test_arrays file =
157157+ let yaml = read_file file in
158158+ let reader = Bytes.Reader.of_string yaml in
159159+ let seq = Yamlt.decode_all Jsont.json reader in
160160+ Printf.printf "Array documents:\n";
161161+ seq |> Seq.iteri (fun i result ->
162162+ match result with
163163+ | Ok json_val ->
164164+ (match Jsont_bytesrw.encode_string Jsont.json json_val with
165165+ | Ok json_str -> Printf.printf " [%d] %s\n" i (String.trim json_str)
166166+ | Error e -> Printf.printf " [%d] ERROR: %s\n" i e)
167167+ | Error e -> Printf.printf " [%d] ERROR: %s\n" i (String.trim e)
168168+ )
169169+170170+(* Test: Scalars in multidoc *)
171171+let test_scalars file =
172172+ let yaml = read_file file in
173173+ let reader = Bytes.Reader.of_string yaml in
174174+ let seq = Yamlt.decode_all Jsont.json reader in
175175+ Printf.printf "Scalar documents:\n";
176176+ seq |> Seq.iteri (fun i result ->
177177+ match result with
178178+ | Ok json_val ->
179179+ (match Jsont_bytesrw.encode_string Jsont.json json_val with
180180+ | Ok json_str -> Printf.printf " [%d] %s\n" i (String.trim json_str)
181181+ | Error e -> Printf.printf " [%d] ERROR: %s\n" i e)
182182+ | Error e -> Printf.printf " [%d] ERROR: %s\n" i (String.trim e)
183183+ )
184184+185185+(* Test: Summary stats - count successes vs failures *)
186186+let test_summary file =
187187+ let module M = struct
188188+ type person = { name : string; age : int }
189189+190190+ let person_codec =
191191+ Jsont.Object.map ~kind:"Person" (fun name age -> { name; age })
192192+ |> Jsont.Object.mem "name" Jsont.string ~enc:(fun p -> p.name)
193193+ |> Jsont.Object.mem "age" Jsont.int ~enc:(fun p -> p.age)
194194+ |> Jsont.Object.finish
195195+ end in
196196+ let yaml = read_file file in
197197+ let reader = Bytes.Reader.of_string yaml in
198198+ let seq = Yamlt.decode_all M.person_codec reader in
199199+ let success = ref 0 in
200200+ let failure = ref 0 in
201201+ seq |> Seq.iter (fun result ->
202202+ match result with
203203+ | Ok _ -> incr success
204204+ | Error _ -> incr failure
205205+ );
206206+ Printf.printf "Summary: %d documents (%d ok, %d error)\n"
207207+ (!success + !failure) !success !failure
208208+209209+let () =
210210+ let usage = "Usage: test_multidoc <command> <file>" in
211211+ if Array.length Sys.argv < 3 then begin
212212+ prerr_endline usage;
213213+ exit 1
214214+ end;
215215+216216+ let test = Sys.argv.(1) in
217217+ let file = Sys.argv.(2) in
218218+ match test with
219219+ | "simple" -> test_simple file
220220+ | "count" -> test_count file
221221+ | "errors" -> test_errors file
222222+ | "locations" -> test_locations file
223223+ | "json" -> test_json_roundtrip file
224224+ | "nested" -> test_nested file
225225+ | "arrays" -> test_arrays file
226226+ | "scalars" -> test_scalars file
227227+ | "summary" -> test_summary file
228228+ | _ ->
229229+ prerr_endline usage;
230230+ prerr_endline "Commands:";
231231+ prerr_endline " simple <file> - Decode person documents";
232232+ prerr_endline " count <file> - Count documents";
233233+ prerr_endline " errors <file> - Show success/error for each document";
234234+ prerr_endline " locations <file> - Test location tracking with locs=true";
235235+ prerr_endline " json <file> - Roundtrip to JSON";
236236+ prerr_endline " nested <file> - Decode nested objects";
237237+ prerr_endline " arrays <file> - Decode arrays";
238238+ prerr_endline " scalars <file> - Decode scalars";
239239+ prerr_endline " summary <file> - Show success/failure summary";
240240+ exit 1
+6-4
tests/bin/test_null_complete.ml
···11+open Bytesrw
22+13let () =
24 Printf.printf "=== Test 1: Jsont.option with YAML null ===\n";
35 let yaml1 = "value: null" in
···79 |> Object.mem "value" (option string) ~enc:(fun v -> v)
810 |> Object.finish
911 in
1010- (match Yamlt.decode_string codec1 yaml1 with
1212+ (match Yamlt.decode codec1 (Bytes.Reader.of_string yaml1) with
1113 | Ok v ->
1214 Printf.printf "Result: %s\n"
1315 (match v with None -> "None" | Some s -> "Some(" ^ s ^ ")")
1416 | Error e -> Printf.printf "Error: %s\n" e);
15171618 Printf.printf "\n=== Test 2: Jsont.option with YAML string ===\n";
1717- (match Yamlt.decode_string codec1 "value: hello" with
1919+ (match Yamlt.decode codec1 (Bytes.Reader.of_string "value: hello") with
1820 | Ok v ->
1921 Printf.printf "Result: %s\n"
2022 (match v with None -> "None" | Some s -> "Some(" ^ s ^ ")")
···2729 |> Object.mem "value" string ~enc:(fun v -> v)
2830 |> Object.finish
2931 in
3030- (match Yamlt.decode_string codec2 "value: null" with
3232+ (match Yamlt.decode codec2 (Bytes.Reader.of_string "value: null") with
3133 | Ok v -> Printf.printf "Result: %s\n" v
3234 | Error e -> Printf.printf "Error (expected): %s\n" e);
33353436 Printf.printf "\n=== Test 4: Jsont.string with YAML string ===\n";
3535- match Yamlt.decode_string codec2 "value: hello" with
3737+ match Yamlt.decode codec2 (Bytes.Reader.of_string "value: hello") with
3638 | Ok v -> Printf.printf "Result: %s\n" v
3739 | Error e -> Printf.printf "Error: %s\n" e
+2-2
tests/bin/test_null_fix.ml
···11-open Jsont
11+open Bytesrw
2233let () =
44 let module M = struct
···14141515 Printf.printf "Testing YAML null handling with Jsont.option Jsont.string:\n\n";
16161717- match Yamlt.decode_string M.data_codec yaml_null with
1717+ match Yamlt.decode M.data_codec (Bytes.Reader.of_string yaml_null) with
1818 | Ok data -> (
1919 match data.M.value with
2020 | None -> Printf.printf "YAML: value=None (CORRECT)\n"
+19-13
tests/bin/test_objects.ml
···5566(** Test object codec functionality with Yamlt *)
7788+open Bytesrw
99+810(* Helper to read file *)
911let read_file path =
1012 let ic = open_in path in
···4042 let yaml = read_file file in
4143 let json = read_file (file ^ ".json") in
4244 let json_result = Jsont_bytesrw.decode_string M.person_codec json in
4343- let yaml_result = Yamlt.decode_string M.person_codec yaml in
4545+ let yaml_result = Yamlt.decode M.person_codec (Bytes.Reader.of_string yaml) in
44464547 show_result_both "person"
4648 (Result.map M.show json_result)
···7173 let yaml = read_file file in
7274 let json = read_file (file ^ ".json") in
7375 let json_result = Jsont_bytesrw.decode_string M.config_codec json in
7474- let yaml_result = Yamlt.decode_string M.config_codec yaml in
7676+ let yaml_result = Yamlt.decode M.config_codec (Bytes.Reader.of_string yaml) in
75777678 show_result_both "config"
7779 (Result.map M.show json_result)
···103105 let yaml = read_file file in
104106 let json = read_file (file ^ ".json") in
105107 let json_result = Jsont_bytesrw.decode_string M.settings_codec json in
106106- let yaml_result = Yamlt.decode_string M.settings_codec yaml in
108108+ let yaml_result = Yamlt.decode M.settings_codec (Bytes.Reader.of_string yaml) in
107109108110 show_result_both "settings"
109111 (Result.map M.show json_result)
···136138 let yaml = read_file file in
137139 let json = read_file (file ^ ".json") in
138140 let json_result = Jsont_bytesrw.decode_string M.employee_codec json in
139139- let yaml_result = Yamlt.decode_string M.employee_codec yaml in
141141+ let yaml_result = Yamlt.decode M.employee_codec (Bytes.Reader.of_string yaml) in
140142141143 show_result_both "employee"
142144 (Result.map M.show json_result)
···153155 |> Jsont.Object.finish
154156 end in
155157 let yaml = read_file file in
156156- let result = Yamlt.decode_string M.strict_codec yaml in
158158+ let result = Yamlt.decode M.strict_codec (Bytes.Reader.of_string yaml) in
157159 match result with
158160 | Ok _ -> Printf.printf "Unexpected success\n"
159161 | Error e -> Printf.printf "Expected error: %s\n" e
···174176 let yaml = read_file file in
175177 let json = read_file (file ^ ".json") in
176178 let json_result = Jsont_bytesrw.decode_string M.flexible_codec json in
177177- let yaml_result = Yamlt.decode_string M.flexible_codec yaml in
179179+ let yaml_result = Yamlt.decode M.flexible_codec (Bytes.Reader.of_string yaml) in
178180179181 show_result_both "flexible"
180182 (Result.map M.show json_result)
···196198 let yaml = read_file file in
197199 let json = read_file (file ^ ".json") in
198200 let json_result = Jsont_bytesrw.decode_string M.circle_codec json in
199199- let yaml_result = Yamlt.decode_string M.circle_codec yaml in
201201+ let yaml_result = Yamlt.decode M.circle_codec (Bytes.Reader.of_string yaml) in
200202201203 show_result_both "shape"
202204 (Result.map M.show json_result)
···214216 |> Jsont.Object.finish
215217 end in
216218 let yaml = read_file file in
217217- let result = Yamlt.decode_string M.required_codec yaml in
219219+ let result = Yamlt.decode M.required_codec (Bytes.Reader.of_string yaml) in
218220 match result with
219221 | Ok _ -> Printf.printf "Unexpected success\n"
220222 | Error e -> Printf.printf "Expected error: %s\n" e
···240242 | Error e -> Printf.printf "JSON ERROR: %s\n" e);
241243242244 (* Encode to YAML Block *)
243243- (match Yamlt.encode_string ~format:Yamlt.Block M.person_codec person with
244244- | Ok s -> Printf.printf "YAML Block:\n%s" s
245245- | Error e -> Printf.printf "YAML Block ERROR: %s\n" e);
245245+ (let b = Buffer.create 256 in
246246+ let writer = Bytes.Writer.of_buffer b in
247247+ match Yamlt.encode ~format:Yamlt.Block M.person_codec person ~eod:true writer with
248248+ | Ok () -> Printf.printf "YAML Block:\n%s" (Buffer.contents b)
249249+ | Error e -> Printf.printf "YAML Block ERROR: %s\n" e);
246250247251 (* Encode to YAML Flow *)
248248- match Yamlt.encode_string ~format:Yamlt.Flow M.person_codec person with
249249- | Ok s -> Printf.printf "YAML Flow: %s" s
252252+ let b = Buffer.create 256 in
253253+ let writer = Bytes.Writer.of_buffer b in
254254+ match Yamlt.encode ~format:Yamlt.Flow M.person_codec person ~eod:true writer with
255255+ | Ok () -> Printf.printf "YAML Flow: %s" (Buffer.contents b)
250256 | Error e -> Printf.printf "YAML Flow ERROR: %s\n" e
251257252258let () =
+3-1
tests/bin/test_opt_array.ml
···11+open Bytesrw
22+13let () =
24 let codec =
35 Jsont.Object.map ~kind:"Test" (fun arr -> arr)
···911 let yaml = "values: [a, b, c]" in
10121113 Printf.printf "Testing optional array field:\n";
1212- match Yamlt.decode_string codec yaml with
1414+ match Yamlt.decode codec (Bytes.Reader.of_string yaml) with
1315 | Ok arr -> (
1416 match arr with
1517 | None -> Printf.printf "Result: None\n"
+37-13
tests/bin/test_roundtrip.ml
···5566(** Test roundtrip encoding/decoding with Yamlt *)
7788+open Bytesrw
99+810(* Test: Roundtrip scalars *)
911let test_scalar_roundtrip () =
1012 let module M = struct
···36383739 (* YAML Block roundtrip *)
3840 let yaml_block_encoded =
3939- Yamlt.encode_string ~format:Yamlt.Block M.data_codec original
4141+ let b = Buffer.create 256 in
4242+ let writer = Bytes.Writer.of_buffer b in
4343+ match Yamlt.encode ~format:Yamlt.Block M.data_codec original ~eod:true writer with
4444+ | Ok () -> Ok (Buffer.contents b)
4545+ | Error e -> Error e
4046 in
4147 let yaml_block_decoded =
4242- Result.bind yaml_block_encoded (Yamlt.decode_string M.data_codec)
4848+ Result.bind yaml_block_encoded (fun yaml ->
4949+ Yamlt.decode M.data_codec (Bytes.Reader.of_string yaml))
4350 in
4451 (match yaml_block_decoded with
4552 | Ok decoded when M.equal original decoded ->
···49565057 (* YAML Flow roundtrip *)
5158 let yaml_flow_encoded =
5252- Yamlt.encode_string ~format:Yamlt.Flow M.data_codec original
5959+ let b = Buffer.create 256 in
6060+ let writer = Bytes.Writer.of_buffer b in
6161+ match Yamlt.encode ~format:Yamlt.Flow M.data_codec original ~eod:true writer with
6262+ | Ok () -> Ok (Buffer.contents b)
6363+ | Error e -> Error e
5364 in
5465 let yaml_flow_decoded =
5555- Result.bind yaml_flow_encoded (Yamlt.decode_string M.data_codec)
6666+ Result.bind yaml_flow_encoded (fun yaml ->
6767+ Yamlt.decode M.data_codec (Bytes.Reader.of_string yaml))
5668 in
5769 match yaml_flow_decoded with
5870 | Ok decoded when M.equal original decoded ->
···9710998110 (* YAML roundtrip *)
99111 let yaml_result =
100100- Result.bind
101101- (Yamlt.encode_string M.data_codec original)
102102- (Yamlt.decode_string M.data_codec)
112112+ let b = Buffer.create 256 in
113113+ let writer = Bytes.Writer.of_buffer b in
114114+ match Yamlt.encode M.data_codec original ~eod:true writer with
115115+ | Ok () ->
116116+ let yaml = Buffer.contents b in
117117+ Yamlt.decode M.data_codec (Bytes.Reader.of_string yaml)
118118+ | Error e -> Error e
103119 in
104120 match yaml_result with
105121 | Ok decoded when M.equal original decoded ->
···162178163179 (* YAML roundtrip *)
164180 let yaml_result =
165165- Result.bind
166166- (Yamlt.encode_string M.company_codec original)
167167- (Yamlt.decode_string M.company_codec)
181181+ let b = Buffer.create 256 in
182182+ let writer = Bytes.Writer.of_buffer b in
183183+ match Yamlt.encode M.company_codec original ~eod:true writer with
184184+ | Ok () ->
185185+ let yaml = Buffer.contents b in
186186+ Yamlt.decode M.company_codec (Bytes.Reader.of_string yaml)
187187+ | Error e -> Error e
168188 in
169189 match yaml_result with
170190 | Ok decoded when M.equal original decoded ->
···210230211231 (* YAML roundtrip *)
212232 let yaml_result =
213213- Result.bind
214214- (Yamlt.encode_string M.data_codec original)
215215- (Yamlt.decode_string M.data_codec)
233233+ let b = Buffer.create 256 in
234234+ let writer = Bytes.Writer.of_buffer b in
235235+ match Yamlt.encode M.data_codec original ~eod:true writer with
236236+ | Ok () ->
237237+ let yaml = Buffer.contents b in
238238+ Yamlt.decode M.data_codec (Bytes.Reader.of_string yaml)
239239+ | Error e -> Error e
216240 in
217241 match yaml_result with
218242 | Ok decoded when M.equal original decoded ->
+48-30
tests/bin/test_scalars.ml
···5566(** Test scalar type resolution with Yamlt codec *)
7788+open Bytesrw
99+810(* Helper to read file *)
911let read_file path =
1012 let ic = open_in path in
···3638 in
37393840 (* Try decoding as null *)
3939- let result = Yamlt.decode_string null_codec yaml in
4141+ let result = Yamlt.decode null_codec (Bytes.Reader.of_string yaml) in
4042 show_result "null_codec" (Result.map (fun () -> "null") result)
41434244(* Test: Boolean type-directed resolution *)
···60626163 Printf.printf "=== Bool Codec ===\n";
6264 let json_result = Jsont_bytesrw.decode_string bool_codec json in
6363- let yaml_result = Yamlt.decode_string bool_codec yaml in
6565+ let yaml_result = Yamlt.decode bool_codec (Bytes.Reader.of_string yaml) in
6466 show_result_json "bool_codec"
6567 (Result.map (Printf.sprintf "%b") json_result)
6668 (Result.map (Printf.sprintf "%b") yaml_result);
67696870 Printf.printf "\n=== String Codec ===\n";
6971 let json_result = Jsont_bytesrw.decode_string string_codec json in
7070- let yaml_result = Yamlt.decode_string string_codec yaml in
7272+ let yaml_result = Yamlt.decode string_codec (Bytes.Reader.of_string yaml) in
7173 show_result_json "string_codec"
7274 (Result.map (Printf.sprintf "%S") json_result)
7375 (Result.map (Printf.sprintf "%S") yaml_result)
···8486 in
85878688 let json_result = Jsont_bytesrw.decode_string number_codec json in
8787- let yaml_result = Yamlt.decode_string number_codec yaml in
8989+ let yaml_result = Yamlt.decode number_codec (Bytes.Reader.of_string yaml) in
88908991 show_result_json "number_codec"
9092 (Result.map (Printf.sprintf "%.17g") json_result)
···102104 in
103105104106 let json_result = Jsont_bytesrw.decode_string string_codec json in
105105- let yaml_result = Yamlt.decode_string string_codec yaml in
107107+ let yaml_result = Yamlt.decode string_codec (Bytes.Reader.of_string yaml) in
106108107109 show_result_json "string_codec"
108110 (Result.map (Printf.sprintf "%S") json_result)
···118120 |> Jsont.Object.finish
119121 in
120122121121- let result = Yamlt.decode_string number_codec yaml in
123123+ let result = Yamlt.decode number_codec (Bytes.Reader.of_string yaml) in
122124 match result with
123125 | Ok f ->
124126 if Float.is_nan f then Printf.printf "value: NaN\n"
···138140 |> Jsont.Object.mem "value" Jsont.bool ~enc:(fun b -> b)
139141 |> Jsont.Object.finish
140142 in
141141- let result = Yamlt.decode_string codec yaml in
143143+ let result = Yamlt.decode codec (Bytes.Reader.of_string yaml) in
142144 match result with
143145 | Ok _ -> Printf.printf "Unexpected success\n"
144146 | Error e -> Printf.printf "Expected error: %s\n" e)
···148150 |> Jsont.Object.mem "value" Jsont.number ~enc:(fun n -> n)
149151 |> Jsont.Object.finish
150152 in
151151- let result = Yamlt.decode_string codec yaml in
153153+ let result = Yamlt.decode codec (Bytes.Reader.of_string yaml) in
152154 match result with
153155 | Ok _ -> Printf.printf "Unexpected success\n"
154156 | Error e -> Printf.printf "Expected error: %s\n" e)
···158160 |> Jsont.Object.mem "value" (Jsont.null ()) ~enc:(fun n -> n)
159161 |> Jsont.Object.finish
160162 in
161161- let result = Yamlt.decode_string codec yaml in
163163+ let result = Yamlt.decode codec (Bytes.Reader.of_string yaml) in
162164 match result with
163165 | Ok _ -> Printf.printf "Unexpected success\n"
164166 | Error e -> Printf.printf "Expected error: %s\n" e)
···176178 in
177179178180 let json_result = Jsont_bytesrw.decode_string any_codec json in
179179- let yaml_result = Yamlt.decode_string any_codec yaml in
181181+ let yaml_result = Yamlt.decode any_codec (Bytes.Reader.of_string yaml) in
180182181183 (* Just show that it decoded successfully *)
182184 show_result_json "any_codec"
···196198 (match Jsont_bytesrw.encode_string codec v with
197199 | Ok s -> Printf.printf "JSON: %s\n" (String.trim s)
198200 | Error e -> Printf.printf "JSON ERROR: %s\n" e);
199199- (match Yamlt.encode_string ~format:Yamlt.Block codec v with
200200- | Ok s -> Printf.printf "YAML Block:\n%s" s
201201- | Error e -> Printf.printf "YAML Block ERROR: %s\n" e);
202202- match Yamlt.encode_string ~format:Yamlt.Flow codec v with
203203- | Ok s -> Printf.printf "YAML Flow: %s" s
201201+ (let b = Buffer.create 256 in
202202+ let writer = Bytes.Writer.of_buffer b in
203203+ match Yamlt.encode ~format:Yamlt.Block codec v ~eod:true writer with
204204+ | Ok () -> Printf.printf "YAML Block:\n%s" (Buffer.contents b)
205205+ | Error e -> Printf.printf "YAML Block ERROR: %s\n" e);
206206+ let b = Buffer.create 256 in
207207+ let writer = Bytes.Writer.of_buffer b in
208208+ match Yamlt.encode ~format:Yamlt.Flow codec v ~eod:true writer with
209209+ | Ok () -> Printf.printf "YAML Flow: %s" (Buffer.contents b)
204210 | Error e -> Printf.printf "YAML Flow ERROR: %s\n" e)
205211 | "number" -> (
206212 let codec =
···212218 (match Jsont_bytesrw.encode_string codec v with
213219 | Ok s -> Printf.printf "JSON: %s\n" (String.trim s)
214220 | Error e -> Printf.printf "JSON ERROR: %s\n" e);
215215- (match Yamlt.encode_string ~format:Yamlt.Block codec v with
216216- | Ok s -> Printf.printf "YAML Block:\n%s" s
217217- | Error e -> Printf.printf "YAML Block ERROR: %s\n" e);
218218- match Yamlt.encode_string ~format:Yamlt.Flow codec v with
219219- | Ok s -> Printf.printf "YAML Flow: %s" s
221221+ (let b = Buffer.create 256 in
222222+ let writer = Bytes.Writer.of_buffer b in
223223+ match Yamlt.encode ~format:Yamlt.Block codec v ~eod:true writer with
224224+ | Ok () -> Printf.printf "YAML Block:\n%s" (Buffer.contents b)
225225+ | Error e -> Printf.printf "YAML Block ERROR: %s\n" e);
226226+ let b = Buffer.create 256 in
227227+ let writer = Bytes.Writer.of_buffer b in
228228+ match Yamlt.encode ~format:Yamlt.Flow codec v ~eod:true writer with
229229+ | Ok () -> Printf.printf "YAML Flow: %s" (Buffer.contents b)
220230 | Error e -> Printf.printf "YAML Flow ERROR: %s\n" e)
221231 | "string" -> (
222232 let codec =
···228238 (match Jsont_bytesrw.encode_string codec v with
229239 | Ok s -> Printf.printf "JSON: %s\n" (String.trim s)
230240 | Error e -> Printf.printf "JSON ERROR: %s\n" e);
231231- (match Yamlt.encode_string ~format:Yamlt.Block codec v with
232232- | Ok s -> Printf.printf "YAML Block:\n%s" s
233233- | Error e -> Printf.printf "YAML Block ERROR: %s\n" e);
234234- match Yamlt.encode_string ~format:Yamlt.Flow codec v with
235235- | Ok s -> Printf.printf "YAML Flow: %s" s
241241+ (let b = Buffer.create 256 in
242242+ let writer = Bytes.Writer.of_buffer b in
243243+ match Yamlt.encode ~format:Yamlt.Block codec v ~eod:true writer with
244244+ | Ok () -> Printf.printf "YAML Block:\n%s" (Buffer.contents b)
245245+ | Error e -> Printf.printf "YAML Block ERROR: %s\n" e);
246246+ let b = Buffer.create 256 in
247247+ let writer = Bytes.Writer.of_buffer b in
248248+ match Yamlt.encode ~format:Yamlt.Flow codec v ~eod:true writer with
249249+ | Ok () -> Printf.printf "YAML Flow: %s" (Buffer.contents b)
236250 | Error e -> Printf.printf "YAML Flow ERROR: %s\n" e)
237251 | "null" -> (
238252 let codec =
···244258 (match Jsont_bytesrw.encode_string codec v with
245259 | Ok s -> Printf.printf "JSON: %s\n" (String.trim s)
246260 | Error e -> Printf.printf "JSON ERROR: %s\n" e);
247247- (match Yamlt.encode_string ~format:Yamlt.Block codec v with
248248- | Ok s -> Printf.printf "YAML Block:\n%s" s
249249- | Error e -> Printf.printf "YAML Block ERROR: %s\n" e);
250250- match Yamlt.encode_string ~format:Yamlt.Flow codec v with
251251- | Ok s -> Printf.printf "YAML Flow: %s" s
261261+ (let b = Buffer.create 256 in
262262+ let writer = Bytes.Writer.of_buffer b in
263263+ match Yamlt.encode ~format:Yamlt.Block codec v ~eod:true writer with
264264+ | Ok () -> Printf.printf "YAML Block:\n%s" (Buffer.contents b)
265265+ | Error e -> Printf.printf "YAML Block ERROR: %s\n" e);
266266+ let b = Buffer.create 256 in
267267+ let writer = Bytes.Writer.of_buffer b in
268268+ match Yamlt.encode ~format:Yamlt.Flow codec v ~eod:true writer with
269269+ | Ok () -> Printf.printf "YAML Flow: %s" (Buffer.contents b)
252270 | Error e -> Printf.printf "YAML Flow ERROR: %s\n" e)
253271 | _ -> failwith "unknown type"
254272
+4-2
tests/bin/test_some_vs_option.ml
···11+open Bytesrw
22+13let () =
24 (* Using Jsont.some like opt_mem does *)
35 let codec1 =
···1113 let yaml = "values: [a, b, c]" in
12141315 Printf.printf "Test 1: Jsont.some (Jsont.array) - like opt_mem:\n";
1414- (match Yamlt.decode_string codec1 yaml with
1616+ (match Yamlt.decode codec1 (Bytes.Reader.of_string yaml) with
1517 | Ok arr -> (
1618 match arr with
1719 | None -> Printf.printf "Result: None\n"
···2830 in
29313032 Printf.printf "\nTest 2: Jsont.option (Jsont.array):\n";
3131- match Yamlt.decode_string codec2 yaml with
3333+ match Yamlt.decode codec2 (Bytes.Reader.of_string yaml) with
3234 | Ok arr -> (
3335 match arr with
3436 | None -> Printf.printf "Result: None\n"
···2525 === With locs=true ===
2626 Error message:
2727 String "not-a-number" does not parse to OCaml int value
2828- File "-", lines 2-3, characters 5-0:
2828+ File "-", line 2, characters 5-18:
2929 File "-", line 2, characters 0-3: in member age of
3030 File "-", line 1, characters 0-1: Person object
3131···5151 === With locs=true ===
5252 Nested error:
5353 String "invalid-zip" does not parse to OCaml int value
5454- File "-", lines 5-6, characters 7-0:
5454+ File "-", line 5, characters 7-19:
5555 File "-", line 5, characters 2-5: in member zip of
5656 File "-", line 3, characters 2-3: Address object
5757 File "-", line 2, characters 0-7: in member address of
···9494 === Without file path ===
9595 Error:
9696 String "not-a-number" does not parse to OCaml int value
9797- File "-", lines 2-3, characters 5-0:
9797+ File "-", line 2, characters 5-18:
9898 File "-", line 2, characters 0-3: in member age of
9999 File "-", line 1, characters 0-1: Person object
100100101101 === With file path ===
102102 Error:
103103 String "not-a-number" does not parse to OCaml int value
104104- File "test.yml", lines 2-3, characters 5-0:
104104+ File "test.yml", line 2, characters 5-18:
105105 File "test.yml", line 2, characters 0-3: in member age of
106106 File "test.yml", line 1, characters 0-1: Person object
107107
+220
tests/cram/multidoc.t
···11+Multi-Document YAML Streams with Yamlt
22+========================================
33+44+This test suite validates multi-document YAML stream decoding using decode_all,
55+including error handling, location tracking, and JSON roundtripping.
66+77+================================================================================
88+BASIC MULTIDOC DECODING
99+================================================================================
1010+1111+Simple multi-document stream with person objects
1212+1313+ $ test_multidoc simple ../data/multidoc/simple.yml
1414+ Documents:
1515+ [0] : Alice (age 30)
1616+ [1] : Bob (age 25)
1717+ [2] : Charlie (age 35)
1818+1919+Count documents in a stream
2020+2121+ $ test_multidoc count ../data/multidoc/simple.yml
2222+ Document count: 3
2323+2424+================================================================================
2525+ERROR HANDLING - MIXED VALID AND INVALID DOCUMENTS
2626+================================================================================
2727+2828+When some documents succeed and others fail, decode_all continues processing
2929+and returns results for each document individually.
3030+3131+Stream with one error in the middle
3232+3333+ $ test_multidoc errors ../data/multidoc/mixed_errors.yml
3434+ Document results:
3535+ [0] OK: Alice (age 30)
3636+ [1] ERROR: String "not-a-number" does not parse to OCaml int value
3737+ File "-":
3838+ File "-": in member age of
3939+ File "-": Person object
4040+ [2] OK: Charlie (age 35)
4141+4242+Summary statistics for mixed documents
4343+4444+ $ test_multidoc summary ../data/multidoc/mixed_errors.yml
4545+ Summary: 3 documents (2 ok, 1 error)
4646+4747+Stream where all documents fail
4848+4949+ $ test_multidoc errors ../data/multidoc/all_errors.yml
5050+ Document results:
5151+ [0] ERROR: String "invalid1" does not parse to OCaml int value
5252+ File "-":
5353+ File "-": in member age of
5454+ File "-": Person object
5555+ [1] ERROR: String "invalid2" does not parse to OCaml int value
5656+ File "-":
5757+ File "-": in member age of
5858+ File "-": Person object
5959+ [2] ERROR: String "invalid3" does not parse to OCaml int value
6060+ File "-":
6161+ File "-": in member age of
6262+ File "-": Person object
6363+6464+Summary for all-error stream
6565+6666+ $ test_multidoc summary ../data/multidoc/all_errors.yml
6767+ Summary: 3 documents (0 ok, 3 error)
6868+6969+================================================================================
7070+LOCATION TRACKING WITH locs=true
7171+================================================================================
7272+7373+Location tracking helps identify exactly where errors occur in each document
7474+of a multi-document stream.
7575+7676+Without locs (default) - basic error information
7777+7878+ $ test_multidoc locations ../data/multidoc/mixed_errors.yml
7979+ === Without locs (default) ===
8080+ [0] OK
8181+ [1] ERROR:
8282+ String "not-a-number" does not parse to OCaml int value
8383+ File "-":
8484+ File "-": in member age of
8585+ File "-": Person object
8686+ [2] OK
8787+8888+ === With locs=true ===
8989+ [0] OK
9090+ [1] ERROR:
9191+ String "not-a-number" does not parse to OCaml int value
9292+ File "test.yml", line 6, characters 5-18:
9393+ File "test.yml", line 6, characters 0-3: in member age of
9494+ File "test.yml", line 5, characters 0-1: Person object
9595+ [2] OK
9696+9797+================================================================================
9898+MISSING FIELDS IN MULTIDOC
9999+================================================================================
100100+101101+Documents with missing required fields generate errors but don't stop
102102+processing of subsequent documents.
103103+104104+ $ test_multidoc errors ../data/multidoc/missing_fields.yml
105105+ Document results:
106106+ [0] OK: Alice (age 30)
107107+ [1] ERROR: Missing member age in Person object
108108+ File "-":
109109+ [2] OK: Charlie (age 35)
110110+111111+Summary of missing fields test
112112+113113+ $ test_multidoc summary ../data/multidoc/missing_fields.yml
114114+ Summary: 3 documents (2 ok, 1 error)
115115+116116+================================================================================
117117+JSON ROUNDTRIPPING
118118+================================================================================
119119+120120+Decode YAML multi-document streams and encode each document as JSON.
121121+This validates that the data model conversion is correct.
122122+123123+Simple documents to JSON
124124+125125+ $ test_multidoc json ../data/multidoc/simple.yml
126126+ JSON outputs:
127127+ [0] {"name":"Alice","age":30}
128128+ [1] {"name":"Bob","age":25}
129129+ [2] {"name":"Charlie","age":35}
130130+131131+Nested objects to JSON
132132+133133+ $ test_multidoc json ../data/multidoc/nested.yml
134134+ JSON outputs:
135135+ [0] {"name":"Alice","age":30,"address":{"street":"123 Main St","city":"Boston"}}
136136+ [1] {"name":"Bob","age":25,"address":{"street":"456 Oak Ave","city":"Seattle"}}
137137+ [2] {"name":"Charlie","age":35,"address":{"street":"789 Pine Rd","city":"Portland"}}
138138+139139+Arrays to JSON
140140+141141+ $ test_multidoc json ../data/multidoc/arrays.yml
142142+ JSON outputs:
143143+ [0] [1,2,3]
144144+ [1] ["apple","banana","cherry"]
145145+ [2] [true,false,true]
146146+147147+Scalar values to JSON
148148+149149+ $ test_multidoc json ../data/multidoc/scalars.yml
150150+ JSON outputs:
151151+ [0] "hello world"
152152+ [1] 42
153153+ [2] true
154154+ [3] null
155155+156156+================================================================================
157157+NESTED OBJECTS IN MULTIDOC
158158+================================================================================
159159+160160+Test decoding complex nested structures across multiple documents.
161161+162162+ $ test_multidoc nested ../data/multidoc/nested.yml
163163+ Nested documents:
164164+ [0] : Alice (age 30) from 123 Main St, Boston
165165+ [1] : Bob (age 25) from 456 Oak Ave, Seattle
166166+ [2] : Charlie (age 35) from 789 Pine Rd, Portland
167167+168168+================================================================================
169169+ARRAYS IN MULTIDOC
170170+================================================================================
171171+172172+Test decoding different array types across documents.
173173+174174+ $ test_multidoc arrays ../data/multidoc/arrays.yml
175175+ Array documents:
176176+ [0] [1,2,3]
177177+ [1] ["apple","banana","cherry"]
178178+ [2] [true,false,true]
179179+180180+================================================================================
181181+SCALARS IN MULTIDOC
182182+================================================================================
183183+184184+Test decoding bare scalar values as documents.
185185+186186+ $ test_multidoc scalars ../data/multidoc/scalars.yml
187187+ Scalar documents:
188188+ [0] "hello world"
189189+ [1] 42
190190+ [2] true
191191+ [3] null
192192+193193+================================================================================
194194+EMPTY DOCUMENTS
195195+================================================================================
196196+197197+Empty or null documents in a stream are handled correctly.
198198+199199+ $ test_multidoc json ../data/multidoc/empty_docs.yml
200200+ JSON outputs:
201201+ [0] {"name":"Alice","age":30}
202202+ [1] null
203203+ [2] {"name":"Charlie","age":35}
204204+205205+Count including empty documents
206206+207207+ $ test_multidoc count ../data/multidoc/empty_docs.yml
208208+ Document count: 3
209209+210210+================================================================================
211211+SUMMARY
212212+================================================================================
213213+214214+The decode_all function:
215215+- Processes all documents in a stream, not stopping on errors
216216+- Returns a sequence of Result values (Ok/Error for each document)
217217+- Supports all decode options: locs, layout, file, max_depth, max_nodes
218218+- Correctly handles document boundaries even when errors occur
219219+- Works with any Jsont codec (objects, arrays, scalars, etc.)
220220+- Can be used for JSON roundtripping and format conversion
+9
tests/data/multidoc/all_errors.yml
···11+---
22+name: Alice
33+age: invalid1
44+---
55+name: Bob
66+age: invalid2
77+---
88+name: Charlie
99+age: invalid3