Skip to content

Commit 24059d3

Browse files
committed
Support alternative representations of variants
1 parent 7b286b5 commit 24059d3

File tree

3 files changed

+331
-112
lines changed

3 files changed

+331
-112
lines changed

README.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ The following table summarizes the correspondence between OCaml types and JSON v
7777
| `Yojson.Safe.t` | any | Identity transformation |
7878
| `unit` | Null | |
7979

80-
Variants (regular and polymorphic) are represented using arrays; the first element is a string with the name of the constructor, the rest are the arguments. Note that the implicit tuple in a polymorphic variant is flattened. For example:
80+
By default, variants (regular and polymorphic) are represented using arrays; the first element is a string with the name of the constructor, the rest are the arguments. Note that the implicit tuple in a polymorphic variant is flattened. For example:
8181

8282
``` ocaml
8383
# type pvs = [ `A | `B of int | `C of int * string ] list [@@deriving yojson];;
@@ -97,7 +97,14 @@ Record variants are represented in the same way as if the nested structure was d
9797
["X",{"v":0}]
9898
```
9999

100-
Record variants are currently not supported for extensible variant types.
100+
Alternative representations of variants can be chosen using the option `variants` (i.e. ``[@@deriving yojson { variants = `Adjacent ("tag", "contents") }]``). The following table lists the ones that are supported:
101+
102+
| `type _ =` | Value | ``variants = `Array`` | ``variants = `External`` | ``variants = `Internal "type"`` | ``variants = `Adjacent ("tag", "contents")`` | ``variants = `Native`` |
103+
| ------------------------- | ---------------- | ---------------------- | ------------------------ | ------------------------------- | -------------------------------------------- | ---------------------- |
104+
| `\| RA` | `RA` | `["RA"]` | `"RA"` | `{"type": "RA"}` | `{"tag": "RA"}` | `<"RA">` |
105+
| `\| RB of int` | `RB 42` | `["RB", 42]` | `{"RB": 42}` | (not supported) | `{"tag": "RB", "contents": 42}` | `<"RB":42>` |
106+
| `\| RC of int * string` | `RC (42, "foo")` | `["RC", 42, "foo"]` | `{"RC": [42, "foo"]}` | (not supported) | `{"tag": "RC", "contents": [42, "foo"]}` | `<"RC":[42, "foo"]>` |
107+
| `\| RD of { z : string }` | `RD {z = "foo"}` | `["RD", {"z": "foo"}]` | `{"RD": {"z": "foo"}}` | `{"type": "RD", "z": "foo"}` | `{"tag": "RD", "contents": {"z": "foo"}}` | `<"RD":{"z": "foo"}>` |
101108

102109
By default, objects are deserialized strictly; that is, all keys in the object have to correspond to fields of the record. Passing `strict = false` as an option to the deriver (i.e. `[@@deriving yojson { strict = false }]`) changes the behavior to ignore any unknown fields.
103110

0 commit comments

Comments
 (0)