package data-encoding

  1. Overview
  2. Docs

With_JSON_discriminant is a subset of Encoding where the union/matching combinators (and associated functions) add discriminant for the JSON backend.

The following restrictions apply:

  • The case encodings must be objects.
  • The case encoding objects must not include a "kind" field.
  • The case encoding objects must not have duplicate field names.
  • The JSON discriminants must all be distinct.
let e =
  let open Data_encoding in
  let open Data_encoding.With_JSON_discriminant in
  …
type case_tag =
  1. | Tag of int * string

case_tag's only variant Tag includes both a numeric tag for the binary encoding and a string tag for the JSON encoding.

type 't case
val case : title:string -> ?description:string -> case_tag -> 'a encoding -> ('t -> 'a option) -> ('a -> 't) -> 't case

case is similar to Encoding.case but it takes a SaferEncoding.case_tag parameter. This includes both a numeric tag and a string tag.

In Binary: This has no impact. The case_tag argument of Encoding already has a numeric tag.

In JSON: The SaferEncoding adds a field for discriminating the different cases, making these encodings less likely to include accidental bugs. More specifically, when you use case (Tag (_, s)) e _ _ then the underlying union uses an encoding based on e and s. Specifically, if e is an object encoding, then it adds the field (req "kind" (constant s)) to e.

  • raises Invalid_argument

    if e is not an object.

  • raises Invalid_argument

    if e is an object with a "kind" field (this field name is reserved for the discriminating field added by case).

union and matching now check that there are no duplicate "kind" discriminating values. If there is, they raises Invalid_argument.

val matched : ?tag_size:[ `Uint8 | `Uint16 ] -> (int * string) -> 'a encoding -> 'a -> match_result

Similarly to case_tag, matched also takes an additional string parameter. This parameter is used in the same way as case (to add a "kind" field to the JSON encoding) and it fails in the same way as case.

  • raises Invalid_argument

    if the encoding is not an object.

  • raises Invalid_argument

    if the encoding is an object with a "kind" field.

val matching : ?tag_size:[ `Uint8 | `Uint16 ] -> 't matching_function -> 't case list -> 't encoding
val union : ?tag_size:[ `Uint8 | `Uint16 ] -> 't case list -> 't encoding