Declarative JSON data manipulation for OCaml
0
fork

Configure Feed

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

at main 1165 lines 40 kB view raw
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(**/**)