package ppx_deriving_yaml
Install
Dune Dependency
Authors
Maintainers
Sources
sha256=9d1df9ebc50b33a8da186e07e3e94b053109aa1fc02c73e2271bdee348cf531c
sha512=fdc7685628258b312471742bc626b78f7ac21fe9104d95af8ebae361db5cfc2956ba6865167a44c666eee2bf3d3d5c81c75cb4b59d576d9b5e7c04d2aac4634f
Description
Build Yaml types from OCaml types
Published: 01 Mar 2022
README
Ppx_deriving_yaml -- OCaml types to YAML types
This ppx is based on ppx_yojson and ppx_deriving_yojson because of the many similarities between json and yaml. In particular many of the semantics of OCaml types <-> Yaml types are the same as those implemented by the Yojson ppx.
This is a small ppx deriver that lets you convert your OCaml types to yaml ones. This means you can describe yaml structures in OCaml and easily convert them to yaml.
Usage
The usage docs are linked to what has been implemented from the checklist
For converting OCaml types to Yaml types ppx_deriving_yaml
will do the conventional dropping of the type name if it is t
. Otherwise the type name is the prefix to the to_yaml
function.
to_yaml
produces a Yaml.value
which is compatible with the Ezjsonm.value
type.
of_yaml
produces OCaml types wrapped in a result
-- this is how ocaml-yaml also handles errors i.e. not using exceptions. Based on your type this should let you move between yaml and OCaml types.
Here is a small example.
type person = { name : string; age : int } [@@deriving yaml]
type users = person list [@@deriving yaml]
This will produce four functions.
val person_to_yaml : person -> Yaml.value
val person_of_yaml : Yaml.value -> (person, [> `Msg of string ]) result
val users_to_yaml : users -> Yaml.value
val users_of_yaml : Yaml.value -> (users, [> `Msg of string ]) result
If you make polymorphic types, then you will have to supply the function to convert the unknown to a yaml value. For example:
type 'a note = { txt : 'a } [@@deriving yaml]
produces the following function.
val note_to_yaml : ('a -> Yaml.value) -> 'a note -> [> `O of (string * Yaml.value) list ]
Implementation Details
One important thing is that 'a option
values within records will return None
if the Yaml you are trying to convert does not exist.
OCaml Type | Yaml Type |
---|---|
int |
`Float |
float |
`Float |
string |
`String |
bool |
`Bool |
None |
`Null |
list |
`A [] |
array |
`A [] |
record e.g { name : string } |
`O [("name", `String s)] |
A of int or [`A of int] |
`O [("A", `A [`Float f])] |
Optional Attributes
OCaml has constraints on the shape that certain words in the syntax can take. For example, record field names cannot begin with a capital letter and variant constructors must start with one. This limits what the generated yaml can look like. To override the yaml names you can use the [@key <string>]
and [@name <string>]
attributes for records and variants respectively.
For example:
type t = {
camel_name : string [@key "camel-name"]
}
Will produce Yaml of the form
camel-name: <string>
Checklist
[x] Simples types (
int, list, records...
) toYaml.value
types[x]
Yaml.value
interface types[x]
Yaml.value
types to OCaml types i.e.of_yaml
[x] More complex types (parametric polymorphic ones) to any of the Yaml types
[x] Design and implement how variants should be handled
[x] Better interface support i.e.
.mli
files[ ] Simple types (
int, list, records...
) toYaml.yaml
types