Crate ocaml[−][src]
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 |
|
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 |
|
custom | Create a custom OCaml type from an existing Rust type |
custom_finalize | Derives |
frame |
|
list | Convenience macro to create an OCaml list |
Structs
Array |
|
List |
|
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 |
Enums
CamlError | Errors that are translated directly into OCaml exceptions |
Error | Error returned by |
Traits
FromValue |
|
ToValue |
|
Type Definitions
Float | OCaml |
Int | Integer type that converts to OCaml |
Uint | Unsigned integer type that converts to OCaml |
Attribute Macros
bytecode_func |
|
func |
|
native_func |
|
Derive Macros
FromValue | |
ToValue |