Struct zerovec::VarZeroVec[][src]

pub struct VarZeroVec<'a, T>(_);

A zero-copy vector for variable-width types.

VarZeroVec<T> is designed as a drop-in replacement for Vec<T> in situations where it is desirable to borrow data from an unaligned byte slice, such as zero-copy deserialization, and where T’s data is variable-length (e.g. String)

T must implement AsVarULE, which is already implemented for String. References are obtained as its AsVarULE::VarULE type, which in the case of String is str.

VarZeroVec<T> behaves much like std::borrow::Cow, where it can be constructed from owned data but can also borrow from some buffer.

How it Works

VarZeroVec<T>, when used with non-human-readable serializers (like bincode), will serialize to a specially formatted list of bytes. The format is:

  • 4 bytes for length (interpreted as a little-endian u32)
  • 4 * length bytes of indices (interpreted as little-endian u32)
  • Remaining bytes for actual data

Each element in the indices array points to the starting index of its corresponding data part in the data list. The ending index can be calculated from the starting index of the next element (or the length of the slice if dealing with the last element).

Safety

VarZeroVec<T> is implemented with a fair amount of unsafe code, but is externally safe to use.

Example

use zerovec::VarZeroVec;

// The little-endian bytes correspond to the list of strings.
let strings = vec!["w".to_owned(), "ω".to_owned(), "文".to_owned(), "𑄃".to_owned()];
let bytes = &[
    4, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,  3, 0, 0, 0,
    6, 0, 0, 0, 119, 207, 137, 230, 150, 135, 240, 145, 132, 131,
];

let zerovec: VarZeroVec<String> = VarZeroVec::try_from_bytes(bytes)?;

assert_eq!(zerovec.get(2), Some("文"));
assert_eq!(zerovec, &*strings);

Implementations

impl<'a, T: AsVarULE> VarZeroVec<'a, T>[src]

pub fn len(&self) -> usize[src]

Get the number of elements in this vector

Example


let strings = vec!["foo".to_owned(), "bar".to_owned(),
                   "baz".to_owned(), "quux".to_owned()];
let bytes = VarZeroVec::get_serializable_bytes(&strings).unwrap();

let mut vec: VarZeroVec<String> = VarZeroVec::try_from_bytes(&bytes)?;
assert_eq!(vec.len(), 4);

pub fn try_from_bytes(
    slice: &'a [u8]
) -> Result<Self, VarZeroVecError<<<T as AsVarULE>::VarULE as VarULE>::Error>>
[src]

Parse a VarZeroVec from a slice of the appropriate format

Slices of the right format can be obtained via VarZeroVec::get_serializable_bytes()

Example


let strings = vec!["foo".to_owned(), "bar".to_owned(),
                   "baz".to_owned(), "quux".to_owned()];
let bytes = VarZeroVec::get_serializable_bytes(&strings).unwrap();

let mut vec: VarZeroVec<String> = VarZeroVec::try_from_bytes(&bytes)?;
assert_eq!(&vec[0], "foo");
assert_eq!(&vec[1], "bar");
assert_eq!(&vec[2], "baz");
assert_eq!(&vec[3], "quux");

pub fn iter<'b: 'a>(&'b self) -> impl Iterator<Item = &'b T::VarULE>[src]

Obtain an iterator over VarZeroVec’s elements

Example


let strings = vec!["foo".to_owned(), "bar".to_owned(),
                   "baz".to_owned(), "quux".to_owned()];
let bytes = VarZeroVec::get_serializable_bytes(&strings).unwrap();
let mut vec: VarZeroVec<String> = VarZeroVec::try_from_bytes(&bytes)?;

let mut iter_results: Vec<&str> = vec.iter().collect();
assert_eq!(iter_results[0], "foo");
assert_eq!(iter_results[1], "bar");
assert_eq!(iter_results[2], "baz");
assert_eq!(iter_results[3], "quux");

pub fn get<'b>(&'b self, idx: usize) -> Option<&'b T::VarULE>[src]

Get one of VarZeroVec’s elements, returning None if the index is out of bounds

Example


let strings = vec!["foo".to_owned(), "bar".to_owned(),
                   "baz".to_owned(), "quux".to_owned()];
let bytes = VarZeroVec::get_serializable_bytes(&strings).unwrap();
let mut vec: VarZeroVec<String> = VarZeroVec::try_from_bytes(&bytes)?;

let mut iter_results: Vec<&str> = vec.iter().collect();
assert_eq!(vec.get(0), Some("foo"));
assert_eq!(vec.get(1), Some("bar"));
assert_eq!(vec.get(2), Some("baz"));
assert_eq!(vec.get(3), Some("quux"));
assert_eq!(vec.get(4), None);

pub fn make_mut(&mut self) -> &mut Vec<T> where
    T: Clone
[src]

Convert this into a mutable vector of the owned T type, cloning if necessary.

Example


let strings = vec!["foo".to_owned(), "bar".to_owned(),
                   "baz".to_owned(), "quux".to_owned()];
let bytes = VarZeroVec::get_serializable_bytes(&strings).unwrap();
let mut vec: VarZeroVec<String> = VarZeroVec::try_from_bytes(&bytes)?;

assert_eq!(vec.len(), 4);
let mutvec = vec.make_mut();
mutvec.push("lorem ipsum".into());
mutvec[2] = "dolor sit".into();
assert_eq!(&vec[0], "foo");
assert_eq!(&vec[1], "bar");
assert_eq!(&vec[2], "dolor sit");
assert_eq!(&vec[3], "quux");
assert_eq!(&vec[4], "lorem ipsum");

pub fn to_owned(&self) -> Vec<T> where
    T: Clone
[src]

Obtain an owned Vec<T> out of this

pub fn get_serializable_bytes(elements: &[T]) -> Option<Vec<u8>>[src]

For a slice of T, get a list of bytes that can be passed to try_from_bytes to recoup the same data.

Returns None if the slice is too large to be represented in a list of bytes whose length fits in a u32.

Example


let strings = vec!["foo".to_owned(), "bar".to_owned(), "baz".to_owned()];
let bytes = VarZeroVec::get_serializable_bytes(&strings).unwrap();

let mut borrowed: VarZeroVec<String> = VarZeroVec::try_from_bytes(&bytes)?;
assert_eq!(borrowed.to_owned(), strings);

impl<'a, T> VarZeroVec<'a, T> where
    T: AsVarULE,
    T::VarULE: Ord
[src]

Binary searches a sorted VarZeroVec<T> for the given element. For more information, see the primitive function binary_search.

Example


let strings = vec!["a".to_owned(), "b".to_owned(),
                   "f".to_owned(), "g".to_owned()];
let bytes = VarZeroVec::get_serializable_bytes(&strings).unwrap();
let mut vec: VarZeroVec<String> = VarZeroVec::try_from_bytes(&bytes)?;

assert_eq!(vec.binary_search("f"), Ok(2));
assert_eq!(vec.binary_search("e"), Err(2));

Trait Implementations

impl<'a, T: Clone> Clone for VarZeroVec<'a, T>[src]

impl<T: AsVarULE> Debug for VarZeroVec<'_, T> where
    T::VarULE: Debug
[src]

impl<'a, T> From<Vec<T, Global>> for VarZeroVec<'a, T>[src]

impl<'a, T: AsVarULE> Index<usize> for VarZeroVec<'a, T>[src]

type Output = T::VarULE

The returned type after indexing.

impl<T> PartialEq<&'_ [T]> for VarZeroVec<'_, T> where
    T: AsVarULE,
    T::VarULE: PartialEq
[src]

impl<'a, 'b, T> PartialEq<VarZeroVec<'b, T>> for VarZeroVec<'a, T> where
    T: AsVarULE,
    T::VarULE: PartialEq
[src]

Auto Trait Implementations

impl<'a, T> RefUnwindSafe for VarZeroVec<'a, T> where
    T: RefUnwindSafe

impl<'a, T> Send for VarZeroVec<'a, T> where
    T: Send + Sync

impl<'a, T> Sync for VarZeroVec<'a, T> where
    T: Sync

impl<'a, T> Unpin for VarZeroVec<'a, T> where
    T: Unpin

impl<'a, T> UnwindSafe for VarZeroVec<'a, T> where
    T: RefUnwindSafe + UnwindSafe

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.