diff --git a/Changes b/Changes index 4811507..b03808b 100644 --- a/Changes +++ b/Changes @@ -7,6 +7,10 @@ o Allow -utf8 with -split-bookmarks -o @B.pdf to produce UTF8 filenames o -merge-add-bookmarks now works with unicode filenames o Better transformation of some annotation types +Fixes: + +o Updated Yojson to remove dependency on Stream, ready for OCaml 5 + 2.5.1 (January 2022) o Fix a regression where standard fonts could not be chosen diff --git a/Makefile b/Makefile index ca8bedb..a997bbc 100644 --- a/Makefile +++ b/Makefile @@ -34,7 +34,8 @@ all : $(TARGETS) clean :: rm -rf doc foo foo2 out.pdf out2.pdf foo.pdf decomp.pdf *.cmt *.cmti \ - *.json test/*.pdf debug/*.pdf *.ps *.aux *.idx *.log *.out *.toc *.cut + *.json test/*.pdf debug/*.pdf *.ps *.aux *.idx *.log *.out *.toc *.cut \ + cpdf.top.dSYM DOC_FILES = cpdfunicodedata.mli cpdferror.mli cpdfdebug.mli cpdfjson.mli \ cpdfstrftime.mli cpdfcoord.mli cpdfattach.mli cpdfpagespec.mli \ diff --git a/cpdfyojson.ml b/cpdfyojson.ml index 503eb54..fbb36f3 100644 --- a/cpdfyojson.ml +++ b/cpdfyojson.ml @@ -1,30 +1,3 @@ -(* Copyright (c) 2010-2012, Martin Jambon All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -Redistributions of source code must retain the above copyright notice, this -list of conditions and the following disclaimer. - -Redistributions in binary form must reproduce the above copyright notice, this -list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. - -Neither the name of nor the names of its contributors may be used to endorse or -promote products derived from this software without specific prior written -permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *) - # 1 "common.ml" let version = "%%VERSION%%" @@ -100,13 +73,6 @@ let code_of_surrogate_pair i j = let utf8_of_surrogate_pair buf i j = utf8_of_code buf (code_of_surrogate_pair i j) -let is_object_or_array x = - match x with - `List _ - | `Assoc _ -> true - | _ -> false - - type lexer_state = { buf : Buffer.t; (* Buffer used to accumulate substrings *) @@ -211,8 +177,6 @@ All possible cases defined in Yojson: comments, so it would be complicated to document only the cases that are preserved by cppo in the type definition. *) -# 12 "yojson.cppo.ml" -type json_max = t # 1 "write.ml" (* included: type.ml *) @@ -331,24 +295,9 @@ let float_needs_period s = false (* - Both write_float_fast and write_float guarantee - that a sufficient number of digits are printed in order to - allow reversibility. - - The _fast version is faster but often produces unnecessarily long numbers. + Guarantees that a sufficient number of digits are printed in order to allow + reversibility. *) -let write_float_fast ob x = - match classify_float x with - FP_nan -> - Buffer.add_string ob "NaN" - | FP_infinite -> - Buffer.add_string ob (if x > 0. then "Infinity" else "-Infinity") - | _ -> - let s = Printf.sprintf "%.17g" x in - Buffer.add_string ob s; - if float_needs_period s then - Buffer.add_string ob ".0" - let write_float ob x = match classify_float x with FP_nan -> @@ -391,6 +340,7 @@ let write_normal_float_prec significant_figures ob x = if float_needs_period s then Buffer.add_string ob ".0" +(* used by atdgen *) let write_float_prec significant_figures ob x = match classify_float x with FP_nan -> @@ -406,22 +356,6 @@ let json_string_of_float x = Buffer.contents ob -let write_std_float_fast ob x = - match classify_float x with - FP_nan -> - json_error "NaN value not allowed in standard JSON" - | FP_infinite -> - json_error - (if x > 0. then - "Infinity value not allowed in standard JSON" - else - "-Infinity value not allowed in standard JSON") - | _ -> - let s = Printf.sprintf "%.17g" x in - Buffer.add_string ob s; - if float_needs_period s then - Buffer.add_string ob ".0" - let write_std_float ob x = match classify_float x with FP_nan -> @@ -442,6 +376,7 @@ let write_std_float ob x = if float_needs_period s then Buffer.add_string ob ".0" +(* used by atdgen *) let write_std_float_prec significant_figures ob x = match classify_float x with FP_nan -> @@ -506,35 +441,35 @@ let rec write_json ob (x : t) = `Null -> write_null ob () | `Bool b -> write_bool ob b -# 293 "write.ml" +# 264 "write.ml" | `Int i -> write_int ob i -# 296 "write.ml" +# 267 "write.ml" | `Intlit s -> Buffer.add_string ob s -# 299 "write.ml" +# 270 "write.ml" | `Float f -> write_float ob f -# 302 "write.ml" +# 273 "write.ml" | `Floatlit s -> Buffer.add_string ob s -# 305 "write.ml" +# 276 "write.ml" | `String s -> write_string ob s -# 308 "write.ml" +# 279 "write.ml" | `Stringlit s -> Buffer.add_string ob s -# 310 "write.ml" +# 281 "write.ml" | `Assoc l -> write_assoc ob l | `List l -> write_list ob l -# 313 "write.ml" +# 284 "write.ml" | `Tuple l -> write_tuple ob l -# 316 "write.ml" +# 287 "write.ml" | `Variant (s, o) -> write_variant ob s o -# 319 "write.ml" +# 290 "write.ml" and write_assoc ob l = let f_elt ob (s, x) = write_string ob s; @@ -550,13 +485,13 @@ and write_list ob l = iter2 write_json f_sep ob l; Buffer.add_char ob ']' -# 335 "write.ml" +# 306 "write.ml" and write_tuple ob l = Buffer.add_char ob '('; iter2 write_json f_sep ob l; Buffer.add_char ob ')' -# 342 "write.ml" +# 313 "write.ml" and write_variant ob s o = Buffer.add_char ob '<'; write_string ob s; @@ -568,7 +503,7 @@ and write_variant ob s o = ); Buffer.add_char ob '>' -# 354 "write.ml" +# 325 "write.ml" let write_t = write_json let rec write_std_json ob (x : t) = @@ -576,35 +511,35 @@ let rec write_std_json ob (x : t) = `Null -> write_null ob () | `Bool b -> write_bool ob b -# 361 "write.ml" +# 332 "write.ml" | `Int i -> write_int ob i -# 364 "write.ml" +# 335 "write.ml" | `Intlit s -> Buffer.add_string ob s -# 367 "write.ml" +# 338 "write.ml" | `Float f -> write_std_float ob f -# 370 "write.ml" +# 341 "write.ml" | `Floatlit s -> Buffer.add_string ob s -# 373 "write.ml" +# 344 "write.ml" | `String s -> write_string ob s -# 376 "write.ml" +# 347 "write.ml" | `Stringlit s -> Buffer.add_string ob s -# 378 "write.ml" +# 349 "write.ml" | `Assoc l -> write_std_assoc ob l | `List l -> write_std_list ob l -# 381 "write.ml" +# 352 "write.ml" | `Tuple l -> write_std_tuple ob l -# 384 "write.ml" +# 355 "write.ml" | `Variant (s, o) -> write_std_variant ob s o -# 387 "write.ml" +# 358 "write.ml" and write_std_assoc ob l = let f_elt ob (s, x) = write_string ob s; @@ -625,7 +560,7 @@ and write_std_tuple ob l = iter2 write_std_json f_sep ob l; Buffer.add_char ob ']' -# 408 "write.ml" +# 379 "write.ml" and write_std_variant ob s o = match o with None -> write_string ob s @@ -637,19 +572,15 @@ and write_std_variant ob s o = Buffer.add_char ob ']' -# 420 "write.ml" -let to_buffer ?(std = false) ob x = - if std then ( - if not (is_object_or_array x) then - json_error "Root is not an object or array" - else - write_std_json ob x - ) +# 391 "write.ml" +let to_buffer ?(suf = "") ?(std = false) ob x = + if std then + write_std_json ob x else - write_json ob x + write_json ob x; + Buffer.add_string ob suf - -let to_string ?buf ?(len = 256) ?std x = +let to_string ?buf ?(len = 256) ?(suf = "") ?std x = let ob = match buf with None -> Buffer.create len @@ -657,43 +588,44 @@ let to_string ?buf ?(len = 256) ?std x = Buffer.clear ob; ob in - to_buffer ?std ob x; + to_buffer ~suf ?std ob x; let s = Buffer.contents ob in Buffer.clear ob; s -let to_channel ?buf ?(len=4096) ?std oc x = +let to_channel ?buf ?(len=4096) ?(suf = "") ?std oc x = let ob = match buf with None -> Buffer.create len - | Some ob -> ob + | Some ob -> Buffer.clear ob; ob in - to_buffer ?std ob x; - Buffer.output_buffer oc ob + to_buffer ~suf ?std ob x; + Buffer.output_buffer oc ob; + Buffer.clear ob -let to_output ?buf ?(len=4096) ?std out x = +let to_output ?buf ?(len=4096) ?(suf = "") ?std out x = let ob = match buf with None -> Buffer.create len - | Some ob -> ob + | Some ob -> Buffer.clear ob; ob in - to_buffer ?std ob x; + to_buffer ~suf ?std ob x; out#output (Buffer.contents ob) 0 (Buffer.length ob); - () + Buffer.clear ob -let to_file ?len ?std file x = +let to_file ?len ?std ?(suf = "\n") file x = let oc = open_out file in try - to_channel ?len ?std oc x; + to_channel ?len ~suf ?std oc x; close_out oc with e -> close_out_noerr oc; raise e -let stream_to_buffer ?std ob st = - Stream.iter (to_buffer ?std ob) st +let seq_to_buffer ?(suf = "\n") ?std ob st = + Seq.iter (to_buffer ~suf ?std ob) st -let stream_to_string ?buf ?(len = 256) ?std st = +let seq_to_string ?buf ?(len = 256) ?(suf = "\n") ?std st = let ob = match buf with None -> Buffer.create len @@ -701,23 +633,27 @@ let stream_to_string ?buf ?(len = 256) ?std st = Buffer.clear ob; ob in - stream_to_buffer ?std ob st; + seq_to_buffer ~suf ?std ob st; let s = Buffer.contents ob in Buffer.clear ob; s -let stream_to_channel ?buf ?(len=2096) ?std oc st = +let seq_to_channel ?buf ?(len=2096) ?(suf = "\n") ?std oc seq = let ob = match buf with None -> Buffer.create len - | Some ob -> ob + | Some ob -> Buffer.clear ob; ob in - stream_to_buffer ?std ob st + Seq.iter (fun json -> + to_buffer ~suf ?std ob json; + Buffer.output_buffer oc ob; + Buffer.clear ob; + ) seq -let stream_to_file ?len ?std file st = +let seq_to_file ?len ?(suf = "\n") ?std file st = let oc = open_out file in try - stream_to_channel ?len ?std oc st; + seq_to_channel ?len ~suf ?std oc st; close_out oc with e -> close_out_noerr oc; @@ -731,18 +667,18 @@ let rec sort = function | `List l -> `List (List.rev (List.rev_map sort l)) -# 513 "write.ml" +# 485 "write.ml" | `Tuple l -> `Tuple (List.rev (List.rev_map sort l)) -# 517 "write.ml" +# 489 "write.ml" | `Variant (k, Some v) as x -> let v' = sort v in if v == v' then x else `Variant (k, Some v') -# 523 "write.ml" +# 495 "write.ml" | x -> x # 1 "monomorphic.ml" let rec pp fmt = @@ -909,66 +845,173 @@ let rec equal a b = # 155 "monomorphic.ml" | _ -> false -# 15 "yojson.cppo.ml" +# 14 "yojson.cppo.ml" module Pretty = struct +# 1 "pretty.ml" +(* + Pretty-print JSON data in an attempt to maximize readability. + + 1. What fits on one line stays on one line. + 2. What doesn't fit on one line gets printed more vertically so as to not + exceed a reasonable page width, if possible. + + Arrays containing only simple elements ("atoms") are pretty-printed with + end-of-line wrapping like ordinary text: + + [ + "hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello", + "hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello" + ] + + Other arrays are printed either horizontally or vertically depending + on whether they fit on a single line: + + [ { "hello": "world" }, { "hello": "world" }, { "hello": "world" } ] + + or + + [ + { "hello": "world" }, + { "hello": "world" }, + { "hello": "world" }, + { "hello": "world" } + ] +*) -# 2 "pretty.ml" let pp_list sep ppx out l = let pp_sep out () = Format.fprintf out "%s@ " sep in Format.pp_print_list ~pp_sep ppx out l -let rec format std (out:Format.formatter) (x : t) : unit = +let is_atom (x: [> t]) = + match x with + | `Null + | `Bool _ + | `Int _ + | `Float _ + | `String _ + | `Intlit _ + | `Floatlit _ + | `Stringlit _ + | `List [] + | `Assoc [] + | `Tuple [] + | `Variant (_, None) -> true + | `List _ + | `Assoc _ + | `Tuple _ + | `Variant (_, Some _) -> false + +let is_atom_list l = + List.for_all is_atom l + +(* + inside_box: indicates that we're already within a box that imposes + a certain style and we shouldn't create a new one. This is used for + printing field values like this: + + foo: [ + bar + ] + + rather than something else like + + foo: + [ + bar + ] +*) +let rec format ~inside_box std (out:Format.formatter) (x:t) : unit = match x with | `Null -> Format.pp_print_string out "null" | `Bool x -> Format.pp_print_bool out x + +# 78 "pretty.ml" | `Int x -> Format.pp_print_string out (json_string_of_int x) + +# 81 "pretty.ml" | `Float x -> let s = if std then std_json_string_of_float x else json_string_of_float x in Format.pp_print_string out s + +# 89 "pretty.ml" | `String s -> Format.pp_print_string out (json_string_of_string s) - | `Intlit s - | `Floatlit s + +# 92 "pretty.ml" + | `Intlit s -> Format.pp_print_string out s + +# 95 "pretty.ml" + | `Floatlit s -> Format.pp_print_string out s + +# 98 "pretty.ml" | `Stringlit s -> Format.pp_print_string out s + +# 100 "pretty.ml" | `List [] -> Format.pp_print_string out "[]" - | `List l -> Format.fprintf out "[@;<1 0>@[%a@]@;<1 -2>]" (pp_list "," (format std)) l + | `List l -> + if not inside_box then Format.fprintf out "@["; + if is_atom_list l then + (* use line wrapping like we would do for a paragraph of text *) + Format.fprintf out "[@;<1 0>@[%a@]@;<1 -2>]" + (pp_list "," (format ~inside_box:false std)) l + else + (* print the elements horizontally if they fit on the line, + otherwise print them in a column *) + Format.fprintf out "[@;<1 0>@[%a@]@;<1 -2>]" + (pp_list "," (format ~inside_box:false std)) l; + if not inside_box then Format.fprintf out "@]"; | `Assoc [] -> Format.pp_print_string out "{}" | `Assoc l -> - Format.fprintf out "{@;<1 0>%a@;<1 -2>}" (pp_list "," (format_field std)) l + if not inside_box then Format.fprintf out "@["; + Format.fprintf out "{@;<1 0>%a@;<1 -2>}" (pp_list "," (format_field std)) l; + if not inside_box then Format.fprintf out "@]"; + +# 119 "pretty.ml" | `Tuple l -> if std then - format std out (`List l) + format ~inside_box std out (`List l) else if l = [] then Format.pp_print_string out "()" - else - Format.fprintf out "(@,%a@;<0 -2>)" (pp_list "," (format std)) l - + else ( + if not inside_box then Format.fprintf out "@["; + Format.fprintf out "(@,%a@;<0 -2>)" (pp_list "," (format ~inside_box:false std)) l; + if not inside_box then Format.fprintf out "@]"; + ) + +# 132 "pretty.ml" | `Variant (s, None) -> if std then - format std out (`String s) + +# 135 "pretty.ml" + let representation = `String s in + +# 139 "pretty.ml" + format ~inside_box std out representation else Format.fprintf out "<%s>" (json_string_of_string s) | `Variant (s, Some x) -> if std then - format std out (`List [ `String s; x ]) + +# 146 "pretty.ml" + let representation = `String s in + +# 150 "pretty.ml" + format ~inside_box std out (`List [ representation; x ]) else let op = json_string_of_string s in - Format.fprintf out "<@[%s: %a@]>" op (format std) x + Format.fprintf out "<@[%s: %a@]>" op (format ~inside_box:true std) x +# 156 "pretty.ml" and format_field std out (name, x) = - Format.fprintf out "@[%s: %a@]" (json_string_of_string name) (format std) x + Format.fprintf out "@[%s: %a@]" (json_string_of_string name) (format ~inside_box:true std) x let pp ?(std = false) out x = - if std && not (is_object_or_array x) then - json_error - "Root is not an object or array as requested by the JSON standard" - else - Format.fprintf out "@[%a@]" (format std) (x :> t) + Format.fprintf out "@[%a@]" (format ~inside_box:true std) (x :> t) let to_string ?std x = Format.asprintf "%a" (pp ?std) x @@ -976,20 +1019,20 @@ let to_string ?std x = let to_channel ?std oc x = let fmt = Format.formatter_of_out_channel oc in Format.fprintf fmt "%a@?" (pp ?std) x -# 18 "yojson.cppo.ml" +# 17 "yojson.cppo.ml" end # 2 "write2.ml" -let pretty_print ?std out (x : t) = - Pretty.pp ?std out (x :> json_max) +let pretty_print ?std out x = + Pretty.pp ?std out x -let pretty_to_string ?std (x : t) = - Pretty.to_string ?std (x :> json_max) +let pretty_to_string ?std x = + Pretty.to_string ?std x -let pretty_to_channel ?std oc (x : t) = - Pretty.to_channel ?std oc (x :> json_max) +let pretty_to_channel ?std oc x = + Pretty.to_channel ?std oc x -# 29 "yojson.cppo.ml" +# 28 "yojson.cppo.ml" module Basic = struct # 1 "type.ml" @@ -1161,24 +1204,9 @@ let float_needs_period s = false (* - Both write_float_fast and write_float guarantee - that a sufficient number of digits are printed in order to - allow reversibility. - - The _fast version is faster but often produces unnecessarily long numbers. + Guarantees that a sufficient number of digits are printed in order to allow + reversibility. *) -let write_float_fast ob x = - match classify_float x with - FP_nan -> - Buffer.add_string ob "NaN" - | FP_infinite -> - Buffer.add_string ob (if x > 0. then "Infinity" else "-Infinity") - | _ -> - let s = Printf.sprintf "%.17g" x in - Buffer.add_string ob s; - if float_needs_period s then - Buffer.add_string ob ".0" - let write_float ob x = match classify_float x with FP_nan -> @@ -1221,6 +1249,7 @@ let write_normal_float_prec significant_figures ob x = if float_needs_period s then Buffer.add_string ob ".0" +(* used by atdgen *) let write_float_prec significant_figures ob x = match classify_float x with FP_nan -> @@ -1236,22 +1265,6 @@ let json_string_of_float x = Buffer.contents ob -let write_std_float_fast ob x = - match classify_float x with - FP_nan -> - json_error "NaN value not allowed in standard JSON" - | FP_infinite -> - json_error - (if x > 0. then - "Infinity value not allowed in standard JSON" - else - "-Infinity value not allowed in standard JSON") - | _ -> - let s = Printf.sprintf "%.17g" x in - Buffer.add_string ob s; - if float_needs_period s then - Buffer.add_string ob ".0" - let write_std_float ob x = match classify_float x with FP_nan -> @@ -1272,6 +1285,7 @@ let write_std_float ob x = if float_needs_period s then Buffer.add_string ob ".0" +(* used by atdgen *) let write_std_float_prec significant_figures ob x = match classify_float x with FP_nan -> @@ -1336,20 +1350,20 @@ let rec write_json ob (x : t) = `Null -> write_null ob () | `Bool b -> write_bool ob b -# 293 "write.ml" +# 264 "write.ml" | `Int i -> write_int ob i -# 299 "write.ml" +# 270 "write.ml" | `Float f -> write_float ob f -# 305 "write.ml" +# 276 "write.ml" | `String s -> write_string ob s -# 310 "write.ml" +# 281 "write.ml" | `Assoc l -> write_assoc ob l | `List l -> write_list ob l -# 319 "write.ml" +# 290 "write.ml" and write_assoc ob l = let f_elt ob (s, x) = write_string ob s; @@ -1367,7 +1381,7 @@ and write_list ob l = -# 354 "write.ml" +# 325 "write.ml" let write_t = write_json let rec write_std_json ob (x : t) = @@ -1375,20 +1389,20 @@ let rec write_std_json ob (x : t) = `Null -> write_null ob () | `Bool b -> write_bool ob b -# 361 "write.ml" +# 332 "write.ml" | `Int i -> write_int ob i -# 367 "write.ml" +# 338 "write.ml" | `Float f -> write_std_float ob f -# 373 "write.ml" +# 344 "write.ml" | `String s -> write_string ob s -# 378 "write.ml" +# 349 "write.ml" | `Assoc l -> write_std_assoc ob l | `List l -> write_std_list ob l -# 387 "write.ml" +# 358 "write.ml" and write_std_assoc ob l = let f_elt ob (s, x) = write_string ob s; @@ -1411,19 +1425,15 @@ and write_std_tuple ob l = -# 420 "write.ml" -let to_buffer ?(std = false) ob x = - if std then ( - if not (is_object_or_array x) then - json_error "Root is not an object or array" - else - write_std_json ob x - ) +# 391 "write.ml" +let to_buffer ?(suf = "") ?(std = false) ob x = + if std then + write_std_json ob x else - write_json ob x + write_json ob x; + Buffer.add_string ob suf - -let to_string ?buf ?(len = 256) ?std x = +let to_string ?buf ?(len = 256) ?(suf = "") ?std x = let ob = match buf with None -> Buffer.create len @@ -1431,43 +1441,44 @@ let to_string ?buf ?(len = 256) ?std x = Buffer.clear ob; ob in - to_buffer ?std ob x; + to_buffer ~suf ?std ob x; let s = Buffer.contents ob in Buffer.clear ob; s -let to_channel ?buf ?(len=4096) ?std oc x = +let to_channel ?buf ?(len=4096) ?(suf = "") ?std oc x = let ob = match buf with None -> Buffer.create len - | Some ob -> ob + | Some ob -> Buffer.clear ob; ob in - to_buffer ?std ob x; - Buffer.output_buffer oc ob + to_buffer ~suf ?std ob x; + Buffer.output_buffer oc ob; + Buffer.clear ob -let to_output ?buf ?(len=4096) ?std out x = +let to_output ?buf ?(len=4096) ?(suf = "") ?std out x = let ob = match buf with None -> Buffer.create len - | Some ob -> ob + | Some ob -> Buffer.clear ob; ob in - to_buffer ?std ob x; + to_buffer ~suf ?std ob x; out#output (Buffer.contents ob) 0 (Buffer.length ob); - () + Buffer.clear ob -let to_file ?len ?std file x = +let to_file ?len ?std ?(suf = "\n") file x = let oc = open_out file in try - to_channel ?len ?std oc x; + to_channel ?len ~suf ?std oc x; close_out oc with e -> close_out_noerr oc; raise e -let stream_to_buffer ?std ob st = - Stream.iter (to_buffer ?std ob) st +let seq_to_buffer ?(suf = "\n") ?std ob st = + Seq.iter (to_buffer ~suf ?std ob) st -let stream_to_string ?buf ?(len = 256) ?std st = +let seq_to_string ?buf ?(len = 256) ?(suf = "\n") ?std st = let ob = match buf with None -> Buffer.create len @@ -1475,23 +1486,27 @@ let stream_to_string ?buf ?(len = 256) ?std st = Buffer.clear ob; ob in - stream_to_buffer ?std ob st; + seq_to_buffer ~suf ?std ob st; let s = Buffer.contents ob in Buffer.clear ob; s -let stream_to_channel ?buf ?(len=2096) ?std oc st = +let seq_to_channel ?buf ?(len=2096) ?(suf = "\n") ?std oc seq = let ob = match buf with None -> Buffer.create len - | Some ob -> ob + | Some ob -> Buffer.clear ob; ob in - stream_to_buffer ?std ob st + Seq.iter (fun json -> + to_buffer ~suf ?std ob json; + Buffer.output_buffer oc ob; + Buffer.clear ob; + ) seq -let stream_to_file ?len ?std file st = +let seq_to_file ?len ?(suf = "\n") ?std file st = let oc = open_out file in try - stream_to_channel ?len ?std oc st; + seq_to_channel ?len ~suf ?std oc st; close_out oc with e -> close_out_noerr oc; @@ -1505,8 +1520,138 @@ let rec sort = function | `List l -> `List (List.rev (List.rev_map sort l)) -# 523 "write.ml" +# 495 "write.ml" | x -> x +# 35 "yojson.cppo.ml" +module Pretty = +struct +# 1 "pretty.ml" +(* + Pretty-print JSON data in an attempt to maximize readability. + + 1. What fits on one line stays on one line. + 2. What doesn't fit on one line gets printed more vertically so as to not + exceed a reasonable page width, if possible. + + Arrays containing only simple elements ("atoms") are pretty-printed with + end-of-line wrapping like ordinary text: + + [ + "hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello", + "hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello" + ] + + Other arrays are printed either horizontally or vertically depending + on whether they fit on a single line: + + [ { "hello": "world" }, { "hello": "world" }, { "hello": "world" } ] + + or + + [ + { "hello": "world" }, + { "hello": "world" }, + { "hello": "world" }, + { "hello": "world" } + ] +*) + +let pp_list sep ppx out l = + let pp_sep out () = Format.fprintf out "%s@ " sep in + Format.pp_print_list ~pp_sep ppx out l + +let is_atom (x: [> t]) = + match x with + | `Null + | `Bool _ + | `Int _ + | `Float _ + | `String _ + | `Intlit _ + | `Floatlit _ + | `Stringlit _ + | `List [] + | `Assoc [] + | `Tuple [] + | `Variant (_, None) -> true + | `List _ + | `Assoc _ + | `Tuple _ + | `Variant (_, Some _) -> false + +let is_atom_list l = + List.for_all is_atom l + +(* + inside_box: indicates that we're already within a box that imposes + a certain style and we shouldn't create a new one. This is used for + printing field values like this: + + foo: [ + bar + ] + + rather than something else like + + foo: + [ + bar + ] +*) +let rec format ~inside_box std (out:Format.formatter) (x:t) : unit = + match x with + | `Null -> Format.pp_print_string out "null" + | `Bool x -> Format.pp_print_bool out x + +# 78 "pretty.ml" + | `Int x -> Format.pp_print_string out (json_string_of_int x) + +# 81 "pretty.ml" + | `Float x -> + let s = + if std then std_json_string_of_float x + else json_string_of_float x + in + Format.pp_print_string out s + +# 89 "pretty.ml" + | `String s -> Format.pp_print_string out (json_string_of_string s) + +# 100 "pretty.ml" + | `List [] -> Format.pp_print_string out "[]" + | `List l -> + if not inside_box then Format.fprintf out "@["; + if is_atom_list l then + (* use line wrapping like we would do for a paragraph of text *) + Format.fprintf out "[@;<1 0>@[%a@]@;<1 -2>]" + (pp_list "," (format ~inside_box:false std)) l + else + (* print the elements horizontally if they fit on the line, + otherwise print them in a column *) + Format.fprintf out "[@;<1 0>@[%a@]@;<1 -2>]" + (pp_list "," (format ~inside_box:false std)) l; + if not inside_box then Format.fprintf out "@]"; + | `Assoc [] -> Format.pp_print_string out "{}" + | `Assoc l -> + if not inside_box then Format.fprintf out "@["; + Format.fprintf out "{@;<1 0>%a@;<1 -2>}" (pp_list "," (format_field std)) l; + if not inside_box then Format.fprintf out "@]"; + +# 156 "pretty.ml" +and format_field std out (name, x) = + Format.fprintf out "@[%s: %a@]" (json_string_of_string name) (format ~inside_box:true std) x + +let pp ?(std = false) out x = + Format.fprintf out "@[%a@]" (format ~inside_box:true std) (x :> t) + +let to_string ?std x = + Format.asprintf "%a" (pp ?std) x + +let to_channel ?std oc x = + let fmt = Format.formatter_of_out_channel oc in + Format.fprintf fmt "%a@?" (pp ?std) x +# 38 "yojson.cppo.ml" +end # 1 "monomorphic.ml" let rec pp fmt = function @@ -1606,14 +1751,14 @@ let rec equal a b = | _ -> false # 2 "write2.ml" -let pretty_print ?std out (x : t) = - Pretty.pp ?std out (x :> json_max) +let pretty_print ?std out x = + Pretty.pp ?std out x -let pretty_to_string ?std (x : t) = - Pretty.to_string ?std (x :> json_max) +let pretty_to_string ?std x = + Pretty.to_string ?std x -let pretty_to_channel ?std oc (x : t) = - Pretty.to_channel ?std oc (x :> json_max) +let pretty_to_channel ?std oc x = + Pretty.to_channel ?std oc x # 1 "lib/read.mll" @@ -1771,7 +1916,7 @@ let pretty_to_channel ?std oc (x : t) = let map_lexeme f lexbuf = let len = lexbuf.lex_curr_pos - lexbuf.lex_start_pos in - f (Bytes.to_string lexbuf.lex_buffer) lexbuf.lex_start_pos len + f (Bytes.sub_string lexbuf.lex_buffer lexbuf.lex_start_pos len) 0 len type variant_kind = [ `Edgy_bracket | `Square_bracket | `Double_quote ] type tuple_kind = [ `Parenthesis | `Square_bracket ] @@ -6510,30 +6655,30 @@ and __ocaml_lex_junk_rec lexbuf __ocaml_lex_state = exception Finally of exn * exn - let stream_from_lexbuf v ?(fin = fun () -> ()) lexbuf = + let seq_from_lexbuf v ?(fin = fun () -> ()) lexbuf = let stream = Some true in - let f i = - try Some (from_lexbuf v ?stream lexbuf) + let rec f () = + try Seq.Cons (from_lexbuf v ?stream lexbuf, f) with End_of_input -> fin (); - None + Seq.Nil | e -> (try fin () with fin_e -> raise (Finally (e, fin_e))); raise e in - Stream.from f + f - let stream_from_string ?buf ?fname ?lnum s = + let seq_from_string ?buf ?fname ?lnum s = let v = init_lexer ?buf ?fname ?lnum () in - stream_from_lexbuf v (Lexing.from_string s) + seq_from_lexbuf v (Lexing.from_string s) - let stream_from_channel ?buf ?fin ?fname ?lnum ic = + let seq_from_channel ?buf ?fin ?fname ?lnum ic = let lexbuf = Lexing.from_channel ic in let v = init_lexer ?buf ?fname ?lnum () in - stream_from_lexbuf v ?fin lexbuf + seq_from_lexbuf v ?fin lexbuf - let stream_from_file ?buf ?fname ?lnum file = + let seq_from_file ?buf ?fname ?lnum file = let ic = open_in file in let fin () = close_in ic in let fname = @@ -6543,29 +6688,28 @@ and __ocaml_lex_junk_rec lexbuf __ocaml_lex_state = in let lexbuf = Lexing.from_channel ic in let v = init_lexer ?buf ?fname ?lnum () in - stream_from_lexbuf v ~fin lexbuf + seq_from_lexbuf v ~fin lexbuf type json_line = [ `Json of t | `Exn of exn ] - let linestream_from_channel + let lineseq_from_channel ?buf ?(fin = fun () -> ()) ?fname ?lnum:(lnum0 = 1) ic = let buf = match buf with None -> Some (Buffer.create 256) | Some _ -> buf in - let f i = + let rec f lnum = fun () -> try let line = input_line ic in - let lnum = lnum0 + i in - Some (`Json (from_string ?buf ?fname ~lnum line)) + Seq.Cons (`Json (from_string ?buf ?fname ~lnum line), f (lnum + 1)) with - End_of_file -> fin (); None - | e -> Some (`Exn e) + End_of_file -> fin (); Seq.Nil + | e -> Seq.Cons (`Exn e, f (lnum + 1)) in - Stream.from f + f lnum0 - let linestream_from_file ?buf ?fname ?lnum file = + let lineseq_from_file ?buf ?fname ?lnum file = let ic = open_in file in let fin () = close_in ic in let fname = @@ -6573,7 +6717,7 @@ and __ocaml_lex_junk_rec lexbuf __ocaml_lex_state = None -> Some file | x -> x in - linestream_from_channel ?buf ~fin ?fname ?lnum ic + lineseq_from_channel ?buf ~fin ?fname ?lnum ic let prettify ?std s = pretty_to_string ?std (from_string s) @@ -6581,11 +6725,9 @@ and __ocaml_lex_junk_rec lexbuf __ocaml_lex_state = let compact ?std s = to_string (from_string s) - let validate_json _path _value = None - -# 3411 "lib/read.ml" -# 39 "yojson.cppo.ml" +# 3408 "lib/read.ml" +# 42 "yojson.cppo.ml" module Util = struct # 1 "util.ml" @@ -6793,9 +6935,9 @@ let combine (first : t) (second : t) = match (first, second) with | (`Assoc a, `Assoc b) -> (`Assoc (a @ b) : t) | (a, b) -> raise (Invalid_argument "Expected two objects, check inputs") -# 42 "yojson.cppo.ml" +# 45 "yojson.cppo.ml" end -# 46 "yojson.cppo.ml" +# 49 "yojson.cppo.ml" end module Safe = @@ -6993,24 +7135,9 @@ let float_needs_period s = false (* - Both write_float_fast and write_float guarantee - that a sufficient number of digits are printed in order to - allow reversibility. - - The _fast version is faster but often produces unnecessarily long numbers. + Guarantees that a sufficient number of digits are printed in order to allow + reversibility. *) -let write_float_fast ob x = - match classify_float x with - FP_nan -> - Buffer.add_string ob "NaN" - | FP_infinite -> - Buffer.add_string ob (if x > 0. then "Infinity" else "-Infinity") - | _ -> - let s = Printf.sprintf "%.17g" x in - Buffer.add_string ob s; - if float_needs_period s then - Buffer.add_string ob ".0" - let write_float ob x = match classify_float x with FP_nan -> @@ -7053,6 +7180,7 @@ let write_normal_float_prec significant_figures ob x = if float_needs_period s then Buffer.add_string ob ".0" +(* used by atdgen *) let write_float_prec significant_figures ob x = match classify_float x with FP_nan -> @@ -7068,22 +7196,6 @@ let json_string_of_float x = Buffer.contents ob -let write_std_float_fast ob x = - match classify_float x with - FP_nan -> - json_error "NaN value not allowed in standard JSON" - | FP_infinite -> - json_error - (if x > 0. then - "Infinity value not allowed in standard JSON" - else - "-Infinity value not allowed in standard JSON") - | _ -> - let s = Printf.sprintf "%.17g" x in - Buffer.add_string ob s; - if float_needs_period s then - Buffer.add_string ob ".0" - let write_std_float ob x = match classify_float x with FP_nan -> @@ -7104,6 +7216,7 @@ let write_std_float ob x = if float_needs_period s then Buffer.add_string ob ".0" +(* used by atdgen *) let write_std_float_prec significant_figures ob x = match classify_float x with FP_nan -> @@ -7168,29 +7281,29 @@ let rec write_json ob (x : t) = `Null -> write_null ob () | `Bool b -> write_bool ob b -# 293 "write.ml" +# 264 "write.ml" | `Int i -> write_int ob i -# 296 "write.ml" +# 267 "write.ml" | `Intlit s -> Buffer.add_string ob s -# 299 "write.ml" +# 270 "write.ml" | `Float f -> write_float ob f -# 305 "write.ml" +# 276 "write.ml" | `String s -> write_string ob s -# 310 "write.ml" +# 281 "write.ml" | `Assoc l -> write_assoc ob l | `List l -> write_list ob l -# 313 "write.ml" +# 284 "write.ml" | `Tuple l -> write_tuple ob l -# 316 "write.ml" +# 287 "write.ml" | `Variant (s, o) -> write_variant ob s o -# 319 "write.ml" +# 290 "write.ml" and write_assoc ob l = let f_elt ob (s, x) = write_string ob s; @@ -7206,13 +7319,13 @@ and write_list ob l = iter2 write_json f_sep ob l; Buffer.add_char ob ']' -# 335 "write.ml" +# 306 "write.ml" and write_tuple ob l = Buffer.add_char ob '('; iter2 write_json f_sep ob l; Buffer.add_char ob ')' -# 342 "write.ml" +# 313 "write.ml" and write_variant ob s o = Buffer.add_char ob '<'; write_string ob s; @@ -7224,7 +7337,7 @@ and write_variant ob s o = ); Buffer.add_char ob '>' -# 354 "write.ml" +# 325 "write.ml" let write_t = write_json let rec write_std_json ob (x : t) = @@ -7232,29 +7345,29 @@ let rec write_std_json ob (x : t) = `Null -> write_null ob () | `Bool b -> write_bool ob b -# 361 "write.ml" +# 332 "write.ml" | `Int i -> write_int ob i -# 364 "write.ml" +# 335 "write.ml" | `Intlit s -> Buffer.add_string ob s -# 367 "write.ml" +# 338 "write.ml" | `Float f -> write_std_float ob f -# 373 "write.ml" +# 344 "write.ml" | `String s -> write_string ob s -# 378 "write.ml" +# 349 "write.ml" | `Assoc l -> write_std_assoc ob l | `List l -> write_std_list ob l -# 381 "write.ml" +# 352 "write.ml" | `Tuple l -> write_std_tuple ob l -# 384 "write.ml" +# 355 "write.ml" | `Variant (s, o) -> write_std_variant ob s o -# 387 "write.ml" +# 358 "write.ml" and write_std_assoc ob l = let f_elt ob (s, x) = write_string ob s; @@ -7275,7 +7388,7 @@ and write_std_tuple ob l = iter2 write_std_json f_sep ob l; Buffer.add_char ob ']' -# 408 "write.ml" +# 379 "write.ml" and write_std_variant ob s o = match o with None -> write_string ob s @@ -7287,19 +7400,15 @@ and write_std_variant ob s o = Buffer.add_char ob ']' -# 420 "write.ml" -let to_buffer ?(std = false) ob x = - if std then ( - if not (is_object_or_array x) then - json_error "Root is not an object or array" - else - write_std_json ob x - ) +# 391 "write.ml" +let to_buffer ?(suf = "") ?(std = false) ob x = + if std then + write_std_json ob x else - write_json ob x + write_json ob x; + Buffer.add_string ob suf - -let to_string ?buf ?(len = 256) ?std x = +let to_string ?buf ?(len = 256) ?(suf = "") ?std x = let ob = match buf with None -> Buffer.create len @@ -7307,43 +7416,44 @@ let to_string ?buf ?(len = 256) ?std x = Buffer.clear ob; ob in - to_buffer ?std ob x; + to_buffer ~suf ?std ob x; let s = Buffer.contents ob in Buffer.clear ob; s -let to_channel ?buf ?(len=4096) ?std oc x = +let to_channel ?buf ?(len=4096) ?(suf = "") ?std oc x = let ob = match buf with None -> Buffer.create len - | Some ob -> ob + | Some ob -> Buffer.clear ob; ob in - to_buffer ?std ob x; - Buffer.output_buffer oc ob + to_buffer ~suf ?std ob x; + Buffer.output_buffer oc ob; + Buffer.clear ob -let to_output ?buf ?(len=4096) ?std out x = +let to_output ?buf ?(len=4096) ?(suf = "") ?std out x = let ob = match buf with None -> Buffer.create len - | Some ob -> ob + | Some ob -> Buffer.clear ob; ob in - to_buffer ?std ob x; + to_buffer ~suf ?std ob x; out#output (Buffer.contents ob) 0 (Buffer.length ob); - () + Buffer.clear ob -let to_file ?len ?std file x = +let to_file ?len ?std ?(suf = "\n") file x = let oc = open_out file in try - to_channel ?len ?std oc x; + to_channel ?len ~suf ?std oc x; close_out oc with e -> close_out_noerr oc; raise e -let stream_to_buffer ?std ob st = - Stream.iter (to_buffer ?std ob) st +let seq_to_buffer ?(suf = "\n") ?std ob st = + Seq.iter (to_buffer ~suf ?std ob) st -let stream_to_string ?buf ?(len = 256) ?std st = +let seq_to_string ?buf ?(len = 256) ?(suf = "\n") ?std st = let ob = match buf with None -> Buffer.create len @@ -7351,23 +7461,27 @@ let stream_to_string ?buf ?(len = 256) ?std st = Buffer.clear ob; ob in - stream_to_buffer ?std ob st; + seq_to_buffer ~suf ?std ob st; let s = Buffer.contents ob in Buffer.clear ob; s -let stream_to_channel ?buf ?(len=2096) ?std oc st = +let seq_to_channel ?buf ?(len=2096) ?(suf = "\n") ?std oc seq = let ob = match buf with None -> Buffer.create len - | Some ob -> ob + | Some ob -> Buffer.clear ob; ob in - stream_to_buffer ?std ob st + Seq.iter (fun json -> + to_buffer ~suf ?std ob json; + Buffer.output_buffer oc ob; + Buffer.clear ob; + ) seq -let stream_to_file ?len ?std file st = +let seq_to_file ?len ?(suf = "\n") ?std file st = let oc = open_out file in try - stream_to_channel ?len ?std oc st; + seq_to_channel ?len ~suf ?std oc st; close_out oc with e -> close_out_noerr oc; @@ -7381,19 +7495,189 @@ let rec sort = function | `List l -> `List (List.rev (List.rev_map sort l)) -# 513 "write.ml" +# 485 "write.ml" | `Tuple l -> `Tuple (List.rev (List.rev_map sort l)) -# 517 "write.ml" +# 489 "write.ml" | `Variant (k, Some v) as x -> let v' = sort v in if v == v' then x else `Variant (k, Some v') -# 523 "write.ml" +# 495 "write.ml" | x -> x +# 62 "yojson.cppo.ml" +module Pretty = +struct +# 1 "pretty.ml" +(* + Pretty-print JSON data in an attempt to maximize readability. + + 1. What fits on one line stays on one line. + 2. What doesn't fit on one line gets printed more vertically so as to not + exceed a reasonable page width, if possible. + + Arrays containing only simple elements ("atoms") are pretty-printed with + end-of-line wrapping like ordinary text: + + [ + "hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello", + "hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello" + ] + + Other arrays are printed either horizontally or vertically depending + on whether they fit on a single line: + + [ { "hello": "world" }, { "hello": "world" }, { "hello": "world" } ] + + or + + [ + { "hello": "world" }, + { "hello": "world" }, + { "hello": "world" }, + { "hello": "world" } + ] +*) + +let pp_list sep ppx out l = + let pp_sep out () = Format.fprintf out "%s@ " sep in + Format.pp_print_list ~pp_sep ppx out l + +let is_atom (x: [> t]) = + match x with + | `Null + | `Bool _ + | `Int _ + | `Float _ + | `String _ + | `Intlit _ + | `Floatlit _ + | `Stringlit _ + | `List [] + | `Assoc [] + | `Tuple [] + | `Variant (_, None) -> true + | `List _ + | `Assoc _ + | `Tuple _ + | `Variant (_, Some _) -> false + +let is_atom_list l = + List.for_all is_atom l + +(* + inside_box: indicates that we're already within a box that imposes + a certain style and we shouldn't create a new one. This is used for + printing field values like this: + + foo: [ + bar + ] + + rather than something else like + + foo: + [ + bar + ] +*) +let rec format ~inside_box std (out:Format.formatter) (x:t) : unit = + match x with + | `Null -> Format.pp_print_string out "null" + | `Bool x -> Format.pp_print_bool out x + +# 78 "pretty.ml" + | `Int x -> Format.pp_print_string out (json_string_of_int x) + +# 81 "pretty.ml" + | `Float x -> + let s = + if std then std_json_string_of_float x + else json_string_of_float x + in + Format.pp_print_string out s + +# 89 "pretty.ml" + | `String s -> Format.pp_print_string out (json_string_of_string s) + +# 92 "pretty.ml" + | `Intlit s -> Format.pp_print_string out s + +# 100 "pretty.ml" + | `List [] -> Format.pp_print_string out "[]" + | `List l -> + if not inside_box then Format.fprintf out "@["; + if is_atom_list l then + (* use line wrapping like we would do for a paragraph of text *) + Format.fprintf out "[@;<1 0>@[%a@]@;<1 -2>]" + (pp_list "," (format ~inside_box:false std)) l + else + (* print the elements horizontally if they fit on the line, + otherwise print them in a column *) + Format.fprintf out "[@;<1 0>@[%a@]@;<1 -2>]" + (pp_list "," (format ~inside_box:false std)) l; + if not inside_box then Format.fprintf out "@]"; + | `Assoc [] -> Format.pp_print_string out "{}" + | `Assoc l -> + if not inside_box then Format.fprintf out "@["; + Format.fprintf out "{@;<1 0>%a@;<1 -2>}" (pp_list "," (format_field std)) l; + if not inside_box then Format.fprintf out "@]"; + +# 119 "pretty.ml" + | `Tuple l -> + if std then + format ~inside_box std out (`List l) + else + if l = [] then + Format.pp_print_string out "()" + else ( + if not inside_box then Format.fprintf out "@["; + Format.fprintf out "(@,%a@;<0 -2>)" (pp_list "," (format ~inside_box:false std)) l; + if not inside_box then Format.fprintf out "@]"; + ) + +# 132 "pretty.ml" + | `Variant (s, None) -> + if std then + +# 135 "pretty.ml" + let representation = `String s in + +# 139 "pretty.ml" + format ~inside_box std out representation + else + Format.fprintf out "<%s>" (json_string_of_string s) + + | `Variant (s, Some x) -> + if std then + +# 146 "pretty.ml" + let representation = `String s in + +# 150 "pretty.ml" + format ~inside_box std out (`List [ representation; x ]) + else + let op = json_string_of_string s in + Format.fprintf out "<@[%s: %a@]>" op (format ~inside_box:true std) x + +# 156 "pretty.ml" +and format_field std out (name, x) = + Format.fprintf out "@[%s: %a@]" (json_string_of_string name) (format ~inside_box:true std) x + +let pp ?(std = false) out x = + Format.fprintf out "@[%a@]" (format ~inside_box:true std) (x :> t) + +let to_string ?std x = + Format.asprintf "%a" (pp ?std) x + +let to_channel ?std oc x = + let fmt = Format.formatter_of_out_channel oc in + Format.fprintf fmt "%a@?" (pp ?std) x +# 65 "yojson.cppo.ml" +end # 1 "monomorphic.ml" let rec pp fmt = function @@ -7543,14 +7827,14 @@ let rec equal a b = | _ -> false # 2 "write2.ml" -let pretty_print ?std out (x : t) = - Pretty.pp ?std out (x :> json_max) +let pretty_print ?std out x = + Pretty.pp ?std out x -let pretty_to_string ?std (x : t) = - Pretty.to_string ?std (x :> json_max) +let pretty_to_string ?std x = + Pretty.to_string ?std x -let pretty_to_channel ?std oc (x : t) = - Pretty.to_channel ?std oc (x :> json_max) +let pretty_to_channel ?std oc x = + Pretty.to_channel ?std oc x # 1 "lib/read.mll" @@ -7708,7 +7992,7 @@ let pretty_to_channel ?std oc (x : t) = let map_lexeme f lexbuf = let len = lexbuf.lex_curr_pos - lexbuf.lex_start_pos in - f (Bytes.to_string lexbuf.lex_buffer) lexbuf.lex_start_pos len + f (Bytes.sub_string lexbuf.lex_buffer lexbuf.lex_start_pos len) 0 len type variant_kind = [ `Edgy_bracket | `Square_bracket | `Double_quote ] type tuple_kind = [ `Parenthesis | `Square_bracket ] @@ -12511,30 +12795,30 @@ and __ocaml_lex_junk_rec lexbuf __ocaml_lex_state = exception Finally of exn * exn - let stream_from_lexbuf v ?(fin = fun () -> ()) lexbuf = + let seq_from_lexbuf v ?(fin = fun () -> ()) lexbuf = let stream = Some true in - let f i = - try Some (from_lexbuf v ?stream lexbuf) + let rec f () = + try Seq.Cons (from_lexbuf v ?stream lexbuf, f) with End_of_input -> fin (); - None + Seq.Nil | e -> (try fin () with fin_e -> raise (Finally (e, fin_e))); raise e in - Stream.from f + f - let stream_from_string ?buf ?fname ?lnum s = + let seq_from_string ?buf ?fname ?lnum s = let v = init_lexer ?buf ?fname ?lnum () in - stream_from_lexbuf v (Lexing.from_string s) + seq_from_lexbuf v (Lexing.from_string s) - let stream_from_channel ?buf ?fin ?fname ?lnum ic = + let seq_from_channel ?buf ?fin ?fname ?lnum ic = let lexbuf = Lexing.from_channel ic in let v = init_lexer ?buf ?fname ?lnum () in - stream_from_lexbuf v ?fin lexbuf + seq_from_lexbuf v ?fin lexbuf - let stream_from_file ?buf ?fname ?lnum file = + let seq_from_file ?buf ?fname ?lnum file = let ic = open_in file in let fin () = close_in ic in let fname = @@ -12544,29 +12828,28 @@ and __ocaml_lex_junk_rec lexbuf __ocaml_lex_state = in let lexbuf = Lexing.from_channel ic in let v = init_lexer ?buf ?fname ?lnum () in - stream_from_lexbuf v ~fin lexbuf + seq_from_lexbuf v ~fin lexbuf type json_line = [ `Json of t | `Exn of exn ] - let linestream_from_channel + let lineseq_from_channel ?buf ?(fin = fun () -> ()) ?fname ?lnum:(lnum0 = 1) ic = let buf = match buf with None -> Some (Buffer.create 256) | Some _ -> buf in - let f i = + let rec f lnum = fun () -> try let line = input_line ic in - let lnum = lnum0 + i in - Some (`Json (from_string ?buf ?fname ~lnum line)) + Seq.Cons (`Json (from_string ?buf ?fname ~lnum line), f (lnum + 1)) with - End_of_file -> fin (); None - | e -> Some (`Exn e) + End_of_file -> fin (); Seq.Nil + | e -> Seq.Cons (`Exn e, f (lnum + 1)) in - Stream.from f + f lnum0 - let linestream_from_file ?buf ?fname ?lnum file = + let lineseq_from_file ?buf ?fname ?lnum file = let ic = open_in file in let fin () = close_in ic in let fname = @@ -12574,7 +12857,7 @@ and __ocaml_lex_junk_rec lexbuf __ocaml_lex_state = None -> Some file | x -> x in - linestream_from_channel ?buf ~fin ?fname ?lnum ic + lineseq_from_channel ?buf ~fin ?fname ?lnum ic let prettify ?std s = pretty_to_string ?std (from_string s) @@ -12582,11 +12865,9 @@ and __ocaml_lex_junk_rec lexbuf __ocaml_lex_state = let compact ?std s = to_string (from_string s) - let validate_json _path _value = None - -# 3411 "lib/read.ml" -# 62 "yojson.cppo.ml" +# 3408 "lib/read.ml" +# 69 "yojson.cppo.ml" module Util = struct # 1 "util.ml" @@ -12794,10 +13075,10 @@ let combine (first : t) (second : t) = match (first, second) with | (`Assoc a, `Assoc b) -> (`Assoc (a @ b) : t) | (a, b) -> raise (Invalid_argument "Expected two objects, check inputs") -# 65 "yojson.cppo.ml" -end # 72 "yojson.cppo.ml" end +# 79 "yojson.cppo.ml" +end module Raw = struct @@ -12976,24 +13257,9 @@ let float_needs_period s = false (* - Both write_float_fast and write_float guarantee - that a sufficient number of digits are printed in order to - allow reversibility. - - The _fast version is faster but often produces unnecessarily long numbers. + Guarantees that a sufficient number of digits are printed in order to allow + reversibility. *) -let write_float_fast ob x = - match classify_float x with - FP_nan -> - Buffer.add_string ob "NaN" - | FP_infinite -> - Buffer.add_string ob (if x > 0. then "Infinity" else "-Infinity") - | _ -> - let s = Printf.sprintf "%.17g" x in - Buffer.add_string ob s; - if float_needs_period s then - Buffer.add_string ob ".0" - let write_float ob x = match classify_float x with FP_nan -> @@ -13036,6 +13302,7 @@ let write_normal_float_prec significant_figures ob x = if float_needs_period s then Buffer.add_string ob ".0" +(* used by atdgen *) let write_float_prec significant_figures ob x = match classify_float x with FP_nan -> @@ -13051,22 +13318,6 @@ let json_string_of_float x = Buffer.contents ob -let write_std_float_fast ob x = - match classify_float x with - FP_nan -> - json_error "NaN value not allowed in standard JSON" - | FP_infinite -> - json_error - (if x > 0. then - "Infinity value not allowed in standard JSON" - else - "-Infinity value not allowed in standard JSON") - | _ -> - let s = Printf.sprintf "%.17g" x in - Buffer.add_string ob s; - if float_needs_period s then - Buffer.add_string ob ".0" - let write_std_float ob x = match classify_float x with FP_nan -> @@ -13087,6 +13338,7 @@ let write_std_float ob x = if float_needs_period s then Buffer.add_string ob ".0" +(* used by atdgen *) let write_std_float_prec significant_figures ob x = match classify_float x with FP_nan -> @@ -13151,26 +13403,26 @@ let rec write_json ob (x : t) = `Null -> write_null ob () | `Bool b -> write_bool ob b -# 296 "write.ml" +# 267 "write.ml" | `Intlit s -> Buffer.add_string ob s -# 302 "write.ml" +# 273 "write.ml" | `Floatlit s -> Buffer.add_string ob s -# 308 "write.ml" +# 279 "write.ml" | `Stringlit s -> Buffer.add_string ob s -# 310 "write.ml" +# 281 "write.ml" | `Assoc l -> write_assoc ob l | `List l -> write_list ob l -# 313 "write.ml" +# 284 "write.ml" | `Tuple l -> write_tuple ob l -# 316 "write.ml" +# 287 "write.ml" | `Variant (s, o) -> write_variant ob s o -# 319 "write.ml" +# 290 "write.ml" and write_assoc ob l = let f_elt ob (s, x) = write_string ob s; @@ -13186,13 +13438,13 @@ and write_list ob l = iter2 write_json f_sep ob l; Buffer.add_char ob ']' -# 335 "write.ml" +# 306 "write.ml" and write_tuple ob l = Buffer.add_char ob '('; iter2 write_json f_sep ob l; Buffer.add_char ob ')' -# 342 "write.ml" +# 313 "write.ml" and write_variant ob s o = Buffer.add_char ob '<'; write_string ob s; @@ -13204,7 +13456,7 @@ and write_variant ob s o = ); Buffer.add_char ob '>' -# 354 "write.ml" +# 325 "write.ml" let write_t = write_json let rec write_std_json ob (x : t) = @@ -13212,26 +13464,26 @@ let rec write_std_json ob (x : t) = `Null -> write_null ob () | `Bool b -> write_bool ob b -# 364 "write.ml" +# 335 "write.ml" | `Intlit s -> Buffer.add_string ob s -# 370 "write.ml" +# 341 "write.ml" | `Floatlit s -> Buffer.add_string ob s -# 376 "write.ml" +# 347 "write.ml" | `Stringlit s -> Buffer.add_string ob s -# 378 "write.ml" +# 349 "write.ml" | `Assoc l -> write_std_assoc ob l | `List l -> write_std_list ob l -# 381 "write.ml" +# 352 "write.ml" | `Tuple l -> write_std_tuple ob l -# 384 "write.ml" +# 355 "write.ml" | `Variant (s, o) -> write_std_variant ob s o -# 387 "write.ml" +# 358 "write.ml" and write_std_assoc ob l = let f_elt ob (s, x) = write_string ob s; @@ -13252,7 +13504,7 @@ and write_std_tuple ob l = iter2 write_std_json f_sep ob l; Buffer.add_char ob ']' -# 408 "write.ml" +# 379 "write.ml" and write_std_variant ob s o = match o with None -> write_string ob s @@ -13264,19 +13516,15 @@ and write_std_variant ob s o = Buffer.add_char ob ']' -# 420 "write.ml" -let to_buffer ?(std = false) ob x = - if std then ( - if not (is_object_or_array x) then - json_error "Root is not an object or array" - else - write_std_json ob x - ) +# 391 "write.ml" +let to_buffer ?(suf = "") ?(std = false) ob x = + if std then + write_std_json ob x else - write_json ob x + write_json ob x; + Buffer.add_string ob suf - -let to_string ?buf ?(len = 256) ?std x = +let to_string ?buf ?(len = 256) ?(suf = "") ?std x = let ob = match buf with None -> Buffer.create len @@ -13284,43 +13532,44 @@ let to_string ?buf ?(len = 256) ?std x = Buffer.clear ob; ob in - to_buffer ?std ob x; + to_buffer ~suf ?std ob x; let s = Buffer.contents ob in Buffer.clear ob; s -let to_channel ?buf ?(len=4096) ?std oc x = +let to_channel ?buf ?(len=4096) ?(suf = "") ?std oc x = let ob = match buf with None -> Buffer.create len - | Some ob -> ob + | Some ob -> Buffer.clear ob; ob in - to_buffer ?std ob x; - Buffer.output_buffer oc ob + to_buffer ~suf ?std ob x; + Buffer.output_buffer oc ob; + Buffer.clear ob -let to_output ?buf ?(len=4096) ?std out x = +let to_output ?buf ?(len=4096) ?(suf = "") ?std out x = let ob = match buf with None -> Buffer.create len - | Some ob -> ob + | Some ob -> Buffer.clear ob; ob in - to_buffer ?std ob x; + to_buffer ~suf ?std ob x; out#output (Buffer.contents ob) 0 (Buffer.length ob); - () + Buffer.clear ob -let to_file ?len ?std file x = +let to_file ?len ?std ?(suf = "\n") file x = let oc = open_out file in try - to_channel ?len ?std oc x; + to_channel ?len ~suf ?std oc x; close_out oc with e -> close_out_noerr oc; raise e -let stream_to_buffer ?std ob st = - Stream.iter (to_buffer ?std ob) st +let seq_to_buffer ?(suf = "\n") ?std ob st = + Seq.iter (to_buffer ~suf ?std ob) st -let stream_to_string ?buf ?(len = 256) ?std st = +let seq_to_string ?buf ?(len = 256) ?(suf = "\n") ?std st = let ob = match buf with None -> Buffer.create len @@ -13328,23 +13577,27 @@ let stream_to_string ?buf ?(len = 256) ?std st = Buffer.clear ob; ob in - stream_to_buffer ?std ob st; + seq_to_buffer ~suf ?std ob st; let s = Buffer.contents ob in Buffer.clear ob; s -let stream_to_channel ?buf ?(len=2096) ?std oc st = +let seq_to_channel ?buf ?(len=2096) ?(suf = "\n") ?std oc seq = let ob = match buf with None -> Buffer.create len - | Some ob -> ob + | Some ob -> Buffer.clear ob; ob in - stream_to_buffer ?std ob st + Seq.iter (fun json -> + to_buffer ~suf ?std ob json; + Buffer.output_buffer oc ob; + Buffer.clear ob; + ) seq -let stream_to_file ?len ?std file st = +let seq_to_file ?len ?(suf = "\n") ?std file st = let oc = open_out file in try - stream_to_channel ?len ?std oc st; + seq_to_channel ?len ~suf ?std oc st; close_out oc with e -> close_out_noerr oc; @@ -13358,19 +13611,181 @@ let rec sort = function | `List l -> `List (List.rev (List.rev_map sort l)) -# 513 "write.ml" +# 485 "write.ml" | `Tuple l -> `Tuple (List.rev (List.rev_map sort l)) -# 517 "write.ml" +# 489 "write.ml" | `Variant (k, Some v) as x -> let v' = sort v in if v == v' then x else `Variant (k, Some v') -# 523 "write.ml" +# 495 "write.ml" | x -> x +# 90 "yojson.cppo.ml" +module Pretty = +struct +# 1 "pretty.ml" +(* + Pretty-print JSON data in an attempt to maximize readability. + + 1. What fits on one line stays on one line. + 2. What doesn't fit on one line gets printed more vertically so as to not + exceed a reasonable page width, if possible. + + Arrays containing only simple elements ("atoms") are pretty-printed with + end-of-line wrapping like ordinary text: + + [ + "hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello", + "hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello" + ] + + Other arrays are printed either horizontally or vertically depending + on whether they fit on a single line: + + [ { "hello": "world" }, { "hello": "world" }, { "hello": "world" } ] + + or + + [ + { "hello": "world" }, + { "hello": "world" }, + { "hello": "world" }, + { "hello": "world" } + ] +*) + +let pp_list sep ppx out l = + let pp_sep out () = Format.fprintf out "%s@ " sep in + Format.pp_print_list ~pp_sep ppx out l + +let is_atom (x: [> t]) = + match x with + | `Null + | `Bool _ + | `Int _ + | `Float _ + | `String _ + | `Intlit _ + | `Floatlit _ + | `Stringlit _ + | `List [] + | `Assoc [] + | `Tuple [] + | `Variant (_, None) -> true + | `List _ + | `Assoc _ + | `Tuple _ + | `Variant (_, Some _) -> false + +let is_atom_list l = + List.for_all is_atom l + +(* + inside_box: indicates that we're already within a box that imposes + a certain style and we shouldn't create a new one. This is used for + printing field values like this: + + foo: [ + bar + ] + + rather than something else like + + foo: + [ + bar + ] +*) +let rec format ~inside_box std (out:Format.formatter) (x:t) : unit = + match x with + | `Null -> Format.pp_print_string out "null" + | `Bool x -> Format.pp_print_bool out x + +# 92 "pretty.ml" + | `Intlit s -> Format.pp_print_string out s + +# 95 "pretty.ml" + | `Floatlit s -> Format.pp_print_string out s + +# 98 "pretty.ml" + | `Stringlit s -> Format.pp_print_string out s + +# 100 "pretty.ml" + | `List [] -> Format.pp_print_string out "[]" + | `List l -> + if not inside_box then Format.fprintf out "@["; + if is_atom_list l then + (* use line wrapping like we would do for a paragraph of text *) + Format.fprintf out "[@;<1 0>@[%a@]@;<1 -2>]" + (pp_list "," (format ~inside_box:false std)) l + else + (* print the elements horizontally if they fit on the line, + otherwise print them in a column *) + Format.fprintf out "[@;<1 0>@[%a@]@;<1 -2>]" + (pp_list "," (format ~inside_box:false std)) l; + if not inside_box then Format.fprintf out "@]"; + | `Assoc [] -> Format.pp_print_string out "{}" + | `Assoc l -> + if not inside_box then Format.fprintf out "@["; + Format.fprintf out "{@;<1 0>%a@;<1 -2>}" (pp_list "," (format_field std)) l; + if not inside_box then Format.fprintf out "@]"; + +# 119 "pretty.ml" + | `Tuple l -> + if std then + format ~inside_box std out (`List l) + else + if l = [] then + Format.pp_print_string out "()" + else ( + if not inside_box then Format.fprintf out "@["; + Format.fprintf out "(@,%a@;<0 -2>)" (pp_list "," (format ~inside_box:false std)) l; + if not inside_box then Format.fprintf out "@]"; + ) + +# 132 "pretty.ml" + | `Variant (s, None) -> + if std then + +# 137 "pretty.ml" + let representation = `Stringlit s in + +# 139 "pretty.ml" + format ~inside_box std out representation + else + Format.fprintf out "<%s>" (json_string_of_string s) + + | `Variant (s, Some x) -> + if std then + +# 148 "pretty.ml" + let representation = `Stringlit s in + +# 150 "pretty.ml" + format ~inside_box std out (`List [ representation; x ]) + else + let op = json_string_of_string s in + Format.fprintf out "<@[%s: %a@]>" op (format ~inside_box:true std) x + +# 156 "pretty.ml" +and format_field std out (name, x) = + Format.fprintf out "@[%s: %a@]" (json_string_of_string name) (format ~inside_box:true std) x + +let pp ?(std = false) out x = + Format.fprintf out "@[%a@]" (format ~inside_box:true std) (x :> t) + +let to_string ?std x = + Format.asprintf "%a" (pp ?std) x + +let to_channel ?std oc x = + let fmt = Format.formatter_of_out_channel oc in + Format.fprintf fmt "%a@?" (pp ?std) x +# 93 "yojson.cppo.ml" +end # 1 "monomorphic.ml" let rec pp fmt = function @@ -13511,14 +13926,14 @@ let rec equal a b = | _ -> false # 2 "write2.ml" -let pretty_print ?std out (x : t) = - Pretty.pp ?std out (x :> json_max) +let pretty_print ?std out x = + Pretty.pp ?std out x -let pretty_to_string ?std (x : t) = - Pretty.to_string ?std (x :> json_max) +let pretty_to_string ?std x = + Pretty.to_string ?std x -let pretty_to_channel ?std oc (x : t) = - Pretty.to_channel ?std oc (x :> json_max) +let pretty_to_channel ?std oc x = + Pretty.to_channel ?std oc x # 1 "lib/read.mll" @@ -13668,7 +14083,7 @@ let pretty_to_channel ?std oc (x : t) = let map_lexeme f lexbuf = let len = lexbuf.lex_curr_pos - lexbuf.lex_start_pos in - f (Bytes.to_string lexbuf.lex_buffer) lexbuf.lex_start_pos len + f (Bytes.sub_string lexbuf.lex_buffer lexbuf.lex_start_pos len) 0 len type variant_kind = [ `Edgy_bracket | `Square_bracket | `Double_quote ] type tuple_kind = [ `Parenthesis | `Square_bracket ] @@ -18470,30 +18885,30 @@ and __ocaml_lex_junk_rec lexbuf __ocaml_lex_state = exception Finally of exn * exn - let stream_from_lexbuf v ?(fin = fun () -> ()) lexbuf = + let seq_from_lexbuf v ?(fin = fun () -> ()) lexbuf = let stream = Some true in - let f i = - try Some (from_lexbuf v ?stream lexbuf) + let rec f () = + try Seq.Cons (from_lexbuf v ?stream lexbuf, f) with End_of_input -> fin (); - None + Seq.Nil | e -> (try fin () with fin_e -> raise (Finally (e, fin_e))); raise e in - Stream.from f + f - let stream_from_string ?buf ?fname ?lnum s = + let seq_from_string ?buf ?fname ?lnum s = let v = init_lexer ?buf ?fname ?lnum () in - stream_from_lexbuf v (Lexing.from_string s) + seq_from_lexbuf v (Lexing.from_string s) - let stream_from_channel ?buf ?fin ?fname ?lnum ic = + let seq_from_channel ?buf ?fin ?fname ?lnum ic = let lexbuf = Lexing.from_channel ic in let v = init_lexer ?buf ?fname ?lnum () in - stream_from_lexbuf v ?fin lexbuf + seq_from_lexbuf v ?fin lexbuf - let stream_from_file ?buf ?fname ?lnum file = + let seq_from_file ?buf ?fname ?lnum file = let ic = open_in file in let fin () = close_in ic in let fname = @@ -18503,29 +18918,28 @@ and __ocaml_lex_junk_rec lexbuf __ocaml_lex_state = in let lexbuf = Lexing.from_channel ic in let v = init_lexer ?buf ?fname ?lnum () in - stream_from_lexbuf v ~fin lexbuf + seq_from_lexbuf v ~fin lexbuf type json_line = [ `Json of t | `Exn of exn ] - let linestream_from_channel + let lineseq_from_channel ?buf ?(fin = fun () -> ()) ?fname ?lnum:(lnum0 = 1) ic = let buf = match buf with None -> Some (Buffer.create 256) | Some _ -> buf in - let f i = + let rec f lnum = fun () -> try let line = input_line ic in - let lnum = lnum0 + i in - Some (`Json (from_string ?buf ?fname ~lnum line)) + Seq.Cons (`Json (from_string ?buf ?fname ~lnum line), f (lnum + 1)) with - End_of_file -> fin (); None - | e -> Some (`Exn e) + End_of_file -> fin (); Seq.Nil + | e -> Seq.Cons (`Exn e, f (lnum + 1)) in - Stream.from f + f lnum0 - let linestream_from_file ?buf ?fname ?lnum file = + let lineseq_from_file ?buf ?fname ?lnum file = let ic = open_in file in let fin () = close_in ic in let fname = @@ -18533,7 +18947,7 @@ and __ocaml_lex_junk_rec lexbuf __ocaml_lex_state = None -> Some file | x -> x in - linestream_from_channel ?buf ~fin ?fname ?lnum ic + lineseq_from_channel ?buf ~fin ?fname ?lnum ic let prettify ?std s = pretty_to_string ?std (from_string s) @@ -18541,9 +18955,7 @@ and __ocaml_lex_junk_rec lexbuf __ocaml_lex_state = let compact ?std s = to_string (from_string s) - let validate_json _path _value = None - -# 3411 "lib/read.ml" -# 91 "yojson.cppo.ml" +# 3408 "lib/read.ml" +# 102 "yojson.cppo.ml" end diff --git a/cpdfyojson.mli b/cpdfyojson.mli index f7e2a48..1fd0e94 100644 --- a/cpdfyojson.mli +++ b/cpdfyojson.mli @@ -1,25 +1,14 @@ # 1 "yojson.cppo.mli" (** - The Yojson library provides runtime functions for reading and writing JSON - data from OCaml. It addresses a few shortcomings of its predecessor - json-wheel and is about twice as fast (2.7x reading, 1.3x writing; results - may vary). - The design goals of Yojson are the following: - - Reducing inter-package dependencies by the use of polymorphic - variants for the JSON tree type. - - Allowing type-aware serializers/deserializers - to read and write directly without going through a generic JSON tree, - for efficiency purposes. - Readers and writers of all JSON syntaxic elements are provided - but are undocumented and meant to be used by generated OCaml code. - - Distinguishing between ints and floats. - - Providing optional extensions of the JSON syntax. - These extensions include comments, arbitrary strings, - optional quotes around field names, tuples and variants. - - @author Martin Jambon - @see JSON specification - *) + The Yojson library provides several types for representing JSON values, with different use cases. + + - The {{!basic}Basic} JSON type, + - The {{!safe}Safe} JSON type, a superset of JSON with safer support for integers, + - The {{!raw}Raw} JSON type, a superset of JSON, safer but less integrated with OCaml types. + +Each of these different types have their own module. + +*) (** {1 Shared types and functions} *) @@ -27,8 +16,12 @@ val version : string exception Json_error of string +(** Exception used: + - in JSON readers, if parsing fails; + - in JSON writers and pretty printing, if [float] value is not allowed in standard JSON. *) val json_error : string -> 'a +(** @raise Json_error *) type lexer_state = { buf : Buffer.t; @@ -74,8 +67,8 @@ exception End_of_input (* end undocumented section *) (**/**) -# 27 "yojson.cppo.mli" -(** {1 Basic JSON tree type} *) +# 16 "yojson.cppo.mli" +(** {1:basic Basic JSON tree type} *) module Basic : sig @@ -145,6 +138,7 @@ All possible cases defined in Yojson: val to_string : ?buf:Buffer.t -> ?len:int -> + ?suf:string -> ?std:bool -> t -> string (** Write a compact JSON value to a string. @@ -152,87 +146,95 @@ val to_string : [Buffer.create]. The buffer is cleared of all contents before starting and right before returning. @param len initial length of the output buffer. + @param suf appended to the output as a suffix, + defaults to empty string. @param std use only standard JSON syntax, i.e. convert tuples and variants into standard JSON (if applicable), refuse to print NaN and infinities, require the root node to be either an object or an array. Default is [false]. + @raise Json_error if [float] value is not allowed in standard JSON. *) val to_channel : ?buf:Buffer.t -> ?len:int -> + ?suf:string -> ?std:bool -> out_channel -> t -> unit (** Write a compact JSON value to a channel. - @param buf allows to reuse an existing buffer created with - [Buffer.create] on the same channel. - [buf] is flushed right - before [to_channel] returns but the [out_channel] is - not flushed automatically. + Note: the [out_channel] is not flushed by this function. - See [to_string] for the role of the other optional arguments. *) + See [to_string] for the role of the optional arguments and raised exceptions. *) val to_output : ?buf:Buffer.t -> ?len:int -> + ?suf:string -> ?std:bool -> < output : string -> int -> int -> int; .. > -> t -> unit (** Write a compact JSON value to an OO channel. - @param buf allows to reuse an existing buffer created with - [Buffer.add_channel] on the same channel. - [buf] is flushed right - before [to_output] returns but the channel itself is - not flushed automatically. - See [to_string] for the role of the other optional arguments. *) + See [to_string] for the role of the optional arguments and raised exceptions. *) val to_file : ?len:int -> ?std:bool -> + ?suf:string -> string -> t -> unit (** Write a compact JSON value to a file. - See [to_string] for the role of the optional arguments. *) + See [to_string] for the role of the optional arguments and raised exceptions. + @param suf is a suffix appended to the output Newline by default + for POSIX compliance. *) val to_buffer : + ?suf:string -> ?std:bool -> Buffer.t -> t -> unit (** Write a compact JSON value to an existing buffer. - See [to_string] for the role of the optional argument. *) + See [to_string] for the role of the optional argument and raised exceptions. *) -val stream_to_string : +val seq_to_string : ?buf:Buffer.t -> ?len:int -> + ?suf:string -> ?std:bool -> - t Stream.t -> string - (** Write a newline-separated sequence of compact one-line JSON values to + t Seq.t -> string + (** Write a sequence of [suf]-suffixed compact one-line JSON values to a string. - See [to_string] for the role of the optional arguments. *) + @param suf is the suffix ouf each value written. Newline by default. + See [to_string] for the role of the optional arguments and raised exceptions. *) -val stream_to_channel : +val seq_to_channel : ?buf:Buffer.t -> ?len:int -> + ?suf:string -> ?std:bool -> - out_channel -> t Stream.t -> unit - (** Write a newline-separated sequence of compact one-line JSON values to + out_channel -> t Seq.t -> unit + (** Write a sequence of [suf]-suffixed compact one-line JSON values to a channel. - See [to_channel] for the role of the optional arguments. *) + @param suf is the suffix of each value written. Newline by default. + See [to_channel] for the role of the optional arguments and raised exceptions. *) -val stream_to_file : +val seq_to_file : ?len:int -> + ?suf:string -> ?std:bool -> - string -> t Stream.t -> unit - (** Write a newline-separated sequence of compact one-line JSON values to + string -> t Seq.t -> unit + (** Write a sequence of [suf]-suffixed compact one-line JSON values to a file. - See [to_string] for the role of the optional arguments. *) + @param suf is the suffix of each value written. Newline by default. + See [to_string] for the role of the optional arguments and raised exceptions. *) -val stream_to_buffer : +val seq_to_buffer : + ?suf:string -> ?std:bool -> Buffer.t -> - t Stream.t -> unit - (** Write a newline-separated sequence of compact one-line JSON values to + t Seq.t -> unit + (** Write a sequence of [suf]-suffixed compact one-line JSON values to an existing buffer. - See [to_string] for the role of the optional arguments. *) + @param suf is the suffix of each value written. Newline by default. + See [to_string] for the role of the optional arguments and raised exceptions. *) val write_t : Buffer.t -> t -> unit (** Write the given JSON value to the given buffer. @@ -251,24 +253,22 @@ val sort : t -> t val write_null : Buffer.t -> unit -> unit val write_bool : Buffer.t -> bool -> unit -# 113 "write.mli" +# 122 "write.mli" val write_int : Buffer.t -> int -> unit -# 116 "write.mli" +# 125 "write.mli" val write_float : Buffer.t -> float -> unit val write_std_float : Buffer.t -> float -> unit -val write_float_fast : Buffer.t -> float -> unit -val write_std_float_fast : Buffer.t -> float -> unit val write_float_prec : int -> Buffer.t -> float -> unit val write_std_float_prec : int -> Buffer.t -> float -> unit -# 124 "write.mli" +# 131 "write.mli" val write_string : Buffer.t -> string -> unit -# 137 "write.mli" +# 144 "write.mli" val write_assoc : Buffer.t -> (string * t) list -> unit val write_list : Buffer.t -> t list -> unit -# 148 "write.mli" +# 155 "write.mli" val write_json : Buffer.t -> t -> unit val write_std_json : Buffer.t -> t -> unit @@ -294,26 +294,29 @@ val equal : t -> t -> bool val pretty_print : ?std:bool -> Format.formatter -> t -> unit (** Pretty-print into a {!Format.formatter}. See [to_string] for the role of the optional [std] argument. + @raise Json_error if [float] value is not allowed in standard JSON. @since 1.3.1 *) val pretty_to_string : ?std:bool -> t -> string (** Pretty-print into a string. See [to_string] for the role of the optional [std] argument. + See [pretty_print] for raised exceptions. *) val pretty_to_channel : ?std:bool -> out_channel -> t -> unit (** Pretty-print to a channel. See [to_string] for the role of the optional [std] argument. + See [pretty_print] for raised exceptions. *) # 1 "read.mli" val prettify : ?std:bool -> string -> string (** Combined parser and pretty-printer. - See [to_string] for the role of the optional [std] argument. *) + See [to_string] for the role of the optional [std] argument and raised exceptions. *) val compact : ?std:bool -> string -> string (** Combined parser and printer. - See [to_string] for the role of the optional [std] argument. *) + See [to_string] for the role of the optional [std] argument and raised exceptions. *) (** {2 JSON readers} *) @@ -331,6 +334,7 @@ val from_string : @param fname data file name to be used in error messages. It does not have to be a real file. @param lnum number of the first line of input. Default is 1. + @raise Json_error if parsing fails. *) val from_channel : @@ -339,7 +343,7 @@ val from_channel : ?lnum:int -> in_channel -> t (** Read a JSON value from a channel. - See [from_string] for the meaning of the optional arguments. *) + See [from_string] for the meaning of the optional arguments and raised exceptions. *) val from_file : ?buf:Buffer.t -> @@ -347,7 +351,7 @@ val from_file : ?lnum:int -> string -> t (** Read a JSON value from a file. - See [from_string] for the meaning of the optional arguments. *) + See [from_string] for the meaning of the optional arguments and raised exceptions. *) type lexer_state = Lexer_state.t = { @@ -374,90 +378,90 @@ val from_lexbuf : Lexing.lexbuf -> t (** Read a JSON value from a lexbuf. A valid initial [lexer_state] can be created with [init_lexer]. - See [from_string] for the meaning of the optional arguments. + See [from_string] for the meaning of the optional arguments and raised exceptions. @param stream indicates whether more data may follow. The default value is false and indicates that only JSON whitespace can be found between the end of the JSON value and the end of the input. *) -val stream_from_string : +val seq_from_string : ?buf:Buffer.t -> ?fname:string -> ?lnum:int -> - string -> t Stream.t + string -> t Seq.t (** Input a sequence of JSON values from a string. Whitespace between JSON values is fine but not required. - See [from_string] for the meaning of the optional arguments. *) + See [from_string] for the meaning of the optional arguments and raised exceptions. *) -val stream_from_channel : +val seq_from_channel : ?buf:Buffer.t -> ?fin:(unit -> unit) -> ?fname:string -> ?lnum:int -> - in_channel -> t Stream.t + in_channel -> t Seq.t (** Input a sequence of JSON values from a channel. Whitespace between JSON values is fine but not required. @param fin finalization function executed once when the end of the - stream is reached either because there is no more input or because + sequence is reached either because there is no more input or because the input could not be parsed, raising an exception. @raise Finally When the parsing and the finalizer both raised, [Finally (exn, fin_exn)] is raised, [exn] being the parsing exception and [fin_exn] the finalizer one. - See [from_string] for the meaning of the other optional arguments. *) + See [from_string] for the meaning of the other optional arguments and other raised exceptions. *) -val stream_from_file : +val seq_from_file : ?buf:Buffer.t -> ?fname:string -> ?lnum:int -> - string -> t Stream.t + string -> t Seq.t (** Input a sequence of JSON values from a file. Whitespace between JSON values is fine but not required. - See [from_string] for the meaning of the optional arguments. *) + See [from_string] for the meaning of the optional arguments and raised exceptions. *) -val stream_from_lexbuf : +val seq_from_lexbuf : lexer_state -> ?fin:(unit -> unit) -> - Lexing.lexbuf -> t Stream.t + Lexing.lexbuf -> t Seq.t (** Input a sequence of JSON values from a lexbuf. A valid initial [lexer_state] can be created with [init_lexer]. Whitespace between JSON values is fine but not required. @raise Finally When the parsing and the finalizer both raised, [Finally (exn, fin_exn)] is raised, [exn] being the parsing exception and [fin_exn] the finalizer one. - See [stream_from_channel] for the meaning of the optional [fin] - argument. *) + See [seq_from_channel] for the meaning of the optional [fin] + argument and other raised exceptions. *) type json_line = [ `Json of t | `Exn of exn ] (** The type of values resulting from a parsing attempt of a JSON value. *) -val linestream_from_channel : +val lineseq_from_channel : ?buf:Buffer.t -> ?fin:(unit -> unit) -> ?fname:string -> ?lnum:int -> - in_channel -> json_line Stream.t + in_channel -> json_line Seq.t (** Input a sequence of JSON values, one per line, from a channel. Exceptions raised when reading malformed lines are caught and represented using [`Exn]. - See [stream_from_channel] for the meaning of the optional [fin] + See [seq_from_channel] for the meaning of the optional [fin] argument. - See [from_string] for the meaning of the other optional arguments. *) + See [from_string] for the meaning of the other optional arguments and raised exceptions. *) -val linestream_from_file : +val lineseq_from_file : ?buf:Buffer.t -> ?fname:string -> ?lnum:int -> - string -> json_line Stream.t + string -> json_line Seq.t (** Input a sequence of JSON values, one per line, from a file. Exceptions raised when reading malformed lines are caught and represented using [`Exn]. - See [stream_from_channel] for the meaning of the optional [fin] + See [seq_from_channel] for the meaning of the optional [fin] argument. - See [from_string] for the meaning of the other optional arguments. *) + See [from_string] for the meaning of the other optional arguments and raised exceptions. *) val read_t : lexer_state -> Lexing.lexbuf -> t (** Read a JSON value from the given lexer_state and lexing buffer and return it. @@ -570,16 +574,10 @@ val read_json : lexer_state -> Lexing.lexbuf -> t val skip_json : lexer_state -> Lexing.lexbuf -> unit val buffer_json : lexer_state -> Lexing.lexbuf -> unit -val validate_json : 'path -> t -> 'error option - (* always returns [None]. - Provided so that atdgen users can write: - - type t = abstract - *) - (* end undocumented section *) (**/**) -# 48 "yojson.cppo.mli" +# 37 "yojson.cppo.mli" +(** This module provides combinators for extracting fields from JSON values. *) module Util : sig # 1 "util.mli" @@ -654,84 +652,99 @@ exception Undefined of string * t of bounds. *) val keys : t -> string list - (** Returns all the key names in the given JSON object *) + (** Returns all the key names in the given JSON object. + @raise Type_error if argument is not a JSON object. *) val values : t -> t list - (** Return all the value in the given JSON object *) + (** Return all the value in the given JSON object. + @raise Type_error if argument is not a JSON object. *) val combine : t -> t -> t - (** Combine two JSON Objects together *) + (** Combine two JSON objects together. + @raise Invalid_argument if either argument is not a JSON object. *) val member : string -> t -> t (** [member k obj] returns the value associated with the key [k] in the JSON - object [obj], or [`Null] if [k] is not present in [obj]. *) + object [obj], or [`Null] if [k] is not present in [obj]. + @raise Type_error if [obj] is not a JSON object. *) val index : int -> t -> t (** [index i arr] returns the value at index [i] in the JSON array [arr]. Negative indices count from the end of the list (so -1 is the last - element). *) + element). + @raise Type_error if [arr] is not a JSON array. + @raise Undefined if index is out of bounds. *) val map : (t -> t) -> t -> t (** [map f arr] calls the function [f] on each element of the JSON array - [arr], and returns a JSON array containing the results. *) + [arr], and returns a JSON array containing the results. + @raise Type_error if [arr] is not an JSON array. *) val to_assoc : t -> (string * t) list - (** Extract the items of a JSON object or raise [Type_error]. *) + (** Extract the items of a JSON object. + @raise Type_error if argument is not a JSON object. *) val to_option : (t -> 'a) -> t -> 'a option (** Return [None] if the JSON value is null or map the JSON value to [Some] value using the provided function. *) val to_bool : t -> bool - (** Extract a boolean value or raise [Type_error]. *) + (** Extract a boolean value. + @raise Type_error if argument is not a JSON boolean. *) val to_bool_option : t -> bool option (** Extract [Some] boolean value, - return [None] if the value is null, - or raise [Type_error] otherwise. *) + return [None] if the value is null. + @raise Type_error if argument is neither. *) val to_number : t -> float - (** Extract a number or raise [Type_error]. *) + (** Extract a number. + @raise Type_error if argument is not a JSON number. *) val to_number_option : t -> float option (** Extract [Some] number, - return [None] if the value is null, - or raise [Type_error] otherwise. *) + return [None] if the value is null. + @raise Type_error if argument is neither. *) val to_float : t -> float - (** Extract a float value or raise [Type_error]. - [to_number] is generally preferred as it also works with int literals. *) + (** Extract a float value. + [to_number] is generally preferred as it also works with int literals. + @raise Type_error if argument is not a JSON float. *) val to_float_option : t -> float option (** Extract [Some] float value, - return [None] if the value is null, - or raise [Type_error] otherwise. + return [None] if the value is null. [to_number_option] is generally preferred as it also works - with int literals. *) + with int literals. + @raise Type_error if argument is neither. *) val to_int : t -> int - (** Extract an int from a JSON int or raise [Type_error]. *) + (** Extract an int from a JSON int. + @raise Type_error if argument is not a JSON int. *) val to_int_option : t -> int option (** Extract [Some] int from a JSON int, - return [None] if the value is null, - or raise [Type_error] otherwise. *) + return [None] if the value is null. + @raise Type_error if argument is neither. *) val to_list : t -> t list - (** Extract a list from JSON array or raise [Type_error]. *) + (** Extract a list from JSON array. + @raise Type_error if argument is not a JSON array. *) val to_string : t -> string - (** Extract a string from a JSON string or raise [Type_error]. *) + (** Extract a string from a JSON string. + @raise Type_error if argument is not a JSON string. *) val to_string_option : t -> string option (** Extract [Some] string from a JSON string, - return [None] if the value is null, - or raise [Type_error] otherwise. *) + return [None] if the value is null. + @raise Type_error if argument is neither. *) val convert_each : (t -> 'a) -> t -> 'a list (** The conversion functions above cannot be used with [map], because they do not return JSON values. This convenience function [convert_each to_f arr] - is equivalent to [List.map to_f (to_list arr)]. *) + is equivalent to [List.map to_f (to_list arr)]. + @raise Type_error if [arr] is not a JSON array. *) (** {3 Exception-free filters} *) @@ -781,12 +794,12 @@ val filter_number : t list -> float list val filter_string : t list -> string list (** Expects JSON strings and unwraps them. *) -# 51 "yojson.cppo.mli" +# 41 "yojson.cppo.mli" end -# 55 "yojson.cppo.mli" +# 45 "yojson.cppo.mli" end -(** {1 Multipurpose JSON tree type} *) +(** {1:safe Multipurpose JSON tree type} *) module Safe : sig @@ -794,7 +807,8 @@ sig This module supports a specific syntax for variants and tuples in addition to the standard JSON nodes. Arbitrary integers are supported and represented as a decimal string - using [`Intlit] when they cannot be represented using OCaml's int type. + using [`Intlit] when they cannot be represented using OCaml's int type + (31 or 63 bits depending on the platform). This module is recommended for intensive use or OCaml-friendly use of JSON. @@ -896,6 +910,7 @@ v} val to_string : ?buf:Buffer.t -> ?len:int -> + ?suf:string -> ?std:bool -> t -> string (** Write a compact JSON value to a string. @@ -903,87 +918,95 @@ val to_string : [Buffer.create]. The buffer is cleared of all contents before starting and right before returning. @param len initial length of the output buffer. + @param suf appended to the output as a suffix, + defaults to empty string. @param std use only standard JSON syntax, i.e. convert tuples and variants into standard JSON (if applicable), refuse to print NaN and infinities, require the root node to be either an object or an array. Default is [false]. + @raise Json_error if [float] value is not allowed in standard JSON. *) val to_channel : ?buf:Buffer.t -> ?len:int -> + ?suf:string -> ?std:bool -> out_channel -> t -> unit (** Write a compact JSON value to a channel. - @param buf allows to reuse an existing buffer created with - [Buffer.create] on the same channel. - [buf] is flushed right - before [to_channel] returns but the [out_channel] is - not flushed automatically. + Note: the [out_channel] is not flushed by this function. - See [to_string] for the role of the other optional arguments. *) + See [to_string] for the role of the optional arguments and raised exceptions. *) val to_output : ?buf:Buffer.t -> ?len:int -> + ?suf:string -> ?std:bool -> < output : string -> int -> int -> int; .. > -> t -> unit (** Write a compact JSON value to an OO channel. - @param buf allows to reuse an existing buffer created with - [Buffer.add_channel] on the same channel. - [buf] is flushed right - before [to_output] returns but the channel itself is - not flushed automatically. - See [to_string] for the role of the other optional arguments. *) + See [to_string] for the role of the optional arguments and raised exceptions. *) val to_file : ?len:int -> ?std:bool -> + ?suf:string -> string -> t -> unit (** Write a compact JSON value to a file. - See [to_string] for the role of the optional arguments. *) + See [to_string] for the role of the optional arguments and raised exceptions. + @param suf is a suffix appended to the output Newline by default + for POSIX compliance. *) val to_buffer : + ?suf:string -> ?std:bool -> Buffer.t -> t -> unit (** Write a compact JSON value to an existing buffer. - See [to_string] for the role of the optional argument. *) + See [to_string] for the role of the optional argument and raised exceptions. *) -val stream_to_string : +val seq_to_string : ?buf:Buffer.t -> ?len:int -> + ?suf:string -> ?std:bool -> - t Stream.t -> string - (** Write a newline-separated sequence of compact one-line JSON values to + t Seq.t -> string + (** Write a sequence of [suf]-suffixed compact one-line JSON values to a string. - See [to_string] for the role of the optional arguments. *) + @param suf is the suffix ouf each value written. Newline by default. + See [to_string] for the role of the optional arguments and raised exceptions. *) -val stream_to_channel : +val seq_to_channel : ?buf:Buffer.t -> ?len:int -> + ?suf:string -> ?std:bool -> - out_channel -> t Stream.t -> unit - (** Write a newline-separated sequence of compact one-line JSON values to + out_channel -> t Seq.t -> unit + (** Write a sequence of [suf]-suffixed compact one-line JSON values to a channel. - See [to_channel] for the role of the optional arguments. *) + @param suf is the suffix of each value written. Newline by default. + See [to_channel] for the role of the optional arguments and raised exceptions. *) -val stream_to_file : +val seq_to_file : ?len:int -> + ?suf:string -> ?std:bool -> - string -> t Stream.t -> unit - (** Write a newline-separated sequence of compact one-line JSON values to + string -> t Seq.t -> unit + (** Write a sequence of [suf]-suffixed compact one-line JSON values to a file. - See [to_string] for the role of the optional arguments. *) + @param suf is the suffix of each value written. Newline by default. + See [to_string] for the role of the optional arguments and raised exceptions. *) -val stream_to_buffer : +val seq_to_buffer : + ?suf:string -> ?std:bool -> Buffer.t -> - t Stream.t -> unit - (** Write a newline-separated sequence of compact one-line JSON values to + t Seq.t -> unit + (** Write a sequence of [suf]-suffixed compact one-line JSON values to an existing buffer. - See [to_string] for the role of the optional arguments. *) + @param suf is the suffix of each value written. Newline by default. + See [to_string] for the role of the optional arguments and raised exceptions. *) val write_t : Buffer.t -> t -> unit (** Write the given JSON value to the given buffer. @@ -1002,32 +1025,30 @@ val sort : t -> t val write_null : Buffer.t -> unit -> unit val write_bool : Buffer.t -> bool -> unit -# 113 "write.mli" +# 122 "write.mli" val write_int : Buffer.t -> int -> unit -# 116 "write.mli" +# 125 "write.mli" val write_float : Buffer.t -> float -> unit val write_std_float : Buffer.t -> float -> unit -val write_float_fast : Buffer.t -> float -> unit -val write_std_float_fast : Buffer.t -> float -> unit val write_float_prec : int -> Buffer.t -> float -> unit val write_std_float_prec : int -> Buffer.t -> float -> unit -# 124 "write.mli" +# 131 "write.mli" val write_string : Buffer.t -> string -> unit -# 128 "write.mli" +# 135 "write.mli" val write_intlit : Buffer.t -> string -> unit -# 137 "write.mli" +# 144 "write.mli" val write_assoc : Buffer.t -> (string * t) list -> unit val write_list : Buffer.t -> t list -> unit -# 140 "write.mli" +# 147 "write.mli" val write_tuple : Buffer.t -> t list -> unit val write_std_tuple : Buffer.t -> t list -> unit -# 144 "write.mli" +# 151 "write.mli" val write_variant : Buffer.t -> string -> t option -> unit val write_std_variant : Buffer.t -> string -> t option -> unit -# 148 "write.mli" +# 155 "write.mli" val write_json : Buffer.t -> t -> unit val write_std_json : Buffer.t -> t -> unit @@ -1039,26 +1060,29 @@ val write_std_json : Buffer.t -> t -> unit val pretty_print : ?std:bool -> Format.formatter -> t -> unit (** Pretty-print into a {!Format.formatter}. See [to_string] for the role of the optional [std] argument. + @raise Json_error if [float] value is not allowed in standard JSON. @since 1.3.1 *) val pretty_to_string : ?std:bool -> t -> string (** Pretty-print into a string. See [to_string] for the role of the optional [std] argument. + See [pretty_print] for raised exceptions. *) val pretty_to_channel : ?std:bool -> out_channel -> t -> unit (** Pretty-print to a channel. See [to_string] for the role of the optional [std] argument. + See [pretty_print] for raised exceptions. *) # 1 "read.mli" val prettify : ?std:bool -> string -> string (** Combined parser and pretty-printer. - See [to_string] for the role of the optional [std] argument. *) + See [to_string] for the role of the optional [std] argument and raised exceptions. *) val compact : ?std:bool -> string -> string (** Combined parser and printer. - See [to_string] for the role of the optional [std] argument. *) + See [to_string] for the role of the optional [std] argument and raised exceptions. *) (** {2 JSON readers} *) @@ -1076,6 +1100,7 @@ val from_string : @param fname data file name to be used in error messages. It does not have to be a real file. @param lnum number of the first line of input. Default is 1. + @raise Json_error if parsing fails. *) val from_channel : @@ -1084,7 +1109,7 @@ val from_channel : ?lnum:int -> in_channel -> t (** Read a JSON value from a channel. - See [from_string] for the meaning of the optional arguments. *) + See [from_string] for the meaning of the optional arguments and raised exceptions. *) val from_file : ?buf:Buffer.t -> @@ -1092,7 +1117,7 @@ val from_file : ?lnum:int -> string -> t (** Read a JSON value from a file. - See [from_string] for the meaning of the optional arguments. *) + See [from_string] for the meaning of the optional arguments and raised exceptions. *) type lexer_state = Lexer_state.t = { @@ -1119,90 +1144,90 @@ val from_lexbuf : Lexing.lexbuf -> t (** Read a JSON value from a lexbuf. A valid initial [lexer_state] can be created with [init_lexer]. - See [from_string] for the meaning of the optional arguments. + See [from_string] for the meaning of the optional arguments and raised exceptions. @param stream indicates whether more data may follow. The default value is false and indicates that only JSON whitespace can be found between the end of the JSON value and the end of the input. *) -val stream_from_string : +val seq_from_string : ?buf:Buffer.t -> ?fname:string -> ?lnum:int -> - string -> t Stream.t + string -> t Seq.t (** Input a sequence of JSON values from a string. Whitespace between JSON values is fine but not required. - See [from_string] for the meaning of the optional arguments. *) + See [from_string] for the meaning of the optional arguments and raised exceptions. *) -val stream_from_channel : +val seq_from_channel : ?buf:Buffer.t -> ?fin:(unit -> unit) -> ?fname:string -> ?lnum:int -> - in_channel -> t Stream.t + in_channel -> t Seq.t (** Input a sequence of JSON values from a channel. Whitespace between JSON values is fine but not required. @param fin finalization function executed once when the end of the - stream is reached either because there is no more input or because + sequence is reached either because there is no more input or because the input could not be parsed, raising an exception. @raise Finally When the parsing and the finalizer both raised, [Finally (exn, fin_exn)] is raised, [exn] being the parsing exception and [fin_exn] the finalizer one. - See [from_string] for the meaning of the other optional arguments. *) + See [from_string] for the meaning of the other optional arguments and other raised exceptions. *) -val stream_from_file : +val seq_from_file : ?buf:Buffer.t -> ?fname:string -> ?lnum:int -> - string -> t Stream.t + string -> t Seq.t (** Input a sequence of JSON values from a file. Whitespace between JSON values is fine but not required. - See [from_string] for the meaning of the optional arguments. *) + See [from_string] for the meaning of the optional arguments and raised exceptions. *) -val stream_from_lexbuf : +val seq_from_lexbuf : lexer_state -> ?fin:(unit -> unit) -> - Lexing.lexbuf -> t Stream.t + Lexing.lexbuf -> t Seq.t (** Input a sequence of JSON values from a lexbuf. A valid initial [lexer_state] can be created with [init_lexer]. Whitespace between JSON values is fine but not required. @raise Finally When the parsing and the finalizer both raised, [Finally (exn, fin_exn)] is raised, [exn] being the parsing exception and [fin_exn] the finalizer one. - See [stream_from_channel] for the meaning of the optional [fin] - argument. *) + See [seq_from_channel] for the meaning of the optional [fin] + argument and other raised exceptions. *) type json_line = [ `Json of t | `Exn of exn ] (** The type of values resulting from a parsing attempt of a JSON value. *) -val linestream_from_channel : +val lineseq_from_channel : ?buf:Buffer.t -> ?fin:(unit -> unit) -> ?fname:string -> ?lnum:int -> - in_channel -> json_line Stream.t + in_channel -> json_line Seq.t (** Input a sequence of JSON values, one per line, from a channel. Exceptions raised when reading malformed lines are caught and represented using [`Exn]. - See [stream_from_channel] for the meaning of the optional [fin] + See [seq_from_channel] for the meaning of the optional [fin] argument. - See [from_string] for the meaning of the other optional arguments. *) + See [from_string] for the meaning of the other optional arguments and raised exceptions. *) -val linestream_from_file : +val lineseq_from_file : ?buf:Buffer.t -> ?fname:string -> ?lnum:int -> - string -> json_line Stream.t + string -> json_line Seq.t (** Input a sequence of JSON values, one per line, from a file. Exceptions raised when reading malformed lines are caught and represented using [`Exn]. - See [stream_from_channel] for the meaning of the optional [fin] + See [seq_from_channel] for the meaning of the optional [fin] argument. - See [from_string] for the meaning of the other optional arguments. *) + See [from_string] for the meaning of the other optional arguments and raised exceptions. *) val read_t : lexer_state -> Lexing.lexbuf -> t (** Read a JSON value from the given lexer_state and lexing buffer and return it. @@ -1315,16 +1340,10 @@ val read_json : lexer_state -> Lexing.lexbuf -> t val skip_json : lexer_state -> Lexing.lexbuf -> unit val buffer_json : lexer_state -> Lexing.lexbuf -> unit -val validate_json : 'path -> t -> 'error option - (* always returns [None]. - Provided so that atdgen users can write: - - type t = abstract - *) - (* end undocumented section *) (**/**) -# 83 "yojson.cppo.mli" +# 74 "yojson.cppo.mli" +(** This module provides combinators for extracting fields from JSON values. *) module Util : sig # 1 "util.mli" @@ -1399,84 +1418,99 @@ exception Undefined of string * t of bounds. *) val keys : t -> string list - (** Returns all the key names in the given JSON object *) + (** Returns all the key names in the given JSON object. + @raise Type_error if argument is not a JSON object. *) val values : t -> t list - (** Return all the value in the given JSON object *) + (** Return all the value in the given JSON object. + @raise Type_error if argument is not a JSON object. *) val combine : t -> t -> t - (** Combine two JSON Objects together *) + (** Combine two JSON objects together. + @raise Invalid_argument if either argument is not a JSON object. *) val member : string -> t -> t (** [member k obj] returns the value associated with the key [k] in the JSON - object [obj], or [`Null] if [k] is not present in [obj]. *) + object [obj], or [`Null] if [k] is not present in [obj]. + @raise Type_error if [obj] is not a JSON object. *) val index : int -> t -> t (** [index i arr] returns the value at index [i] in the JSON array [arr]. Negative indices count from the end of the list (so -1 is the last - element). *) + element). + @raise Type_error if [arr] is not a JSON array. + @raise Undefined if index is out of bounds. *) val map : (t -> t) -> t -> t (** [map f arr] calls the function [f] on each element of the JSON array - [arr], and returns a JSON array containing the results. *) + [arr], and returns a JSON array containing the results. + @raise Type_error if [arr] is not an JSON array. *) val to_assoc : t -> (string * t) list - (** Extract the items of a JSON object or raise [Type_error]. *) + (** Extract the items of a JSON object. + @raise Type_error if argument is not a JSON object. *) val to_option : (t -> 'a) -> t -> 'a option (** Return [None] if the JSON value is null or map the JSON value to [Some] value using the provided function. *) val to_bool : t -> bool - (** Extract a boolean value or raise [Type_error]. *) + (** Extract a boolean value. + @raise Type_error if argument is not a JSON boolean. *) val to_bool_option : t -> bool option (** Extract [Some] boolean value, - return [None] if the value is null, - or raise [Type_error] otherwise. *) + return [None] if the value is null. + @raise Type_error if argument is neither. *) val to_number : t -> float - (** Extract a number or raise [Type_error]. *) + (** Extract a number. + @raise Type_error if argument is not a JSON number. *) val to_number_option : t -> float option (** Extract [Some] number, - return [None] if the value is null, - or raise [Type_error] otherwise. *) + return [None] if the value is null. + @raise Type_error if argument is neither. *) val to_float : t -> float - (** Extract a float value or raise [Type_error]. - [to_number] is generally preferred as it also works with int literals. *) + (** Extract a float value. + [to_number] is generally preferred as it also works with int literals. + @raise Type_error if argument is not a JSON float. *) val to_float_option : t -> float option (** Extract [Some] float value, - return [None] if the value is null, - or raise [Type_error] otherwise. + return [None] if the value is null. [to_number_option] is generally preferred as it also works - with int literals. *) + with int literals. + @raise Type_error if argument is neither. *) val to_int : t -> int - (** Extract an int from a JSON int or raise [Type_error]. *) + (** Extract an int from a JSON int. + @raise Type_error if argument is not a JSON int. *) val to_int_option : t -> int option (** Extract [Some] int from a JSON int, - return [None] if the value is null, - or raise [Type_error] otherwise. *) + return [None] if the value is null. + @raise Type_error if argument is neither. *) val to_list : t -> t list - (** Extract a list from JSON array or raise [Type_error]. *) + (** Extract a list from JSON array. + @raise Type_error if argument is not a JSON array. *) val to_string : t -> string - (** Extract a string from a JSON string or raise [Type_error]. *) + (** Extract a string from a JSON string. + @raise Type_error if argument is not a JSON string. *) val to_string_option : t -> string option (** Extract [Some] string from a JSON string, - return [None] if the value is null, - or raise [Type_error] otherwise. *) + return [None] if the value is null. + @raise Type_error if argument is neither. *) val convert_each : (t -> 'a) -> t -> 'a list (** The conversion functions above cannot be used with [map], because they do not return JSON values. This convenience function [convert_each to_f arr] - is equivalent to [List.map to_f (to_list arr)]. *) + is equivalent to [List.map to_f (to_list arr)]. + @raise Type_error if [arr] is not a JSON array. *) (** {3 Exception-free filters} *) @@ -1526,9 +1560,9 @@ val filter_number : t list -> float list val filter_string : t list -> string list (** Expects JSON strings and unwraps them. *) -# 86 "yojson.cppo.mli" +# 78 "yojson.cppo.mli" end -# 93 "yojson.cppo.mli" +# 85 "yojson.cppo.mli" end (** {1 JSON tree type with literal int/float/string leaves} *) @@ -1619,6 +1653,7 @@ val equal : t -> t -> bool val to_string : ?buf:Buffer.t -> ?len:int -> + ?suf:string -> ?std:bool -> t -> string (** Write a compact JSON value to a string. @@ -1626,87 +1661,95 @@ val to_string : [Buffer.create]. The buffer is cleared of all contents before starting and right before returning. @param len initial length of the output buffer. + @param suf appended to the output as a suffix, + defaults to empty string. @param std use only standard JSON syntax, i.e. convert tuples and variants into standard JSON (if applicable), refuse to print NaN and infinities, require the root node to be either an object or an array. Default is [false]. + @raise Json_error if [float] value is not allowed in standard JSON. *) val to_channel : ?buf:Buffer.t -> ?len:int -> + ?suf:string -> ?std:bool -> out_channel -> t -> unit (** Write a compact JSON value to a channel. - @param buf allows to reuse an existing buffer created with - [Buffer.create] on the same channel. - [buf] is flushed right - before [to_channel] returns but the [out_channel] is - not flushed automatically. + Note: the [out_channel] is not flushed by this function. - See [to_string] for the role of the other optional arguments. *) + See [to_string] for the role of the optional arguments and raised exceptions. *) val to_output : ?buf:Buffer.t -> ?len:int -> + ?suf:string -> ?std:bool -> < output : string -> int -> int -> int; .. > -> t -> unit (** Write a compact JSON value to an OO channel. - @param buf allows to reuse an existing buffer created with - [Buffer.add_channel] on the same channel. - [buf] is flushed right - before [to_output] returns but the channel itself is - not flushed automatically. - See [to_string] for the role of the other optional arguments. *) + See [to_string] for the role of the optional arguments and raised exceptions. *) val to_file : ?len:int -> ?std:bool -> + ?suf:string -> string -> t -> unit (** Write a compact JSON value to a file. - See [to_string] for the role of the optional arguments. *) + See [to_string] for the role of the optional arguments and raised exceptions. + @param suf is a suffix appended to the output Newline by default + for POSIX compliance. *) val to_buffer : + ?suf:string -> ?std:bool -> Buffer.t -> t -> unit (** Write a compact JSON value to an existing buffer. - See [to_string] for the role of the optional argument. *) + See [to_string] for the role of the optional argument and raised exceptions. *) -val stream_to_string : +val seq_to_string : ?buf:Buffer.t -> ?len:int -> + ?suf:string -> ?std:bool -> - t Stream.t -> string - (** Write a newline-separated sequence of compact one-line JSON values to + t Seq.t -> string + (** Write a sequence of [suf]-suffixed compact one-line JSON values to a string. - See [to_string] for the role of the optional arguments. *) + @param suf is the suffix ouf each value written. Newline by default. + See [to_string] for the role of the optional arguments and raised exceptions. *) -val stream_to_channel : +val seq_to_channel : ?buf:Buffer.t -> ?len:int -> + ?suf:string -> ?std:bool -> - out_channel -> t Stream.t -> unit - (** Write a newline-separated sequence of compact one-line JSON values to + out_channel -> t Seq.t -> unit + (** Write a sequence of [suf]-suffixed compact one-line JSON values to a channel. - See [to_channel] for the role of the optional arguments. *) + @param suf is the suffix of each value written. Newline by default. + See [to_channel] for the role of the optional arguments and raised exceptions. *) -val stream_to_file : +val seq_to_file : ?len:int -> + ?suf:string -> ?std:bool -> - string -> t Stream.t -> unit - (** Write a newline-separated sequence of compact one-line JSON values to + string -> t Seq.t -> unit + (** Write a sequence of [suf]-suffixed compact one-line JSON values to a file. - See [to_string] for the role of the optional arguments. *) + @param suf is the suffix of each value written. Newline by default. + See [to_string] for the role of the optional arguments and raised exceptions. *) -val stream_to_buffer : +val seq_to_buffer : + ?suf:string -> ?std:bool -> Buffer.t -> - t Stream.t -> unit - (** Write a newline-separated sequence of compact one-line JSON values to + t Seq.t -> unit + (** Write a sequence of [suf]-suffixed compact one-line JSON values to an existing buffer. - See [to_string] for the role of the optional arguments. *) + @param suf is the suffix of each value written. Newline by default. + See [to_string] for the role of the optional arguments and raised exceptions. *) val write_t : Buffer.t -> t -> unit (** Write the given JSON value to the given buffer. @@ -1726,24 +1769,24 @@ val sort : t -> t val write_null : Buffer.t -> unit -> unit val write_bool : Buffer.t -> bool -> unit -# 128 "write.mli" +# 135 "write.mli" val write_intlit : Buffer.t -> string -> unit -# 131 "write.mli" +# 138 "write.mli" val write_floatlit : Buffer.t -> string -> unit -# 134 "write.mli" +# 141 "write.mli" val write_stringlit : Buffer.t -> string -> unit -# 137 "write.mli" +# 144 "write.mli" val write_assoc : Buffer.t -> (string * t) list -> unit val write_list : Buffer.t -> t list -> unit -# 140 "write.mli" +# 147 "write.mli" val write_tuple : Buffer.t -> t list -> unit val write_std_tuple : Buffer.t -> t list -> unit -# 144 "write.mli" +# 151 "write.mli" val write_variant : Buffer.t -> string -> t option -> unit val write_std_variant : Buffer.t -> string -> t option -> unit -# 148 "write.mli" +# 155 "write.mli" val write_json : Buffer.t -> t -> unit val write_std_json : Buffer.t -> t -> unit @@ -1755,26 +1798,29 @@ val write_std_json : Buffer.t -> t -> unit val pretty_print : ?std:bool -> Format.formatter -> t -> unit (** Pretty-print into a {!Format.formatter}. See [to_string] for the role of the optional [std] argument. + @raise Json_error if [float] value is not allowed in standard JSON. @since 1.3.1 *) val pretty_to_string : ?std:bool -> t -> string (** Pretty-print into a string. See [to_string] for the role of the optional [std] argument. + See [pretty_print] for raised exceptions. *) val pretty_to_channel : ?std:bool -> out_channel -> t -> unit (** Pretty-print to a channel. See [to_string] for the role of the optional [std] argument. + See [pretty_print] for raised exceptions. *) # 1 "read.mli" val prettify : ?std:bool -> string -> string (** Combined parser and pretty-printer. - See [to_string] for the role of the optional [std] argument. *) + See [to_string] for the role of the optional [std] argument and raised exceptions. *) val compact : ?std:bool -> string -> string (** Combined parser and printer. - See [to_string] for the role of the optional [std] argument. *) + See [to_string] for the role of the optional [std] argument and raised exceptions. *) (** {2 JSON readers} *) @@ -1792,6 +1838,7 @@ val from_string : @param fname data file name to be used in error messages. It does not have to be a real file. @param lnum number of the first line of input. Default is 1. + @raise Json_error if parsing fails. *) val from_channel : @@ -1800,7 +1847,7 @@ val from_channel : ?lnum:int -> in_channel -> t (** Read a JSON value from a channel. - See [from_string] for the meaning of the optional arguments. *) + See [from_string] for the meaning of the optional arguments and raised exceptions. *) val from_file : ?buf:Buffer.t -> @@ -1808,7 +1855,7 @@ val from_file : ?lnum:int -> string -> t (** Read a JSON value from a file. - See [from_string] for the meaning of the optional arguments. *) + See [from_string] for the meaning of the optional arguments and raised exceptions. *) type lexer_state = Lexer_state.t = { @@ -1835,90 +1882,90 @@ val from_lexbuf : Lexing.lexbuf -> t (** Read a JSON value from a lexbuf. A valid initial [lexer_state] can be created with [init_lexer]. - See [from_string] for the meaning of the optional arguments. + See [from_string] for the meaning of the optional arguments and raised exceptions. @param stream indicates whether more data may follow. The default value is false and indicates that only JSON whitespace can be found between the end of the JSON value and the end of the input. *) -val stream_from_string : +val seq_from_string : ?buf:Buffer.t -> ?fname:string -> ?lnum:int -> - string -> t Stream.t + string -> t Seq.t (** Input a sequence of JSON values from a string. Whitespace between JSON values is fine but not required. - See [from_string] for the meaning of the optional arguments. *) + See [from_string] for the meaning of the optional arguments and raised exceptions. *) -val stream_from_channel : +val seq_from_channel : ?buf:Buffer.t -> ?fin:(unit -> unit) -> ?fname:string -> ?lnum:int -> - in_channel -> t Stream.t + in_channel -> t Seq.t (** Input a sequence of JSON values from a channel. Whitespace between JSON values is fine but not required. @param fin finalization function executed once when the end of the - stream is reached either because there is no more input or because + sequence is reached either because there is no more input or because the input could not be parsed, raising an exception. @raise Finally When the parsing and the finalizer both raised, [Finally (exn, fin_exn)] is raised, [exn] being the parsing exception and [fin_exn] the finalizer one. - See [from_string] for the meaning of the other optional arguments. *) + See [from_string] for the meaning of the other optional arguments and other raised exceptions. *) -val stream_from_file : +val seq_from_file : ?buf:Buffer.t -> ?fname:string -> ?lnum:int -> - string -> t Stream.t + string -> t Seq.t (** Input a sequence of JSON values from a file. Whitespace between JSON values is fine but not required. - See [from_string] for the meaning of the optional arguments. *) + See [from_string] for the meaning of the optional arguments and raised exceptions. *) -val stream_from_lexbuf : +val seq_from_lexbuf : lexer_state -> ?fin:(unit -> unit) -> - Lexing.lexbuf -> t Stream.t + Lexing.lexbuf -> t Seq.t (** Input a sequence of JSON values from a lexbuf. A valid initial [lexer_state] can be created with [init_lexer]. Whitespace between JSON values is fine but not required. @raise Finally When the parsing and the finalizer both raised, [Finally (exn, fin_exn)] is raised, [exn] being the parsing exception and [fin_exn] the finalizer one. - See [stream_from_channel] for the meaning of the optional [fin] - argument. *) + See [seq_from_channel] for the meaning of the optional [fin] + argument and other raised exceptions. *) type json_line = [ `Json of t | `Exn of exn ] (** The type of values resulting from a parsing attempt of a JSON value. *) -val linestream_from_channel : +val lineseq_from_channel : ?buf:Buffer.t -> ?fin:(unit -> unit) -> ?fname:string -> ?lnum:int -> - in_channel -> json_line Stream.t + in_channel -> json_line Seq.t (** Input a sequence of JSON values, one per line, from a channel. Exceptions raised when reading malformed lines are caught and represented using [`Exn]. - See [stream_from_channel] for the meaning of the optional [fin] + See [seq_from_channel] for the meaning of the optional [fin] argument. - See [from_string] for the meaning of the other optional arguments. *) + See [from_string] for the meaning of the other optional arguments and raised exceptions. *) -val linestream_from_file : +val lineseq_from_file : ?buf:Buffer.t -> ?fname:string -> ?lnum:int -> - string -> json_line Stream.t + string -> json_line Seq.t (** Input a sequence of JSON values, one per line, from a file. Exceptions raised when reading malformed lines are caught and represented using [`Exn]. - See [stream_from_channel] for the meaning of the optional [fin] + See [seq_from_channel] for the meaning of the optional [fin] argument. - See [from_string] for the meaning of the other optional arguments. *) + See [from_string] for the meaning of the other optional arguments and raised exceptions. *) val read_t : lexer_state -> Lexing.lexbuf -> t (** Read a JSON value from the given lexer_state and lexing buffer and return it. @@ -2031,19 +2078,12 @@ val read_json : lexer_state -> Lexing.lexbuf -> t val skip_json : lexer_state -> Lexing.lexbuf -> unit val buffer_json : lexer_state -> Lexing.lexbuf -> unit -val validate_json : 'path -> t -> 'error option - (* always returns [None]. - Provided so that atdgen users can write: - - type t = abstract - *) - (* end undocumented section *) (**/**) -# 121 "yojson.cppo.mli" +# 113 "yojson.cppo.mli" end -(** {1 Supertype of all JSON tree types} *) +(** {1:raw Supertype of all JSON tree types} *) # 1 "type.ml" (** {3 Type of the JSON tree} *) @@ -2125,14 +2165,13 @@ val equal : t -> t -> bool duplicate keys which will be considered equal as long as they are in the same input order. *) -# 135 "yojson.cppo.mli" -type json_max = t # 1 "write.mli" (** {2 JSON writers} *) val to_string : ?buf:Buffer.t -> ?len:int -> + ?suf:string -> ?std:bool -> t -> string (** Write a compact JSON value to a string. @@ -2140,87 +2179,95 @@ val to_string : [Buffer.create]. The buffer is cleared of all contents before starting and right before returning. @param len initial length of the output buffer. + @param suf appended to the output as a suffix, + defaults to empty string. @param std use only standard JSON syntax, i.e. convert tuples and variants into standard JSON (if applicable), refuse to print NaN and infinities, require the root node to be either an object or an array. Default is [false]. + @raise Json_error if [float] value is not allowed in standard JSON. *) val to_channel : ?buf:Buffer.t -> ?len:int -> + ?suf:string -> ?std:bool -> out_channel -> t -> unit (** Write a compact JSON value to a channel. - @param buf allows to reuse an existing buffer created with - [Buffer.create] on the same channel. - [buf] is flushed right - before [to_channel] returns but the [out_channel] is - not flushed automatically. + Note: the [out_channel] is not flushed by this function. - See [to_string] for the role of the other optional arguments. *) + See [to_string] for the role of the optional arguments and raised exceptions. *) val to_output : ?buf:Buffer.t -> ?len:int -> + ?suf:string -> ?std:bool -> < output : string -> int -> int -> int; .. > -> t -> unit (** Write a compact JSON value to an OO channel. - @param buf allows to reuse an existing buffer created with - [Buffer.add_channel] on the same channel. - [buf] is flushed right - before [to_output] returns but the channel itself is - not flushed automatically. - See [to_string] for the role of the other optional arguments. *) + See [to_string] for the role of the optional arguments and raised exceptions. *) val to_file : ?len:int -> ?std:bool -> + ?suf:string -> string -> t -> unit (** Write a compact JSON value to a file. - See [to_string] for the role of the optional arguments. *) + See [to_string] for the role of the optional arguments and raised exceptions. + @param suf is a suffix appended to the output Newline by default + for POSIX compliance. *) val to_buffer : + ?suf:string -> ?std:bool -> Buffer.t -> t -> unit (** Write a compact JSON value to an existing buffer. - See [to_string] for the role of the optional argument. *) + See [to_string] for the role of the optional argument and raised exceptions. *) -val stream_to_string : +val seq_to_string : ?buf:Buffer.t -> ?len:int -> + ?suf:string -> ?std:bool -> - t Stream.t -> string - (** Write a newline-separated sequence of compact one-line JSON values to + t Seq.t -> string + (** Write a sequence of [suf]-suffixed compact one-line JSON values to a string. - See [to_string] for the role of the optional arguments. *) + @param suf is the suffix ouf each value written. Newline by default. + See [to_string] for the role of the optional arguments and raised exceptions. *) -val stream_to_channel : +val seq_to_channel : ?buf:Buffer.t -> ?len:int -> + ?suf:string -> ?std:bool -> - out_channel -> t Stream.t -> unit - (** Write a newline-separated sequence of compact one-line JSON values to + out_channel -> t Seq.t -> unit + (** Write a sequence of [suf]-suffixed compact one-line JSON values to a channel. - See [to_channel] for the role of the optional arguments. *) + @param suf is the suffix of each value written. Newline by default. + See [to_channel] for the role of the optional arguments and raised exceptions. *) -val stream_to_file : +val seq_to_file : ?len:int -> + ?suf:string -> ?std:bool -> - string -> t Stream.t -> unit - (** Write a newline-separated sequence of compact one-line JSON values to + string -> t Seq.t -> unit + (** Write a sequence of [suf]-suffixed compact one-line JSON values to a file. - See [to_string] for the role of the optional arguments. *) + @param suf is the suffix of each value written. Newline by default. + See [to_string] for the role of the optional arguments and raised exceptions. *) -val stream_to_buffer : +val seq_to_buffer : + ?suf:string -> ?std:bool -> Buffer.t -> - t Stream.t -> unit - (** Write a newline-separated sequence of compact one-line JSON values to + t Seq.t -> unit + (** Write a sequence of [suf]-suffixed compact one-line JSON values to an existing buffer. - See [to_string] for the role of the optional arguments. *) + @param suf is the suffix of each value written. Newline by default. + See [to_string] for the role of the optional arguments and raised exceptions. *) val write_t : Buffer.t -> t -> unit (** Write the given JSON value to the given buffer. @@ -2239,36 +2286,34 @@ val sort : t -> t val write_null : Buffer.t -> unit -> unit val write_bool : Buffer.t -> bool -> unit -# 113 "write.mli" +# 122 "write.mli" val write_int : Buffer.t -> int -> unit -# 116 "write.mli" +# 125 "write.mli" val write_float : Buffer.t -> float -> unit val write_std_float : Buffer.t -> float -> unit -val write_float_fast : Buffer.t -> float -> unit -val write_std_float_fast : Buffer.t -> float -> unit val write_float_prec : int -> Buffer.t -> float -> unit val write_std_float_prec : int -> Buffer.t -> float -> unit -# 124 "write.mli" +# 131 "write.mli" val write_string : Buffer.t -> string -> unit -# 128 "write.mli" +# 135 "write.mli" val write_intlit : Buffer.t -> string -> unit -# 131 "write.mli" +# 138 "write.mli" val write_floatlit : Buffer.t -> string -> unit -# 134 "write.mli" +# 141 "write.mli" val write_stringlit : Buffer.t -> string -> unit -# 137 "write.mli" +# 144 "write.mli" val write_assoc : Buffer.t -> (string * t) list -> unit val write_list : Buffer.t -> t list -> unit -# 140 "write.mli" +# 147 "write.mli" val write_tuple : Buffer.t -> t list -> unit val write_std_tuple : Buffer.t -> t list -> unit -# 144 "write.mli" +# 151 "write.mli" val write_variant : Buffer.t -> string -> t option -> unit val write_std_variant : Buffer.t -> string -> t option -> unit -# 148 "write.mli" +# 155 "write.mli" val write_json : Buffer.t -> t -> unit val write_std_json : Buffer.t -> t -> unit @@ -2280,16 +2325,18 @@ val write_std_json : Buffer.t -> t -> unit val pretty_print : ?std:bool -> Format.formatter -> t -> unit (** Pretty-print into a {!Format.formatter}. See [to_string] for the role of the optional [std] argument. + @raise Json_error if [float] value is not allowed in standard JSON. @since 1.3.1 *) val pretty_to_string : ?std:bool -> t -> string (** Pretty-print into a string. See [to_string] for the role of the optional [std] argument. + See [pretty_print] for raised exceptions. *) val pretty_to_channel : ?std:bool -> out_channel -> t -> unit (** Pretty-print to a channel. See [to_string] for the role of the optional [std] argument. + See [pretty_print] for raised exceptions. *) -