如何更改 ppx_yojson_conv 表示变体的方式?

How can I change how ppx_yojson_conv represents variants?

我正在尝试在 ocaml 类型中模拟编写 elasticsearch DSL。通常,有些事物可以通过变体很好地建模,其中标签是对象中的单例键。例如在 interval queries 上,我们可能有一个 匹配 、一个 前缀 、一个 通配符 等等。DSL 是这样表示的;

{"match": {...match params}}
{"wildcard": {...wildcard params}}
{"prefix": {...prefix params}}

手写 yojson_of_x 函数似乎是大量的样板文件,所以我想推导它们,但是 ppx_yojson_conv 说它代表了这样的变体;

["match", {...match_params}]

有没有办法添加一些其他注释来改变它的行为?来自 rust world,serde 称其为“外部标记”表示,但我不知道是否可以以类似的方式配置 ppx_yojson_conv

您无法更改 ppx_yojson_conv 使用的表示,但您可以在顶部添加一个图层来执行您想要的转换:

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

然后您可以将 yojson 个转换器转换为您自己的转换器:

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)