A PPX deriver that generates string conversion functions for variant and polymorphic variant types.
Provides four derivers:
Deriver | Style | Generated functions |
|---|---|---|
| Reason (camelCase) |
|
| Reason (camelCase) |
|
| OCaml (snake_case) |
|
| OCaml (snake_case) |
|
When the type name is t, the prefix is dropped: toString, fromString, fromStringExn, to_string, of_string, and of_string_exn.
type color =
| Red
| Green
| Blue
[@@deriving toString, fromString]
let () =
assert (colorToString Red = "Red");
assert (colorFromString "Green" = Some Green);
assert (colorFromString "purple" = None);
assert (colorFromStringExn "Blue" = Blue)type direction = [ `North | `South | `East | `West ]
[@@deriving toString, fromString]
let () =
assert (directionToString `North = "North");
assert (directionFromString "South" = Some `South)Polymorphic variant inheritance is supported when the inherited type has the same deriver:
type base =
[ `Foo [@name "foo"]
| `Bar [@name "bar"]
]
[@@deriving to_string, of_string]
type extended =
[ base
| `Baz [@name "baz"]
]
[@@deriving to_string, of_string]
let () =
assert (extended_to_string `Foo = "foo");
assert (extended_of_string "baz" = Some `Baz)Use [@as "..."] or [@name "..."] to control the string value used for a constructor:
type status =
| Active [@as "active"]
| Inactive [@name "inactive"]
| Pending
[@@deriving toString, fromString]
let () =
assert (statusToString Active = "active");
assert (statusToString Pending = "Pending");
assert (statusFromString "inactive" = Some Inactive);
assert (statusFromString "Active" = None)Both attributes behave identically. If both are present, [@as] takes precedence.
type my_type =
| Foo
| Bar [@as "bar"]
[@@deriving to_string, of_string]
let () =
assert (my_type_to_string Foo = "Foo");
assert (my_type_of_string "bar" = Some Bar);
assert (my_type_of_string_exn "bar" = Bar)Payload constructors are rejected by default because the deriver cannot infer a lossless string conversion for their arguments.
Use [@no_args] when only the constructor tag matters. The generated to_string/toString function ignores the payload, while of_string/fromString skips that constructor because it cannot reconstruct the payload.
type event =
| Started
| Unknown of string [@no_args]
[@@deriving to_string, of_string]
let () =
assert (event_to_string (Unknown "x") = "Unknown");
assert (event_of_string "Unknown" = None)Use [@no_string_exn] when stringifying the constructor should fail loudly:
type event =
| Started
| Unknown of string [@no_string_exn]
[@@deriving to_string, of_string]event_to_string (Unknown "x") raises Failure, and event_of_string skips Unknown.
For polymorphic variants only, [@no_string] also narrows the return type of of_string/fromString so the marked constructor is excluded from parser results:
type event =
[ `Started
| `Unknown of string [@no_string]
]
[@@deriving to_string, of_string]
let parsed : [ `Started ] option = event_of_string "Started"The derivers reject:
[@no_args], [@no_string_exn], or polymorphic-variant-only [@no_string]dune build
dune test