[][src]Crate ocaml

ocaml-rs is a library for directly interacting with the C OCaml runtime, in Rust.

The OCaml manual chapter Interfacing C with OCaml does a great job of explaining low-level details about how to safely interact with the OCaml runtime. This crate aims to be a slightly higher-level of abstraction, with minimal added overhead.

Getting started

Take a look at the ocaml-rust-starter project for a basic example to help get started with ocaml-rs.

Examples

// Automatically derive `ToValue` and `FromValue`
#[cfg(feature = "derive")]
#[derive(ocaml::ToValue, ocaml::FromValue)]
struct Example<'a> {
    name: &'a str,
    i: ocaml::Int,
}

#[cfg(feature = "derive")]
#[ocaml::func]
pub fn incr_example(mut e: Example<'static>) -> Example<'static> {
    e.i += 1;
    e
}

#[cfg(feature = "derive")]
#[ocaml::func]
pub fn build_tuple(i: ocaml::Int) -> (ocaml::Int, ocaml::Int, ocaml::Int) {
    (i + 1, i + 2, i + 3)
}

#[cfg(feature = "derive")]
#[ocaml::func]
pub fn average(arr: ocaml::Array<f64>) -> Result<f64, ocaml::Error> {
    let mut sum = 0f64;

    for i in 0..arr.len() {
        sum += arr.get_double(i)?;
    }

    Ok(sum / arr.len() as f64)
}

// A `native_func` must take `ocaml::Value` for every argument or `f64` for
// every unboxed argument and return an `ocaml::Value` (or `f64`).
// `native_func` has minimal overhead compared to wrapping with `func`
#[cfg(feature = "derive")]
#[ocaml::native_func]
pub fn incr(value: ocaml::Value) -> ocaml::Value {
    let i = value.int_val();
    ocaml::Value::int(i + 1)
}

// This is equivalent to:
#[no_mangle]
pub extern "C" fn incr2(value: ocaml::Value) -> ocaml::Value {
    ocaml::body!((value) {
        let i = value.int_val();
        ocaml::Value::int( i + 1)
    })
}

// `ocaml::native_func` is responsible for:
// - Ensures that #[no_mangle] and extern "C" are added, in addition to wrapping
// - Wraps the function body using `ocaml::body!`

// Finally, if your function is marked [@@unboxed] and [@@noalloc] in OCaml then you can avoid
// boxing altogether for f64 arguments using a plain C function and a bytecode function
// definition:
#[no_mangle]
pub extern "C" fn incrf(input: f64) -> f64 {
    input + 1.0
}

#[cfg(feature = "derive")]
#[ocaml::bytecode_func]
pub fn incrf_bytecode(input: f64) -> f64 {
    incrf(input)
}

The OCaml stubs would look like this:

type example = {
    name: string;
    i: int;
}

external incr_example: example -> example = "incr_example"
external build_tuple: int -> int * int * int = "build_tuple"
external average: float array -> float = "average"
external incr: int -> int = "incr"
external incr2: int -> int = "incr2"
external incrf: float -> float = "incrf_bytecode" "incrf" [@@unboxed] [@@noalloc]

Re-exports

pub use ocaml_sys as sys;
pub use crate::custom::Custom;
pub use crate::runtime::*;

Modules

bigarray

bigarray contains wrappers for OCaml Bigarray values. These types can be used to transfer arrays of numbers between Rust and OCaml directly without the allocation overhead of an array or list

custom

Custom types, used for allocating Rust values owned by the OCaml garbage collector

runtime

Functions for interacting with the OCaml runtime

Macros

array

Convenience macro to create an OCaml array

body

body! is needed to help the OCaml runtime to manage garbage collection, it should be used to wrap the body of each function exported to OCaml. Panics from Rust code will automatically be unwound/caught here (unless the no-std feature is enabled)

custom

Create a custom OCaml type from an existing Rust type

custom_finalize

Derives Custom with the given finalizer for a type

frame

frame! can be used to create new local variables that play nicely with the garbage collector

list

Convenience macro to create an OCaml list

Structs

Array

Array<A> wraps an OCaml 'a array without converting it to Rust

List

List<A> wraps an OCaml 'a list without converting it to Rust, this introduces no additional overhead compared to a Value type

Pointer

A handle to a Rust value/reference owned by the OCaml heap.

Tag

OCaml tags are used to provide type information to the garbage collector

Value

Value wraps the native OCaml value type transparently, this means it has the same representation as an ocaml_sys::Value

Enums

CamlError

Errors that are translated directly into OCaml exceptions

Error

Error returned by ocaml-rs functions

Traits

FromValue

FromValue is used to convert from OCaml values to Rust types

ToValue

ToValue is used to convert from Rust types to OCaml values

Functions

ocamlopt

Wraps sys::COMPILER as std::process::Command

Type Definitions

Float

OCaml float

Int

Integer type that converts to OCaml int

Uint

Unsigned integer type that converts to OCaml int

Attribute Macros

bytecode_func

bytecode_func is used export Rust functions to OCaml, performing the necessary wrapping/unwrapping automatically.

func

func is used export Rust functions to OCaml, performing the necessary wrapping/unwrapping automatically.

native_func

native_func is used export Rust functions to OCaml, it has much lower overhead than func and expects all arguments and return type to to be Value.

Derive Macros

FromValue
ToValue