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 u8
s, 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. Binary
s 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.