Declarative JSON data manipulation for OCaml
0
fork

Configure Feed

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

ocaml-json: inline Codec docs into json.mli and tighten cross-refs

Move the Codec signature inline under Json so the declarative codec
combinators are visible at the top-level module. Rewrite cross-refs to
use val-/module- disambiguators so odoc no longer complains about
overloaded identifiers. Drop the Object.Member submodule in favour of
calling Json.Codec.Object.{member,opt_member} directly.

+807 -85
+1 -1
lib/brr/json_brr.ml
··· 3 3 SPDX-License-Identifier: ISC 4 4 ---------------------------------------------------------------------------*) 5 5 6 - module I = Json.Codec.Internal__ 6 + module I = Json__Codec.Internal 7 7 open I 8 8 9 9 let jv_error_to_error e =
+12 -36
lib/codec.ml
··· 1053 1053 1054 1054 (* Members *) 1055 1055 1056 - module Member = struct 1057 - type ('o, 'a) map = ('o, 'a) mem_map 1058 - 1059 - let no_enc name = 1060 - fun _v -> Error.failf Meta.none "No encoder for member %a" pp_code name 1061 - 1062 - let map ?(doc = "") ?dec_absent ?enc ?enc_omit name type' = 1063 - let id = Type.Id.make () in 1064 - let enc = match enc with None -> no_enc name | Some enc -> enc in 1065 - let enc_omit = 1066 - match enc_omit with None -> Fun.const false | Some omit -> omit 1067 - in 1068 - { name; doc; type'; id; dec_absent; enc; enc_omit } 1056 + let no_enc name = 1057 + fun _v -> Error.failf Meta.none "No encoder for member %a" pp_code name 1069 1058 1070 - let app object_map mm = 1071 - let mem_decs = String_map.add mm.name (Mem_dec mm) object_map.mem_decs in 1072 - let mem_encs = Mem_enc mm :: object_map.mem_encs in 1073 - let dec = Dec_app (object_map.dec, mm.id) in 1074 - { object_map with dec; mem_decs; mem_encs } 1075 - end 1059 + let mem_map ?(doc = "") ?dec_absent ?enc ?enc_omit name type' = 1060 + let id = Type.Id.make () in 1061 + let enc = match enc with None -> no_enc name | Some enc -> enc in 1062 + let enc_omit = 1063 + match enc_omit with None -> Fun.const false | Some omit -> omit 1064 + in 1065 + { name; doc; type'; id; dec_absent; enc; enc_omit } 1076 1066 1077 1067 let member ?(doc = "") ?dec_absent ?enc ?enc_omit name type' map = 1078 - let mmap = Member.map ~doc ?dec_absent ?enc ?enc_omit name type' in 1068 + let mmap = mem_map ~doc ?dec_absent ?enc ?enc_omit name type' in 1079 1069 let mem_decs = String_map.add name (Mem_dec mmap) map.mem_decs in 1080 1070 let mem_encs = Mem_enc mmap :: map.mem_encs in 1081 1071 let dec = Dec_app (map.dec, mmap.id) in ··· 1133 1123 ?dec_absent ?enc ?enc_omit ?enc_case name type' cases map = 1134 1124 let () = check_case_mem map cases ~dec_absent ~tag_compare ~tag_to_string in 1135 1125 let tag = case_tag_mem ?doc name type' ~dec_absent ~enc_omit in 1136 - let enc = match enc with None -> Member.no_enc name | Some e -> e in 1126 + let enc = match enc with None -> no_enc name | Some e -> e in 1137 1127 let enc_case = 1138 1128 match enc_case with 1139 1129 | Some enc_case -> enc_case ··· 1242 1232 let enc () = null in 1243 1233 any ~kind ~dec_null:null ~dec_bool ~dec_number ~dec_string ~dec_array 1244 1234 ~dec_object ~enc () 1245 - 1246 - let todo ?(kind = "") ?doc ?dec_stub () = 1247 - let pp_kind ppf () = 1248 - if kind = "" then () else Fmt.pf ppf " %a" Fmt.code kind 1249 - in 1250 - let dec = 1251 - match dec_stub with 1252 - | Some v -> Fun.const v 1253 - | None -> fun _v -> Error.failf Meta.none "TODO: decode%a" pp_kind () 1254 - in 1255 - let enc _v = Error.failf Meta.none "TODO: encode%a" pp_kind () in 1256 - map ~kind ?doc ~dec ~enc ignore 1257 1235 1258 1236 (* Generic-AST codecs. These preserve the AST shape when (de)coding. *) 1259 1237 ··· 1958 1936 let absent = if allow_absent then Some v else None in 1959 1937 update_path ?stub ?absent p (const t v) 1960 1938 1961 - module Internal__ = struct 1939 + module Internal = struct 1962 1940 module String_map = String_map 1963 1941 1964 1942 type ('ret, 'f) dec_fun_ = ('ret, 'f) dec_fun = ··· 2099 2077 let repr t = t 2100 2078 let array_kinded_sort = array_kinded_sort 2101 2079 let object_kinded_sort = object_kinded_sort 2102 - let pp_kind = pp_kind 2103 - let pp_code = pp_code 2104 2080 let fail_push_array = fail_push_array 2105 2081 let fail_push_object = fail_push_object 2106 2082 let fail_type_mismatch = fail_type_mismatch
+9 -45
lib/codec.mli
··· 23 23 |> C.Object.seal 24 24 ]} 25 25 26 - Decode and encode with {!Json.of_string} and {!Json.to_string}, or use the 27 - runtime functions in this module when you already have a {!Json.t}. *) 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 28 29 29 (** {1:core Core concepts} *) 30 30 ··· 517 517 518 518 (** {1:mems Members} *) 519 519 520 - (** Member maps. 521 - 522 - Usually it's better to use {!Json.Codec.Object.member} or 523 - {!Json.Codec.Object.opt_member} directly. But this may be useful in 524 - certain abstraction contexts. *) 525 - module Member : sig 526 - type ('o, 'dec) object_map := ('o, 'dec) map 527 - 528 - type ('o, 'a) map 529 - (** The type for mapping a member object to a value ['a] stored in an OCaml 530 - value of type ['o]. *) 531 - 532 - val map : 533 - ?doc:string -> 534 - ?dec_absent:'a -> 535 - ?enc:('o -> 'a) -> 536 - ?enc_omit:('a -> bool) -> 537 - string -> 538 - 'a codec -> 539 - ('o, 'a) map 540 - (** See {!Json.Codec.Object.member}. *) 541 - 542 - val app : ('o, 'a -> 'b) object_map -> ('o, 'a) map -> ('o, 'b) object_map 543 - (** [app map mmap] applies the member map [mmap] to the contructor of the 544 - object map [map]. In turn this adds the [mmap] member definition to the 545 - object described by [map]. *) 546 - end 547 - 548 520 val member : 549 521 ?doc:string -> 550 522 ?dec_absent:'a -> ··· 763 735 (** [zero] lossily maps all JSON values to [()] on decoding and encodes JSON 764 736 nulls. *) 765 737 766 - val todo : ?kind:string -> ?doc:string -> ?dec_stub:'a -> unit -> 'a t 767 - (** [todo ?dec_stub ()] maps all JSON values to [dec_stub] if specified (errors 768 - otherwise) and errors on encoding. *) 769 - 770 738 (** {1:generic_ast Generic AST codecs} 771 739 772 740 Codecs that preserve the generic {!value} AST. *) ··· 893 861 val delete_path : ?allow_absent:bool -> Path.t -> value t 894 862 (** [delete_path p] deletes the last index of [p]. *) 895 863 896 - (** {1:runtime Runtime} *) 864 + (** {1:runtime Runtime} 865 + 866 + These functions apply a codec to an existing {!Json.t}. Use 867 + {!Json.val-of_string} and {!Json.val-to_string} when the boundary is a JSON 868 + text. *) 897 869 898 870 val decode : 'a t -> value -> ('a, Error.t) result 899 871 (** [decode t v] decodes [v] as a value of type ['a] according to [t]. *) ··· 904 876 val encode : 'a t -> 'a -> value 905 877 (** [encode t v] encodes [v] as a generic JSON value according to [t]. *) 906 878 907 - (** {1:stream Byte-stream I/O} 908 - 909 - Scoped under [Stream] so [open Codec] doesn't shadow callers' own 910 - [of_string] / [to_string]. Top-level users should prefer {!Json.of_string} 911 - and friends. *) 879 + (**/**) 912 880 913 881 module Stream : sig 914 882 val of_reader : ··· 947 915 string 948 916 end 949 917 950 - (**/**) 951 - 952 - module Internal__ : sig 918 + module Internal : sig 953 919 module String_map : module type of Map.Make (String) 954 920 955 921 type ('ret, 'f) dec_fun_ = ··· 1089 1055 val repr : 'a t -> 'a repr 1090 1056 val array_kinded_sort : ('a, 'elt, 'builder) array_map_ -> string 1091 1057 val object_kinded_sort : ('o, 'dec) object_map_ -> string 1092 - val pp_kind : string Fmt.t 1093 - val pp_code : string Fmt.t 1094 1058 1095 1059 val fail_push_array : 1096 1060 Meta.t -> ('array, 'elt, 'builder) array_map_ -> int node -> Error.t -> 'a
+785 -3
lib/json.mli
··· 104 104 105 105 (** {1:codecs Typed codecs} *) 106 106 107 - module Codec = Codec 108 107 (** Typed codec combinators. Build codecs here, then pass them to 109 108 {!val-of_string}, {!val-to_string}, {!val-decode}, {!val-encode}, or the 110 - browser-native functions from [json.brr]. *) 109 + browser-native functions from {!module-Json_brr}. *) 110 + module Codec : sig 111 + (** Typed JSON codecs. 112 + 113 + A codec value describes how JSON maps to an OCaml value and back. Use the 114 + small predefined codecs for JSON scalars, combine them with the array and 115 + object builders, then pass the resulting codec to {!Json.val-of_string}, 116 + {!Json.val-to_string}, {!Json.val-decode}, {!Json.val-encode}, or 117 + {!module-Json_brr}. 118 + 119 + {[ 120 + module C = Json.Codec 121 + 122 + type person = { name : string; age : int } 123 + 124 + let person name age = { name; age } 125 + 126 + let person_codec = 127 + C.Object.map person 128 + |> C.Object.member "name" C.string ~enc:(fun p -> p.name) 129 + |> C.Object.member "age" C.int ~enc:(fun p -> p.age) 130 + |> C.Object.seal 131 + ]} *) 132 + 133 + type 'a t = 'a Codec.t 134 + (** The type of codecs mapping JSON values to OCaml values of type ['a]. *) 135 + 136 + type 'a codec = 'a t 137 + (** Alias for {!type-t}, useful in nested signatures. *) 138 + 139 + type value = Value.t 140 + (** Alias for the generic JSON value type. *) 141 + 142 + type name = Value.name 143 + (** The type for JSON member names. *) 144 + 145 + type member = Value.member 146 + (** The type for generic JSON object members. *) 147 + 148 + type object' = Value.object' 149 + (** The type for generic JSON objects. *) 150 + 151 + module Meta = Loc.Meta 152 + (** JSON node metadata. Custom codecs use this to report source locations or 153 + preserve layout. *) 154 + 155 + module Path = Loc.Path 156 + (** JSON paths used by query and update codecs. *) 157 + 158 + module Sort = Sort 159 + (** JSON sorts used in diagnostics. *) 160 + 161 + val kinded_sort : 'a t -> string 162 + (** [kinded_sort c] is the diagnostic sort expected by [c], including its 163 + custom kind when one was supplied. *) 164 + 165 + val kind : 'a t -> string 166 + (** [kind c] is the short kind name used in diagnostics for [c]. *) 167 + 168 + val doc : 'a t -> string 169 + (** [doc c] is the documentation string attached to [c], if any. *) 170 + 171 + val with_doc : ?kind:string -> ?doc:string -> 'a t -> 'a t 172 + (** [with_doc c] is [c] with updated [kind] and [doc] metadata. *) 173 + 174 + module Base : sig 175 + (** Low-level maps for custom scalar codecs. Most users can start with 176 + {!Json.Codec.map}, {!Json.Codec.of_of_string}, or the predefined scalar 177 + codecs. *) 178 + 179 + type ('json, 'a) map 180 + (** A bidirectional map between a JSON scalar representation and an OCaml 181 + value. *) 182 + 183 + val map : 184 + ?kind:string -> 185 + ?doc:string -> 186 + ?dec:(Meta.t -> 'json -> 'a) -> 187 + ?enc:('a -> 'json) -> 188 + ?enc_meta:('a -> Meta.t) -> 189 + unit -> 190 + ('json, 'a) map 191 + (** [map ()] builds a scalar map. Omit [dec] for encode-only maps and [enc] 192 + for decode-only maps. *) 193 + 194 + val id : ('a, 'a) map 195 + (** The identity map. *) 196 + 197 + val ignore : ('a, unit) map 198 + (** A map that ignores decoded values and errors on encoding. *) 199 + 200 + val null : (unit, 'a) map -> 'a t 201 + (** Build a codec over JSON nulls. *) 202 + 203 + val bool : (bool, 'a) map -> 'a t 204 + (** Build a codec over JSON booleans. *) 205 + 206 + val number : (float, 'a) map -> 'a t 207 + (** Build a codec over JSON numbers, represented as OCaml [float]s. *) 208 + 209 + val string : (string, 'a) map -> 'a t 210 + (** Build a codec over JSON strings, represented as UTF-8 OCaml strings. *) 211 + 212 + val dec : ('json -> 'a) -> Meta.t -> 'json -> 'a 213 + (** Adapt a total decoding function. *) 214 + 215 + val dec_result : 216 + ?kind:string -> ('json -> ('a, string) result) -> Meta.t -> 'json -> 'a 217 + (** Adapt a result-returning decoding function. *) 218 + 219 + val dec_failure : ?kind:string -> ('json -> 'a) -> Meta.t -> 'json -> 'a 220 + (** Adapt a decoding function that may raise [Failure]. *) 221 + 222 + val enc : ('a -> 'json) -> 'a -> 'json 223 + (** Adapt a total encoding function. *) 224 + 225 + val enc_result : 226 + ?kind:string -> ('a -> ('json, string) result) -> 'a -> 'json 227 + (** Adapt a result-returning encoding function. *) 228 + 229 + val enc_failure : ?kind:string -> ('a -> 'json) -> 'a -> 'json 230 + (** Adapt an encoding function that may raise [Failure]. *) 231 + end 232 + 233 + val null : ?kind:string -> ?doc:string -> 'a -> 'a t 234 + (** [null v] maps JSON nulls to [v] and encodes all values as JSON null. *) 235 + 236 + val none : 'a option t 237 + (** [none] maps JSON nulls to [None]. *) 238 + 239 + val some : 'a t -> 'a option t 240 + (** [some c] maps values like [c] but wraps decoded values in [Some]. Encoding 241 + [None] fails. *) 242 + 243 + val option : ?kind:string -> ?doc:string -> 'a t -> 'a option t 244 + (** [option c] maps JSON nulls to [None] and other values with [c]. *) 245 + 246 + val bool : bool t 247 + (** JSON booleans. *) 248 + 249 + val number : float t 250 + (** JSON numbers as floats. JSON null decodes to [Float.nan]; non-finite 251 + floats encode as JSON null. *) 252 + 253 + val any_float : float t 254 + (** IEEE 754 floats using JSON numbers when possible and JSON strings for 255 + non-finite values. Use only when both sides agree on this extension. *) 256 + 257 + val float_as_hex_string : float t 258 + (** Floats encoded as hexadecimal JSON strings. *) 259 + 260 + val uint8 : int t 261 + (** Unsigned 8-bit integers encoded as JSON numbers. *) 262 + 263 + val uint16 : int t 264 + (** Unsigned 16-bit integers encoded as JSON numbers. *) 265 + 266 + val int8 : int t 267 + (** Signed 8-bit integers encoded as JSON numbers. *) 268 + 269 + val int16 : int t 270 + (** Signed 16-bit integers encoded as JSON numbers. *) 271 + 272 + val int32 : int32 t 273 + (** 32-bit integers encoded as JSON numbers. *) 274 + 275 + val int64 : int64 t 276 + (** 64-bit integers encoded as JSON numbers when exact in JavaScript, or as 277 + decimal strings otherwise. *) 278 + 279 + val int64_as_string : int64 t 280 + (** 64-bit integers encoded as JSON strings. *) 281 + 282 + val int : int t 283 + (** OCaml integers encoded as JSON numbers when exact in JavaScript, or as 284 + decimal strings otherwise. *) 285 + 286 + val int_as_string : int t 287 + (** OCaml integers encoded as JSON strings. *) 288 + 289 + val string : string t 290 + (** JSON strings as UTF-8 OCaml strings. *) 291 + 292 + val of_of_string : 293 + ?kind:string -> 294 + ?doc:string -> 295 + ?enc:('a -> string) -> 296 + (string -> ('a, string) result) -> 297 + 'a t 298 + (** [of_of_string parse] builds a JSON string codec from a parser and optional 299 + printer. *) 300 + 301 + val enum : 302 + ?cmp:('a -> 'a -> int) -> 303 + ?kind:string -> 304 + ?doc:string -> 305 + (string * 'a) list -> 306 + 'a t 307 + (** [enum assoc] maps JSON strings in [assoc] to their OCaml values and back. 308 + *) 309 + 310 + val binary_string : string t 311 + (** Binary strings encoded as lower-case hexadecimal JSON strings. *) 312 + 313 + module Array : sig 314 + (** Low-level maps for custom JSON array representations. Prefer 315 + {!Json.Codec.list}, {!Json.Codec.array}, and the tuple helpers when they 316 + fit. *) 317 + 318 + type ('array, 'elt) enc = { 319 + enc : 'acc. ('acc -> int -> 'elt -> 'acc) -> 'acc -> 'array -> 'acc; 320 + } 321 + (** A fold over the elements to encode. *) 322 + 323 + type ('array, 'elt, 'builder) map 324 + (** A bidirectional map for JSON arrays. *) 325 + 326 + val map : 327 + ?kind:string -> 328 + ?doc:string -> 329 + ?dec_empty:(unit -> 'builder) -> 330 + ?dec_skip:(int -> 'builder -> bool) -> 331 + ?dec_add:(int -> 'elt -> 'builder -> 'builder) -> 332 + ?dec_finish:(Meta.t -> int -> 'builder -> 'array) -> 333 + ?enc:('array, 'elt) enc -> 334 + ?enc_meta:('array -> Meta.t) -> 335 + 'elt t -> 336 + ('array, 'elt, 'builder) map 337 + (** Build a custom JSON array map. *) 338 + 339 + val list_map : 340 + ?kind:string -> 341 + ?doc:string -> 342 + ?dec_skip:(int -> 'a list -> bool) -> 343 + 'a t -> 344 + ('a list, 'a, 'a list) map 345 + (** A map for OCaml lists. *) 346 + 347 + type 'a array_builder 348 + (** Builder state for OCaml arrays. *) 349 + 350 + val array_map : 351 + ?kind:string -> 352 + ?doc:string -> 353 + ?dec_skip:(int -> 'a array_builder -> bool) -> 354 + 'a t -> 355 + ('a array, 'a, 'a array_builder) map 356 + (** A map for OCaml arrays. *) 357 + 358 + type ('a, 'b, 'c) bigarray_builder 359 + (** Builder state for bigarrays. *) 360 + 361 + val bigarray_map : 362 + ?kind:string -> 363 + ?doc:string -> 364 + ?dec_skip:(int -> ('a, 'b, 'c) bigarray_builder -> bool) -> 365 + ('a, 'b) Bigarray.kind -> 366 + 'c Bigarray.layout -> 367 + 'a t -> 368 + (('a, 'b, 'c) Bigarray.Array1.t, 'a, ('a, 'b, 'c) bigarray_builder) map 369 + (** A map for one-dimensional bigarrays. *) 370 + 371 + val array : ('a, _, _) map -> 'a t 372 + (** Build a codec from an array map. *) 373 + 374 + val ignore : unit t 375 + (** Ignore JSON arrays on decoding and error on encoding. *) 376 + 377 + val zero : unit t 378 + (** Ignore JSON arrays on decoding and encode an empty array. *) 379 + end 380 + 381 + val list : ?kind:string -> ?doc:string -> 'a t -> 'a list t 382 + (** JSON arrays as OCaml lists. *) 383 + 384 + val array : ?kind:string -> ?doc:string -> 'a t -> 'a array t 385 + (** JSON arrays as OCaml arrays. *) 386 + 387 + val array_as_string_map : 388 + ?kind:string -> 389 + ?doc:string -> 390 + key:('a -> string) -> 391 + 'a t -> 392 + 'a Map.Make(String).t t 393 + (** JSON arrays indexed into string maps by [key]. *) 394 + 395 + val bigarray : 396 + ?kind:string -> 397 + ?doc:string -> 398 + ('a, 'b) Bigarray.kind -> 399 + 'a t -> 400 + ('a, 'b, Bigarray.c_layout) Bigarray.Array1.t t 401 + (** JSON arrays as one-dimensional bigarrays. *) 402 + 403 + val t2 : 404 + ?kind:string -> 405 + ?doc:string -> 406 + ?dec:('a -> 'a -> 't2) -> 407 + ?enc:('t2 -> int -> 'a) -> 408 + 'a t -> 409 + 't2 t 410 + (** JSON arrays with exactly two elements. *) 411 + 412 + val t3 : 413 + ?kind:string -> 414 + ?doc:string -> 415 + ?dec:('a -> 'a -> 'a -> 't3) -> 416 + ?enc:('t3 -> int -> 'a) -> 417 + 'a t -> 418 + 't3 t 419 + (** JSON arrays with exactly three elements. *) 420 + 421 + val t4 : 422 + ?kind:string -> 423 + ?doc:string -> 424 + ?dec:('a -> 'a -> 'a -> 'a -> 't4) -> 425 + ?enc:('t4 -> int -> 'a) -> 426 + 'a t -> 427 + 't4 t 428 + (** JSON arrays with exactly four elements. *) 429 + 430 + val tn : ?kind:string -> ?doc:string -> n:int -> 'a t -> 'a array t 431 + (** JSON arrays with exactly [n] elements. *) 432 + 433 + module Object : sig 434 + (** Builders for JSON object codecs. *) 435 + 436 + type ('o, 'dec) map 437 + (** An object under construction. ['o] is the encoded object type; ['dec] is 438 + the remaining decoder function type. *) 439 + 440 + val map : ?kind:string -> ?doc:string -> 'dec -> ('o, 'dec) map 441 + (** [map make] starts an object codec decoded by progressively applying 442 + decoded members to [make]. *) 443 + 444 + val map_with_meta : 445 + ?kind:string -> 446 + ?doc:string -> 447 + ?enc_meta:('o -> Meta.t) -> 448 + (Meta.t -> 'dec) -> 449 + ('o, 'dec) map 450 + (** Like {!val-map}, but the decoder receives the object's metadata. *) 451 + 452 + val enc_only : 453 + ?kind:string -> 454 + ?doc:string -> 455 + ?enc_meta:('o -> Meta.t) -> 456 + unit -> 457 + ('o, 'a) map 458 + (** Start an object map that can only encode. *) 459 + 460 + val seal : ('o, 'o) map -> 'o t 461 + (** Finish an object map. Raises [Invalid_argument] if member names are 462 + duplicated. *) 463 + 464 + val member : 465 + ?doc:string -> 466 + ?dec_absent:'a -> 467 + ?enc:('o -> 'a) -> 468 + ?enc_omit:('a -> bool) -> 469 + string -> 470 + 'a codec -> 471 + ('o, 'a -> 'b) map -> 472 + ('o, 'b) map 473 + (** Add a required object member. [dec_absent] supplies a default when the 474 + member is missing; [enc] projects the member for encoding; [enc_omit] 475 + can omit encoded members. *) 476 + 477 + val opt_member : 478 + ?doc:string -> 479 + ?enc:('o -> 'a option) -> 480 + string -> 481 + 'a codec -> 482 + ('o, 'a option -> 'b) map -> 483 + ('o, 'b) map 484 + (** Add an optional object member. Missing and JSON null members decode to 485 + [None]; [None] is omitted on encoding. *) 486 + 487 + module Case : sig 488 + (** Tagged object cases for sum types. *) 489 + 490 + type 'a codec := 'a codec 491 + 492 + type ('cases, 'case, 'tag) map 493 + (** A single case object before it is added to a case set. *) 494 + 495 + val map : 496 + ?dec:('case -> 'cases) -> 497 + 'tag -> 498 + 'case codec -> 499 + ('cases, 'case, 'tag) map 500 + (** [map tag codec] declares [codec] as the object shape for [tag]. *) 501 + 502 + val map_tag : ('cases, 'case, 'tag) map -> 'tag 503 + (** The tag of a case map. *) 504 + 505 + type ('cases, 'tag) t 506 + (** A case in a tagged object set. *) 507 + 508 + val make : ('cases, 'case, 'tag) map -> ('cases, 'tag) t 509 + (** Add a case map to a case set. *) 510 + 511 + val tag : ('cases, 'tag) t -> 'tag 512 + (** The tag of a case. *) 513 + 514 + type ('cases, 'tag) value 515 + (** An encoded case value selected from an OCaml sum value. *) 516 + 517 + val value : ('cases, 'case, 'tag) map -> 'case -> ('cases, 'tag) value 518 + (** [value map v] selects [map] and case payload [v] for encoding. *) 519 + end 520 + 521 + val case_member : 522 + ?doc:string -> 523 + ?tag_compare:('tag -> 'tag -> int) -> 524 + ?tag_to_string:('tag -> string) -> 525 + ?dec_absent:'tag -> 526 + ?enc:('o -> 'cases) -> 527 + ?enc_omit:('tag -> bool) -> 528 + ?enc_case:('cases -> ('cases, 'tag) Case.value) -> 529 + string -> 530 + 'tag codec -> 531 + ('cases, 'tag) Case.t list -> 532 + ('o, 'cases -> 'a) map -> 533 + ('o, 'a) map 534 + (** Add a discriminating member whose value selects one of several object 535 + cases. *) 536 + 537 + module Members : sig 538 + (** Maps for unknown or uniform object members. *) 539 + 540 + type 'a codec := 'a codec 541 + 542 + type ('mems, 'a) enc = { 543 + enc : 544 + 'acc. 545 + (Meta.t -> string -> 'a -> 'acc -> 'acc) -> 'mems -> 'acc -> 'acc; 546 + } 547 + (** A fold over members to encode. *) 548 + 549 + type ('mems, 'a, 'builder) map 550 + (** A map for a set of object members whose values share one codec. *) 551 + 552 + val map : 553 + ?kind:string -> 554 + ?doc:string -> 555 + ?dec_empty:(unit -> 'builder) -> 556 + ?dec_add:(Meta.t -> string -> 'a -> 'builder -> 'builder) -> 557 + ?dec_finish:(Meta.t -> 'builder -> 'mems) -> 558 + ?enc:('mems, 'a) enc -> 559 + 'a codec -> 560 + ('mems, 'a, 'builder) map 561 + (** Build a custom uniform-member map. *) 562 + 563 + val string_map : 564 + ?kind:string -> 565 + ?doc:string -> 566 + 'a codec -> 567 + ('a Stdlib.Map.Make(String).t, 'a, 'a Stdlib.Map.Make(String).t) map 568 + (** Uniform members collected in a string map. *) 569 + end 570 + 571 + val skip_unknown : ('o, 'dec) map -> ('o, 'dec) map 572 + (** Ignore members not declared by the object map. *) 573 + 574 + val error_unknown : ('o, 'dec) map -> ('o, 'dec) map 575 + (** Reject members not declared by the object map. *) 576 + 577 + val keep_unknown : 578 + ?enc:('o -> 'mems) -> 579 + ('mems, _, _) Members.map -> 580 + ('o, 'mems -> 'a) map -> 581 + ('o, 'a) map 582 + (** Decode unknown members with [mems] and pass them to the object 583 + constructor. *) 584 + 585 + val as_string_map : 586 + ?kind:string -> 587 + ?doc:string -> 588 + 'a codec -> 589 + 'a Stdlib.Map.Make(String).t codec 590 + (** JSON objects as string maps with uniform member values. *) 591 + 592 + val zero : unit codec 593 + (** Ignore JSON objects on decoding and encode an empty object. *) 594 + end 595 + 596 + val any : 597 + ?kind:string -> 598 + ?doc:string -> 599 + ?dec_null:'a t -> 600 + ?dec_bool:'a t -> 601 + ?dec_number:'a t -> 602 + ?dec_string:'a t -> 603 + ?dec_array:'a t -> 604 + ?dec_object:'a t -> 605 + ?enc:('a -> 'a t) -> 606 + unit -> 607 + 'a t 608 + (** [any ()] maps one OCaml type across multiple JSON sorts. Supply the 609 + [dec_*] codecs for the accepted sorts and [enc] to choose the codec used 610 + for encoding. *) 611 + 612 + val map : 613 + ?kind:string -> 614 + ?doc:string -> 615 + ?dec:('a -> 'b) -> 616 + ?enc:('b -> 'a) -> 617 + 'a t -> 618 + 'b t 619 + (** Transform a codec's OCaml type. *) 620 + 621 + val iter : 622 + ?kind:string -> 623 + ?doc:string -> 624 + ?dec:('a -> unit) -> 625 + ?enc:('a -> unit) -> 626 + 'a t -> 627 + 'a t 628 + (** Run side-effecting checks while otherwise preserving the codec's type. *) 629 + 630 + val fix : 'a t Lazy.t -> 'a t 631 + (** Recursive codecs. *) 632 + 633 + val ignore : unit t 634 + (** Decode any JSON value to [()] and error on encoding. *) 635 + 636 + val zero : unit t 637 + (** Decode any JSON value to [()] and encode JSON null. *) 638 + 639 + module Value : sig 640 + (** Codecs for the generic {!Json.t} AST. *) 641 + 642 + val t : value t 643 + (** Any JSON value as a generic AST. *) 644 + 645 + val null : value t 646 + (** Generic JSON null values. *) 647 + 648 + val bool : value t 649 + (** Generic JSON boolean values. *) 650 + 651 + val number : value t 652 + (** Generic JSON number values. *) 653 + 654 + val string : value t 655 + (** Generic JSON string values. *) 656 + 657 + val array : value t 658 + (** Generic JSON array values. *) 659 + 660 + val object' : value t 661 + (** Generic JSON object values. *) 662 + 663 + val members : (value, value, member list) Object.Members.map 664 + (** Generic object members as an unknown-member map. *) 665 + end 666 + 667 + val const : 'a t -> 'a -> 'a t 668 + (** Decode any JSON value to a constant and encode that constant with [c]. *) 669 + 670 + val recode : dec:'a t -> ('a -> 'b) -> enc:'b t -> 'b t 671 + (** Decode with [dec] then transform; encode with [enc]. *) 672 + 673 + val update : 'a t -> value t 674 + (** Decode and immediately re-encode a value with the same codec. *) 675 + 676 + val nth : ?absent:'a -> int -> 'a t -> 'a t 677 + (** Decode the [n]th element of a JSON array. *) 678 + 679 + val set_nth : 680 + ?stub:value -> ?allow_absent:bool -> 'a t -> int -> 'a -> value t 681 + (** Set the [n]th array element while decoding to a generic JSON value. *) 682 + 683 + val update_nth : ?stub:value -> ?absent:'a -> int -> 'a t -> value t 684 + (** Recode the [n]th array element. *) 685 + 686 + val delete_nth : ?allow_absent:bool -> int -> value t 687 + (** Delete the [n]th array element. *) 688 + 689 + val filter_map_array : 'a t -> 'b t -> (int -> 'a -> 'b option) -> value t 690 + (** Filter and map JSON array elements. *) 691 + 692 + val fold_array : 'a t -> (int -> 'a -> 'b -> 'b) -> 'b -> 'b t 693 + (** Fold over JSON array elements. *) 694 + 695 + val member : ?absent:'a -> string -> 'a t -> 'a t 696 + (** Decode an object member. *) 697 + 698 + val set_member : ?allow_absent:bool -> 'a t -> string -> 'a -> value t 699 + (** Set an object member while decoding to a generic JSON value. *) 700 + 701 + val update_member : ?absent:'a -> string -> 'a t -> value t 702 + (** Recode an object member. *) 703 + 704 + val delete_member : ?allow_absent:bool -> string -> value t 705 + (** Delete an object member. *) 706 + 707 + val filter_map_object : 708 + 'a t -> 'b t -> (Meta.t -> string -> 'a -> (name * 'b) option) -> value t 709 + (** Filter, rename, and map JSON object members. *) 710 + 711 + val fold_object : 'a t -> (Meta.t -> string -> 'a -> 'b -> 'b) -> 'b -> 'b t 712 + (** Fold over JSON object members. *) 713 + 714 + val index : ?absent:'a -> Path.step -> 'a t -> 'a t 715 + (** Decode an array element or object member selected by one path step. *) 716 + 717 + val set_index : ?allow_absent:bool -> 'a t -> Path.step -> 'a -> value t 718 + (** Set one path step while decoding to a generic JSON value. *) 719 + 720 + val update_index : ?stub:value -> ?absent:'a -> Path.step -> 'a t -> value t 721 + (** Recode one path step. *) 722 + 723 + val delete_index : ?allow_absent:bool -> Path.step -> value t 724 + (** Delete one path step. *) 725 + 726 + val path : ?absent:'a -> Path.t -> 'a t -> 'a t 727 + (** Decode a value selected by a path. *) 728 + 729 + val set_path : 730 + ?stub:value -> ?allow_absent:bool -> 'a t -> Path.t -> 'a -> value t 731 + (** Set a path while decoding to a generic JSON value. *) 732 + 733 + val update_path : ?stub:value -> ?absent:'a -> Path.t -> 'a t -> value t 734 + (** Recode the value selected by a path. *) 735 + 736 + val delete_path : ?allow_absent:bool -> Path.t -> value t 737 + (** Delete the value selected by a path. *) 738 + 739 + val decode : 'a t -> value -> ('a, Error.t) result 740 + (** Apply a codec to an existing {!Json.t}. *) 741 + 742 + val decode_exn : 'a t -> value -> 'a 743 + (** [decode_exn] is like {!val-decode} but raises {!Json.exception-Error}. *) 744 + 745 + val encode : 'a t -> 'a -> value 746 + (** Encode an OCaml value to a generic {!Json.t}. *) 747 + end 111 748 112 749 type 'a codec = 'a Codec.t 113 750 (** The type for JSON codecs: a bidirectional map between JSON values and OCaml ··· 202 839 top level. *) 203 840 204 841 module Value : sig 205 - include module type of Value with type t = t and type name = name 842 + (** Generic JSON value helpers. 843 + 844 + This is the AST layer for callers who need to keep, inspect, or construct 845 + arbitrary JSON data. Prefer {!module-Json.Codec} when JSON should map 846 + directly to ordinary OCaml values. *) 847 + 848 + module Meta = Loc.Meta 849 + (** JSON node metadata. *) 850 + 851 + type 'a node = 'a * Meta.t 852 + (** A payload plus metadata. *) 853 + 854 + type nonrec name = name 855 + (** A JSON member name. *) 856 + 857 + type nonrec member = member 858 + (** A JSON object member. *) 859 + 860 + type nonrec object' = object' 861 + (** A JSON object as an ordered member list. *) 862 + 863 + type nonrec t = t = 864 + | Null of unit node 865 + | Bool of bool node 866 + | Number of float node 867 + | String of string node 868 + | Array of t list node 869 + | Object of object' node (** The generic JSON value type. *) 870 + 871 + type 'a cons = ?meta:Meta.t -> 'a -> t 872 + (** Constructors that lift OCaml values to JSON values. *) 873 + 874 + val meta : t -> Meta.t 875 + (** [meta v] is the metadata attached to [v]. *) 876 + 877 + val set_meta : Meta.t -> t -> t 878 + (** [set_meta m v] replaces [v]'s metadata with [m]. *) 879 + 880 + val copy_layout : t -> dst:t -> t 881 + (** [copy_layout src ~dst] copies [src]'s layout metadata onto [dst]. *) 882 + 883 + val sort : t -> Sort.t 884 + (** [sort v] is the JSON sort of [v]. *) 885 + 886 + val compare : t -> t -> int 887 + (** Total order on JSON values. Metadata is ignored. *) 888 + 889 + val equal : t -> t -> bool 890 + (** [equal a b] is [compare a b = 0]. *) 891 + 892 + val null : unit cons 893 + (** JSON null. *) 894 + 895 + val option : 'a cons -> 'a option cons 896 + (** Lift a constructor to encode [None] as JSON null. *) 897 + 898 + val bool : bool cons 899 + (** JSON booleans. *) 900 + 901 + val number : float cons 902 + (** JSON numbers. Non-finite floats must be encoded as JSON null for strict 903 + JSON output. *) 904 + 905 + val any_float : float cons 906 + (** Finite floats as JSON numbers and non-finite floats as JSON strings. *) 907 + 908 + val int32 : int32 cons 909 + (** 32-bit integers as JSON numbers. *) 910 + 911 + val int64 : int64 cons 912 + (** 64-bit integers as JSON numbers when exact in JavaScript, or JSON strings 913 + otherwise. *) 914 + 915 + val int64_as_string : int64 cons 916 + (** 64-bit integers as JSON strings. *) 917 + 918 + val int : int cons 919 + (** OCaml integers as JSON numbers when exact in JavaScript, or JSON strings 920 + otherwise. *) 921 + 922 + val int_as_string : int cons 923 + (** OCaml integers as JSON strings. *) 924 + 925 + val string : string cons 926 + (** JSON strings. *) 927 + 928 + val list : t list cons 929 + (** JSON arrays from lists. *) 930 + 931 + val array : t array cons 932 + (** JSON arrays from arrays. *) 933 + 934 + val object' : member list cons 935 + (** JSON objects from member lists. *) 936 + 937 + val empty_array : t 938 + (** The empty JSON array. *) 939 + 940 + val empty_object : t 941 + (** The empty JSON object. *) 942 + 943 + val name : ?meta:Meta.t -> string -> name 944 + (** [name s] is a JSON member name. *) 945 + 946 + val member : name -> t -> member 947 + (** [member n v] binds member name [n] to value [v]. *) 948 + 949 + val member_key : string -> member list -> member option 950 + (** [member_key k mems] is the first member in [mems] whose key is [k], if 951 + any. *) 952 + 953 + val member_names : member list -> name list 954 + (** Member names in order. *) 955 + 956 + val member_keys : member list -> string list 957 + (** Member keys as bare strings in order. *) 958 + 959 + val zero : ?meta:Meta.t -> t -> t 960 + (** The natural zero for a value's JSON sort. *) 961 + 962 + val pp_null : unit Fmt.t 963 + (** Print JSON null. *) 964 + 965 + val pp_bool : bool Fmt.t 966 + (** Print JSON booleans. *) 967 + 968 + val pp_string : string Fmt.t 969 + (** Print JSON strings with escaping. *) 970 + 971 + type number_format = Value.number_format 972 + (** Format strings for JSON numbers. *) 973 + 974 + val default_number_format : number_format 975 + (** The default number format, [%.17g]. *) 976 + 977 + val pp_number : float Fmt.t 978 + (** Print JSON numbers with {!val-default_number_format}. *) 979 + 980 + val pp_number' : number_format -> float Fmt.t 981 + (** Print JSON numbers with an explicit format. *) 982 + 983 + val pp : t Fmt.t 984 + (** Print JSON values with {!val-default_number_format}. *) 985 + 986 + val pp' : number_format -> t Fmt.t 987 + (** Print JSON values with an explicit number format. *) 206 988 207 989 (** {1:io_value Byte-level I/O for the AST} 208 990