Reputation: 430
I'm trying to model write the elasticsearch DSL in ocaml types. frequently, there are things that are well modeled by variants where the tag is a singleton key in an object. For instance on interval queries, we might have a match, a prefix, a wildcard, etc. The DSL represents these like this;
{"match": {...match params}}
{"wildcard": {...wildcard params}}
{"prefix": {...prefix params}}
Writing out the yojson_of_x
functions by hand seems like a huge amount of boilerplate, so I'd like to derive them, but ppx_yojson_conv says it represents variants like this;
["match", {...match_params}]
Is there a way to add some other annotation to get it to change its behavior? coming from rust world, serde calls this the "externally tagged" representation, but I don't know if it's possible to configure ppx_yojson_conv
in a similar way.
Upvotes: 2
Views: 224
Reputation: 18902
You cannot change the representation used by ppx_yojson_conv, but you can add a layer on top that does the conversion that you want:
let to_assoc: [> Yojson.Safe.t ] -> Yojson.Safe.t as 'a = function
| `List (`String key::l) -> `Assoc [key,`List l]
| x -> x
let to_list = function
| `Assoc [key,`List l] -> `List (`String key::l)
| x -> x
Then you can transform yojson
converters to your own with:
type t =
| A of int
| B of int
[@@deriving yojson]
let yojson_of_t x = to_assoc (yojson_of_t x)
let t_of_yojson x = t_of_yojson (to_list x)
Upvotes: 3