Struct ZeroVec

struct ZeroVec<'a, T> { ... }
where
    T: AsULE

A zero-copy, byte-aligned 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. For variable-width types like str, see VarZeroVec. zerovec::make_ule may be used to automatically implement AsULE for a type and generate the underlying ULE type.

Typically, the zero-copy equivalent of a Vec<T> will simply be ZeroVec<'a, T>.

Most of the methods on ZeroVec<'a, T> come from its Deref implementation to ZeroSlice<T>.

For creating zero-copy vectors of fixed-size types, see VarZeroVec.

ZeroVec<T> behaves much like Cow, where it can be constructed from owned data (and then mutated!) but can also borrow from some buffer.

Example

use zerovec::ZeroVec;

// The little-endian bytes correspond to the numbers on the following line.
let nums: &[u16] = &[211, 281, 421, 461];

#[derive(serde::Serialize, serde::Deserialize)]
struct Data<'a> {
    #[serde(borrow)]
    nums: ZeroVec<'a, u16>,
}

// The owned version will allocate
let data = Data {
    nums: ZeroVec::alloc_from_slice(nums),
};
let bincode_bytes =
    bincode::serialize(&data).expect("Serialization should be successful");

// Will deserialize without allocations
let deserialized: Data = bincode::deserialize(&bincode_bytes)
    .expect("Deserialization should be successful");

// This deserializes without allocation!
assert!(!deserialized.nums.is_owned());
assert_eq!(deserialized.nums.get(2), Some(421));
assert_eq!(deserialized.nums, nums);

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, with some results found in the crate-level documentation.

See the design doc for more details.

Implementations

impl<'a> ZeroVec<'a, u8>

fn try_into_parsed<T: AsULE>(self: Self) -> Result<ZeroVec<'a, T>, UleError>

Converts a ZeroVec<u8> into a ZeroVec<T>, retaining the current ownership model.

Note that the length of the ZeroVec may change.

Examples

Convert a borrowed ZeroVec:

use zerovec::ZeroVec;

let bytes: &[u8] = &[0xD3, 0x00, 0x19, 0x01, 0xA5, 0x01, 0xCD, 0x01];
let zv_bytes = ZeroVec::new_borrowed(bytes);
let zerovec: ZeroVec<u16> = zv_bytes.try_into_parsed().expect("infallible");

assert!(!zerovec.is_owned());
assert_eq!(zerovec.get(0), Some(211));

Convert an owned ZeroVec:

use zerovec::ZeroVec;

let bytes: Vec<u8> = vec![0xD3, 0x00, 0x19, 0x01, 0xA5, 0x01, 0xCD, 0x01];
let zv_bytes = ZeroVec::new_owned(bytes);
let zerovec: ZeroVec<u16> = zv_bytes.try_into_parsed().expect("infallible");

assert!(zerovec.is_owned());
assert_eq!(zerovec.get(0), Some(211));

impl<'a, T> ZeroVec<'a, T>

fn alloc_from_slice(other: &[T]) -> Self

Creates a ZeroVec<T> from a &[T] by allocating memory.

This function 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::alloc_from_slice(nums);

assert!(zerovec.is_owned());
assert_eq!(bytes, zerovec.as_bytes());
fn to_vec(self: &Self) -> Vec<T>

Creates a Vec<T> from a ZeroVec<T>.

Example

use zerovec::ZeroVec;

let nums: &[u16] = &[211, 281, 421, 461];
let vec: Vec<u16> = ZeroVec::alloc_from_slice(nums).to_vec();

assert_eq!(nums, vec.as_slice());

impl<'a, T> ZeroVec<'a, T>

fn try_from_slice(slice: &'a [T]) -> Option<Self>

Attempts to create a ZeroVec<'a, T> from a &'a [T] by borrowing the argument.

If this is not possible, such as on a big-endian platform, None is returned.

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];

if let Some(zerovec) = ZeroVec::try_from_slice(nums) {
    assert!(!zerovec.is_owned());
    assert_eq!(bytes, zerovec.as_bytes());
}
fn from_slice_or_alloc(slice: &'a [T]) -> Self

Creates a ZeroVec<'a, T> from a &'a [T], either by borrowing the argument or by allocating a new vector.

This is a cheap operation on little-endian platforms, falling back to a more expensive operation on big-endian platforms.

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_slice_or_alloc(nums);

// Note: zerovec could be either borrowed or owned.
assert_eq!(bytes, zerovec.as_bytes());

impl<'a, T> ZeroVec<'a, T>

fn for_each_mut<impl FnMut(&mut T): FnMut(&mut T)>(self: &mut Self, f: impl FnMut(&mut T))

Mutates each element according to a given function, meant to be a more convenient version of calling .iter_mut() with [ZeroVec::with_mut()] which serves fewer use cases.

This will convert the ZeroVec into an owned ZeroVec if not already the case.

Example

use zerovec::ZeroVec;

let bytes: &[u8] = &[0xD3, 0x00, 0x19, 0x01, 0xA5, 0x01, 0xCD, 0x01];
let mut zerovec: ZeroVec<u16> =
    ZeroVec::parse_bytes(bytes).expect("infallible");

zerovec.for_each_mut(|item| *item += 1);

assert_eq!(zerovec.to_vec(), &[212, 282, 422, 462]);
assert!(zerovec.is_owned());
fn try_for_each_mut<E, impl FnMut(&mut T) -> Result<(), E>: FnMut(&mut T) -> Result<(), E>>(self: &mut Self, f: impl FnMut(&mut T) -> Result<(), E>) -> Result<(), E>

Same as [ZeroVec::for_each_mut()], but bubbles up errors.

Example

use zerovec::ZeroVec;

let bytes: &[u8] = &[0xD3, 0x00, 0x19, 0x01, 0xA5, 0x01, 0xCD, 0x01];
let mut zerovec: ZeroVec<u16> =
    ZeroVec::parse_bytes(bytes).expect("infallible");

zerovec.try_for_each_mut(|item| {
    *item = item.checked_add(1).ok_or(())?;
    Ok(())
})?;

assert_eq!(zerovec.to_vec(), &[212, 282, 422, 462]);
assert!(zerovec.is_owned());
# Ok::<(), ()>(())
fn into_owned(self: Self) -> ZeroVec<'static, T>

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::parse_bytes(bytes).expect("infallible");
assert!(!zerovec.is_owned());

let owned = zerovec.into_owned();
assert!(owned.is_owned());
fn with_mut<R, impl FnOnce(&mut alloc::vec::Vec<T::ULE>) -> R: FnOnce(&mut alloc::vec::Vec<<T as >::ULE>) -> R>(self: &mut Self, f: impl FnOnce(&mut Vec<<T as >::ULE>) -> R) -> R

Allows the ZeroVec to be mutated by converting it to an owned variant, and producing a mutable vector of ULEs. If you only need a mutable slice, consider using [Self::to_mut_slice()] instead.

Example

# use crate::zerovec::ule::AsULE;
use zerovec::ZeroVec;

let bytes: &[u8] = &[0xD3, 0x00, 0x19, 0x01, 0xA5, 0x01, 0xCD, 0x01];
let mut zerovec: ZeroVec<u16> =
    ZeroVec::parse_bytes(bytes).expect("infallible");
assert!(!zerovec.is_owned());

zerovec.with_mut(|v| v.push(12_u16.to_unaligned()));
assert!(zerovec.is_owned());
fn to_mut_slice(self: &mut Self) -> &mut [<T as >::ULE]

Allows the ZeroVec to be mutated by converting it to an owned variant (if necessary) and returning a slice to its backing buffer. [Self::with_mut()] allows for mutation of the vector itself.

Example

# use crate::zerovec::ule::AsULE;
use zerovec::ZeroVec;

let bytes: &[u8] = &[0xD3, 0x00, 0x19, 0x01, 0xA5, 0x01, 0xCD, 0x01];
let mut zerovec: ZeroVec<u16> =
    ZeroVec::parse_bytes(bytes).expect("infallible");
assert!(!zerovec.is_owned());

zerovec.to_mut_slice()[1] = 5u16.to_unaligned();
assert!(zerovec.is_owned());
fn clear(self: &mut Self)

Remove all elements from this ZeroVec and reset it to an empty borrowed state.

fn take_first(self: &mut Self) -> Option<T>

Removes the first element of the ZeroVec. The ZeroVec remains in the same borrowed or owned state.

Examples

# use crate::zerovec::ule::AsULE;
use zerovec::ZeroVec;

let bytes: &[u8] = &[0xD3, 0x00, 0x19, 0x01, 0xA5, 0x01, 0xCD, 0x01];
let mut zerovec: ZeroVec<u16> =
    ZeroVec::parse_bytes(bytes).expect("infallible");
assert!(!zerovec.is_owned());

let first = zerovec.take_first().unwrap();
assert_eq!(first, 0x00D3);
assert!(!zerovec.is_owned());

let mut zerovec = zerovec.into_owned();
assert!(zerovec.is_owned());
let first = zerovec.take_first().unwrap();
assert_eq!(first, 0x0119);
assert!(zerovec.is_owned());
fn take_last(self: &mut Self) -> Option<T>

Removes the last element of the ZeroVec. The ZeroVec remains in the same borrowed or owned state.

Examples

# use crate::zerovec::ule::AsULE;
use zerovec::ZeroVec;

let bytes: &[u8] = &[0xD3, 0x00, 0x19, 0x01, 0xA5, 0x01, 0xCD, 0x01];
let mut zerovec: ZeroVec<u16> =
    ZeroVec::parse_bytes(bytes).expect("infallible");
assert!(!zerovec.is_owned());

let last = zerovec.take_last().unwrap();
assert_eq!(last, 0x01CD);
assert!(!zerovec.is_owned());

let mut zerovec = zerovec.into_owned();
assert!(zerovec.is_owned());
let last = zerovec.take_last().unwrap();
assert_eq!(last, 0x01A5);
assert!(zerovec.is_owned());
fn into_cow(self: Self) -> Cow<'a, [<T as >::ULE]>

Converts the type into a Cow<'a, [T::ULE]>, which is the logical equivalent of this type's internal representation

impl<'a, T: AsULE> ZeroVec<'a, T>

const fn new() -> Self

Creates a new, borrowed, empty ZeroVec<T>.

Examples

use zerovec::ZeroVec;

let zv: ZeroVec<u16> = ZeroVec::new();
assert!(zv.is_empty());
const fn const_len(self: &Self) -> usize

Same as ZeroSlice::len, which is available through Deref and not const.

fn new_owned(vec: Vec<<T as >::ULE>) -> Self

Creates a new owned ZeroVec using an existing allocated backing buffer

If you have a slice of &[T]s, prefer using [Self::alloc_from_slice()].

const fn new_borrowed(slice: &'a [<T as >::ULE]) -> Self

Creates a new borrowed ZeroVec using an existing backing buffer

fn with_capacity(capacity: usize) -> Self

Creates a new, owned, empty ZeroVec<T>, with a certain capacity pre-allocated.

fn parse_bytes(bytes: &'a [u8]) -> Result<Self, UleError>

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_bytes_to_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::parse_bytes(bytes).expect("infallible");

assert!(!zerovec.is_owned());
assert_eq!(zerovec.get(2), Some(421));
unsafe const fn from_bytes_unchecked(bytes: &'a [u8]) -> Self

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

Safety

bytes need to be an output from [ZeroSlice::as_bytes()].

fn into_bytes(self: Self) -> ZeroVec<'a, u8>

Converts a ZeroVec<T> into a ZeroVec<u8>, retaining the current ownership model.

Note that the length of the ZeroVec may change.

Examples

Convert a borrowed ZeroVec:

use zerovec::ZeroVec;

let bytes: &[u8] = &[0xD3, 0x00, 0x19, 0x01, 0xA5, 0x01, 0xCD, 0x01];
let zerovec: ZeroVec<u16> =
    ZeroVec::parse_bytes(bytes).expect("infallible");
let zv_bytes = zerovec.into_bytes();

assert!(!zv_bytes.is_owned());
assert_eq!(zv_bytes.get(0), Some(0xD3));

Convert an owned ZeroVec:

use zerovec::ZeroVec;

let nums: &[u16] = &[211, 281, 421, 461];
let zerovec = ZeroVec::alloc_from_slice(nums);
let zv_bytes = zerovec.into_bytes();

assert!(zv_bytes.is_owned());
assert_eq!(zv_bytes.get(0), Some(0xD3));
const fn as_slice(self: &Self) -> &ZeroSlice<T>

Returns this ZeroVec as a ZeroSlice.

To get a reference with a longer lifetime from a borrowed ZeroVec, use ZeroVec::as_maybe_borrowed.

fn cast<P>(self: Self) -> ZeroVec<'a, P>
where
    P: AsULE<ULE = <T as >::ULE>

Casts a ZeroVec<T> to a compatible ZeroVec<P>.

T and P are compatible if they have the same ULE representation.

If the ULEs of T and P are different types but have the same size, use [Self::try_into_converted()].

Examples

use zerovec::ZeroVec;

let bytes: &[u8] = &[0xD3, 0x00, 0x19, 0x01, 0xA5, 0x01, 0xCD, 0x80];

let zerovec_u16: ZeroVec<u16> =
    ZeroVec::parse_bytes(bytes).expect("infallible");
assert_eq!(zerovec_u16.get(3), Some(32973));

let zerovec_i16: ZeroVec<i16> = zerovec_u16.cast();
assert_eq!(zerovec_i16.get(3), Some(-32563));
fn try_into_converted<P: AsULE>(self: Self) -> Result<ZeroVec<'a, P>, UleError>

Converts a ZeroVec<T> into a ZeroVec<P>, retaining the current ownership model.

If T and P have the exact same ULE, use [Self::cast()].

Panics

Panics if T::ULE and P::ULE are not the same size.

Examples

Convert a borrowed ZeroVec:

use zerovec::ZeroVec;

let bytes: &[u8] = &[0x7F, 0xF3, 0x01, 0x49, 0xF6, 0x01];
let zv_char: ZeroVec<char> =
    ZeroVec::parse_bytes(bytes).expect("valid code points");
let zv_u8_3: ZeroVec<[u8; 3]> =
    zv_char.try_into_converted().expect("infallible conversion");

assert!(!zv_u8_3.is_owned());
assert_eq!(zv_u8_3.get(0), Some([0x7F, 0xF3, 0x01]));

Convert an owned ZeroVec:

use zerovec::ZeroVec;

let chars: &[char] = &['🍿', '🙉'];
let zv_char = ZeroVec::alloc_from_slice(chars);
let zv_u8_3: ZeroVec<[u8; 3]> =
    zv_char.try_into_converted().expect("length is divisible");

assert!(zv_u8_3.is_owned());
assert_eq!(zv_u8_3.get(0), Some([0x7F, 0xF3, 0x01]));

If the types are not the same size, we refuse to convert:

use zerovec::ZeroVec;

let bytes: &[u8] = &[0x7F, 0xF3, 0x01, 0x49, 0xF6, 0x01];
let zv_char: ZeroVec<char> =
    ZeroVec::parse_bytes(bytes).expect("valid code points");

// Panics! core::mem::size_of::<char::ULE> != core::mem::size_of::<u16::ULE>
zv_char.try_into_converted::<u16>();

Instead, convert to bytes and then parse:

use zerovec::ZeroVec;

let bytes: &[u8] = &[0x7F, 0xF3, 0x01, 0x49, 0xF6, 0x01];
let zv_char: ZeroVec<char> =
    ZeroVec::parse_bytes(bytes).expect("valid code points");
let zv_u16: ZeroVec<u16> =
    zv_char.into_bytes().try_into_parsed().expect("infallible");

assert!(!zv_u16.is_owned());
assert_eq!(zv_u16.get(0), Some(0xF37F));
fn is_owned(self: &Self) -> bool

Check if this type is fully owned

fn as_maybe_borrowed(self: &Self) -> Option<&'a ZeroSlice<T>>

If this is a borrowed ZeroVec, return it as a slice that covers its lifetime parameter.

To infallibly get a ZeroSlice with a shorter lifetime, use ZeroVec::as_slice.

fn owned_capacity(self: &Self) -> Option<NonZeroUsize>

If the ZeroVec is owned, returns the capacity of the vector.

Otherwise, if the ZeroVec is borrowed, returns None.

Examples

use zerovec::ZeroVec;

let mut zv = ZeroVec::<u8>::new_borrowed(&[0, 1, 2, 3]);
assert!(!zv.is_owned());
assert_eq!(zv.owned_capacity(), None);

// Convert to owned without appending anything
zv.with_mut(|v| ());
assert!(zv.is_owned());
assert_eq!(zv.owned_capacity(), Some(4.try_into().unwrap()));

// Double the size by appending
zv.with_mut(|v| v.push(0));
assert!(zv.is_owned());
assert_eq!(zv.owned_capacity(), Some(8.try_into().unwrap()));

impl<'a, 'b, T> PartialEq for ZeroVec<'a, T>

fn eq(self: &Self, other: &ZeroVec<'b, T>) -> bool

impl<'a, T> Freeze for ZeroVec<'a, T>

impl<'a, T> MutableZeroVecLike for ZeroVec<'a, T>

fn zvl_insert(self: &mut Self, index: usize, value: &T)
fn zvl_remove(self: &mut Self, index: usize) -> T
fn zvl_replace(self: &mut Self, index: usize, value: &T) -> T
fn zvl_push(self: &mut Self, value: &T)
fn zvl_with_capacity(cap: usize) -> Self
fn zvl_clear(self: &mut Self)
fn zvl_reserve(self: &mut Self, addl: usize)
fn owned_as_t(o: &<Self as >::OwnedType) -> &T
fn zvl_from_borrowed(b: &'a ZeroSlice<T>) -> Self
fn zvl_as_borrowed_inner(self: &Self) -> Option<&'a ZeroSlice<T>>
fn zvl_permute(self: &mut Self, permutation: &mut [usize])

impl<'a, T> PartialEq for ZeroVec<'a, T>

fn eq(self: &Self, other: &ZeroSlice<T>) -> bool

impl<'a, T> RefUnwindSafe for ZeroVec<'a, T>

impl<'a, T> Unpin for ZeroVec<'a, T>

impl<'a, T> UnsafeUnpin for ZeroVec<'a, T>

impl<'a, T> UnwindSafe for ZeroVec<'a, T>

impl<'a, T> ZeroVecLike for ZeroVec<'a, T>

fn zvl_new_borrowed() -> &'static <Self as >::SliceVariant
fn zvl_binary_search_in_range(self: &Self, k: &T, range: Range<usize>) -> Option<Result<usize, usize>>
where
    T: Ord
fn 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 as >::ULE>
fn zvl_len(self: &Self) -> usize
fn zvl_as_borrowed(self: &Self) -> &ZeroSlice<T>
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 + AsULE> Yokeable for ZeroVec<'static, T>

fn transform(self: &'a Self) -> &'a <Self as >::Output
fn transform_owned(self: Self) -> <Self as >::Output
unsafe fn make(from: <Self as >::Output) -> Self
fn transform_mut<F>(self: &'a mut Self, f: F)
where
    F: 'static + for<'b> FnOnce(&'b mut <Self as >::Output)

impl<'a, T: AsULE + Ord> Ord for ZeroVec<'a, T>

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

impl<'a, T: AsULE + PartialOrd> PartialOrd for ZeroVec<'a, T>

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

impl<'a, T: AsULE> AsRef for ZeroVec<'a, T>

fn as_ref(self: &Self) -> &ZeroSlice<T>

impl<'a, T: AsULE> AsRef for ZeroVec<'a, T>

fn as_ref(self: &Self) -> &[<T as >::ULE]

impl<'a, T: AsULE> Clone for ZeroVec<'a, T>

fn clone(self: &Self) -> Self

impl<'a, T: AsULE> Default for ZeroVec<'a, T>

fn default() -> Self

impl<'a, T: AsULE> Deref for ZeroVec<'a, T>

fn deref(self: &Self) -> &<Self as >::Target

impl<'a, T: AsULE> From for ZeroVec<'a, T>

fn from(other: Vec<<T as >::ULE>) -> Self

impl<'a, T: AsULE> From for ZeroVec<'a, T>

fn from(other: &'a [<T as >::ULE]) -> Self

impl<'a, T: AsULE> Send for ZeroVec<'a, T>

impl<'a, T: AsULE> Sync for ZeroVec<'a, T>

impl<'zf, T> ZeroFrom for ZeroVec<'zf, T>

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

impl<'zf, T> ZeroFrom for ZeroVec<'zf, T>

fn zero_from(other: &'zf ZeroVec<'_, T>) -> Self

impl<P, T> Receiver for ZeroVec<'a, T>

impl<T> Any for ZeroVec<'a, T>

fn type_id(self: &Self) -> TypeId

impl<T> Borrow for ZeroVec<'a, T>

fn borrow(self: &Self) -> &T

impl<T> BorrowMut for ZeroVec<'a, T>

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

impl<T> CloneToUninit for ZeroVec<'a, T>

unsafe fn clone_to_uninit(self: &Self, dest: *mut u8)

impl<T> Debug for ZeroVec<'_, T>

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

impl<T> EncodeAsVarULE for ZeroVec<'_, T>

fn encode_var_ule_as_slices<R, impl FnOnce(&[&[u8]]) -> R: FnOnce(&[&[u8]]) -> R>(self: &Self, _: impl FnOnce(&[&[u8]]) -> R) -> R
fn encode_var_ule_len(self: &Self) -> usize
fn encode_var_ule_write(self: &Self, dst: &mut [u8])

impl<T> Eq for ZeroVec<'_, T>

impl<T> ErasedDestructor for ZeroVec<'a, T>

impl<T> From for ZeroVec<'a, T>

fn from(t: T) -> T

Returns the argument unchanged.

impl<T> PartialEq for ZeroVec<'_, T>

fn eq(self: &Self, other: &&[T]) -> bool

impl<T> ToOwned for ZeroVec<'a, T>

fn to_owned(self: &Self) -> T
fn clone_into(self: &Self, target: &mut T)

impl<T, N: usize> PartialEq for ZeroVec<'_, T>

fn eq(self: &Self, other: &[T; N]) -> bool

impl<T, U> Into for ZeroVec<'a, T>

fn into(self: Self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of [From]<T> for U chooses to do.

impl<T, U> TryFrom for ZeroVec<'a, T>

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

impl<T, U> TryInto for ZeroVec<'a, T>

fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error>

impl<T: AsULE> FromIterator for ZeroVec<'_, T>

fn from_iter<I>(iter: I) -> Self
where
    I: IntoIterator<Item = T>

Creates an owned ZeroVec from an iterator of values.