PPX deriver for dune's Dyn.t converters
ppx_deriving_dyn derives basic Dyn.t converters from type definitions.
Attach the [@@deriving dyn] attribute to your type definitions to generate
the corresponding to_dyn function.
It can be used to derive both the function and its signature depending on the context.
For example you can use it in your .ml files like this:
type t = int
[@@deriving dyn]to generate the following:
let to_dyn = Dyn.intor in your .mli files:
type t
[@@deriving dyn]to generate the following:
val to_dyn : t Dyn.builderppx_deriving_dyn follows the following rules:
- The converter is named
to_dynfor types namedtand<type name>_to_dynfor any other type name. - It uses the builders provided by
Dynfor the following base types:unitcharstringintint32int64nativeintfloatboollistarrayoption
- Tuple types are converted using an inline
(fun (x0, x1, x2, x3) -> Dyn.Tuple [...]) - It uses
Dyn.recordfor record types - It uses
Dyn.variantfor variant and polymorphic variant types. Inline record arguments are converted usingDyn.recordas well. - An
'a Dyn.builderextra argument is expected for each type parameter, following the declaration order, e.g. for atype ('a, 'b) tit will generateval to_dyn : 'a Dyn.builder -> 'b Dyn.builder -> ('a, 'b) t Dyn.builder
ppx_deriving_dyn allows you to override the default behaviour using the
following attributes.
It can be used as [@to_dyn ...] or [@ppx_deriving_dyn.to_dyn ...] and allows
you to define how a specific part of a type should be converted to a Dyn.t
value by attaching this attribute to it and passing the function to use in the
payload.
Here are some examples on how to use it:
type t = float [@to_dyn special_float_to_dyn]
[@@deriving dyn]type t = int * string * (bool [@to_dyn fun b -> Dyn.string (string_of_bool b)])
[@@deriving dyn]type t =
{ a : int
; b : string option
[@to_dyn
function
| Some s -> Dyn.string s
| None -> Dyn.string "null"]
}
[@@deriving dyn]The attribute can be attached to a core type or record field and accepts function identifier, partial function applications and anonymous functions as payload.
It can be used as [@ignore], [@to_dyn.ignore] or
[@ppx_deriving_dyn.to_dyn.ignore] and allows you to exclude part of a tuple,
record or variant arguments from the output of derived to_dyn function.
For example, with the following type definition:
type t = int * (string[@ignore]) * bool
[@@deriving dyn]The generated dyn converter will ignore the string element of the tuple and
return a Dyn.t value describing an int * bool pair. To clarify this a bit,
the generated code will look roughly like this:
let to_dyn (x0, _, x2) = Dyn.Tuple [Dyn.int x0; Dyn.bool x2]It can also be used to similarly ignore fields of a record:
type t =
{ field_a : int
; field_b : string [@ignore]
; field_c : bool
}
[@@deriving dyn]which will produce the following dyn converter:
let to_dyn {field_a; field_b = _; field_c} =
Dyn.record
[("field_a", (Dyn.int field_a)); ("field_c", (Dyn.bool field_c))]Finally, you can use it on sum type constructor or polymorphic variant's arguments:
type t =
| A of int * (string [@ignore])
[@@deriving dyn]which will produce the following dyn converter:
let to_dyn = function
| A (x0, _) -> Dyn.variant "A" [Dyn.int x0]Note that you cannot ignore all elements of a tuple or all fields of a record
but you can ignore all arguments of a constructor, in which case the to_dyn
function will treat it as if it had no argument, e.g.:
type t =
| A of (int[@ignore])
[@@deriving dyn]will derive:
let to_dyn = function
| A _ -> Dyn.variant "A" []It is also worth noting that if you ignore all elements of a tuple but one, the dyn converter will treat it as it was just that type and not as a tuple anymore, e.g.:
type t = int * (string [@ignore])
[@@deriving dyn]will derive:
let to_dyn (x0, _) = Dyn.int x0This attribute can be used only in very specific places so it's easy to misuse
it if you forget to add the right brackets. If you're having trouble with it, we
recommend you add -check to your dune file's (pps ...) field. This will
enable some ppxlib driver's check including one reporting unused attributes.
It should help you debug issues with [@ignore] as a misplaced one is likely
not to be consumed by ppx_deriving_dyn and therefore reported as such by the
driver when building your project.