Module rustler::types::binary[][src]

Expand description

Safe wrappers around Erlang binaries.

Rustler provides two binary types: Binary and OwnedBinary. Both represent a contiguous region u8s, and they both use the Erlang allocator. The primary difference between the two is their ownership semantics.

The owned in OwnedBinary refers to the fact that it owns the binary it wraps. The owner of an OwnedBinary is free to modify its contents. Ownership lasts until it is dropped or consumed by converting it into a regular Binary. An OwnedBinary cannot be copied or cloned and is thus always moved.

The Binary type is an immutable shared-reference to a binary. Binarys are cheap to copy: all copies of a Binary point to the original Binary’s data. Additionally, a Binary’s lifetime is tied to that of the NIF’s Env, preventing outstanding references to the data after a NIF returns.

Examples

Constructing an OwnedBinary:

{
    let mut bin = OwnedBinary::new(5).expect("allocation failed");
    bin.as_mut_slice().copy_from_slice("hello".as_bytes());
} // <- `bin` is dropped here

The following NIF takes a binary as its only parameter and returns a new binary where each element is exclusive-or’ed with a constant:

#[rustler::nif]
fn xor_example<'a>(env: Env<'a>, bin: Binary<'a>) -> NifResult<Binary<'a>> {
    let mut owned: OwnedBinary = bin.to_owned().ok_or(Error::Term(Box::new("no mem")))?;
    for byte in owned.as_mut_slice() {
        *byte ^= 0xAA;
    }

    // Ownership of `owned`'s data is transferred to `env` on the
    // following line, so no additional heap allocations are incurred.
    Ok(Binary::from_owned(owned, env))
}

The contents of a newly-allocated OwnedBinary is not initialized to any particular value. If your usage of the binary requires the it’s data to be zeroed, for example, then you must explicit zero it. In this example, we manually zeroize the binary before passing it as slice to a third party function.

#[rustler::nif]
fn wrapper_for_some_<'a>(env: Env<'a>) -> NifResult<Binary<'a>> {
    let mut owned = OwnedBinary::new(100).ok_or(Error::Term(Box::new("no mem")))?;
    for byte in owned.as_mut_slice() {
        *byte = 0;
    }

    // Some third party API which requires the slice to be all zeros on entry.
    some_third_party_api(owned.as_mut_slice());

    // The imaginary API call presumedly filled in our binary with meaningful
    // data, so let's return it.
    Ok(Binary::from_owned(owned, env))
}

Structs

An immutable smart-pointer to an Erlang binary.

An mutable smart-pointer to an Erlang binary.