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 Vec
s.
§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_bytes(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>
impl<T: VarULE + ?Sized, F: VarZeroVecFormat> VarZeroSlice<T, F>
Sourcepub const unsafe fn from_bytes_unchecked(bytes: &[u8]) -> &Self
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()
.
Sourcepub fn len(&self) -> usize
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);
Sourcepub fn is_empty(&self) -> bool
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());
Sourcepub fn iter<'b>(&'b self) -> VarZeroSliceIter<'b, T, F> ⓘ
pub fn iter<'b>(&'b self) -> VarZeroSliceIter<'b, T, F> ⓘ
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");
Sourcepub fn get(&self, idx: usize) -> Option<&T>
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);
Sourcepub unsafe fn get_unchecked(&self, idx: usize) -> &T
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");
}
Sourcepub const fn as_bytes(&self) -> &[u8] ⓘ
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_bytes()
.
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_bytes(vzv.as_bytes()).unwrap());
Sourcepub const fn as_varzerovec<'a>(&'a self) -> VarZeroVec<'a, T, F>
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
Sourcepub fn parse_bytes<'a>(slice: &'a [u8]) -> Result<&'a Self, UleError>
pub fn parse_bytes<'a>(slice: &'a [u8]) -> Result<&'a Self, UleError>
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>
impl<T, F> VarZeroSlice<T, F>
Sourcepub fn binary_search(&self, x: &T) -> Result<usize, usize>
pub fn binary_search(&self, x: &T) -> Result<usize, usize>
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));
Sourcepub fn binary_search_in_range(
&self,
x: &T,
range: Range<usize>,
) -> Option<Result<usize, usize>>
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>
impl<T, F> VarZeroSlice<T, F>
Sourcepub fn binary_search_by(
&self,
predicate: impl FnMut(&T) -> Ordering,
) -> Result<usize, usize>
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));
Sourcepub fn binary_search_in_range_by(
&self,
predicate: impl FnMut(&T) -> Ordering,
range: Range<usize>,
) -> Option<Result<usize, usize>>
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>
impl<T: ?Sized, F: VarZeroVecFormat> AsRef<VarZeroSlice<T, F>> for VarZeroSlice<T, F>
Source§fn as_ref(&self) -> &VarZeroSlice<T, F>
fn as_ref(&self) -> &VarZeroSlice<T, F>
Source§impl<T, F: VarZeroVecFormat> Debug for VarZeroSlice<T, F>
impl<T, F: VarZeroVecFormat> Debug for VarZeroSlice<T, F>
Source§impl<T, E, F> EncodeAsVarULE<VarZeroSlice<T, F>> for &[E]
impl<T, E, F> EncodeAsVarULE<VarZeroSlice<T, F>> for &[E]
Source§fn encode_var_ule_as_slices<R>(&self, _: impl FnOnce(&[&[u8]]) -> R) -> R
fn encode_var_ule_as_slices<R>(&self, _: impl FnOnce(&[&[u8]]) -> R) -> R
cb
with a piecewise list of byte slices that when concatenated
produce the memory pattern of the corresponding instance of T
. Read moreSource§fn encode_var_ule_len(&self) -> usize
fn encode_var_ule_len(&self) -> usize
VarULE
typeSource§fn encode_var_ule_write(&self, dst: &mut [u8])
fn encode_var_ule_write(&self, dst: &mut [u8])
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>
impl<T, F> EncodeAsVarULE<VarZeroSlice<T, F>> for VarZeroVec<'_, T, F>
Source§fn encode_var_ule_as_slices<R>(&self, _: impl FnOnce(&[&[u8]]) -> R) -> R
fn encode_var_ule_as_slices<R>(&self, _: impl FnOnce(&[&[u8]]) -> R) -> R
cb
with a piecewise list of byte slices that when concatenated
produce the memory pattern of the corresponding instance of T
. Read moreSource§fn encode_var_ule_len(&self) -> usize
fn encode_var_ule_len(&self) -> usize
VarULE
typeSource§fn encode_var_ule_write(&self, dst: &mut [u8])
fn encode_var_ule_write(&self, dst: &mut [u8])
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>
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
fn encode_var_ule_as_slices<R>(&self, _: impl FnOnce(&[&[u8]]) -> R) -> R
cb
with a piecewise list of byte slices that when concatenated
produce the memory pattern of the corresponding instance of T
. Read moreSource§fn encode_var_ule_len(&self) -> usize
fn encode_var_ule_len(&self) -> usize
VarULE
typeSource§fn encode_var_ule_write(&self, dst: &mut [u8])
fn encode_var_ule_write(&self, dst: &mut [u8])
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>
impl<'a, T: ?Sized, F> From<&'a VarZeroSlice<T, F>> for VarZeroVec<'a, T, F>
Source§fn from(other: &'a VarZeroSlice<T, F>) -> Self
fn from(other: &'a VarZeroSlice<T, F>) -> Self
Source§impl<'a, T: ?Sized + VarULE, F: VarZeroVecFormat> From<&'a VarZeroSlice<T, F>> for VarZeroVecOwned<T, F>
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
fn from(other: &'a VarZeroSlice<T, F>) -> Self
Source§impl<T: VarULE + ?Sized, F: VarZeroVecFormat> Index<usize> for VarZeroSlice<T, F>
impl<T: VarULE + ?Sized, F: VarZeroVecFormat> Index<usize> for VarZeroSlice<T, F>
Source§impl<T: VarULE + ?Sized + Ord, F: VarZeroVecFormat> Ord for VarZeroSlice<T, F>
impl<T: VarULE + ?Sized + Ord, F: VarZeroVecFormat> Ord for VarZeroSlice<T, F>
Source§impl<T, F> PartialEq for VarZeroSlice<T, F>
impl<T, F> PartialEq for VarZeroSlice<T, F>
Source§impl<T: VarULE + ?Sized + PartialOrd, F: VarZeroVecFormat> PartialOrd for VarZeroSlice<T, F>
impl<T: VarULE + ?Sized + PartialOrd, F: VarZeroVecFormat> PartialOrd for VarZeroSlice<T, F>
Source§impl<T: VarULE + ?Sized + 'static, F: VarZeroVecFormat> VarULE for VarZeroSlice<T, F>
impl<T: VarULE + ?Sized + 'static, F: VarZeroVecFormat> VarULE for VarZeroSlice<T, F>
Source§fn validate_bytes(bytes: &[u8]) -> Result<(), UleError>
fn validate_bytes(bytes: &[u8]) -> Result<(), UleError>
&[u8]
. Read moreSource§unsafe fn from_bytes_unchecked(bytes: &[u8]) -> &Self
unsafe fn from_bytes_unchecked(bytes: &[u8]) -> &Self
&[u8]
, and return it as &Self
with the same lifetime, assuming
that this byte slice has previously been run through Self::parse_bytes()
with
success. Read moreSource§impl<'zf, T> ZeroFrom<'zf, VarZeroSlice<T>> for &'zf VarZeroSlice<T>
impl<'zf, T> ZeroFrom<'zf, VarZeroSlice<T>> for &'zf VarZeroSlice<T>
Source§fn zero_from(other: &'zf VarZeroSlice<T>) -> Self
fn zero_from(other: &'zf VarZeroSlice<T>) -> Self
C
into a struct that may retain references into C
.Source§impl<'zf, T, F: VarZeroVecFormat> ZeroFrom<'zf, VarZeroSlice<T, F>> for VarZeroVec<'zf, T, F>
impl<'zf, T, F: VarZeroVecFormat> ZeroFrom<'zf, VarZeroSlice<T, F>> for VarZeroVec<'zf, T, F>
Source§fn zero_from(other: &'zf VarZeroSlice<T, F>) -> Self
fn zero_from(other: &'zf VarZeroSlice<T, F>) -> Self
C
into a struct that may retain references into C
.Source§impl<T, F> ZeroVecLike<T> for VarZeroSlice<T, F>
impl<T, F> ZeroVecLike<T> for VarZeroSlice<T, F>
Source§type SliceVariant = VarZeroSlice<T, F>
type SliceVariant = VarZeroSlice<T, F>
Source§fn zvl_new_borrowed() -> &'static Self::SliceVariant
fn zvl_new_borrowed() -> &'static Self::SliceVariant
Source§fn zvl_binary_search(&self, k: &T) -> Result<usize, usize>where
T: Ord,
fn zvl_binary_search(&self, k: &T) -> Result<usize, usize>where
T: Ord,
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,
fn zvl_binary_search_in_range(
&self,
k: &T,
range: Range<usize>,
) -> Option<Result<usize, usize>>where
T: Ord,
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>
fn zvl_binary_search_by( &self, predicate: impl FnMut(&T) -> Ordering, ) -> Result<usize, usize>
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>>
fn zvl_binary_search_in_range_by( &self, predicate: impl FnMut(&T) -> Ordering, range: Range<usize>, ) -> Option<Result<usize, usize>>
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_as_borrowed(&self) -> &VarZeroSlice<T, F>
fn zvl_as_borrowed(&self) -> &VarZeroSlice<T, F>
&self
. Read moreSource§fn zvl_get_as_t<R>(g: &Self::GetType, f: impl FnOnce(&T) -> R) -> R
fn zvl_get_as_t<R>(g: &Self::GetType, f: impl FnOnce(&T) -> R) -> R
Source§fn zvl_is_ascending(&self) -> boolwhere
T: Ord,
fn zvl_is_ascending(&self) -> boolwhere
T: Ord,
T
s Ord
implSource§fn zvl_is_empty(&self) -> bool
fn zvl_is_empty(&self) -> bool
impl<T, F> Eq for VarZeroSlice<T, F>
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>
impl<T, F = Index16> !Sized for VarZeroSlice<T, F>
impl<T, F> Sync for VarZeroSlice<T, F>
impl<T, F> Unpin for VarZeroSlice<T, F>
impl<T, F> UnwindSafe for VarZeroSlice<T, F>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> EncodeAsVarULE<T> for T
impl<T> EncodeAsVarULE<T> for T
Source§fn encode_var_ule_as_slices<R>(&self, cb: impl FnOnce(&[&[u8]]) -> R) -> R
fn encode_var_ule_as_slices<R>(&self, cb: impl FnOnce(&[&[u8]]) -> R) -> R
cb
with a piecewise list of byte slices that when concatenated
produce the memory pattern of the corresponding instance of T
. Read moreSource§fn encode_var_ule_len(&self) -> usize
fn encode_var_ule_len(&self) -> usize
VarULE
typeSource§fn encode_var_ule_write(&self, dst: &mut [u8])
fn encode_var_ule_write(&self, dst: &mut [u8])
VarULE
type to the dst
buffer. dst
should
be the size of Self::encode_var_ule_len()
Layout§
Note: Most layout information is completely unstable and may even differ between compilations. The only exception is types with certain repr(...)
attributes. Please see the Rust Reference's “Type Layout” chapter for details on type layout guarantees.
Size: (unsized)