Macro ocaml_interop::ocaml_unpack_variant[][src]

macro_rules! ocaml_unpack_variant {
    ($self : ident =>
 {
     $($($tag : ident) :: +
       $(($($slot_name : ident : $slot_typ : ty), + $(,) ?)) ?
       $(=> $conv : expr) ?), + $(,) ?
 }) => { ... };
    ($self : ident =>
 {
     $($($tag : ident) :: +
       $({ $($slot_name : ident : $slot_typ : ty), + $(,) ? }) ?
       $(=> $conv : expr) ?), + $(,) ?
 }) => { ... };
}
Expand description

Unpacks an OCaml variant and maps it into a Rust enum.

This macro works on OCaml<'gc, T> values.

It is important that the order of the fields remains the same as in the OCaml type declaration.

Note

Unlike with ocaml_unpack_record!, the result of ocaml_unpack_variant! is a Result value. An error will be returned in the case of an unexpected tag value. This may change in the future.

Examples

enum Movement {
    StepLeft,
    StepRight,
    Rotate(f64),
}

// Assuming an OCaml type declaration like:
//
//      type movement =
//        | StepLeft
//        | StepRight
//        | Rotate of float
//
// NOTE: What is important is the order of the tags, not their names.

let ocaml_variant_root = make_ocaml_movement(cr, &OCaml::unit());
let ocaml_variant = cr.get(&ocaml_variant_root);
let result = ocaml_unpack_variant! {
    ocaml_variant => {
        // Alternative: StepLeft  => Movement::StepLeft
        //              <anyname> => <build-expr>
        Movement::StepLeft,
        Movement::StepRight,
        // Tag field names are mandatory
        Movement::Rotate(rotation: OCamlFloat),
    }
}.unwrap();
// ...