Module Jsont.Repr

Low level representation (unstable).

This representation may change even between minor versions of the library. It can be used to devise new processors on JSON types.

Processors should be ready to catch the Jsont.Error exception when they invoke functional members of the representation.

Processors should make sure they interpret mappings correctly. In particular:

See the source of Json.decode' and Json.encode' for a simple example on how to process this representation. The paper in the Jsont source repository may also help to understand this menagerie of types.

type 'a t' := 'a t
module String_map : Stdlib.Map.S with type key = string

A Map.Make(String) instance.

module Type : sig ... end

Type identifiers. Can be removed once we require OCaml 5.1

type ('ret, 'f) dec_fun =
  1. | Dec_fun : 'f -> ('ret, 'f) dec_fun
    (*

    The function and its return type.

    *)
  2. | Dec_app : ('ret, 'a -> 'b) dec_fun * 'a Type.Id.t -> ('ret, 'b) dec_fun
    (*

    Application of an argument to a function witnessed by a type identifier. The type identifier can be used to lookup a value of the right type in an heterogenous dictionary.

    *)

The type for decoding functions.

Base value maps

type ('a, 'b) base_map = {
  1. kind : string;
    (*

    The kind of JSON value that are mapped (documentation)

    *)
  2. doc : string;
    (*

    A doc string for the kind of JSON value.

    *)
  3. dec : Meta.t -> 'a -> 'b;
    (*

    dec decodes a base value represented by its metadata and 'a to 'b.

    *)
  4. enc : 'b -> 'a;
    (*

    enc encodes a value of type 'b to a base JSON value represented by 'a.

    *)
  5. enc_meta : 'b -> Meta.t;
    (*

    enc_meta recovers the base JSON value metadata from 'b (if any).

    *)
}

The type for mapping JSON base values represented in OCaml by 'a (these values are fixed by the cases in t) to a value of type 'b.

JSON types

type 'a t =
  1. | Null : (unit, 'a) base_map -> 'a t
    (*

    Null maps.

    *)
  2. | Bool : (bool, 'a) base_map -> 'a t
    (*

    Boolean maps.

    *)
  3. | Number : (float, 'a) base_map -> 'a t
    (*

    Number maps.

    *)
  4. | String : (string, 'a) base_map -> 'a t
    (*

    String maps.

    *)
  5. | Array : ('a, 'elt, 'builder) array_map -> 'a t
    (*

    Array maps.

    *)
  6. | Object : ('o, 'o) object_map -> 'o t
    (*

    Object maps.

    *)
  7. | Any : 'a any_map -> 'a t
    (*

    Map for different sorts of JSON values.

    *)
  8. | Map : ('b, 'a) map -> 'a t
    (*

    Map from JSON type 'b to JSON type 'a.

    *)
  9. | Rec : 'a t Stdlib.Lazy.t -> 'a t
    (*

    Recursive definition.

    *)

The type for JSON types.

Array maps

and ('array, 'elt, 'builder) array_map = {
  1. kind : string;
    (*

    The kind of JSON array mapped (documentation).

    *)
  2. doc : string;
    (*

    Documentation string for the JSON array.

    *)
  3. elt : 'elt t;
    (*

    The type for the array elements.

    *)
  4. dec_empty : unit -> 'builder;
    (*

    dec_empty () creates a new empty array builder.

    *)
  5. dec_skip : int -> 'builder -> bool;
    (*

    dec_skip i b determines if the ith index of the JSON array can be skipped.

    *)
  6. dec_add : int -> 'elt -> 'builder -> 'builder;
    (*

    dec_add adds the ith index value of the JSON array as decoded by elt to the builder.

    *)
  7. dec_finish : Meta.t -> int -> 'builder -> 'array;
    (*

    dec_finish turns the builder into an array given its metadata and length.

    *)
  8. enc : 'acc. ('acc -> int -> 'elt -> 'acc) -> 'acc -> 'array -> 'acc;
    (*

    enc folds over the elements of the array for encoding.

    *)
  9. enc_meta : 'array -> Meta.t;
    (*

    enc_meta recovers the metadata of an array (if any).

    *)
}

The type for mapping JSON arrays to values of type 'array with array elements mapped to type 'elt and using a 'builder value to construct the array.

Object maps

and ('o, 'dec) object_map = {
  1. kind : string;
    (*

    The kind of JSON object (documentation).

    *)
  2. doc : string;
    (*

    A doc string for the JSON member.

    *)
  3. dec : ('o, 'dec) dec_fun;
    (*

    The object decoding function to construct an 'o value.

    *)
  4. mem_decs : mem_dec String_map.t;
    (*

    mem_decs are the member decoders sorted by member name.

    *)
  5. mem_encs : 'o mem_enc list;
    (*

    mem_encs is the list of member encoders.

    *)
  6. enc_meta : 'o -> Meta.t;
    (*

    enc_meta recovers the metadata of an object (if any).

    *)
  7. shape : 'o object_shape;
    (*

    shape is the shape of the object.

    *)
}

The type for mapping a JSON object to values of type 'o using a decoding function of type 'dec. mem_decs and mem_encs have the same mem_map values they are just sorted differently for decoding and encoding purposes.

and mem_dec =
  1. | Mem_dec : ('o, 'a) mem_map -> mem_dec
    (*

    The type for member maps in decoding position.

    *)
and 'o mem_enc =
  1. | Mem_enc : ('o, 'a) mem_map -> 'o mem_enc
    (*

    The type for member maps in encoding position.

    *)
and ('o, 'a) mem_map = {
  1. name : string;
    (*

    The JSON member name.

    *)
  2. doc : string;
    (*

    Documentation for the JSON member.

    *)
  3. type' : 'a t;
    (*

    The type for the member value.

    *)
  4. id : 'a Type.Id.t;
    (*

    A type identifier for the member. This allows to store the decode in a Dict.t on decode and give it in time to the object decoding function of the object map.

    *)
  5. dec_absent : 'a option;
    (*

    The value to use if absent (if any).

    *)
  6. enc : 'o -> 'a;
    (*

    enc recovers the value to encode from 'o.

    *)
  7. enc_omit : 'a -> bool;
    (*

    enc_omit is true if the result of enc should not be encoded.

    *)
}

The type for mapping a JSON member to a value of type 'a in an object represented by a value of type 'o.

and 'o object_shape =
  1. | Object_basic : ('o, 'mems, 'builder) unknown_mems -> 'o object_shape
    (*

    A basic object, possibly indicating how to handle unknown members

    *)
  2. | Object_cases : ('o, 'mems, 'builder) unknown_mems option * ('o, 'cases, 'tag) object_cases -> 'o object_shape
    (*

    An object with a case member each case further describing an object map.

    *)

The type for object shapes.

Unknown members

and ('o, 'mems, 'builder) unknown_mems =
  1. | Unknown_skip : ('o, unit, unit) unknown_mems
    (*

    Skip unknown members.

    *)
  2. | Unknown_error : ('o, unit, unit) unknown_mems
    (*

    Error on unknown members.

    *)
  3. | Unknown_keep : ('mems, 'a, 'builder) mems_map * ('o -> 'mems) -> ('o, 'mems, 'builder) unknown_mems
    (*

    Gather unknown members in a member map.

    *)

The type for specifying decoding behaviour on unknown JSON object members.

and ('mems, 'a, 'builder) mems_map = {
  1. kind : string;
    (*

    The kind for unknown members (documentation).

    *)
  2. doc : string;
    (*

    Documentation string for the unknown members.

    *)
  3. mems_type : 'a t;
    (*

    The uniform type according which unknown members are typed.

    *)
  4. id : 'mems Type.Id.t;
    (*

    A type identifier for the unknown member map.

    *)
  5. dec_empty : unit -> 'builder;
    (*

    dec_empty create a new empty member map builder.

    *)
  6. dec_add : Meta.t -> string -> 'a -> 'builder -> 'builder;
    (*

    dec_add adds a member named n with metadata meta and value parsed by mems_type to the builder.

    *)
  7. dec_finish : 'builder -> 'mems;
    (*

    dec_finish turns the builder into an unknown member map.

    *)
  8. enc : 'acc. (Meta.t -> string -> 'a -> 'acc -> 'acc) -> 'mems -> 'acc -> 'acc;
    (*

    enc folds over the member map for encoding.

    *)
}

The type for gathering unknown JSON members uniformly typed according to 'a in a map 'mems constructed with 'builder.

Case objects

and ('o, 'cases, 'tag) object_cases = {
  1. tag : ('tag, 'tag) mem_map;
    (*

    The JSON member used to decide cases. The enc field of this mem_map should be the identity, this allows encoders to reuse generic encoding code for members. We don't have ('o, 'tag) mem_map here because the tag is not stored we recover the case via enc and enc_case below.

    *)
  2. tag_compare : 'tag -> 'tag -> int;
    (*

    The function to compare tags.

    *)
  3. tag_to_string : ('tag -> string) option;
    (*

    The function to stringify tags for error reporting.

    *)
  4. id : 'cases Type.Id.t;
    (*

    A type identifier for the tag.

    *)
  5. cases : ('cases, 'tag) case list;
    (*

    The list of possible cases.

    *)
  6. enc : 'o -> 'cases;
    (*

    enc is the function to recover case values from the value 'o the object is mapped to.

    *)
  7. enc_case : 'cases -> ('cases, 'tag) case_value;
    (*

    enc_case retrieves the concrete case from the common cases values. You can see it as preforming a match.

    *)
}

The type for object cases mapped to a common type 'cases stored in a vlue of type 'o and identified by tag values of type 'tag.

and ('cases, 'case, 'tag) case_map = {
  1. tag : 'tag;
    (*

    The tag value for the case.

    *)
  2. object_map : ('case, 'case) object_map;
    (*

    The object map for the case.

    *)
  3. dec : 'case -> 'cases;
    (*

    dec is the function used on decoding to inject the case into the common 'cases type.

    *)
}

The type for an object case with common type 'cases specific type 'case and tag type 'tag.

and ('cases, 'tag) case_value =
  1. | Case_value : ('cases, 'case, 'tag) case_map * 'case -> ('cases, 'tag) case_value
    (*

    The type for case values. This packs a case value and its description.

    *)
and ('cases, 'tag) case =
  1. | Case : ('cases, 'case, 'tag) case_map -> ('cases, 'tag) case
    (*

    The type for hiding the the concrete type of a case .

    *)

Any maps

and 'a any_map = {
  1. kind : string;
    (*

    The kind of JSON values mapped (documentation).

    *)
  2. doc : string;
    (*

    Documentation string for the kind of values.

    *)
  3. dec_null : 'a t option;
    (*

    dec_null, if any, is used for decoding JSON nulls.

    *)
  4. dec_bool : 'a t option;
    (*

    dec_bool, if any, is used for decoding JSON bools.

    *)
  5. dec_number : 'a t option;
    (*

    dec_number, if any, is used for decoding JSON numbers.

    *)
  6. dec_string : 'a t option;
    (*

    dec_string, if any, is used for decoding JSON strings.

    *)
  7. dec_array : 'a t option;
    (*

    dec_array, if any, is used for decoding JSON arrays.

    *)
  8. dec_object : 'a t option;
    (*

    dec_object, if any, is used for decoding JSON objects.

    *)
  9. enc : 'a -> 'a t;
    (*

    enc specifies the encoder to use on a given value.

    *)
}

The type for mapping JSON values with multiple sorts to a value of type 'a. If a decoding case is None, the decoding errors on these JSON values.

Type maps

and ('a, 'b) map = {
  1. kind : string;
    (*

    The kind of JSON values mapped (documentation).

    *)
  2. doc : string;
    (*

    Documentation string for the kind of values.

    *)
  3. dom : 'a t;
    (*

    The domain of the map.

    *)
  4. dec : 'a -> 'b;
    (*

    dec decodes 'a to 'b.

    *)
  5. enc : 'b -> 'a;
    (*

    enc encodes 'b to 'a.

    *)
}

The type for mapping JSON types of type 'a to a JSON type of type 'b.

Convert

val of_t : 'a t' -> 'a t

of_t is Stdlib.Fun.id.

val unsafe_to_t : 'a t -> 'a t'

unsafe_to_t r converts the representation to a type r. It is unsafe because constructors of the Jsont module do maintain some invariants.

Kinds and doc

val kinded_sort : 'a t -> string

kinded_sort t is kinded sort of t, see Jsont.kinded_sort.

val array_map_kinded_sort : ('a, 'elt, 'builder) array_map -> string

array_map_kinded_sort map is like kinded_sort but acts directly on the array map.

val object_map_kinded_sort : ('o, 'dec) object_map -> string

object_map_kind map is like kinded_sort but acts directly on the object map.

val pp_kind : string fmt

pp_kind formats kinds.

val doc : 'a t -> string

Errors

val error_push_array : Meta.t -> ('array, 'elt, 'builder) array_map -> int node -> Error.t -> 'a

error_push_array is like Error.push_array but uses the given array meta and array map to caracterize the context.

val error_push_object : Meta.t -> ('o, 'dec) object_map -> string node -> Error.t -> 'a

error_push_object is like Error.push_object but uses the given object meta and object map to caracterize the context.

val type_error : Meta.t -> 'a t -> fnd:Sort.t -> 'b

type_error meta ~exp ~fnd errors when kind exp was expected but sort fnd was found.

val missing_mems_error : Meta.t -> ('o, 'o) object_map -> exp:mem_dec String_map.t -> fnd:string list -> 'a

missing_mems_error is like Error.missing_mems but with information derived from the given argument map descriptions. In exp only those member map which do not have a default value are reported.

val unexpected_mems_error : Meta.t -> ('o, 'o) object_map -> fnd:(string * Meta.t) list -> 'a
val unexpected_case_tag_error : Meta.t -> ('o, 'o) object_map -> ('o, 'd, 'tag) object_cases -> 'tag -> 'a

Processor toolbox

val object_meta_arg : Meta.t Type.Id.t

object_meta_arg holds the Jsont.Object.mem to

module Dict : sig ... end

Heterogeneous dictionaries.

val apply_dict : ('ret, 'f) dec_fun -> Dict.t -> 'f

apply_dict dec dict applies dict to f in order to get the value 'f. Raises Invalid_argument if dict has not all the type identifiers that dec needs.

type unknown_mems_option =
  1. | Unknown_mems : ('o, 'mems, 'builder) unknown_mems option -> unknown_mems_option
    (*

    A type for hiding an optional unknown_mems values.

    *)
val override_unknown_mems : by:unknown_mems_option -> unknown_mems_option -> Dict.t -> unknown_mems_option * Dict.t

override_unknown_mems ~by current dict preforms the unknown member overriding logic for Jsont.Object.Case objects. In particular if current is a Jsont.Object.Mems.map it adds an empty one in dict so that the associated decoding function does not fail.

val finish_object_decode : ('o, 'o) object_map -> Meta.t -> ('p, 'mems, 'builder) unknown_mems -> 'builder -> mem_dec String_map.t -> Dict.t -> Dict.t

finish_object_decode map meta unknown_mems umap rem_mems dict finishes an object map map decode. It adds the umap (if needed) to dict, it adds meta to dict under object_meta_arg and tries to find andd default values to dict for rem_mems (and errors if it can't).

val pp_code : string fmt