[][src]Macro ocaml_interop::ocaml_export

macro_rules! ocaml_export {
    {} => { ... };
    {
        fn $name:ident( $gc:ident $($nokeep:ident)?, $($args:tt)*) -> f64
           $body:block

        $($t:tt)*
    } => { ... };
    {
        fn $name:ident( $gc:ident $($nokeep:ident)?, $($args:tt)*) $(-> $rtyp:ty)?
           $body:block

        $($t:tt)*
    } => { ... };
}

Defines Rust functions callable from OCaml.

The first argument in these function declarations must be an identifier to which the OCaml frame GC handle will be bound. Optionally, it can be annotated with nokeep when local roots (registered with the keep method) are not needed.

Arguments and return values must be of type OCaml<T>, or f64 in the case of unboxed floats.

The return type defaults to unit when omitted.

The body of the function has an implicit ocaml_frame! wrapper, with the lifetimes of every OCaml<T> argument bound to the lifetime of the variable bound to the function's OCaml frame GC handle.

Examples

ocaml_export! {
    fn rust_twice(_gc nokeep, num: OCaml<OCamlInt>) -> OCaml<OCamlInt> {
        let num: i64 = num.into_rust();
        unsafe { OCaml::of_i64(num * 2) }
    }

    fn rust_twice_boxed_i32(gc, num: OCaml<OCamlInt32>) -> OCaml<OCamlInt32> {
        let num: i32 = num.into_rust();
        let result = num * 2;
        ocaml_alloc!(result.to_ocaml(gc))
    }

    fn rust_add_unboxed_floats_noalloc(_gc nokeep, num: f64, num2: f64) -> f64 {
        num * num2
    }

    fn rust_twice_boxed_float(gc, num: OCaml<f64>) -> OCaml<f64> {
        let num: f64 = num.into_rust();
        let result = num * 2.0;
        ocaml_alloc!(result.to_ocaml(gc))
    }

    fn rust_increment_ints_list(gc, ints: OCaml<OCamlList<OCamlInt>>) -> OCaml<OCamlList<OCamlInt>> {
        let mut vec: Vec<i64> = ints.into_rust();

        for i in 0..vec.len() {
            vec[i] += 1;
        }

        ocaml_alloc!(vec.to_ocaml(gc))
    }

    fn rust_make_tuple(gc, fst: OCaml<String>, snd: OCaml<OCamlInt>) -> OCaml<(String, OCamlInt)> {
        let fst: String = fst.into_rust();
        let snd: i64 = snd.into_rust();
        let tuple = (fst, snd);
        ocaml_alloc!(tuple.to_ocaml(gc))
    }
}