···1313exception Error = Loc.Error
14141515type 'a node = 'a * Meta.t
1616+type meta = [ `None | `Locs | `Full ]
16171718type ('ret, 'f) dec_fun =
1819 | Dec_fun : 'f -> ('ret, 'f) dec_fun
···22322233 ws : tokbuf; (* Bufferizes whitespace when layout is [true]. *)
22332234}
2234223522352235-let decoder ?(locs = false) ?(layout = false) ?(file = "-") reader =
22362236+let meta_flags = function
22372237+ | `None -> (false, false)
22382238+ | `Locs -> (true, false)
22392239+ | `Full -> (true, true)
22402240+22412241+let decoder ?(meta = `None) ?(file = "-") reader =
22422242+ let locs, layout = meta_flags meta in
22362243 let overlap = Stdlib.Bytes.create uchar_max_utf8_bytes in
22372244 let token = tokbuf_create 255 and ws = tokbuf_create 255 in
22382245 let meta_none = Meta.make (Loc.(set_file none) file) in
···32133220 | u when is_number_start u -> case d t map.dec_number
32143221 | _ -> err_not_json_value d
3215322232163216-let of_reader_exn ?layout ?locs ?file t reader =
32173217- let d = decoder ?layout ?locs ?file reader in
32233223+let of_reader_exn ?meta ?file t reader =
32243224+ let d = decoder ?meta ?file reader in
32183225 let v =
32193226 nextc d;
32203227 parse d t
32213228 in
32223229 if d.u <> eot then err_exp_eot d else v
3223323032243224-let of_reader ?layout ?locs ?file t reader =
32253225- try Ok (of_reader_exn ?layout ?locs ?file t reader) with Error e -> Error e
32313231+let of_reader ?meta ?file t reader =
32323232+ try Ok (of_reader_exn ?meta ?file t reader) with Error e -> Error e
3226323332273227-let of_string_exn ?layout ?locs ?file t s =
32283228- of_reader_exn ?layout ?locs ?file t (Bytes.Reader.of_string s)
32343234+let of_string_exn ?meta ?file t s =
32353235+ of_reader_exn ?meta ?file t (Bytes.Reader.of_string s)
3229323632303230-let of_string ?layout ?locs ?file t s =
32313231- of_reader ?layout ?locs ?file t (Bytes.Reader.of_string s)
32373237+let of_string ?meta ?file t s =
32383238+ of_reader ?meta ?file t (Bytes.Reader.of_string s)
3232323932333240(* Encoding *)
32343241
+12-16
lib/codec.mli
···8181type 'a node = 'a * Meta.t
8282(** A payload with node metadata. *)
83838484+type meta = [ `None | `Locs | `Full ]
8585+(** Metadata captured while decoding:
8686+ - [`None] captures no locations or layout. This is the default and fastest
8787+ mode.
8888+ - [`Locs] captures source locations for parsed nodes and errors.
8989+ - [`Full] captures source locations and surrounding whitespace, enabling
9090+ layout-preserving output with [~preserve:true]. *)
9191+8492module Path = Loc.Path
8593(** JSON paths used by query and update codecs. *)
8694···904912905913module Stream : sig
906914 val of_reader :
907907- ?layout:bool ->
908908- ?locs:bool ->
915915+ ?meta:meta ->
909916 ?file:string ->
910917 'a t ->
911918 Bytesrw.Bytes.Reader.t ->
912919 ('a, Error.t) result
913920914921 val of_reader_exn :
915915- ?layout:bool ->
916916- ?locs:bool ->
917917- ?file:string ->
918918- 'a t ->
919919- Bytesrw.Bytes.Reader.t ->
920920- 'a
922922+ ?meta:meta -> ?file:string -> 'a t -> Bytesrw.Bytes.Reader.t -> 'a
921923922924 val of_string :
923923- ?layout:bool ->
924924- ?locs:bool ->
925925- ?file:string ->
926926- 'a t ->
927927- string ->
928928- ('a, Error.t) result
925925+ ?meta:meta -> ?file:string -> 'a t -> string -> ('a, Error.t) result
929926930930- val of_string_exn :
931931- ?layout:bool -> ?locs:bool -> ?file:string -> 'a t -> string -> 'a
927927+ val of_string_exn : ?meta:meta -> ?file:string -> 'a t -> string -> 'a
932928933929 val to_writer :
934930 ?buf:Bytes.t ->
+10-9
lib/json.ml
···3333 | Object of object' node
34343535type number_format = Value.number_format
3636+type meta = Codec.meta
36373738let pp = Value.pp
3839let decode = Codec.decode
3940let decode_exn = Codec.decode_exn
4041let encode = Codec.encode
41424242-let pp_value ?(number_format = Value.default_number_format) t () ppf v =
4343+let pp_value ?(number_format = Value.default_number_format) t ppf v =
4344 match encode t v with
4445 | j -> Value.pp' number_format ppf j
4546 | exception Error e -> Value.pp_string ppf (Loc.Error.to_string e)
···5657module Value = struct
5758 include Value
58595959- let of_string ?layout ?locs ?file s =
6060- Codec.Stream.of_string ?layout ?locs ?file Codec.Value.t s
6060+ let of_string ?meta ?file s =
6161+ Codec.Stream.of_string ?meta ?file Codec.Value.t s
61626262- let of_string_exn ?layout ?locs ?file s =
6363- Codec.Stream.of_string_exn ?layout ?locs ?file Codec.Value.t s
6363+ let of_string_exn ?meta ?file s =
6464+ Codec.Stream.of_string_exn ?meta ?file Codec.Value.t s
64656565- let of_reader ?layout ?locs ?file r =
6666- Codec.Stream.of_reader ?layout ?locs ?file Codec.Value.t r
6666+ let of_reader ?meta ?file r =
6767+ Codec.Stream.of_reader ?meta ?file Codec.Value.t r
67686868- let of_reader_exn ?layout ?locs ?file r =
6969- Codec.Stream.of_reader_exn ?layout ?locs ?file Codec.Value.t r
6969+ let of_reader_exn ?meta ?file r =
7070+ Codec.Stream.of_reader_exn ?meta ?file Codec.Value.t r
70717172 let to_string ?buf ?indent ?preserve ?number_format v =
7273 Codec.Stream.to_string ?buf ?indent ?preserve ?number_format Codec.Value.t v
+21-28
lib/json.mli
···8888type number_format = Value.number_format
8989(** The type for JSON number formatters. *)
90909191+type meta = Codec.meta
9292+(** Metadata captured while decoding:
9393+ - [`None] captures no locations or layout. This is the default and fastest
9494+ mode.
9595+ - [`Locs] captures source locations for parsed nodes and errors.
9696+ - [`Full] captures source locations and surrounding whitespace, enabling
9797+ layout-preserving output with [~preserve:true]. *)
9898+9199module Error = Error
92100(** Typed JSON errors. See {!module-Error} for the full set. *)
93101···123131 Use {!Value.of_string} if you specifically want a generic {!type-t} tree. *)
124132125133val of_reader :
126126- ?layout:bool ->
127127- ?locs:bool ->
134134+ ?meta:meta ->
128135 ?file:fpath ->
129136 'a codec ->
130137 Bytes.Reader.t ->
131138 ('a, Error.t) result
132139(** [of_reader t r] decodes a value from [r] according to [t].
133133- - If [layout] is [true] whitespace is preserved in {!Meta.t} values.
134134- Defaults to [false].
135135- - If [locs] is [true] locations are preserved in {!Meta.t} values and error
136136- messages are precisely located. Defaults to [false].
140140+ - [meta] controls whether source locations and layout are preserved.
141141+ Defaults to [`None].
137142 - [file] is the file path from which [r] is assumed to read. Defaults to the
138143 empty path. *)
139144140145val of_reader_exn :
141141- ?layout:bool -> ?locs:bool -> ?file:fpath -> 'a codec -> Bytes.Reader.t -> 'a
146146+ ?meta:meta -> ?file:fpath -> 'a codec -> Bytes.Reader.t -> 'a
142147(** [of_reader_exn] is like {!val-of_reader} but raises {!Json.exception-Error}.
143148*)
144149145150val of_string :
146146- ?layout:bool ->
147147- ?locs:bool ->
148148- ?file:fpath ->
149149- 'a codec ->
150150- string ->
151151- ('a, Error.t) result
151151+ ?meta:meta -> ?file:fpath -> 'a codec -> string -> ('a, Error.t) result
152152(** [of_string c s] decodes [s] directly with codec [c]. *)
153153154154-val of_string_exn :
155155- ?layout:bool -> ?locs:bool -> ?file:fpath -> 'a codec -> string -> 'a
154154+val of_string_exn : ?meta:meta -> ?file:fpath -> 'a codec -> string -> 'a
156155(** [of_string_exn] is like {!val-of_string} but raises {!Json.exception-Error}.
157156*)
158157···211210 {!Json.val-to_string}, etc., using the identity codec ({!Codec.Value.t}).
212211 *)
213212214214- val of_string :
215215- ?layout:bool -> ?locs:bool -> ?file:fpath -> string -> (t, Error.t) result
213213+ val of_string : ?meta:meta -> ?file:fpath -> string -> (t, Error.t) result
216214 (** [of_string s] parses [s] to a generic JSON value. *)
217215218218- val of_string_exn : ?layout:bool -> ?locs:bool -> ?file:fpath -> string -> t
216216+ val of_string_exn : ?meta:meta -> ?file:fpath -> string -> t
219217 (** [of_string_exn] is like {!val-of_string} but raises
220218 {!Json.exception-Error}. *)
221219222220 val of_reader :
223223- ?layout:bool ->
224224- ?locs:bool ->
225225- ?file:fpath ->
226226- Bytesrw.Bytes.Reader.t ->
227227- (t, Error.t) result
221221+ ?meta:meta -> ?file:fpath -> Bytesrw.Bytes.Reader.t -> (t, Error.t) result
228222 (** [of_reader r] parses [r] to a generic JSON value. *)
229223230230- val of_reader_exn :
231231- ?layout:bool -> ?locs:bool -> ?file:fpath -> Bytesrw.Bytes.Reader.t -> t
224224+ val of_reader_exn : ?meta:meta -> ?file:fpath -> Bytesrw.Bytes.Reader.t -> t
232225 (** [of_reader_exn] is like {!val-of_reader} but raises
233226 {!Json.exception-Error}. *)
234227···258251val pp : t Fmt.t
259252(** [pp] formats JSON values. Alias of {!Value.pp}. *)
260253261261-val pp_value : ?number_format:number_format -> 'a codec -> unit -> 'a Fmt.t
262262-(** [pp_value c ()] formats values of type ['a] by encoding them with codec [c]
263263- and pretty-printing the resulting JSON. A codec error is formatted as a JSON
254254+val pp_value : ?number_format:number_format -> 'a codec -> 'a Fmt.t
255255+(** [pp_value c] formats values of type ['a] by encoding them with codec [c] and
256256+ pretty-printing the resulting JSON. A codec error is formatted as a JSON
264257 string carrying the error message, so this function always produces valid
265258 JSON. *)
266259
+4-3
test/codecs/geojson.ml
···335335 | file -> In_channel.with_open_bin file (process file)
336336 with Sys_error e -> Error e
337337338338-let trip ~file ~indent ~locs ~dec_only =
338338+let trip ~file ~indent ~meta ~dec_only =
339339 log_if_error ~use:1 @@ with_infile file
340340 @@ fun r ->
341341 log_if_error ~use:1
342342 @@
343343- let* t = Json.of_reader ~file ~locs Geojson.codec r in
343343+ let* t = Json.of_reader ~file ~meta Geojson.codec r in
344344 if dec_only then Ok 0
345345 else
346346 let w = Bytesrw.Bytes.Writer.of_out_channel stdout in
···367367 let doc = "Decode only." in
368368 Arg.(value & flag & info [ "d" ] ~doc)
369369 in
370370- trip ~file ~indent ~locs ~dec_only
370370+ let meta = if locs then `Locs else `None in
371371+ trip ~file ~indent ~meta ~dec_only
371372372373let main () = Cmd.eval' geojson
373374let () = if !Sys.interactive then () else exit (main ())
···296296 | file -> In_channel.with_open_bin file (process file)
297297 with Sys_error e -> Error e
298298299299-let trip ~file ~indent ~locs ~dec_only =
299299+let trip ~file ~indent ~meta ~dec_only =
300300 log_if_error ~use:1 @@ with_infile file
301301 @@ fun r ->
302302 log_if_error ~use:1
303303 @@
304304- let* t = Json.of_reader ~file ~locs Topology.codec r in
304304+ let* t = Json.of_reader ~file ~meta Topology.codec r in
305305 if dec_only then Ok 0
306306 else
307307 let w = Bytesrw.Bytes.Writer.of_out_channel stdout in
···328328 let doc = "Decode only." in
329329 Arg.(value & flag & info [ "d" ] ~doc)
330330 in
331331- trip ~file ~indent ~locs ~dec_only
331331+ let meta = if locs then `Locs else `None in
332332+ trip ~file ~indent ~meta ~dec_only
332333333334let main () = Cmd.eval' topojson
334335let () = if !Sys.interactive then () else exit (main ())