Expand description
§Part 2: Fundamental Concepts
A thorough understanding of these core types is essential for the effective utilization of [ocaml-interop].
§2.1 Representing OCaml Values within Rust
-
OCaml<'gc, T>: This type serves as the primary wrapper for an OCaml value within Rust code.'gc: Represents a lifetime parameter associated with an active OCaml runtime scope. This signifies that the OCaml Garbage Collector (GC) may relocate or deallocate the value if it is not “rooted.”T: Denotes the Rust type corresponding to the OCaml value (e.g.,OCamlInt,String,OCamlList<OCamlFloat>).- Instances of this type are generally ephemeral and should be regarded as potentially invalid subsequent to any invocation into the OCaml runtime, unless explicitly rooted.
-
BoxRoot<T>: A smart pointer that “roots” an OCaml value, thereby ensuring that the OCaml GC does not deallocate or move it while theBoxRoot<T>instance persists.- It adheres to the RAII (Resource Acquisition Is Initialization) principle: the OCaml value
is automatically unrooted when the
BoxRoot<T>instance is dropped. - This mechanism is crucial for safely retaining OCaml values across multiple operations or Rust scopes.
- Instances are created by:
- Calling
.to_boxroot(cr)on a Rust value (e.g.,rust_value.to_boxroot(cr)), which converts it to an OCaml value and roots it. - Calling
.root()on an existingOCaml<T>value (e.g.,ocaml_val.root()). - Using
BoxRoot::new(ocaml_val)with an existingOCaml<T>value. Note thatBoxRoot::new()will panic if the underlying boxroot allocation fails.
- Calling
BoxRoot<T>is!Sendand!Syncdue to its direct interaction with OCaml’s domain-specific GC state and memory management, meaning it cannot be safely transferred across threads or shared concurrently between threads.
- It adheres to the RAII (Resource Acquisition Is Initialization) principle: the OCaml value
is automatically unrooted when the
-
RawOCaml: An unsafe, raw pointer-sized type representing an OCaml value. Direct interaction with this type is infrequent, asOCaml<T>andBoxRoot<T>provide safe abstractions.
§2.2 Converting Data Between Rust and OCaml
The traits ToOCaml<T> and FromOCaml<T> are provided to facilitate data conversions.
-
- Implemented by Rust types that are convertible to OCaml values of
OCamlType. - Provides the method
.to_ocaml(cr: &mut OCamlRuntime)to create an OCaml value. - Provides the method
.to_boxroot(cr: &mut OCamlRuntime)to create a rooted OCaml value. - Example:
let ocaml_string: OCaml<String> = "hello".to_ocaml(cr);;
- Implemented by Rust types that are convertible to OCaml values of
-
- Implemented by Rust types that can be instantiated from OCaml values of
OCamlType. OCaml<T>provides.to_rust::<RustType>().BoxRoot<T>provides.to_rust::<RustType>(cr: &mut OCamlRuntime).- Example:
let rust_int: i64 = ocaml_int_value.to_rust();
- Implemented by Rust types that can be instantiated from OCaml values of
Common Type Mappings:
- Rust
i64corresponds to OCamlint(represented asOCamlInt). - Rust
f64corresponds to OCamlfloat(represented asOCamlFloat). - Rust
String/&strcorresponds to OCamlstring. - Rust
Vec<T>corresponds to OCamllistorarray(e.g.,OCamlList<T>,OCamlUniformArray<T>). - Rust
Option<T>corresponds to OCamloption. - Rust
Result<T, E>corresponds to OCamlresult(often withOCaml<String>for error types).