zerovec

Struct VarZeroSlice

Source
pub struct VarZeroSlice<T: ?Sized, F = Index16> { /* private fields */ }
Expand description

A zero-copy “slice”, that works for unsized types, i.e. the zero-copy version of [T] where T is not Sized.

This behaves similarly to VarZeroVec<T>, however VarZeroVec<T> is allowed to contain owned data and as such is ideal for deserialization since most human readable serialization formats cannot unconditionally deserialize zero-copy.

This type can be used inside VarZeroVec<T> and ZeroMap: This essentially allows for the construction of zero-copy types isomorphic to Vec<Vec<T>> by instead using VarZeroVec<ZeroSlice<T>>.

The F type parameter is a VarZeroVecFormat (see its docs for more details), which can be used to select the precise format of the backing buffer with various size and performance tradeoffs. It defaults to Index16.

This type can be nested within itself to allow for multi-level nested Vecs.

§Examples

§Nested Slices

The following code constructs the conceptual zero-copy equivalent of Vec<Vec<Vec<str>>>

use zerovec::{VarZeroSlice, VarZeroVec};
let strings_1: Vec<&str> = vec!["foo", "bar", "baz"];
let strings_2: Vec<&str> = vec!["twelve", "seventeen", "forty two"];
let strings_3: Vec<&str> = vec!["我", "喜歡", "烏龍茶"];
let strings_4: Vec<&str> = vec!["w", "ω", "文", "𑄃"];
let strings_12 = vec![&*strings_1, &*strings_2];
let strings_34 = vec![&*strings_3, &*strings_4];
let all_strings = vec![strings_12, strings_34];

let vzv_1: VarZeroVec<str> = VarZeroVec::from(&strings_1);
let vzv_2: VarZeroVec<str> = VarZeroVec::from(&strings_2);
let vzv_3: VarZeroVec<str> = VarZeroVec::from(&strings_3);
let vzv_4: VarZeroVec<str> = VarZeroVec::from(&strings_4);
let vzv_12 = VarZeroVec::from(&[vzv_1.as_slice(), vzv_2.as_slice()]);
let vzv_34 = VarZeroVec::from(&[vzv_3.as_slice(), vzv_4.as_slice()]);
let vzv_all = VarZeroVec::from(&[vzv_12.as_slice(), vzv_34.as_slice()]);

let reconstructed: Vec<Vec<Vec<String>>> = vzv_all
    .iter()
    .map(|v: &VarZeroSlice<VarZeroSlice<str>>| {
        v.iter()
            .map(|x: &VarZeroSlice<_>| {
                x.as_varzerovec()
                    .iter()
                    .map(|s| s.to_owned())
                    .collect::<Vec<String>>()
            })
            .collect::<Vec<_>>()
    })
    .collect::<Vec<_>>();
assert_eq!(reconstructed, all_strings);

let bytes = vzv_all.as_bytes();
let vzv_from_bytes: VarZeroVec<VarZeroSlice<VarZeroSlice<str>>> =
    VarZeroVec::parse_byte_slice(bytes).unwrap();
assert_eq!(vzv_from_bytes, vzv_all);

§Iterate over Windows

Although VarZeroSlice does not itself have a .windows iterator like core::slice::Windows, this behavior can be easily modeled using an iterator:

use zerovec::VarZeroVec;

let vzv = VarZeroVec::<str>::from(&["a", "b", "c", "d"]);

let mut it = vzv.iter().peekable();
while let (Some(x), Some(y)) = (it.next(), it.peek()) {
    // Evaluate (x, y) here.
}

Implementations§

Source§

impl<T: VarULE + ?Sized, F: VarZeroVecFormat> VarZeroSlice<T, F>

Source

pub const fn new_empty() -> &'static Self

Construct a new empty VarZeroSlice

Source

pub const unsafe fn from_bytes_unchecked(bytes: &[u8]) -> &Self

Uses a &[u8] buffer as a VarZeroSlice<T> without any verification.

§Safety

bytes need to be an output from VarZeroSlice::as_bytes().

Source

pub fn len(&self) -> usize

Get the number of elements in this slice

§Example

let strings = vec!["foo", "bar", "baz", "quux"];
let vec = VarZeroVec::<str>::from(&strings);

assert_eq!(vec.len(), 4);
Source

pub fn is_empty(&self) -> bool

Returns true if the slice contains no elements.

§Examples

let strings: Vec<String> = vec![];
let vec = VarZeroVec::<str>::from(&strings);

assert!(vec.is_empty());
Source

pub fn iter<'b>(&'b self) -> impl Iterator<Item = &'b T>

Obtain an iterator over this slice’s elements

§Example

let strings = vec!["foo", "bar", "baz", "quux"];
let vec = VarZeroVec::<str>::from(&strings);

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");
Source

pub fn get(&self, idx: usize) -> Option<&T>

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

§Example

let strings = vec!["foo", "bar", "baz", "quux"];
let vec = VarZeroVec::<str>::from(&strings);

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);
Source

pub unsafe fn get_unchecked(&self, idx: usize) -> &T

Get one of this slice’s elements

§Safety

index must be in range

§Example

let strings = vec!["foo", "bar", "baz", "quux"];
let vec = VarZeroVec::<str>::from(&strings);

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

pub fn to_vec(&self) -> Vec<Box<T>>

Obtain an owned Vec<Box<T>> out of this

Source

pub const fn as_bytes(&self) -> &[u8]

Get a reference to the entire encoded backing buffer of this slice

The bytes can be passed back to Self::parse_byte_slice().

To take the bytes as a vector, see VarZeroVec::into_bytes().

§Example

let strings = vec!["foo", "bar", "baz"];
let vzv = VarZeroVec::<str>::from(&strings);

assert_eq!(vzv, VarZeroVec::parse_byte_slice(vzv.as_bytes()).unwrap());
Source

pub const fn as_varzerovec<'a>(&'a self) -> VarZeroVec<'a, T, F>

Get this VarZeroSlice as a borrowed VarZeroVec

If you wish to repeatedly call methods on this VarZeroSlice, it is more efficient to perform this conversion first

Source

pub fn parse_byte_slice<'a>(slice: &'a [u8]) -> Result<&'a Self, ZeroVecError>

Parse a VarZeroSlice from a slice of the appropriate format

Slices of the right format can be obtained via VarZeroSlice::as_bytes()

Source§

impl<T, F> VarZeroSlice<T, F>
where T: VarULE + ?Sized + Ord, F: VarZeroVecFormat,

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

§Example

let strings = vec!["a", "b", "f", "g"];
let vec = VarZeroVec::<str>::from(&strings);

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

pub fn binary_search_in_range( &self, x: &T, range: Range<usize>, ) -> Option<Result<usize, usize>>

Binary searches a VarZeroVec<T> for the given element within a certain sorted range.

If the range is out of bounds, returns None. Otherwise, returns a Result according to the behavior of the standard library function binary_search.

The index is returned relative to the start of the range.

§Example

let strings = vec!["a", "b", "f", "g", "m", "n", "q"];
let vec = VarZeroVec::<str>::from(&strings);

// Same behavior as binary_search when the range covers the whole slice:
assert_eq!(vec.binary_search_in_range("g", 0..7), Some(Ok(3)));
assert_eq!(vec.binary_search_in_range("h", 0..7), Some(Err(4)));

// Will not look outside of the range:
assert_eq!(vec.binary_search_in_range("g", 0..1), Some(Err(1)));
assert_eq!(vec.binary_search_in_range("g", 6..7), Some(Err(0)));

// Will return indices relative to the start of the range:
assert_eq!(vec.binary_search_in_range("g", 1..6), Some(Ok(2)));
assert_eq!(vec.binary_search_in_range("h", 1..6), Some(Err(3)));

// Will return `None` if the range is out of bounds:
assert_eq!(vec.binary_search_in_range("x", 100..200), None);
assert_eq!(vec.binary_search_in_range("x", 0..200), None);
Source§

impl<T, F> VarZeroSlice<T, F>
where T: VarULE + ?Sized, F: VarZeroVecFormat,

Source

pub fn binary_search_by( &self, predicate: impl FnMut(&T) -> Ordering, ) -> Result<usize, usize>

Binary searches a sorted VarZeroVec<T> for the given predicate. For more information, see the standard library function binary_search_by.

§Example

let strings = vec!["a", "b", "f", "g"];
let vec = VarZeroVec::<str>::from(&strings);

assert_eq!(vec.binary_search_by(|probe| probe.cmp("f")), Ok(2));
assert_eq!(vec.binary_search_by(|probe| probe.cmp("e")), Err(2));
Source

pub fn binary_search_in_range_by( &self, predicate: impl FnMut(&T) -> Ordering, range: Range<usize>, ) -> Option<Result<usize, usize>>

Binary searches a VarZeroVec<T> for the given predicate within a certain sorted range.

If the range is out of bounds, returns None. Otherwise, returns a Result according to the behavior of the standard library function binary_search.

The index is returned relative to the start of the range.

§Example

let strings = vec!["a", "b", "f", "g", "m", "n", "q"];
let vec = VarZeroVec::<str>::from(&strings);

// Same behavior as binary_search when the range covers the whole slice:
assert_eq!(
    vec.binary_search_in_range_by(|v| v.cmp("g"), 0..7),
    Some(Ok(3))
);
assert_eq!(
    vec.binary_search_in_range_by(|v| v.cmp("h"), 0..7),
    Some(Err(4))
);

// Will not look outside of the range:
assert_eq!(
    vec.binary_search_in_range_by(|v| v.cmp("g"), 0..1),
    Some(Err(1))
);
assert_eq!(
    vec.binary_search_in_range_by(|v| v.cmp("g"), 6..7),
    Some(Err(0))
);

// Will return indices relative to the start of the range:
assert_eq!(
    vec.binary_search_in_range_by(|v| v.cmp("g"), 1..6),
    Some(Ok(2))
);
assert_eq!(
    vec.binary_search_in_range_by(|v| v.cmp("h"), 1..6),
    Some(Err(3))
);

// Will return `None` if the range is out of bounds:
assert_eq!(
    vec.binary_search_in_range_by(|v| v.cmp("x"), 100..200),
    None
);
assert_eq!(vec.binary_search_in_range_by(|v| v.cmp("x"), 0..200), None);

Trait Implementations§

Source§

impl<T: ?Sized, F: VarZeroVecFormat> AsRef<VarZeroSlice<T, F>> for VarZeroSlice<T, F>

Source§

fn as_ref(&self) -> &VarZeroSlice<T, F>

Converts this type into a shared reference of the (usually inferred) input type.
Source§

impl<T, F: VarZeroVecFormat> Debug for VarZeroSlice<T, F>
where T: Debug + VarULE + ?Sized,

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<T, E, F> EncodeAsVarULE<VarZeroSlice<T, F>> for &[E]

Source§

fn encode_var_ule_as_slices<R>(&self, _: impl FnOnce(&[&[u8]]) -> R) -> R

Calls cb with a piecewise list of byte slices that when concatenated produce the memory pattern of the corresponding instance of T. Read more
Source§

fn encode_var_ule_len(&self) -> usize

Return the length, in bytes, of the corresponding VarULE type
Source§

fn encode_var_ule_write(&self, dst: &mut [u8])

Write the corresponding VarULE type to the dst buffer. dst should be the size of Self::encode_var_ule_len()
Source§

impl<T, F> EncodeAsVarULE<VarZeroSlice<T, F>> for VarZeroVec<'_, T, F>
where T: VarULE + ?Sized, F: VarZeroVecFormat,

Source§

fn encode_var_ule_as_slices<R>(&self, _: impl FnOnce(&[&[u8]]) -> R) -> R

Calls cb with a piecewise list of byte slices that when concatenated produce the memory pattern of the corresponding instance of T. Read more
Source§

fn encode_var_ule_len(&self) -> usize

Return the length, in bytes, of the corresponding VarULE type
Source§

fn encode_var_ule_write(&self, dst: &mut [u8])

Write the corresponding VarULE type to the dst buffer. dst should be the size of Self::encode_var_ule_len()
Source§

impl<T, E, F> EncodeAsVarULE<VarZeroSlice<T, F>> for Vec<E>

Source§

fn encode_var_ule_as_slices<R>(&self, _: impl FnOnce(&[&[u8]]) -> R) -> R

Calls cb with a piecewise list of byte slices that when concatenated produce the memory pattern of the corresponding instance of T. Read more
Source§

fn encode_var_ule_len(&self) -> usize

Return the length, in bytes, of the corresponding VarULE type
Source§

fn encode_var_ule_write(&self, dst: &mut [u8])

Write the corresponding VarULE type to the dst buffer. dst should be the size of Self::encode_var_ule_len()
Source§

impl<'a, T: ?Sized, F> From<&'a VarZeroSlice<T, F>> for VarZeroVec<'a, T, F>

Source§

fn from(other: &'a VarZeroSlice<T, F>) -> Self

Converts to this type from the input type.
Source§

impl<'a, T: ?Sized + VarULE, F: VarZeroVecFormat> From<&'a VarZeroSlice<T, F>> for VarZeroVecOwned<T, F>

Source§

fn from(other: &'a VarZeroSlice<T, F>) -> Self

Converts to this type from the input type.
Source§

impl<T: VarULE + ?Sized, F: VarZeroVecFormat> Index<usize> for VarZeroSlice<T, F>

Source§

type Output = T

The returned type after indexing.
Source§

fn index(&self, index: usize) -> &Self::Output

Performs the indexing (container[index]) operation. Read more
Source§

impl<T: VarULE + ?Sized + Ord, F: VarZeroVecFormat> Ord for VarZeroSlice<T, F>

Source§

fn cmp(&self, other: &Self) -> Ordering

This method returns an Ordering between self and other. Read more
Source§

impl<T, F> PartialEq for VarZeroSlice<T, F>

Source§

fn eq(&self, other: &VarZeroSlice<T, F>) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl<T: VarULE + ?Sized + PartialOrd, F: VarZeroVecFormat> PartialOrd for VarZeroSlice<T, F>

Source§

fn partial_cmp(&self, other: &Self) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · Source§

fn lt(&self, other: &Rhs) -> bool

Tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · Source§

fn le(&self, other: &Rhs) -> bool

Tests less than or equal to (for self and other) and is used by the <= operator. Read more
1.0.0 · Source§

fn gt(&self, other: &Rhs) -> bool

Tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · Source§

fn ge(&self, other: &Rhs) -> bool

Tests greater than or equal to (for self and other) and is used by the >= operator. Read more
Source§

impl<T: VarULE + ?Sized + 'static, F: VarZeroVecFormat> VarULE for VarZeroSlice<T, F>

Source§

fn validate_byte_slice(bytes: &[u8]) -> Result<(), ZeroVecError>

Validates a byte slice, &[u8]. Read more
Source§

unsafe fn from_byte_slice_unchecked(bytes: &[u8]) -> &Self

Takes a byte slice, &[u8], and return it as &Self with the same lifetime, assuming that this byte slice has previously been run through Self::parse_byte_slice() with success. Read more
Source§

fn as_byte_slice(&self) -> &[u8]

Given &Self, returns a &[u8] with the same lifetime. Read more
Source§

fn parse_byte_slice(bytes: &[u8]) -> Result<&Self, ZeroVecError>

Parses a byte slice, &[u8], and return it as &Self with the same lifetime. Read more
Source§

fn to_boxed(&self) -> Box<Self>

Allocate on the heap as a Box<T>
Source§

impl<'zf, T> ZeroFrom<'zf, VarZeroSlice<T>> for &'zf VarZeroSlice<T>
where T: 'static + VarULE + ?Sized,

Source§

fn zero_from(other: &'zf VarZeroSlice<T>) -> Self

Clone the other C into a struct that may retain references into C.
Source§

impl<'zf, T> ZeroFrom<'zf, VarZeroSlice<T>> for VarZeroVec<'zf, T>
where T: 'static + VarULE + ?Sized,

Source§

fn zero_from(other: &'zf VarZeroSlice<T>) -> Self

Clone the other C into a struct that may retain references into C.
Source§

impl<T, F> ZeroVecLike<T> for VarZeroSlice<T, F>
where T: VarULE + ?Sized, F: VarZeroVecFormat,

Source§

type GetType = T

The type returned by Self::get()
Source§

type SliceVariant = VarZeroSlice<T, F>

A fully borrowed version of this
Source§

fn zvl_new_borrowed() -> &'static Self::SliceVariant

Create a new, empty borrowed variant
Search for a key in a sorted vector, returns Ok(index) if found, returns Err(insert_index) if not found, where insert_index is the index where it should be inserted to maintain sort order.
Source§

fn zvl_binary_search_in_range( &self, k: &T, range: Range<usize>, ) -> Option<Result<usize, usize>>
where T: Ord,

Search for a key within a certain range in a sorted vector. Returns None if the range is out of bounds, and Ok or Err in the same way as zvl_binary_search. Indices are returned relative to the start of the range.
Source§

fn zvl_binary_search_by( &self, predicate: impl FnMut(&T) -> Ordering, ) -> Result<usize, usize>

Search for a key in a sorted vector by a predicate, returns Ok(index) if found, returns Err(insert_index) if not found, where insert_index is the index where it should be inserted to maintain sort order.
Source§

fn zvl_binary_search_in_range_by( &self, predicate: impl FnMut(&T) -> Ordering, range: Range<usize>, ) -> Option<Result<usize, usize>>

Search for a key within a certain range in a sorted vector by a predicate. Returns None if the range is out of bounds, and Ok or Err in the same way as zvl_binary_search. Indices are returned relative to the start of the range.
Source§

fn zvl_get(&self, index: usize) -> Option<&T>

Get element at index
Source§

fn zvl_len(&self) -> usize

The length of this vector
Source§

fn zvl_as_borrowed(&self) -> &VarZeroSlice<T, F>

Construct a borrowed variant by borrowing from &self. Read more
Source§

fn zvl_get_as_t<R>(g: &Self::GetType, f: impl FnOnce(&T) -> R) -> R

Obtain a reference to T, passed to a closure Read more
Source§

fn zvl_is_ascending(&self) -> bool
where T: Ord,

Check if this vector is in ascending order according to Ts Ord impl
Source§

fn zvl_is_empty(&self) -> bool

Check if this vector is empty
Source§

fn t_cmp_get(t: &T, g: &Self::GetType) -> Ordering
where T: Ord,

Compare this type with a Self::GetType. This must produce the same result as if g were converted to Self
Source§

fn get_cmp_get(a: &Self::GetType, b: &Self::GetType) -> Ordering
where T: Ord,

Compare two values of Self::GetType. This must produce the same result as if both a and b were converted to Self
Source§

impl<T, F> Eq for VarZeroSlice<T, F>
where T: VarULE + ?Sized + Eq, F: VarZeroVecFormat,

Auto Trait Implementations§

§

impl<T, F> Freeze for VarZeroSlice<T, F>
where T: ?Sized,

§

impl<T, F> RefUnwindSafe for VarZeroSlice<T, F>

§

impl<T, F> Send for VarZeroSlice<T, F>
where F: Send, T: Send + ?Sized,

§

impl<T, F = Index16> !Sized for VarZeroSlice<T, F>

§

impl<T, F> Sync for VarZeroSlice<T, F>
where F: Sync, T: Sync + ?Sized,

§

impl<T, F> Unpin for VarZeroSlice<T, F>
where F: Unpin, T: Unpin + ?Sized,

§

impl<T, F> UnwindSafe for VarZeroSlice<T, F>
where F: UnwindSafe, T: UnwindSafe + ?Sized,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> EncodeAsVarULE<T> for T
where T: VarULE + ?Sized,

Source§

fn encode_var_ule_as_slices<R>(&self, cb: impl FnOnce(&[&[u8]]) -> R) -> R

Calls cb with a piecewise list of byte slices that when concatenated produce the memory pattern of the corresponding instance of T. Read more
Source§

fn encode_var_ule_len(&self) -> usize

Return the length, in bytes, of the corresponding VarULE type
Source§

fn encode_var_ule_write(&self, dst: &mut [u8])

Write the corresponding VarULE type to the dst buffer. dst should be the size of Self::encode_var_ule_len()