Пользовательский генератор json для варианта типа суммы с ppx_deriving_yojson

Я хотел бы создать объекты JSON, представляющие AST, и я смотрю на ppx_deriving_yojson для этого (точнее, to_yojsonчасть). Конечно, бывают случаи, когда я хотел бы прибегнуть к индивидуальной кодировке. Как упоминалось в документации, настроить представление поля записи очень просто:

type bar = { test: int;
             test1: int [@to_yojson fun i -> `String (string_of_int i)] }
[@@deriving to_yojson]

let j1 = bar_to_yojson { test = 0; test1 = 1 }

даст мне

val j1 : Yojson.Safe.t = `Assoc [("test", `Int 0); ("test1", `String "1")]

Но есть места, где я хотел бы иметь настраиваемое представление для варианта типа суммы, а to_yojson атрибут здесь не распознается:

type foo = Bar | Bla of string [@to_yojson fun s -> `String (s ^ "_suffix")]
[@@deriving to_yojson]

let j2 = foo_to_yojson (Bla "bla")

дает мне

val j2 : Yojson.Safe.t = `List [`String "Bla"; `String "bla"]

т.е. кодировка по умолчанию ppx_deriving_yojson. Что-то мне не хватает или просто невозможно достичь того, чего я хочу?

NB: результат получается с utop а также #require "ppx_deriving_yojson";; как первая команда

1 ответ

Я забыл о встроенных записях. Это будет примерно то, что я хочу:

type foo = Bar | Bla of { bla: string [@to_yojson fun s -> `String (s ^ "_suffix")]}
[@@deriving to_yojson]

let j2 = foo_to_yojson (Bla { bla = "bla"})

дает

val j2 : Yojson.Safe.t =
  `List [`String "Bla"; `Assoc [("bla", `String "bla_suffix")]]

Однако, хотя это решение работает для совершенно новой разработки, оно потребует значительных усилий по рефакторингу существующих типов. Таким образом, я все еще ищу менее навязчивое решение.

Другие вопросы по тегам