A PPX deriver that generates string conversion functions for variant and polymorphic variant types.
Provides four derivers:
| Deriver | Style | Generated functions |
|---|---|---|
[@@deriving toString] |
Reason (camelCase) | typeNameToString : t -> string |
[@@deriving fromString] |
Reason (camelCase) | typeNameFromString : string -> t option, typeNameFromStringExn : string -> t |
[@@deriving to_string] |
OCaml (snake_case) | type_name_to_string : t -> string |
[@@deriving of_string] |
OCaml (snake_case) | type_name_of_string : string -> t option, type_name_of_string_exn : string -> t |
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:
- Records
- Abstract types without a polymorphic variant manifest
- Open types
- Payload constructors unless they use
[@no_args],[@no_string_exn], or polymorphic-variant-only[@no_string] - Non-type polymorphic variant inheritance
dune build
dune test