Struct VarZeroVec
struct VarZeroVec<'a, T: ?Sized, F = Index16>(_)
A zero-copy, byte-aligned 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 VarULE, which is already implemented for str and [u8]. For storing more
complicated series of elements, it is implemented on ZeroSlice<T> as well as VarZeroSlice<T>
for nesting. zerovec::make_varule may be used to generate
a dynamically-sized VarULE type and conversions to and from a custom type.
For example, here are some owned types and their zero-copy equivalents:
Vec<String>:VarZeroVec<'a, str>Vec<Vec<u8>>>:VarZeroVec<'a, [u8]>Vec<Vec<u32>>:VarZeroVec<'a, ZeroSlice<u32>>Vec<Vec<String>>:VarZeroVec<'a, VarZeroSlice<str>>
Most of the methods on VarZeroVec<'a, T> come from its Deref implementation to VarZeroSlice<T>.
For creating zero-copy vectors of fixed-size types, see ZeroVec.
VarZeroVec<T> behaves much like Cow, where it can be constructed from
owned data (and then mutated!) but can also borrow from some buffer.
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.
Bytes and Equality
Two VarZeroVecs are equal if and only if their bytes are equal, as described in the trait
VarULE. However, we do not guarantee stability of byte equality or serialization format
across major SemVer releases.
To compare a [Vec<T>] to a [VarZeroVec<T>], it is generally recommended to use
Iterator::eq, since it is somewhat expensive at runtime to convert from a [Vec<T>] to a
[VarZeroVec<T>] or vice-versa.
Prior to zerovec reaching 1.0, the precise byte representation of VarZeroVec is still
under consideration, with different options along the space-time spectrum. See
#1410.
Example
use VarZeroVec;
// The little-endian bytes correspond to the list of strings.
let strings = vec!;
let data = Data ;
let bincode_bytes =
serialize.expect;
// Will deserialize without allocations
let deserialized: Data = deserialize
.expect;
assert_eq!;
assert_eq!;
Here's another example with ZeroSlice<T> (similar to [T]):
use VarZeroVec;
use ZeroSlice;
// The structured list correspond to the list of integers.
let numbers: & = &;
let data = Data ;
let bincode_bytes =
serialize.expect;
let deserialized: Data = deserialize
.expect;
assert_eq!;
assert_eq!;
VarZeroVecs can be nested infinitely via a similar mechanism, see the docs of VarZeroSlice
for more information.
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:
- 2 bytes for
length(interpreted as a little-endian u16) 2 * (length - 1)bytes ofindices(interpreted as little-endian u16s)- Remaining bytes for actual
data
The format is tweakable by setting the F parameter, by default it uses u16 indices and lengths but other
VarZeroVecFormat types can set other sizes.
Each element in the indices array points to the ending index of its corresponding
data part in the data list. The starting index can be calculated from the ending index
of the next element (or 0 for the first element). The last ending index, not stored in the array, is
the length of the data segment.
See the design doc for more details.
Implementations
impl<'a, T: VarULE + ?Sized, F: VarZeroVecFormat> VarZeroVec<'a, T, F>
const fn new() -> SelfCreates a new, empty
VarZeroVec<T>.Examples
use VarZeroVec; let vzv: = new; assert!;fn parse_bytes(slice: &'a [u8]) -> Result<Self, UleError>Parse a VarZeroVec from a slice of the appropriate format
Slices of the right format can be obtained via [
VarZeroSlice::as_bytes()].Example
# use VarZeroVec; let strings = vec!; let vec = from; assert_eq!; assert_eq!; assert_eq!; assert_eq!;unsafe const fn from_bytes_unchecked(bytes: &'a [u8]) -> SelfUses a
&[u8]buffer as aVarZeroVec<T>without any verification.Safety
bytesneed to be an output from [VarZeroSlice::as_bytes()].fn make_mut(self: &mut Self) -> &mut VarZeroVecOwned<T, F>Convert this into a mutable vector of the owned
Ttype, cloning if necessary.Example
# use VarZeroVec; let strings = vec!; let mut vec = from; assert_eq!; let mutvec = vec.make_mut; mutvec.push; mutvec = "dolor sit".into; assert_eq!; assert_eq!; assert_eq!; assert_eq!; assert_eq!;fn into_owned(self: Self) -> VarZeroVec<'static, T, F>Converts a borrowed ZeroVec to an owned ZeroVec. No-op if already owned.
Example
# use VarZeroVec; let strings = vec!; let vec = from; assert_eq!; // has 'static lifetime let owned = vec.into_owned;fn as_slice(self: &Self) -> &VarZeroSlice<T, F>Obtain this
VarZeroVecas aVarZeroSlicefn into_bytes(self: Self) -> Vec<u8>Takes the byte vector representing the encoded data of this VarZeroVec. If borrowed, this function allocates a byte vector and copies the borrowed bytes into it.
The bytes can be passed back to [
Self::parse_bytes()].To get a reference to the bytes without moving, see [
VarZeroSlice::as_bytes()].Example
# use VarZeroVec; let strings = vec!; let bytes = from.into_bytes; let mut borrowed: = parse_bytes.unwrap; assert_eq!;fn is_owned(self: &Self) -> boolReturn whether the
VarZeroVecis operating on owned or borrowed data. [VarZeroVec::into_owned()] and [VarZeroVec::make_mut()] can be used to force it into an owned type
impl<'a, 'b, T, F> PartialEq for VarZeroVec<'a, T, F>
fn eq(self: &Self, other: &VarZeroVec<'b, T, F>) -> bool
impl<'a, T, F> Eq for VarZeroVec<'a, T, F>
impl<'a, T, F> Freeze for VarZeroVec<'a, T, F>
impl<'a, T, F> MutableZeroVecLike for VarZeroVec<'a, T, F>
fn zvl_insert(self: &mut Self, index: usize, value: &T)fn zvl_remove(self: &mut Self, index: usize) -> Box<T>fn zvl_replace(self: &mut Self, index: usize, value: &T) -> Box<T>fn zvl_push(self: &mut Self, value: &T)fn zvl_with_capacity(cap: usize) -> Selffn zvl_clear(self: &mut Self)fn zvl_reserve(self: &mut Self, addl: usize)fn owned_as_t(o: &<Self as >::OwnedType) -> &Tfn zvl_from_borrowed(b: &'a VarZeroSlice<T, F>) -> Selffn zvl_as_borrowed_inner(self: &Self) -> Option<&'a VarZeroSlice<T, F>>fn zvl_permute(self: &mut Self, permutation: &mut [usize])
impl<'a, T, F> RefUnwindSafe for VarZeroVec<'a, T, F>
impl<'a, T, F> Send for VarZeroVec<'a, T, F>
impl<'a, T, F> Sync for VarZeroVec<'a, T, F>
impl<'a, T, F> Unpin for VarZeroVec<'a, T, F>
impl<'a, T, F> UnsafeUnpin for VarZeroVec<'a, T, F>
impl<'a, T, F> UnwindSafe for VarZeroVec<'a, T, F>
impl<'a, T, F> ZeroVecLike for VarZeroVec<'a, T, F>
fn zvl_new_borrowed() -> &'static <Self as >::SliceVariantfn zvl_binary_search(self: &Self, k: &T) -> Result<usize, usize> where T: Ordfn zvl_binary_search_in_range(self: &Self, k: &T, range: Range<usize>) -> Option<Result<usize, usize>> where T: Ordfn zvl_binary_search_by<impl FnMut(&T) -> Ordering: FnMut(&T) -> Ordering>(self: &Self, predicate: impl FnMut(&T) -> Ordering) -> Result<usize, usize>fn zvl_binary_search_in_range_by<impl FnMut(&T) -> Ordering: FnMut(&T) -> Ordering>(self: &Self, predicate: impl FnMut(&T) -> Ordering, range: Range<usize>) -> Option<Result<usize, usize>>fn zvl_get(self: &Self, index: usize) -> Option<&T>fn zvl_len(self: &Self) -> usizefn zvl_as_borrowed(self: &Self) -> &VarZeroSlice<T, F>fn zvl_get_as_t<R, impl FnOnce(&T) -> R: FnOnce(&T) -> R>(g: &<Self as >::GetType, f: impl FnOnce(&T) -> R) -> R
impl<'a, T: 'static + VarULE + ?Sized> Yokeable for VarZeroVec<'static, T>
fn transform(self: &'a Self) -> &'a <Self as >::Outputfn transform_owned(self: Self) -> <Self as >::Outputunsafe fn make(from: <Self as >::Output) -> Selffn transform_mut<F>(self: &'a mut Self, f: F) where F: 'static + for<'b> FnOnce(&'b mut <Self as >::Output)
impl<'a, T: ?Sized, F> Clone for VarZeroVec<'a, T, F>
fn clone(self: &Self) -> Self
impl<'a, T: ?Sized, F> From for VarZeroVec<'a, T, F>
fn from(other: &'a VarZeroSlice<T, F>) -> Self
impl<'a, T: ?Sized, F> From for VarZeroVec<'a, T, F>
fn from(other: VarZeroVecOwned<T, F>) -> Self
impl<'a, T: VarULE + ?Sized + Ord, F: VarZeroVecFormat> Ord for VarZeroVec<'a, T, F>
fn cmp(self: &Self, other: &Self) -> Ordering
impl<'a, T: VarULE + ?Sized + PartialOrd, F: VarZeroVecFormat> PartialOrd for VarZeroVec<'a, T, F>
fn partial_cmp(self: &Self, other: &Self) -> Option<Ordering>
impl<'zf, T, F: VarZeroVecFormat> ZeroFrom for VarZeroVec<'zf, T, F>
fn zero_from(other: &'zf VarZeroVec<'_, T, F>) -> Self
impl<'zf, T, F: VarZeroVecFormat> ZeroFrom for VarZeroVec<'zf, T, F>
fn zero_from(other: &'zf VarZeroSlice<T, F>) -> Self
impl<A, T, F> From for VarZeroVec<'static, T, F>
fn from(elements: &[A]) -> Self
impl<A, T, F> From for VarZeroVec<'static, T, F>
fn from(elements: &Vec<A>) -> Self
impl<A, T, F, N: usize> From for VarZeroVec<'static, T, F>
fn from(elements: &[A; N]) -> Self
impl<P, T> Receiver for VarZeroVec<'a, T, F>
impl<T> Any for VarZeroVec<'a, T, F>
fn type_id(self: &Self) -> TypeId
impl<T> Borrow for VarZeroVec<'a, T, F>
fn borrow(self: &Self) -> &T
impl<T> BorrowMut for VarZeroVec<'a, T, F>
fn borrow_mut(self: &mut Self) -> &mut T
impl<T> CloneToUninit for VarZeroVec<'a, T, F>
unsafe fn clone_to_uninit(self: &Self, dest: *mut u8)
impl<T> ErasedDestructor for VarZeroVec<'a, T, F>
impl<T> From for VarZeroVec<'a, T, F>
fn from(t: T) -> TReturns the argument unchanged.
impl<T> ToOwned for VarZeroVec<'a, T, F>
fn to_owned(self: &Self) -> Tfn clone_into(self: &Self, target: &mut T)
impl<T, A, F> PartialEq for VarZeroVec<'_, T, F>
fn eq(self: &Self, other: &&[A]) -> bool
impl<T, A, F, N: usize> PartialEq for VarZeroVec<'_, T, F>
fn eq(self: &Self, other: &[A; N]) -> bool
impl<T, F> EncodeAsVarULE for VarZeroVec<'_, T, F>
fn encode_var_ule_as_slices<R, impl FnOnce(&[&[u8]]) -> R: FnOnce(&[&[u8]]) -> R>(self: &Self, _: impl FnOnce(&[&[u8]]) -> R) -> Rfn encode_var_ule_len(self: &Self) -> usizefn encode_var_ule_write(self: &Self, dst: &mut [u8])
impl<T, F: VarZeroVecFormat> Debug for VarZeroVec<'_, T, F>
fn fmt(self: &Self, f: &mut Formatter<'_>) -> Result
impl<T, U> Into for VarZeroVec<'a, T, F>
fn into(self: Self) -> UCalls
U::from(self).That is, this conversion is whatever the implementation of
[From]<T> for Uchooses to do.
impl<T, U> TryFrom for VarZeroVec<'a, T, F>
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
impl<T, U> TryInto for VarZeroVec<'a, T, F>
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error>
impl<T: VarULE + ?Sized> Default for VarZeroVec<'_, T>
fn default() -> Self
impl<T: VarULE + ?Sized, F: VarZeroVecFormat> Deref for VarZeroVec<'_, T, F>
fn deref(self: &Self) -> &VarZeroSlice<T, F>