Enum zerovec::ZeroVec [−][src]
#[non_exhaustive] pub enum ZeroVec<'a, T: ?Sized> where
T: AsULE, { Owned(Vec<T::ULE>), Borrowed(&'a [T::ULE]), }
Expand description
A zero-copy vector for fixed-width types.
ZeroVec<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.
T
must implement AsULE
, which is auto-implemented for a number of built-in types,
including all fixed-width multibyte integers.
How it Works
ZeroVec<T>
represents a slice of T
as a slice of T::ULE
. The difference between T
and
T::ULE
is that T::ULE
must be encoded in little-endian with 1-byte alignment. When accessing
items from ZeroVec<T>
, we fetch the T::ULE
, convert it on the fly to T
, and return T
by
value.
Benchmarks can be found in the project repository. We found that for common operations on small
and large vectors, ZeroVec<T>
performs from slightly faster to 15% slower than Vec<T>
.
However, the main performance improvement on ZeroVec<T>
is when deserializing from a byte
array; ZeroVec<T>
deserializes 80% faster than Vec<T>
in Serde Bincode, and it does not
require any heap allocations.
Safety
ZeroVec<T>
contains no unsafe code. However, the conversion from &[u8]
to &[T::ULE]
may
be unsafe. For more information, see the ule
module.
Example
use zerovec::ZeroVec; // The little-endian bytes correspond to the numbers on the following line. let bytes: &[u8] = &[0xD3, 0x00, 0x19, 0x01, 0xA5, 0x01, 0xCD, 0x01]; let nums: &[u16] = &[211, 281, 421, 461]; // Conversion from &[u8] to &[u16::ULE] is infallible. let zerovec: ZeroVec<u16> = ZeroVec::try_from_bytes(bytes).expect("infallible"); assert!(matches!(zerovec, ZeroVec::Borrowed(_))); assert_eq!(zerovec.get(2), Some(421)); assert_eq!(zerovec, nums);
Variants (Non-exhaustive)
This enum is marked as non-exhaustive
Implementations
Parses a &[u8]
buffer into a ZeroVec<T>
.
This function is infallible for built-in integer types, but fallible for other types,
such as char
. For more information, see ULE::parse_byte_slice
.
The bytes within the byte buffer must remain constant for the life of the ZeroVec.
Endianness
The byte buffer must be encoded in little-endian, even if running in a big-endian environment. This ensures a consistent representation of data across platforms.
Example
use zerovec::ZeroVec; let bytes: &[u8] = &[0xD3, 0x00, 0x19, 0x01, 0xA5, 0x01, 0xCD, 0x01]; let zerovec: ZeroVec<u16> = ZeroVec::try_from_bytes(bytes).expect("infallible"); assert!(matches!(zerovec, ZeroVec::Borrowed(_))); assert_eq!(zerovec.get(2), Some(421));
Returns a ZeroVec<T>
as its underlying &[u8]
byte buffer representation.
Useful for serialization.
Example
use zerovec::ZeroVec; // The little-endian bytes correspond to the numbers on the following line. let bytes: &[u8] = &[0xD3, 0x00, 0x19, 0x01, 0xA5, 0x01, 0xCD, 0x01]; let nums: &[u16] = &[211, 281, 421, 461]; let zerovec = ZeroVec::from_aligned(nums); assert_eq!(bytes, zerovec.as_bytes());
Dereferences this ZeroVec<T>
as &[T::ULE]
. Most other functions on ZeroVec<T>
use
this function as a building block.
Returns the number of elements in this ZeroVec<T>
.
Example
use zerovec::ZeroVec; use zerovec::ule::AsULE; let bytes: &[u8] = &[0xD3, 0x00, 0x19, 0x01, 0xA5, 0x01, 0xCD, 0x01]; let zerovec: ZeroVec<u16> = ZeroVec::try_from_bytes(bytes).expect("infallible"); assert_eq!(4, zerovec.len()); assert_eq!( bytes.len(), zerovec.len() * std::mem::size_of::<<u16 as AsULE>::ULE>() );
Returns whether the vec is empty.
Example
use zerovec::ZeroVec; let bytes: &[u8] = &[0xD3, 0x00, 0x19, 0x01, 0xA5, 0x01, 0xCD, 0x01]; let zerovec: ZeroVec<u16> = ZeroVec::try_from_bytes(bytes).expect("infallible"); assert!(!zerovec.is_empty()); let emptyvec: ZeroVec<u16> = ZeroVec::try_from_bytes(&[]).expect("infallible"); assert!(emptyvec.is_empty());
Creates a ZeroVec<T>
from a &[T]
.
This function allocates memory and results in an Owned
instance of ZeroVec<T>
.
Example
use zerovec::ZeroVec; // The little-endian bytes correspond to the numbers on the following line. let bytes: &[u8] = &[0xD3, 0x00, 0x19, 0x01, 0xA5, 0x01, 0xCD, 0x01]; let nums: &[u16] = &[211, 281, 421, 461]; let zerovec = ZeroVec::from_aligned(nums); assert!(matches!(zerovec, ZeroVec::Owned(_))); assert_eq!(bytes, zerovec.as_bytes());
Gets the element at the specified index. Returns None if out of range.
The element is returned by value, so T
must implement Copy
.
Example
use zerovec::ZeroVec; let bytes: &[u8] = &[0xD3, 0x00, 0x19, 0x01, 0xA5, 0x01, 0xCD, 0x01]; let zerovec: ZeroVec<u16> = ZeroVec::try_from_bytes(bytes).expect("infallible"); assert_eq!(zerovec.get(2), Some(421)); assert_eq!(zerovec.get(4), None);
Gets the first element. Returns None if empty.
The element is returned by value, so T
must implement Copy
.
Example
use zerovec::ZeroVec; let bytes: &[u8] = &[0xD3, 0x00, 0x19, 0x01, 0xA5, 0x01, 0xCD, 0x01]; let zerovec: ZeroVec<u16> = ZeroVec::try_from_bytes(bytes).expect("infallible"); assert_eq!(zerovec.first(), Some(211));
Gets the last element. Returns None if empty.
The element is returned by value, so T
must implement Copy
.
Example
use zerovec::ZeroVec; let bytes: &[u8] = &[0xD3, 0x00, 0x19, 0x01, 0xA5, 0x01, 0xCD, 0x01]; let zerovec: ZeroVec<u16> = ZeroVec::try_from_bytes(bytes).expect("infallible"); assert_eq!(zerovec.last(), Some(461));
Gets an iterator over the elements.
The elements are returned by value, so T
must implement Copy
.
Example
use zerovec::ZeroVec; let bytes: &[u8] = &[0xD3, 0x00, 0x19, 0x01, 0xA5, 0x01, 0xCD, 0x01]; let zerovec: ZeroVec<u16> = ZeroVec::try_from_bytes(bytes).expect("infallible"); let mut it = zerovec.iter(); assert_eq!(it.next(), Some(211)); assert_eq!(it.next(), Some(281)); assert_eq!(it.next(), Some(421)); assert_eq!(it.next(), Some(461)); assert_eq!(it.next(), None);
Converts a borrowed ZeroVec to an owned ZeroVec. No-op if already owned.
Example
use zerovec::ZeroVec; let bytes: &[u8] = &[0xD3, 0x00, 0x19, 0x01, 0xA5, 0x01, 0xCD, 0x01]; let zerovec: ZeroVec<u16> = ZeroVec::try_from_bytes(bytes).expect("infallible"); assert!(matches!(zerovec, ZeroVec::Borrowed(_))); let owned = zerovec.into_owned(); assert!(matches!(owned, ZeroVec::Owned(_)));
Binary searches a sorted ZeroVec<T>
for the given element. For more information, see
the primitive function binary_search
.
Example
use zerovec::ZeroVec; let bytes: &[u8] = &[0xD3, 0x00, 0x19, 0x01, 0xA5, 0x01, 0xCD, 0x01]; let zerovec: ZeroVec<u16> = ZeroVec::try_from_bytes(bytes).expect("infallible"); assert_eq!(zerovec.binary_search(&281), Ok(1)); assert_eq!(zerovec.binary_search(&282), Err(2));
Trait Implementations
impl<'de, 'a, T> Deserialize<'de> for ZeroVec<'a, T> where
T: 'de + Deserialize<'de> + AsULE,
<<T as AsULE>::ULE as ULE>::Error: Display,
'de: 'a,
impl<'de, 'a, T> Deserialize<'de> for ZeroVec<'a, T> where
T: 'de + Deserialize<'de> + AsULE,
<<T as AsULE>::ULE as ULE>::Error: Display,
'de: 'a,
This impl can be made available by enabling the optional serde
feature of the zerovec
crate
Deserialize this value from the given Serde deserializer. Read more
This impl can be made available by enabling the optional serde
feature of the zerovec
crate
This impl can be made available by enabling the optional yoke
feature of the zerovec
crate
This method must cast self
between &'a Self<'static>
and &'a Self<'a>
. Read more
This method must cast self
between Self<'static>
and Self<'a>
. Read more
This method can be used to cast away Self<'a>
’s lifetime. Read more
fn transform_mut<F>(&'a mut self, f: F) where
F: 'static + for<'b> FnOnce(&'b mut Self::Output),
fn transform_mut<F>(&'a mut self, f: F) where
F: 'static + for<'b> FnOnce(&'b mut Self::Output),
This method must cast self
between &'a mut Self<'static>
and &'a mut Self<'a>
,
and pass it to f
. Read more
Clone the cart C
into a Yokeable
struct, which may retain references into C
.
type NeedleType = T
type NeedleType = T
The type received by Self::binary_search()
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. Read more
Replace the element at index
with another one, returning the old element
Create a new, empty vector, with given capacity
Check if this vector is in ascending order according to T
s Ord
impl
Auto Trait Implementations
impl<'a, T: ?Sized> RefUnwindSafe for ZeroVec<'a, T> where
<T as AsULE>::ULE: RefUnwindSafe,
impl<'a, T: ?Sized> UnwindSafe for ZeroVec<'a, T> where
<T as AsULE>::ULE: RefUnwindSafe + UnwindSafe,
Blanket Implementations
Mutably borrows from an owned value. Read more