Declarative JSON data manipulation for OCaml
1(** Typed JSON codecs.
2
3 A codec value of type ['a t] describes how JSON is mapped to an OCaml value
4 of type ['a]. The same description is used for:
5 - decoding JSON to OCaml values,
6 - encoding OCaml values to JSON,
7 - querying and updating JSON without forcing callers to build a generic JSON
8 tree.
9
10 The usual entry point is to compose small codecs:
11
12 {[
13 module C = Json.Codec
14
15 type person = { name : string; age : int }
16
17 let person name age = { name; age }
18
19 let person_codec =
20 C.Object.map person
21 |> C.Object.member "name" C.string ~enc:(fun p -> p.name)
22 |> C.Object.member "age" C.int ~enc:(fun p -> p.age)
23 |> C.Object.seal
24 ]}
25
26 Decode and encode with {!Json.val-of_string} and {!Json.val-to_string}; if
27 you already have a {!Json.t}, use {!val-decode} and {!val-encode}. *)
28
29(** {1:core Core concepts} *)
30
31type 'a t
32(** The type of codecs mapping JSON values to OCaml values of type ['a]. *)
33
34val kinded_sort : 'a t -> string
35(** [kinded_sort c] is a human-readable description of the JSON sort expected by
36 [c], including the codec kind when one was provided. It is mainly used in
37 diagnostics. *)
38
39val kind : 'a t -> string
40(** [kind c] is the short kind name used in diagnostics for [c]. *)
41
42val doc : 'a t -> string
43(** [doc c] is the documentation string attached to [c], if any. *)
44
45val with_doc : ?kind:string -> ?doc:string -> 'a t -> 'a t
46(** [with_doc c] is [c] with updated [kind] and [doc] metadata. *)
47
48(** {1:combinators Building codecs} *)
49
50module Ast = Value
51(** Alias for the generic JSON AST module. This stays accessible inside
52 [open Codec] regions where the nested [Codec.Value] codec sub-module would
53 shadow the [Value] AST module. *)
54
55type value = Value.t
56(** Alias for the generic JSON AST; codec signatures below produce/consume
57 codecs over [Value.t]. *)
58
59type name = Value.name
60(** The type for JSON member names. *)
61
62type member = Value.member
63(** The type for generic JSON object members. *)
64
65type object' = Value.object'
66(** The type for generic JSON objects. *)
67
68type number_format = Value.number_format
69(** The type for JSON number formatters. *)
70
71(** {1:support Codec support types} *)
72
73module Meta = Loc.Meta
74(** Node metadata: source location and surrounding whitespace. Most callers only
75 handle this when preserving layout, reporting precise errors, or writing
76 custom maps. *)
77
78type 'a node = 'a * Meta.t
79(** A payload with node metadata. *)
80
81type meta = [ `None | `Locs | `Full ]
82(** Metadata captured while decoding:
83 - [`None] captures no locations or layout. This is the default and fastest
84 mode.
85 - [`Locs] captures source locations for parsed nodes and errors.
86 - [`Full] captures source locations and surrounding whitespace, enabling
87 layout-preserving output with [~preserve:true]. *)
88
89module Path = Loc.Path
90(** JSON paths used by query and update codecs. *)
91
92module Sort = Sort
93(** JSON sorts used in diagnostics. *)
94
95(** {1:base Base types} *)
96
97(** Mapping JSON base types. *)
98module Base : sig
99 (** {1:maps Maps} *)
100
101 type ('a, 'b) map
102 (** The type for mapping JSON values of type ['a] to values of type ['b]. *)
103
104 val map :
105 ?kind:string ->
106 ?doc:string ->
107 ?dec:(Meta.t -> 'a -> 'b) ->
108 ?enc:('b -> 'a) ->
109 ?enc_meta:('b -> Meta.t) ->
110 unit ->
111 ('a, 'b) map
112 (** [map ~kind ~doc ~dec ~enc ~enc_meta ()] maps JSON base types represented
113 by value of type ['a] to values of type ['b] with:
114 - [kind] names the entities represented by the map and [doc] documents
115 them. Both default to [""].
116 - [dec] is used to decode values of type ['a] to values of type ['b]. Can
117 be omitted if the map is only used for encoding, the default
118 unconditionally errors.
119 - [enc] is used to encode values of type ['b] to values of type ['a]. Can
120 be omitted if the map is only used for decoding, the default
121 unconditionally errors.
122 - [enc_meta] is used to recover JSON metadata (source text layout
123 information) from a value to encode. The default unconditionnaly returns
124 {!Json.Meta.none}.
125
126 {{!decenc}These functions} can be used to quickly devise [dec] and [enc]
127 functions from standard OCaml conversion interfaces. *)
128
129 val id : ('a, 'a) map
130 (** [id] is the identity map. *)
131
132 val ignore : ('a, unit) map
133 (** [ignore] is the ignoring map. It ignores decodes and errors on encodes. *)
134
135 (** {2:codecs Codec constructors} *)
136
137 val null : (unit, 'a) map -> 'a t
138 (** [null map] maps with [map] JSON nulls represented by [()] to values of
139 type ['a]. See also {!Codec.null}. *)
140
141 val bool : (bool, 'a) map -> 'a t
142 (** [bool map] maps with [map] JSON booleans represented by [bool] values to
143 values of type ['a]. See also {!Codec.bool}. *)
144
145 val number : (float, 'a) map -> 'a t
146 (** [number map] maps with [map] JSON nulls or numbers represented by [float]
147 values to values of type ['a]. The [float] representation decodes JSON
148 nulls to [Float.nan] and lossily encodes any non-finite number to JSON
149 null. See also {!Codec.number}. *)
150
151 val string : (string, 'a) map -> 'a t
152 (** [string map] maps with [map] {e unescaped} JSON strings represented by
153 UTF-8 encoded [string] values to values of type ['a]. See also
154 {!Codec.string}. *)
155
156 (** {1:decenc Decoding and encoding functions}
157
158 These function create suitable [dec] and [enc] functions to give to
159 {!val-map} from standard OCaml conversion interfaces. See also
160 {!Codec.of_of_string}. *)
161
162 val dec : ('a -> 'b) -> Meta.t -> 'a -> 'b
163 (** [dec f] is a decoding function from [f]. This assumes [f] never fails. *)
164
165 val dec_result :
166 ?kind:string -> ('a -> ('b, string) result) -> Meta.t -> 'a -> 'b
167 (** [dec f] is a decoding function from [f]. [Error _] values are given to
168 {!Error.msg}, prefixed by [kind:] (if specified). *)
169
170 val dec_failure : ?kind:string -> ('a -> 'b) -> Meta.t -> 'a -> 'b
171 (** [dec f] is a decoding function from [f]. [Failure _] exceptions are
172 catched and given to {!Error.msg}, prefixed by [kind:] (if specified). *)
173
174 val enc : ('b -> 'a) -> 'b -> 'a
175 (** [enc f] is an encoding function from [f]. This assumes [f] never fails. *)
176
177 val enc_result : ?kind:string -> ('b -> ('a, string) result) -> 'b -> 'a
178 (** [enc_result f] is an encoding function from [f]. [Error _] values are
179 given to {!Error.msg}, prefixed by [kind:] (if specified). *)
180
181 val enc_failure : ?kind:string -> ('b -> 'a) -> 'b -> 'a
182 (** [enc_failure f] is an encoding function from [f]. [Failure _] exceptions
183 are catched and given to {!Error.msg}, prefixed by [kind:] (if specified).
184 *)
185end
186
187(** {2:option Nulls and options}
188
189 JSON's [null] (RFC 8259 §3) is a single literal value with no native
190 [option] analogue; the codecs below pick a convention for mapping OCaml
191 [option] / unit-like sentinels onto it. *)
192
193val null : ?kind:string -> ?doc:string -> 'a -> 'a t
194(** [null v] maps JSON nulls to [v]. On encodes any value of type ['a] is
195 encoded by null. [doc] and [kind] are given to the underlying base map. See
196 also {!Base.null}. *)
197
198val none : 'a option t
199(** [none] maps JSON nulls to [None]. *)
200
201val some : 'a t -> 'a option t
202(** [some t] maps JSON like [t] does but wraps results in [Some]. Encoding fails
203 if the value is [None]. *)
204
205val option : ?kind:string -> ?doc:string -> 'a t -> 'a option t
206(** [option t] maps JSON nulls to [None] and other values by [t]. [doc] and
207 [kind] are given to the underlying {!val-any} map. *)
208
209(** {2:booleans Booleans}
210
211 [true] / [false] literals (RFC 8259 §3). *)
212
213val bool : bool t
214(** [bool] maps JSON booleans to [bool] values. See also {!Base.bool}. *)
215
216(** {2:numbers Numbers}
217
218 JSON's number grammar (RFC 8259 §6) does not constrain precision; the codecs
219 below pick OCaml-side representations and document how each handles JSON's
220 open-ended integer range. *)
221
222val number : float t
223(** [number] maps JSON nulls or numbers to [float] values. On decodes JSON null
224 is mapped to [Float.nan]. On encodes any non-finite float is lossily mapped
225 to JSON null. See also {!Base.number}, {!any_float} and the integer
226 combinators below. *)
227
228val any_float : float t
229(** [any_float] is a lossless representation for IEEE 754 doubles. It maps
230 non-finite floats by the JSON strings defined by [Float.to_string]. This
231 contrasts with {!val-number} which maps them to JSON null values. Note that
232 on decodes this still maps JSON nulls to [Float.nan] and any successful
233 string decode of [Float.of_string_opt] (so numbers can also be written as
234 strings). See also {!val-number}.
235
236 {b Warning.} [any_float] should only be used between parties that have
237 agreed on such an encoding. To maximize interoperability you should use the
238 lossy {!val-number} map. *)
239
240val float_as_hex_string : float t
241(** [float_as_hex_string] maps JSON strings made of IEEE 754 doubles in hex
242 notation to float values. On encodes strings this uses the ["%h"] format
243 string. On decodes it accepts anything sucessfully decoded by
244 [Float.of_string_opt]. *)
245
246val uint8 : int t
247(** [uint8] maps JSON numbers to unsigned 8-bit integers. JSON numbers are
248 sucessfully decoded if after truncation they can be represented on the
249 \[0;255\] range. Encoding errors if the integer is out of range. *)
250
251val uint16 : int t
252(** [uint16] maps JSON numbers to unsigned 16-bit integers. JSON numbers are
253 sucessfully decoded if after truncation they can be represented on the
254 \[0;65535\] range. Encoding errors if the integer is out of range. *)
255
256val int8 : int t
257(** [int8] maps JSON numbers to 8-bit integers. JSON numbers are sucessfully
258 decoded if after truncation they can be represented on the \[-128;127\]
259 range. Encoding errors if the integer is out of range. *)
260
261val int16 : int t
262(** [int16] maps JSON numbers to 16-bit integers. JSON numbers are sucessfully
263 decoded if after truncation they can be represented on the \[-32768;32767\]
264 range. Encoding errors if the integer is out of range. *)
265
266val int32 : int32 t
267(** [int32] maps JSON numbers to 32-bit integers. JSON numbers are sucessfully
268 decoded if after truncation they can be represented on the [int32] range,
269 otherwise the decoder errors. *)
270
271val int64 : int64 t
272(** [int64] maps truncated JSON numbers or JSON strings to 64-bit integers.
273 - JSON numbers are sucessfully decoded if after truncation they can be
274 represented on the [int64] range, otherwise the decoder errors. [int64]
275 values are encoded as JSON numbers if the integer is in the
276 \[-2{^ 53};2{^ 53}\] range.
277 - JSON strings are decoded using [int_of_string_opt], this allows binary,
278 octal, decimal and hex syntaxes and errors on overflow and syntax errors.
279 [int64] values are encoded as JSON strings with [Int64.to_string] when the
280 integer is outside the \[-2{^ 53};2{^ 53}\] range. *)
281
282val int64_as_string : int64 t
283(** [int64_as_string] maps JSON strings to 64-bit integers. On decodes this uses
284 [Int64.of_string_opt] which allows binary, octal, decimal and hex syntaxes
285 and errors on overflow and syntax errors. On encodes uses [Int64.to_string].
286*)
287
288val int : int t
289(** [int] maps truncated JSON numbers or JSON strings to [int] values.
290 - JSON numbers are sucessfully decoded if after truncation they can be
291 represented on the [int] range, otherwise the decoder errors. [int] values
292 are encoded as JSON numbers if the integer is in the \[-2{^ 53};2{^ 53}\]
293 range.
294 - JSON strings are decoded using [int_of_string_opt], this allows binary,
295 octal, decimal and hex syntaxes and errors on overflow and syntax errors.
296 [int] values are encoded as JSON strings with [Int.to_string] when the
297 integer is outside the \[-2{^ 53};2{^ 53}\] range
298
299 {b Warning.} The behaviour of this function is platform dependent, it
300 depends on the value of [Sys.int_size]. *)
301
302val int_as_string : int t
303(** [int_as_string] maps JSON strings to [int] values. On decodes this uses
304 [int_of_string_opt] which allows binary, octal, decimal and hex syntaxes and
305 errors on overflow and syntax errors. On encodes uses [Int.to_string].
306
307 {b Warning.} The behaviour of this function is platform dependent, it
308 depends on the value of [Sys.int_size]. *)
309
310(** {2:enums Strings and enums}
311
312 JSON strings (RFC 8259 §7): a sequence of Unicode code points enclosed
313 in [" "], with [\] escapes for control characters and [\uXXXX] for
314 BMP code points (or surrogate pairs for non-BMP). *)
315
316val string : string t
317(** [string] maps unescaped JSON strings to UTF-8 encoded [string] values. See
318 also {!Base.string}.
319
320 {b Warning.} Encoders assume OCaml [string]s have been checked for UTF-8
321 validity. *)
322
323val of_of_string :
324 ?kind:string ->
325 ?doc:string ->
326 ?enc:('a -> string) ->
327 (string -> ('a, string) result) ->
328 'a t
329(** [of_of_string of_string] maps JSON string with a base map using [of_string]
330 for decoding and [enc] for encoding. *)
331
332val enum :
333 ?cmp:('a -> 'a -> int) ->
334 ?kind:string ->
335 ?doc:string ->
336 (string * 'a) list ->
337 'a t
338(** [enum assoc] maps JSON strings member of the [assoc] list to the
339 corresponding OCaml value and vice versa in log(n). [cmp] is used to compare
340 the OCaml values, it defaults to [Stdlib.compare]. Decoding and encoding
341 errors on strings or values not part of [assoc]. *)
342
343val binary_string : string t
344(** [binary_string] maps JSON strings made of an even number of hexdecimal
345 US-ASCII upper or lower case digits to the corresponding byte sequence. On
346 encoding uses only lower case hexadecimal digits to encode the byte
347 sequence. *)
348
349(** {1:arrays Arrays and tuples}
350
351 JSON arrays (RFC 8259 §5): an ordered sequence of values enclosed in [[ ]]
352 with [,] separators. Element order is significant. *)
353
354(** Mapping JSON arrays. *)
355module Array : sig
356 (** {1:maps Maps} *)
357
358 type ('array, 'elt) enc = {
359 enc : 'acc. ('acc -> int -> 'elt -> 'acc) -> 'acc -> 'array -> 'acc;
360 }
361 (** The type for specifying array encoding functions. A function to fold over
362 the elements of type ['elt] of the array of type ['array]. *)
363
364 type ('array, 'elt, 'builder) map
365 (** The type for mapping JSON arrays with elements of type ['elt] to arrays of
366 type ['array] using values of type ['builder] to build them. *)
367
368 val map :
369 ?kind:string ->
370 ?doc:string ->
371 ?dec_empty:(unit -> 'builder) ->
372 ?dec_skip:(int -> 'builder -> bool) ->
373 ?dec_add:(int -> 'elt -> 'builder -> 'builder) ->
374 ?dec_finish:(Meta.t -> int -> 'builder -> 'array) ->
375 ?enc:('array, 'elt) enc ->
376 ?enc_meta:('array -> Meta.t) ->
377 'elt t ->
378 ('array, 'elt, 'builder) map
379 (** [map elt] maps JSON arrays of type ['elt] to arrays of type ['array] built
380 with type ['builder]. See the [Array] module documentation for argument
381 descriptions. *)
382
383 val list_map :
384 ?kind:string ->
385 ?doc:string ->
386 ?dec_skip:(int -> 'a list -> bool) ->
387 'a t ->
388 ('a list, 'a, 'a list) map
389 (** [list_map elt] maps JSON arrays with elements of type [elt] to [list]
390 values. See also {!Codec.list}. *)
391
392 type 'a array_builder
393 (** The type for array builders. *)
394
395 val array_map :
396 ?kind:string ->
397 ?doc:string ->
398 ?dec_skip:(int -> 'a array_builder -> bool) ->
399 'a t ->
400 ('a array, 'a, 'a array_builder) map
401 (** [array_map elt] maps JSON arrays with elements of type [elt] to [array]
402 values. See also [array]. *)
403
404 type ('a, 'b, 'c) bigarray_builder
405 (** The type for bigarray_builders. *)
406
407 val bigarray_map :
408 ?kind:string ->
409 ?doc:string ->
410 ?dec_skip:(int -> ('a, 'b, 'c) bigarray_builder -> bool) ->
411 ('a, 'b) Bigarray.kind ->
412 'c Bigarray.layout ->
413 'a t ->
414 (('a, 'b, 'c) Bigarray.Array1.t, 'a, ('a, 'b, 'c) bigarray_builder) map
415 (** [bigarray k l elt] maps JSON arrays with elements of type [elt] to
416 bigarray values of kind [k] and layout [l]. See also {!Codec.bigarray}. *)
417
418 (** {1:codecs Codec constructors} *)
419
420 val array : ('a, _, _) map -> 'a t
421 (** [array map] maps with [map] JSON arrays to values of type ['a]. See the
422 the {{!section-arrays}array combinators}. *)
423
424 val ignore : unit t
425 (** [ignore] ignores JSON arrays on decoding and errors on encoding. *)
426
427 val zero : unit t
428 (** [zero] ignores JSON arrays on decoding and encodes an empty array. *)
429end
430
431val list : ?kind:string -> ?doc:string -> 'a t -> 'a list t
432(** [list t] maps JSON arrays of type [t] to [list] values. See also
433 {!Array.list_map}. *)
434
435val array : ?kind:string -> ?doc:string -> 'a t -> 'a array t
436(** [array t] maps JSON arrays of type [t] to [array] values. See also
437 {!Array.array_map}. *)
438
439val array_as_string_map :
440 ?kind:string ->
441 ?doc:string ->
442 key:('a -> string) ->
443 'a t ->
444 'a Map.Make(String).t t
445(** [array_as_string_map ~key t] maps JSON array elements of type [t] to string
446 maps by indexing them with [key]. If two elements have the same [key] the
447 element with the greatest index takes over. Elements of the map are encoded
448 to a JSON array in (binary) key order. *)
449
450val bigarray :
451 ?kind:string ->
452 ?doc:string ->
453 ('a, 'b) Bigarray.kind ->
454 'a t ->
455 ('a, 'b, Bigarray.c_layout) Bigarray.Array1.t t
456(** [bigarray k t] maps JSON arrays of type [t] to [Bigarray.Array1.t] values.
457 See also {!Array.bigarray_map}. *)
458
459val t2 :
460 ?kind:string ->
461 ?doc:string ->
462 ?dec:('a -> 'a -> 't2) ->
463 ?enc:('t2 -> int -> 'a) ->
464 'a t ->
465 't2 t
466(** [t2 ?dec ?enc t] maps JSON arrays with exactly 2 elements of type [t] to
467 value of type ['t2]. Decodes error if there are more elements. [enc v i]
468 must return the zero-based [i]th element. *)
469
470val t3 :
471 ?kind:string ->
472 ?doc:string ->
473 ?dec:('a -> 'a -> 'a -> 't3) ->
474 ?enc:('t3 -> int -> 'a) ->
475 'a t ->
476 't3 t
477(** [t3] is like {!t2} but for 3 elements. *)
478
479val t4 :
480 ?kind:string ->
481 ?doc:string ->
482 ?dec:('a -> 'a -> 'a -> 'a -> 't4) ->
483 ?enc:('t4 -> int -> 'a) ->
484 'a t ->
485 't4 t
486(** [t4] is like {!t2} but for 4 elements. *)
487
488val tn : ?kind:string -> ?doc:string -> n:int -> 'a t -> 'a array t
489(** [tn ~n t] maps JSON arrays of exactly [n] elements of type [t] to [array]
490 values. This is {!val-array} limited by [n]. *)
491
492(** {1:objects Objects}
493
494 JSON objects (RFC 8259 §4): an unordered set of [name : value] members
495 enclosed in [{ }] with [,] separators. The RFC says member order is
496 insignificant; we preserve it for layout fidelity. The RFC also says
497 duplicate names ["SHOULD" be unique] (§4) but does not forbid them; the
498 object combinators reject duplicates by default — see [Object.case]. *)
499
500(** Mapping JSON objects. *)
501module Object : sig
502 (** {1:maps Maps} *)
503
504 type ('o, 'dec) map
505 (** The type for mapping JSON objects to values of type ['o]. The ['dec] type
506 is used to construct ['o] from members; see {!val-member}. *)
507
508 val map : ?kind:string -> ?doc:string -> 'dec -> ('o, 'dec) map
509 (** [map dec] is an empty JSON object decoded by function [dec].
510 - [kind] names the entities represented by the map and [doc] documents
511 them. Both default to [""].
512 - [dec] is a constructor eventually returning a value of type ['o] to be
513 saturated with calls to {!val-member}, {!val-case_member} or
514 {!val-keep_unknown}. This is needed for decoding. Use {!enc_only} if the
515 result is only used for encoding. *)
516
517 val map_with_meta :
518 ?kind:string ->
519 ?doc:string ->
520 ?enc_meta:('o -> Meta.t) ->
521 (Meta.t -> 'dec) ->
522 ('o, 'dec) map
523 (** [map_with_meta dec] is like {!val-map} except [dec] receives the object's
524 decoding metadata and [?enc_meta] is used to recover it on encoding. *)
525
526 val enc_only :
527 ?kind:string ->
528 ?doc:string ->
529 ?enc_meta:('o -> Meta.t) ->
530 unit ->
531 ('o, 'a) map
532 (** [enc_only ()] is like {!val-map} but can only be used for encoding. *)
533
534 val seal : ('o, 'o) map -> 'o t
535 (** [seal map] is a codec for objects mapped by [map]. Raises
536 [Invalid_argument] if [map] describes a member name more than once. *)
537
538 (** {1:mems Members} *)
539
540 val member :
541 ?doc:string ->
542 ?dec_absent:'a ->
543 ?enc:('o -> 'a) ->
544 ?enc_omit:('a -> bool) ->
545 string ->
546 'a t ->
547 ('o, 'a -> 'b) map ->
548 ('o, 'b) map
549 (** [member name t map] is a member named [name] of type [t] for an object of
550 type ['o] being constructed by [map].
551 - [doc] is a documentation string for the member. Defaults to [""].
552 - [dec_absent], if specified, is the value used for the decoding direction
553 when the member named [name] is missing. If unspecified decoding errors
554 when the member is absent.
555 - [enc] is used to project the member's value from the object
556 representation ['o] for encoding to JSON with [t]. It can be omitted if
557 the result is only used for decoding.
558 - [enc_omit] is for the encoding direction. If the member value returned
559 by [enc] returns [true] on [enc_omit], the member is omited in the
560 encoded JSON object. Defaults to [Fun.const false]. *)
561
562 val opt_member :
563 ?doc:string ->
564 ?enc:('o -> 'a option) ->
565 string ->
566 'a t ->
567 ('o, 'a option -> 'b) map ->
568 ('o, 'b) map
569 (** [opt_member name t map] is:
570 {[
571 let opt_member name t map =
572 let dec_absent = None and enc_omit = Option.is_none in
573 Json.Codec.Object.member name (Json.Codec.some t) map ~dec_absent
574 ~enc_omit
575 ]} *)
576
577 (** {1:cases Case objects} *)
578
579 (** Case objects. *)
580 module Case : sig
581 (** {1:maps Maps} *)
582
583 type ('cases, 'case, 'tag) map
584 (** The type for mapping a case object. *)
585
586 val map :
587 ?dec:('case -> 'cases) -> 'tag -> 'case t -> ('cases, 'case, 'tag) map
588 (** [map ~dec v obj] defines the object map [obj] as being the case for the
589 tag value [v] of the case member. [dec] indicates how to inject the
590 object case into the type common to all cases.
591
592 Raises [Invalid_argument] if [obj] is not a direct result of {!seal},
593 that is if [obj] does not describe an object. *)
594
595 val map_tag : ('cases, 'case, 'tag) map -> 'tag
596 (** [map_tag m] is [m]'s tag. *)
597
598 (** {1:cases Cases} *)
599
600 type ('cases, 'tag) t
601 (** The type for a case of the type ['cases]. *)
602
603 val make : ('cases, 'case, 'tag) map -> ('cases, 'tag) t
604 (** [make map] is [map] as a case. *)
605
606 val tag : ('cases, 'tag) t -> 'tag
607 (** [tag c] is the tag of [c]. *)
608
609 (** {1:case Case values} *)
610
611 type ('cases, 'tag) value
612 (** The type for case values. *)
613
614 val value : ('cases, 'case, 'tag) map -> 'case -> ('cases, 'tag) value
615 (** [value map v] is a case value [v] described by [map]. *)
616 end
617
618 val case_member :
619 ?doc:string ->
620 ?tag_compare:('tag -> 'tag -> int) ->
621 ?tag_to_string:('tag -> string) ->
622 ?dec_absent:'tag ->
623 ?enc:('o -> 'cases) ->
624 ?enc_omit:('tag -> bool) ->
625 ?enc_case:('cases -> ('cases, 'tag) Case.value) ->
626 string ->
627 'tag t ->
628 ('cases, 'tag) Case.t list ->
629 ('o, 'cases -> 'a) map ->
630 ('o, 'a) map
631 (** [case_member name t cases map] is mostly like {!val-member} except the
632 member [name] selects an object representation according to the member
633 value of type [t]. *)
634
635 (** {1:unknown_members Unknown members} *)
636
637 (** Uniform members. *)
638 module Members : sig
639 (** {1:maps Maps} *)
640
641 type ('mems, 'a) enc = {
642 enc :
643 'acc. (Meta.t -> string -> 'a -> 'acc -> 'acc) -> 'mems -> 'acc -> 'acc;
644 }
645 (** The type for specifying unknown members encoding function. *)
646
647 type ('mems, 'a, 'builder) map
648 (** The type for mapping members of uniform type ['a] to values of type
649 ['mems] using a builder of type ['builder]. *)
650
651 val map :
652 ?kind:string ->
653 ?doc:string ->
654 ?dec_empty:(unit -> 'builder) ->
655 ?dec_add:(Meta.t -> string -> 'a -> 'builder -> 'builder) ->
656 ?dec_finish:(Meta.t -> 'builder -> 'mems) ->
657 ?enc:('mems, 'a) enc ->
658 'a t ->
659 ('mems, 'a, 'builder) map
660 (** [map type'] maps unknown members of uniform type ['a] to values of type
661 ['mems] built with type ['builder]. *)
662
663 val string_map :
664 ?kind:string ->
665 ?doc:string ->
666 'a t ->
667 ('a Stdlib.Map.Make(String).t, 'a, 'a Stdlib.Map.Make(String).t) map
668 (** [string_map t] collects unknown member by name and types their values
669 with [t]. *)
670 end
671
672 val skip_unknown : ('o, 'dec) map -> ('o, 'dec) map
673 (** [skip_unknown map] makes [map] skip unknown members. *)
674
675 val error_unknown : ('o, 'dec) map -> ('o, 'dec) map
676 (** [error_unknown map] makes [map] error on unknown members. *)
677
678 val keep_unknown :
679 ?enc:('o -> 'mems) ->
680 ('mems, _, _) Members.map ->
681 ('o, 'mems -> 'a) map ->
682 ('o, 'a) map
683 (** [keep_unknown mems map] makes [map] keep unknown member with [mems]. *)
684
685 (** {1:codecs Codec constructors} *)
686
687 val as_string_map :
688 ?kind:string -> ?doc:string -> 'a t -> 'a Stdlib.Map.Make(String).t t
689 (** [as_string_map t] maps object to key-value maps of type [t]. *)
690
691 val zero : unit t
692 (** [zero] ignores JSON objects on decoding and encodes an empty object. *)
693end
694
695(** {1:any Any value}
696
697 Per {{:https://www.rfc-editor.org/rfc/rfc8259#section-3}RFC 8259 § 3}, a
698 JSON {e value} is one of [null], [true]/[false], a number, a string, an
699 array, or an object. *)
700
701val any :
702 ?kind:string ->
703 ?doc:string ->
704 ?dec_null:'a t ->
705 ?dec_bool:'a t ->
706 ?dec_number:'a t ->
707 ?dec_string:'a t ->
708 ?dec_array:'a t ->
709 ?dec_object:'a t ->
710 ?enc:('a -> 'a t) ->
711 unit ->
712 'a t
713(** [any ()] maps subsets of JSON values of different
714 {{:https://www.rfc-editor.org/rfc/rfc8259#section-3}sorts} to values of type
715 ['a]. *)
716
717(** {1:maps Maps & recursion} *)
718
719val map :
720 ?kind:string ->
721 ?doc:string ->
722 ?dec:('a -> 'b) ->
723 ?enc:('b -> 'a) ->
724 'a t ->
725 'b t
726(** [map t] changes the type of [t] from ['a] to ['b]. For mapping base types
727 use [Base.map]. *)
728
729val iter :
730 ?kind:string ->
731 ?doc:string ->
732 ?dec:('a -> unit) ->
733 ?enc:('a -> unit) ->
734 'a t ->
735 'a t
736(** [iter ?enc dec t] applies [dec] on decoding and [enc] on encoding but
737 otherwise behaves like [t] does. *)
738
739val fix : 'a t Lazy.t -> 'a t
740(** [fix] maps recursive JSON values. *)
741
742(** {1:ignoring Ignoring} *)
743
744val ignore : unit t
745(** [ignore] lossily maps all JSON values to [()] on decoding and errors on
746 encoding. *)
747
748val zero : unit t
749(** [zero] lossily maps all JSON values to [()] on decoding and encodes JSON
750 nulls. *)
751
752(** {1:generic_ast Generic AST codecs}
753
754 Codecs that preserve the generic {!value} AST. *)
755
756module Value : sig
757 val t : value t
758 (** [t] maps any JSON value to its generic representation. Use {!val-any} with
759 [dec_*] arguments to restrict to a subset of sorts. *)
760
761 val null : value t
762 (** [null] decodes JSON nulls to {!Null} and encodes {!Null} values. *)
763
764 val bool : value t
765 (** [bool] decodes JSON booleans to {!Bool} and encodes {!Bool} values. *)
766
767 val number : value t
768 (** [number] decodes JSON numbers to {!Number} and encodes {!Number} values.
769 *)
770
771 val string : value t
772 (** [string] decodes JSON strings to {!String} and encodes {!String} values.
773 *)
774
775 val array : value t
776 (** [array] decodes JSON arrays to [Array] and encodes [Array] values. *)
777
778 val object' : value t
779 (** [object'] decodes JSON objects to [Object] and encodes [Object] values. *)
780
781 val members : (value, value, member list) Object.Members.map
782 (** [members] is an [Object.Members.map] for the generic [member list] type.
783 *)
784end
785
786(** {1:queries Queries and updates}
787
788 Queries are lossy or aggregating decodes. Updates yield codecs that decode
789 to generic {!value} values but transform the data along the way. They allow
790 to process JSON data without having to fully model it. *)
791
792val const : 'a t -> 'a -> 'a t
793(** [const t v] maps any JSON value to [v] on decodes and unconditionally
794 encodes [v] with [t]. *)
795
796val recode : dec:'a t -> ('a -> 'b) -> enc:'b t -> 'b t
797(** [recode ~dec f ~enc] maps on decodes like [dec] does followed by [f] and on
798 encodes uses [enc]. *)
799
800val update : 'a t -> value t
801(** [update t] decodes any JSON with [t] and directly encodes it back with [t]
802 to yield the decode result. *)
803
804(** {2:array_queries Arrays} *)
805
806val nth : ?absent:'a -> int -> 'a t -> 'a t
807(** [nth n t] decodes the [n]th index of a JSON array with [t]. *)
808
809val set_nth : ?stub:value -> ?allow_absent:bool -> 'a t -> int -> 'a -> value t
810(** [set_nth t n v] on decodes sets the [n]th value to [v]. *)
811
812val update_nth : ?stub:value -> ?absent:'a -> int -> 'a t -> value t
813(** [update_nth n t] recodes the [n]th value of a JSON array with [t]. *)
814
815val delete_nth : ?allow_absent:bool -> int -> value t
816(** [delete_nth n] drops the [n]th index of a JSON array. *)
817
818val filter_map_array : 'a t -> 'b t -> (int -> 'a -> 'b option) -> value t
819(** [filter_map_array a b f] maps the [a] elements with [f] to [b] elements or
820 deletes them on [None]. *)
821
822val fold_array : 'a t -> (int -> 'a -> 'b -> 'b) -> 'b -> 'b t
823(** [fold_array t f acc] folds [f] over the [t] elements of a JSON array. *)
824
825(** {2:object_queries Objects} *)
826
827val member : ?absent:'a -> string -> 'a t -> 'a t
828(** [member name t] decodes the member named [name] of a JSON object with [t].
829*)
830
831val set_member : ?allow_absent:bool -> 'a t -> string -> 'a -> value t
832(** [set_member t name v] sets the member value of [name] to an encoding of [v].
833*)
834
835val update_member : ?absent:'a -> string -> 'a t -> value t
836(** [update_member name t] recodes the member value of [name]. *)
837
838val delete_member : ?allow_absent:bool -> string -> value t
839(** [delete_member name] deletes the member named [name]. *)
840
841val filter_map_object :
842 'a t -> 'b t -> (Meta.t -> string -> 'a -> (name * 'b) option) -> value t
843(** [filter_map_object a b f] maps the [a] members with [f] to [(n, b)] members
844 or deletes them on [None]. *)
845
846val fold_object : 'a t -> (Meta.t -> string -> 'a -> 'b -> 'b) -> 'b -> 'b t
847(** [fold_object t f acc] folds [f] over the [t] members of a JSON object. *)
848
849(** {2:index_queries Indices} *)
850
851val index : ?absent:'a -> Path.step -> 'a t -> 'a t
852(** [index] uses {!val-nth} or {!val-member} on the given index. *)
853
854val set_index : ?allow_absent:bool -> 'a t -> Path.step -> 'a -> value t
855(** [set_index] uses {!val-set_nth} or {!val-set_member} on the given index. *)
856
857val update_index : ?stub:value -> ?absent:'a -> Path.step -> 'a t -> value t
858(** [update_index] uses {!val-update_nth} or {!val-update_member}. *)
859
860val delete_index : ?allow_absent:bool -> Path.step -> value t
861(** [delete_index] uses {!val-delete_nth} or {!val-delete_member}. *)
862
863(** {2:path_queries Paths} *)
864
865val path : ?absent:'a -> Path.t -> 'a t -> 'a t
866(** [path p t] decodes with [t] on the last index of [p]. *)
867
868val set_path :
869 ?stub:value -> ?allow_absent:bool -> 'a t -> Path.t -> 'a -> value t
870(** [set_path t p v] sets the last index of [p]. *)
871
872val update_path : ?stub:value -> ?absent:'a -> Path.t -> 'a t -> value t
873(** [update_path p t] updates the last index of [p] with [t]. *)
874
875val delete_path : ?allow_absent:bool -> Path.t -> value t
876(** [delete_path p] deletes the last index of [p]. *)
877
878(** {1:runtime Runtime}
879
880 These functions apply a codec to an existing {!Json.t}. Use
881 {!Json.val-of_string} and {!Json.val-to_string} when the boundary is a JSON
882 text. *)
883
884val decode : 'a t -> value -> ('a, Error.t) result
885(** [decode t v] decodes [v] as a value of type ['a] according to [t]. *)
886
887val decode_exn : 'a t -> value -> 'a
888(** [decode_exn] is like {!val-decode} but raises [Json.Error]. *)
889
890val encode : 'a t -> 'a -> value
891(** [encode t v] encodes [v] as a generic JSON value according to [t]. *)
892
893(**/**)
894
895module Stream : sig
896 val of_reader :
897 ?meta:meta ->
898 ?file:string ->
899 'a t ->
900 Bytesrw.Bytes.Reader.t ->
901 ('a, Error.t) result
902 (** [of_reader t r] decodes a JSON value from [r] with [t]. *)
903
904 val of_reader_exn :
905 ?meta:meta -> ?file:string -> 'a t -> Bytesrw.Bytes.Reader.t -> 'a
906 (** [of_reader_exn] is like {!val-of_reader} but raises [Json.Error]. *)
907
908 val of_string :
909 ?meta:meta -> ?file:string -> 'a t -> string -> ('a, Error.t) result
910 (** [of_string t s] decodes JSON text [s] with [t]. *)
911
912 val of_string_exn : ?meta:meta -> ?file:string -> 'a t -> string -> 'a
913 (** [of_string_exn] is like {!val-of_string} but raises [Json.Error]. *)
914
915 val to_writer :
916 ?buf:Bytes.t ->
917 ?indent:int ->
918 ?preserve:bool ->
919 ?number_format:number_format ->
920 'a t ->
921 'a ->
922 eod:bool ->
923 Bytesrw.Bytes.Writer.t ->
924 unit
925 (** [to_writer t v ~eod w] encodes [v] with [t] on [w]. *)
926
927 val to_string :
928 ?buf:Bytes.t ->
929 ?indent:int ->
930 ?preserve:bool ->
931 ?number_format:number_format ->
932 'a t ->
933 'a ->
934 string
935 (** [to_string t v] encodes [v] with [t] to JSON text. *)
936end
937
938module Internal : sig
939 module String_map : module type of Map.Make (String)
940
941 type ('ret, 'f) dec_fun_ =
942 | Dec_fun : 'f -> ('ret, 'f) dec_fun_
943 | Dec_app : ('ret, 'a -> 'b) dec_fun_ * 'a Type.Id.t -> ('ret, 'b) dec_fun_
944
945 type ('a, 'b) base_map = {
946 kind : string;
947 doc : string;
948 dec : Meta.t -> 'a -> 'b;
949 enc : 'b -> 'a;
950 enc_meta : 'b -> Meta.t;
951 }
952
953 type 'a repr =
954 | Null : (unit, 'a) base_map -> 'a repr
955 | Bool : (bool, 'a) base_map -> 'a repr
956 | Number : (float, 'a) base_map -> 'a repr
957 | String : (string, 'a) base_map -> 'a repr
958 | Array : ('a, 'elt, 'builder) array_map_ -> 'a repr
959 | Object : ('o, 'o) object_map_ -> 'o repr
960 | Any : 'a any_map_ -> 'a repr
961 | Map : ('a, 'b) map_ -> 'b repr
962 | Rec : 'a t Lazy.t -> 'a repr
963 | Ignore : unit repr
964
965 and ('array, 'elt, 'builder) array_map_ = {
966 kind : string;
967 doc : string;
968 elt : 'elt t;
969 dec_empty : unit -> 'builder;
970 dec_skip : int -> 'builder -> bool;
971 dec_add : int -> 'elt -> 'builder -> 'builder;
972 dec_finish : Meta.t -> int -> 'builder -> 'array;
973 enc : 'acc. ('acc -> int -> 'elt -> 'acc) -> 'acc -> 'array -> 'acc;
974 enc_meta : 'array -> Meta.t;
975 }
976
977 and ('o, 'dec) object_map_ = {
978 kind : string;
979 doc : string;
980 dec : ('o, 'dec) dec_fun_;
981 mem_decs : mem_dec_ String_map.t;
982 mem_encs : 'o mem_enc_ list;
983 enc_meta : 'o -> Meta.t;
984 shape : 'o object_shape_;
985 }
986
987 and mem_dec_ = Mem_dec : ('o, 'a) mem_map_ -> mem_dec_
988 and 'o mem_enc_ = Mem_enc : ('o, 'a) mem_map_ -> 'o mem_enc_
989
990 and ('o, 'a) mem_map_ = {
991 name : string;
992 doc : string;
993 type' : 'a t;
994 id : 'a Type.Id.t;
995 dec_absent : 'a option;
996 enc : 'o -> 'a;
997 enc_omit : 'a -> bool;
998 }
999
1000 and 'o object_shape_ =
1001 | Object_basic : ('o, 'mems, 'builder) unknown_mems_ -> 'o object_shape_
1002 | Object_cases :
1003 ('o, 'mems, 'builder) unknown_mems_ option
1004 * ('o, 'cases, 'tag) object_cases_
1005 -> 'o object_shape_
1006
1007 and ('o, 'mems, 'builder) unknown_mems_ =
1008 | Unknown_skip : ('o, unit, unit) unknown_mems_
1009 | Unknown_error : ('o, unit, unit) unknown_mems_
1010 | Unknown_keep :
1011 ('mems, 'a, 'builder) mems_map_ * ('o -> 'mems)
1012 -> ('o, 'mems, 'builder) unknown_mems_
1013
1014 and ('mems, 'a, 'builder) mems_map_ = {
1015 kind : string;
1016 doc : string;
1017 mems_type : 'a t;
1018 id : 'mems Type.Id.t;
1019 dec_empty : unit -> 'builder;
1020 dec_add : Meta.t -> string -> 'a -> 'builder -> 'builder;
1021 dec_finish : Meta.t -> 'builder -> 'mems;
1022 enc :
1023 'acc. (Meta.t -> string -> 'a -> 'acc -> 'acc) -> 'mems -> 'acc -> 'acc;
1024 }
1025
1026 and ('o, 'cases, 'tag) object_cases_ = {
1027 tag : ('tag, 'tag) mem_map_;
1028 tag_compare : 'tag -> 'tag -> int;
1029 tag_to_string : ('tag -> string) option;
1030 id : 'cases Type.Id.t;
1031 cases : ('cases, 'tag) case_ list;
1032 enc : 'o -> 'cases;
1033 enc_case : 'cases -> ('cases, 'tag) case_value_;
1034 }
1035
1036 and ('cases, 'case, 'tag) case_map_ = {
1037 tag : 'tag;
1038 object_map : ('case, 'case) object_map_;
1039 dec : 'case -> 'cases;
1040 }
1041
1042 and ('cases, 'tag) case_value_ =
1043 | Case_value :
1044 ('cases, 'case, 'tag) case_map_ * 'case
1045 -> ('cases, 'tag) case_value_
1046
1047 and ('cases, 'tag) case_ =
1048 | Case : ('cases, 'case, 'tag) case_map_ -> ('cases, 'tag) case_
1049
1050 and 'a any_map_ = {
1051 kind : string;
1052 doc : string;
1053 dec_null : 'a t option;
1054 dec_bool : 'a t option;
1055 dec_number : 'a t option;
1056 dec_string : 'a t option;
1057 dec_array : 'a t option;
1058 dec_object : 'a t option;
1059 enc : 'a -> 'a t;
1060 }
1061
1062 and ('a, 'b) map_ = {
1063 kind : string;
1064 doc : string;
1065 dom : 'a t;
1066 dec : 'a -> 'b;
1067 enc : 'b -> 'a;
1068 }
1069
1070 type unknown_mems_option_ =
1071 | Unknown_mems :
1072 ('o, 'mems, 'builder) unknown_mems_ option
1073 -> unknown_mems_option_
1074
1075 val repr : 'a t -> 'a repr
1076 (** [repr t] exposes [t]'s internal representation for sibling libraries. *)
1077
1078 val array_kinded_sort : ('a, 'elt, 'builder) array_map_ -> string
1079 (** [array_kinded_sort m] is the diagnostic kinded sort for array map [m]. *)
1080
1081 val object_kinded_sort : ('o, 'dec) object_map_ -> string
1082 (** [object_kinded_sort m] is the diagnostic kinded sort for object map [m].
1083 *)
1084
1085 val fail_push_array :
1086 Meta.t -> ('array, 'elt, 'builder) array_map_ -> int node -> Error.t -> 'a
1087 (** [fail_push_array meta map index e] raises [e] with [index] pushed in the
1088 error context for [map]. *)
1089
1090 val fail_push_object :
1091 Meta.t -> ('o, 'dec) object_map_ -> string node -> Error.t -> 'a
1092 (** [fail_push_object meta map name e] raises [e] with [name] pushed in the
1093 error context for [map]. *)
1094
1095 val fail_type_mismatch : Meta.t -> 'a t -> fnd:Sort.t -> 'b
1096 (** [fail_type_mismatch meta t ~fnd] raises the sort mismatch error for [t].
1097 *)
1098
1099 val fail_missing_members :
1100 Meta.t ->
1101 ('o, 'o) object_map_ ->
1102 exp:mem_dec_ String_map.t ->
1103 fnd:string list ->
1104 'a
1105 (** [fail_missing_members meta map ~exp ~fnd] raises the missing-members error
1106 for [map]. *)
1107
1108 val fail_unexpected_members :
1109 Meta.t -> ('o, 'o) object_map_ -> fnd:(string * Meta.t) list -> 'a
1110 (** [fail_unexpected_members meta map ~fnd] raises the unexpected-members
1111 error for [map]. *)
1112
1113 val fail_unexpected_case_tag :
1114 Meta.t -> ('o, 'o) object_map_ -> ('o, 'd, 'tag) object_cases_ -> 'tag -> 'a
1115 (** [fail_unexpected_case_tag meta map cases tag] raises the unexpected case
1116 tag error for [tag]. *)
1117
1118 val object_meta_arg : Meta.t Type.Id.t
1119 (** Dictionary key used to pass object metadata to object decoders. *)
1120
1121 module Dict : sig
1122 type binding = B : 'a Type.Id.t * 'a -> binding
1123 type t
1124
1125 val empty : t
1126 (** The empty dictionary. *)
1127
1128 val mem : 'a Type.Id.t -> t -> bool
1129 (** [mem id d] is [true] iff [d] binds [id]. *)
1130
1131 val add : 'a Type.Id.t -> 'a -> t -> t
1132 (** [add id v d] binds [id] to [v] in [d]. *)
1133
1134 val remove : 'a Type.Id.t -> t -> t
1135 (** [remove id d] removes [id] from [d]. *)
1136
1137 val find : 'a Type.Id.t -> t -> 'a option
1138 (** [find id d] is [Some v] if [d] binds [id] to [v]. *)
1139 end
1140
1141 val apply_dict : ('ret, 'f) dec_fun_ -> Dict.t -> 'f
1142 (** [apply_dict f d] applies delayed decoder function [f] with arguments from
1143 [d]. *)
1144
1145 val override_unknown_mems :
1146 by:unknown_mems_option_ ->
1147 unknown_mems_option_ ->
1148 Dict.t ->
1149 unknown_mems_option_ * Dict.t
1150 (** [override_unknown_mems ~by current dict] combines nested unknown-member
1151 policies and returns the updated policy and dictionary. *)
1152
1153 val finish_object_decode :
1154 ('o, 'o) object_map_ ->
1155 Meta.t ->
1156 ('p, 'mems, 'builder) unknown_mems_ ->
1157 'builder ->
1158 mem_dec_ String_map.t ->
1159 Dict.t ->
1160 Dict.t
1161 (** [finish_object_decode map meta unknown builder missing dict] finalizes
1162 object decoding and inserts default or unknown-member values in [dict]. *)
1163end
1164
1165(**/**)