Create a single encoding from a series of cases.
In JSON, all cases are tried one after the other using the case list
. The caller is responsible for avoiding collisions. If there are collisions (i.e., if multiple cases produce the same JSON output) then the encoding and decoding processes might not be inverse of each other. In other words, destruct e (construct e v)
may not be equal to v
.
In binary, a prefix tag is added to discriminate quickly between cases. The default is `Uint8
and you must use a `Uint16
if you are going to have more than 256 cases.
The matching function is used during binary encoding of a value v
to efficiently determine which of the cases corresponds to v
. The case list is used during decoding to reconstruct a value based on the encoded tag. (Decoding is optimised internally: tag look-up has a constant cost.)
The caller is responsible for ensuring that the matching_function
and the case list
describe the same encoding. If they describe different encodings, then the decoding and encoding processes will not be inverses of each others. In other words, of_bytes e (to_bytes e v)
will not be equal to v
.
If you do not wish to be responsible for this, you can use the unoptimised union
that uses a case list
only (see below). Beware that in union
the complexity of the encoding is linear in the number of cases.
Following: a basic example use. Note that the matching_function
uses the same tags, payload conversions, and payload encoding as the case list
.
type t = A of string | B of int * int | C
let encoding_t =
(* Tags and payload encodings for each constructors *)
let a_tag = 0 and a_encoding = string in
let b_tag = 1 and b_encoding = obj2 (req "x" int) (req "y" int) in
let c_tag = 2 and c_encoding = unit in
matching
(* optimised encoding function *)
(function
| A s -> matched a_tag a_encoding s
| B (x, y) -> matched b_tag b_encoding (x, y)
| C -> matched c_tag c_encoding ())
(* decoding case list *)
[
case ~title:"A"
(Tag a_tag)
a_encoding
(function A s -> Some s | _ -> None) (fun s -> A s);
case ~title:"B"
(Tag b_tag)
b_encoding
(function B (x, y) -> Some (x, y) | _ -> None) (fun (x, y) -> B (x, y));
case ~title:"C"
(Tag c_tag)
c_encoding
(function C -> Some () | _ -> None) (fun () -> C);
]