summaryrefslogtreecommitdiffstats
path: root/vendor/zerovec/src
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/zerovec/src')
-rw-r--r--vendor/zerovec/src/error.rs4
-rw-r--r--vendor/zerovec/src/flexzerovec/databake.rs41
-rw-r--r--vendor/zerovec/src/flexzerovec/owned.rs29
-rw-r--r--vendor/zerovec/src/flexzerovec/slice.rs12
-rw-r--r--vendor/zerovec/src/flexzerovec/vec.rs2
-rw-r--r--vendor/zerovec/src/hashmap/algorithms.rs162
-rw-r--r--vendor/zerovec/src/hashmap/mod.rs238
-rw-r--r--vendor/zerovec/src/hashmap/serde.rs147
-rw-r--r--vendor/zerovec/src/lib.rs6
-rw-r--r--vendor/zerovec/src/map/borrowed.rs4
-rw-r--r--vendor/zerovec/src/map/databake.rs28
-rw-r--r--vendor/zerovec/src/map/vecs.rs11
-rw-r--r--vendor/zerovec/src/map2d/databake.rs98
-rw-r--r--vendor/zerovec/src/map2d/map.rs14
-rw-r--r--vendor/zerovec/src/map2d/serde.rs10
-rw-r--r--vendor/zerovec/src/ule/chars.rs2
-rw-r--r--vendor/zerovec/src/ule/encode.rs4
-rw-r--r--vendor/zerovec/src/ule/multi.rs2
-rw-r--r--vendor/zerovec/src/ule/niche.rs16
-rw-r--r--vendor/zerovec/src/ule/option.rs16
-rw-r--r--vendor/zerovec/src/varzerovec/components.rs7
-rw-r--r--vendor/zerovec/src/varzerovec/databake.rs42
-rw-r--r--vendor/zerovec/src/varzerovec/owned.rs21
-rw-r--r--vendor/zerovec/src/varzerovec/vec.rs10
-rw-r--r--vendor/zerovec/src/yoke_impls.rs46
-rw-r--r--vendor/zerovec/src/zerofrom_impls.rs4
-rw-r--r--vendor/zerovec/src/zerovec/databake.rs30
-rw-r--r--vendor/zerovec/src/zerovec/mod.rs2
-rw-r--r--vendor/zerovec/src/zerovec/slice.rs27
29 files changed, 800 insertions, 235 deletions
diff --git a/vendor/zerovec/src/error.rs b/vendor/zerovec/src/error.rs
index 457a0d650..85de3ecc8 100644
--- a/vendor/zerovec/src/error.rs
+++ b/vendor/zerovec/src/error.rs
@@ -22,10 +22,10 @@ impl fmt::Display for ZeroVecError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
match *self {
ZeroVecError::InvalidLength { ty, len } => {
- write!(f, "Invalid length {} for slice of type {}", len, ty)
+ write!(f, "Invalid length {len} for slice of type {ty}")
}
ZeroVecError::ParseError { ty } => {
- write!(f, "Could not parse bytes to slice of type {}", ty)
+ write!(f, "Could not parse bytes to slice of type {ty}")
}
ZeroVecError::VarZeroVecFormatError => {
write!(f, "Invalid format for VarZeroVec buffer")
diff --git a/vendor/zerovec/src/flexzerovec/databake.rs b/vendor/zerovec/src/flexzerovec/databake.rs
index 23bf156ef..4ce5f7dea 100644
--- a/vendor/zerovec/src/flexzerovec/databake.rs
+++ b/vendor/zerovec/src/flexzerovec/databake.rs
@@ -8,16 +8,24 @@ use databake::*;
impl Bake for FlexZeroVec<'_> {
fn bake(&self, env: &CrateEnv) -> TokenStream {
env.insert("zerovec");
- let bytes = self.as_bytes();
- quote! { unsafe { ::zerovec::vecs::FlexZeroSlice::from_byte_slice_unchecked(&[#(#bytes),*]).as_flexzerovec() } }
+ if self.is_empty() {
+ quote! { ::zerovec::vecs::FlexZeroVec::new() }
+ } else {
+ let slice = self.as_ref().bake(env);
+ quote! { #slice.as_flexzerovec() }
+ }
}
}
impl Bake for &FlexZeroSlice {
fn bake(&self, env: &CrateEnv) -> TokenStream {
env.insert("zerovec");
- let bytes = self.as_bytes();
- quote! { unsafe { ::zerovec::vecs::FlexZeroSlice::from_byte_slice_unchecked(&[#(#bytes),*]) } }
+ if self.is_empty() {
+ quote! { ::zerovec::vecs::FlexZeroSlice::new_empty() }
+ } else {
+ let bytes = databake::Bake::bake(&self.as_bytes(), env);
+ quote! { unsafe { ::zerovec::vecs::FlexZeroSlice::from_byte_slice_unchecked(#bytes) } }
+ }
}
}
@@ -25,12 +33,16 @@ impl Bake for &FlexZeroSlice {
fn test_baked_vec() {
test_bake!(
FlexZeroVec,
+ const: crate::vecs::FlexZeroVec::new(),
+ zerovec
+ );
+ test_bake!(
+ FlexZeroVec,
const: unsafe {
- crate::vecs::FlexZeroSlice::from_byte_slice_unchecked(&[
- 2u8, 1u8, 0u8, 22u8, 0u8, 77u8, 1u8, 92u8, 17u8,
- ])
- .as_flexzerovec()
- },
+ crate::vecs::FlexZeroSlice::from_byte_slice_unchecked(
+ b"\x02\x01\0\x16\0M\x01\x11"
+ )
+ }.as_flexzerovec(),
zerovec
);
}
@@ -39,10 +51,15 @@ fn test_baked_vec() {
fn test_baked_slice() {
test_bake!(
&FlexZeroSlice,
+ const: crate::vecs::FlexZeroSlice::new_empty(),
+ zerovec
+ );
+ test_bake!(
+ &FlexZeroSlice,
const: unsafe {
- crate::vecs::FlexZeroSlice::from_byte_slice_unchecked(&[
- 2u8, 1u8, 0u8, 22u8, 0u8, 77u8, 1u8, 92u8, 17u8,
- ])
+ crate::vecs::FlexZeroSlice::from_byte_slice_unchecked(
+ b"\x02\x01\0\x16\0M\x01\x11"
+ )
},
zerovec
);
diff --git a/vendor/zerovec/src/flexzerovec/owned.rs b/vendor/zerovec/src/flexzerovec/owned.rs
index 1039c59ae..7d7bfb33d 100644
--- a/vendor/zerovec/src/flexzerovec/owned.rs
+++ b/vendor/zerovec/src/flexzerovec/owned.rs
@@ -30,7 +30,7 @@ impl FlexZeroVecOwned {
/// Obtains this [`FlexZeroVecOwned`] as a [`FlexZeroSlice`].
pub fn as_slice(&self) -> &FlexZeroSlice {
- let slice: &[u8] = &*self.0;
+ let slice: &[u8] = &self.0;
unsafe {
// safety: the slice is known to come from a valid parsed FlexZeroSlice
FlexZeroSlice::from_byte_slice_unchecked(slice)
@@ -39,7 +39,7 @@ impl FlexZeroVecOwned {
/// Mutably obtains this `FlexZeroVecOwned` as a [`FlexZeroSlice`].
pub(crate) fn as_mut_slice(&mut self) -> &mut FlexZeroSlice {
- let slice: &mut [u8] = &mut *self.0;
+ let slice: &mut [u8] = &mut self.0;
unsafe {
// safety: the slice is known to come from a valid parsed FlexZeroSlice
FlexZeroSlice::from_byte_slice_mut_unchecked(slice)
@@ -255,42 +255,27 @@ mod test {
use super::*;
fn check_contents(fzv: &FlexZeroSlice, expected: &[usize]) {
- assert_eq!(
- fzv.len(),
- expected.len(),
- "len: {:?} != {:?}",
- fzv,
- expected
- );
+ assert_eq!(fzv.len(), expected.len(), "len: {fzv:?} != {expected:?}");
assert_eq!(
fzv.is_empty(),
expected.is_empty(),
- "is_empty: {:?} != {:?}",
- fzv,
- expected
+ "is_empty: {fzv:?} != {expected:?}"
);
assert_eq!(
fzv.first(),
expected.first().copied(),
- "first: {:?} != {:?}",
- fzv,
- expected
+ "first: {fzv:?} != {expected:?}"
);
assert_eq!(
fzv.last(),
expected.last().copied(),
- "last: {:?} != {:?}",
- fzv,
- expected
+ "last: {fzv:?} != {expected:?}"
);
for i in 0..(expected.len() + 1) {
assert_eq!(
fzv.get(i),
expected.get(i).copied(),
- "@{}: {:?} != {:?}",
- i,
- fzv,
- expected
+ "@{i}: {fzv:?} != {expected:?}"
);
}
}
diff --git a/vendor/zerovec/src/flexzerovec/slice.rs b/vendor/zerovec/src/flexzerovec/slice.rs
index ee164d05b..fb58d6215 100644
--- a/vendor/zerovec/src/flexzerovec/slice.rs
+++ b/vendor/zerovec/src/flexzerovec/slice.rs
@@ -22,6 +22,12 @@ pub struct FlexZeroSlice {
data: [u8],
}
+impl fmt::Debug for FlexZeroSlice {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ self.to_vec().fmt(f)
+ }
+}
+
impl PartialEq for FlexZeroSlice {
fn eq(&self, other: &Self) -> bool {
self.width == other.width && self.data == other.data
@@ -507,12 +513,6 @@ impl FlexZeroSlice {
}
}
-impl fmt::Debug for &FlexZeroSlice {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "{:?}", self.to_vec())
- }
-}
-
#[inline]
pub(crate) fn get_item_width(item_bytes: &[u8; USIZE_WIDTH]) -> usize {
USIZE_WIDTH - item_bytes.iter().rev().take_while(|b| **b == 0).count()
diff --git a/vendor/zerovec/src/flexzerovec/vec.rs b/vendor/zerovec/src/flexzerovec/vec.rs
index a08f54e5d..dfd64ce65 100644
--- a/vendor/zerovec/src/flexzerovec/vec.rs
+++ b/vendor/zerovec/src/flexzerovec/vec.rs
@@ -134,7 +134,7 @@ impl<'a> FlexZeroVec<'a> {
/// let zv: FlexZeroVec = FlexZeroVec::new();
/// assert!(zv.is_empty());
/// ```
- pub fn new() -> Self {
+ pub const fn new() -> Self {
Self::Borrowed(FlexZeroSlice::new_empty())
}
diff --git a/vendor/zerovec/src/hashmap/algorithms.rs b/vendor/zerovec/src/hashmap/algorithms.rs
new file mode 100644
index 000000000..58ffc48f4
--- /dev/null
+++ b/vendor/zerovec/src/hashmap/algorithms.rs
@@ -0,0 +1,162 @@
+// This file is part of ICU4X. For terms of use, please see the file
+// called LICENSE at the top level of the ICU4X source tree
+// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
+
+use alloc::vec;
+use alloc::vec::Vec;
+use core::hash::{Hash, Hasher};
+use t1ha::T1haHasher;
+
+// Const seed to be used with [`T1haHasher::with_seed`].
+const SEED: u64 = 0xaabbccdd;
+
+/// Split the 64bit `hash` into (g, f0, f1).
+/// g denotes the highest 16bits of the hash modulo `m`, and is referred to as first level hash.
+/// (f0, f1) denotes the middle, and lower 24bits of the hash respectively.
+/// (f0, f1) are used to distribute the keys with same g, into distinct slots.
+///
+/// # Arguments
+///
+/// * `hash` - The hash to split.
+/// * `m` - The modulo used to split the hash.
+pub const fn split_hash64(hash: u64, m: usize) -> (usize, u32, u32) {
+ (
+ ((hash >> 48) as usize % m),
+ ((hash >> 24) as u32 & 0xffffff),
+ ((hash & 0xffffff) as u32),
+ )
+}
+
+/// Compute hash using [`T1haHasher`].
+pub fn compute_hash<K: Hash + ?Sized>(key: &K) -> u64 {
+ let mut hasher = T1haHasher::with_seed(SEED);
+ key.hash(&mut hasher);
+ hasher.finish()
+}
+
+/// Calculate the index using (f0, f1), (d0, d1) in modulo m.
+/// Returns [`None`] if d is (0, 0) or modulo is 0
+/// else returns the index computed using (f0 + f1 * d0 + d1) mod m.
+pub fn compute_index(f: (u32, u32), d: (u32, u32), m: u32) -> Option<usize> {
+ if d == (0, 0) || m == 0 {
+ None
+ } else {
+ Some((f.1.wrapping_mul(d.0).wrapping_add(f.0).wrapping_add(d.1) % m) as usize)
+ }
+}
+
+/// Compute displacements for the given `key_hashes`, which split the keys into distinct slots by a
+/// two-level hashing schema.
+/// Returns a tuple of where the first item is the displacement array and the second item is the
+/// reverse mapping used to permute keys, values into their slots.
+///
+/// 1. Split the hashes into (g, f0, f1).
+/// 2. Bucket and sort the split hash on g in descending order.
+/// 3. In decreasing order of bucket size, try until a (d0, d1) is found that splits the keys
+/// in the bucket into distinct slots.
+/// 4. Mark the slots for current bucket as occupied and store the reverse mapping.
+/// 5. Repeat untill all the keys have been assigned distinct slots.
+///
+/// # Arguments
+///
+/// * `key_hashes` - [`ExactSizeIterator`] over the hashed key values
+#[allow(clippy::indexing_slicing, clippy::unwrap_used)]
+pub fn compute_displacements(
+ key_hashes: impl ExactSizeIterator<Item = u64>,
+) -> (Vec<(u32, u32)>, Vec<usize>) {
+ let len = key_hashes.len();
+
+ // A vector to track the size of buckets for sorting.
+ let mut bucket_sizes = vec![0; len];
+
+ // A flattened representation of items in the buckets after applying first level hash function
+ let mut bucket_flatten = Vec::with_capacity(len);
+
+ // Compute initial displacement and bucket sizes
+
+ key_hashes.into_iter().enumerate().for_each(|(i, kh)| {
+ let h = split_hash64(kh, len);
+ bucket_sizes[h.0] += 1;
+ bucket_flatten.push((h, i))
+ });
+
+ // Sort by decreasing order of bucket_sizes.
+ bucket_flatten.sort_by(|&(ha, _), &(hb, _)| {
+ // ha.0, hb.0 are always within bounds of `bucket_sizes`
+ (bucket_sizes[hb.0], hb).cmp(&(bucket_sizes[ha.0], ha))
+ });
+
+ // Generation count while iterating buckets.
+ // Each trial of ((d0, d1), bucket chain) is a new generation.
+ // We use this to track which all slots are assigned for the current bucket chain.
+ let mut generation = 0;
+
+ // Whether a slot has been occupied by previous buckets with a different first level hash (different
+ // bucket chain).
+ let mut occupied = vec![false; len];
+
+ // Track generation count for the slots.
+ // A slot is empty if either it is unoccupied by the previous bucket chains and the
+ // assignment is not equal to generation.
+ let mut assignments = vec![0; len];
+
+ // Vec to store the displacements (saves us a recomputation of hash while assigning slots).
+ let mut current_displacements = Vec::with_capacity(16);
+
+ // (d0, d1) which splits the bucket into different slots
+ let mut displacements = vec![(0, 0); len];
+
+ // Vec to store mapping to the original order of keys.
+ // This is a permutation which will be applied to keys, values at the end.
+ let mut reverse_mapping = vec![0; len];
+
+ let mut start = 0;
+ while start < len {
+ // Bucket span with the same first level hash
+ // start is always within bounds of `bucket_flatten`
+ let g = bucket_flatten[start].0 .0;
+ // g is always within bounds of `bucket_sizes`
+ let end = start + bucket_sizes[g];
+ // start, end - 1 are always within bounds of `bucket_sizes`
+ let buckets = &bucket_flatten[start..end];
+
+ 'd0: for d0 in 0..len as u32 {
+ 'd1: for d1 in 0..len as u32 {
+ if (d0, d1) == (0, 0) {
+ continue;
+ }
+ current_displacements.clear();
+ generation += 1;
+
+ for ((_, f0, f1), _) in buckets {
+ let displacement_idx = compute_index((*f0, *f1), (d0, d1), len as u32).unwrap();
+
+ // displacement_idx is always within bounds
+ if occupied[displacement_idx] || assignments[displacement_idx] == generation {
+ continue 'd1;
+ }
+ assignments[displacement_idx] = generation;
+ current_displacements.push(displacement_idx);
+ }
+
+ // Successfully found a (d0, d1), store it as index g.
+ // g < displacements.len() due to modulo operation
+ displacements[g] = (d0, d1);
+
+ for (i, displacement_idx) in current_displacements.iter().enumerate() {
+ // `current_displacements` has same size as `buckets`
+ let (_, idx) = &buckets[i];
+
+ // displacement_idx is always within bounds
+ occupied[*displacement_idx] = true;
+ reverse_mapping[*displacement_idx] = *idx;
+ }
+ break 'd0;
+ }
+ }
+
+ start = end;
+ }
+
+ (displacements, reverse_mapping)
+}
diff --git a/vendor/zerovec/src/hashmap/mod.rs b/vendor/zerovec/src/hashmap/mod.rs
new file mode 100644
index 000000000..5d91114ad
--- /dev/null
+++ b/vendor/zerovec/src/hashmap/mod.rs
@@ -0,0 +1,238 @@
+// This file is part of ICU4X. For terms of use, please see the file
+// called LICENSE at the top level of the ICU4X source tree
+// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
+
+use crate::map::{MutableZeroVecLike, ZeroMapKV, ZeroVecLike};
+use crate::ZeroVec;
+use alloc::borrow::Borrow;
+use alloc::vec;
+use core::hash::Hash;
+
+pub mod algorithms;
+use algorithms::*;
+
+#[cfg(feature = "serde")]
+mod serde;
+
+/// A perfect zerohashmap optimized for lookups over immutable keys.
+///
+/// # Examples
+/// ```
+/// use zerovec::ZeroHashMap;
+///
+/// let kv = vec![(0, "a"), (1, "b"), (2, "c")];
+/// let hashmap: ZeroHashMap<i32, str> = ZeroHashMap::from_iter(kv.into_iter());
+/// assert_eq!(hashmap.get(&0), Some("a"));
+/// assert_eq!(hashmap.get(&2), Some("c"));
+/// assert_eq!(hashmap.get(&4), None);
+/// ```
+#[derive(Debug)]
+pub struct ZeroHashMap<'a, K, V>
+where
+ K: ZeroMapKV<'a> + ?Sized,
+ V: ZeroMapKV<'a> + ?Sized,
+{
+ /// Array of (d0, d1) which splits the keys with same first level hash into distinct
+ /// slots.
+ /// The ith index of the array splits the keys with first level hash i.
+ /// If no key with first level hash is found in the original keys, (0, 0) is used as an empty
+ /// placeholder.
+ displacements: ZeroVec<'a, (u32, u32)>,
+ keys: K::Container,
+ values: V::Container,
+}
+
+impl<'a, K, V> ZeroHashMap<'a, K, V>
+where
+ K: ZeroMapKV<'a> + ?Sized,
+ V: ZeroMapKV<'a> + ?Sized,
+{
+ /// The number of elements in the [`ZeroHashMap`].
+ pub fn len(&self) -> usize {
+ self.values.zvl_len()
+ }
+
+ /// Whether the [`ZeroHashMap`] is empty.
+ pub fn is_empty(&self) -> bool {
+ self.len() == 0
+ }
+}
+
+impl<'a, K, V> ZeroHashMap<'a, K, V>
+where
+ K: ZeroMapKV<'a> + ?Sized + Hash + Eq,
+ V: ZeroMapKV<'a> + ?Sized,
+{
+ /// Given a `key` return the index for the key or [`None`] if the key is absent.
+ fn index<A>(&self, key: &A) -> Option<usize>
+ where
+ A: Borrow<K> + ?Sized,
+ {
+ let hash = compute_hash(key.borrow());
+ let (g, f0, f1) = split_hash64(hash, self.len());
+
+ #[allow(clippy::unwrap_used)] // g is in-range
+ let (d0, d1) = self.displacements.get(g).unwrap();
+ let index = compute_index((f0, f1), (d0, d1), self.displacements.len() as u32)?;
+
+ #[allow(clippy::unwrap_used)] // index is in 0..self.keys.len()
+ let found = self.keys.zvl_get(index).unwrap();
+ if K::Container::zvl_get_as_t(found, |found| found == key.borrow()) {
+ Some(index)
+ } else {
+ None
+ }
+ }
+
+ /// Get the value corresponding to `key`.
+ /// If absent [`None`] is returned.
+ ///
+ /// # Example
+ /// ```
+ /// use zerovec::ZeroHashMap;
+ ///
+ /// let hashmap: ZeroHashMap<str, str> =
+ /// ZeroHashMap::from_iter(vec![("a", "A"), ("z", "Z")].into_iter());
+ ///
+ /// assert_eq!(hashmap.get("a"), Some("A"));
+ /// assert_eq!(hashmap.get("z"), Some("Z"));
+ /// assert_eq!(hashmap.get("0"), None);
+ /// ```
+ pub fn get<'b, A>(&'b self, key: &A) -> Option<&'b V::GetType>
+ where
+ A: Borrow<K> + ?Sized + 'b,
+ {
+ self.index(key).and_then(|i| self.values.zvl_get(i))
+ }
+
+ /// Returns whether `key` is contained in this hashmap
+ ///
+ /// # Example
+ /// ```rust
+ /// use zerovec::ZeroHashMap;
+ ///
+ /// let hashmap: ZeroHashMap<str, str> =
+ /// ZeroHashMap::from_iter(vec![("a", "A"), ("z", "Z")].into_iter());
+ ///
+ /// assert!(hashmap.contains_key("a"));
+ /// assert!(!hashmap.contains_key("p"));
+ /// ```
+ pub fn contains_key(&self, key: &K) -> bool {
+ self.index(key).is_some()
+ }
+}
+
+impl<'a, K, V> ZeroHashMap<'a, K, V>
+where
+ K: ZeroMapKV<'a> + ?Sized,
+ V: ZeroMapKV<'a> + ?Sized,
+{
+ // Produce an iterator over (key, value) pairs.
+ pub fn iter<'b>(
+ &'b self,
+ ) -> impl ExactSizeIterator<
+ Item = (
+ &'b <K as ZeroMapKV<'a>>::GetType,
+ &'b <V as ZeroMapKV<'a>>::GetType,
+ ),
+ > {
+ (0..self.len()).map(|index| {
+ (
+ #[allow(clippy::unwrap_used)] // index is in range
+ self.keys.zvl_get(index).unwrap(),
+ #[allow(clippy::unwrap_used)] // index is in range
+ self.values.zvl_get(index).unwrap(),
+ )
+ })
+ }
+
+ // Produce an iterator over keys.
+ pub fn iter_keys<'b>(
+ &'b self,
+ ) -> impl ExactSizeIterator<Item = &'b <K as ZeroMapKV<'a>>::GetType> {
+ #[allow(clippy::unwrap_used)] // index is in range
+ (0..self.len()).map(|index| self.keys.zvl_get(index).unwrap())
+ }
+
+ // Produce an iterator over values.
+ pub fn iter_values<'b>(
+ &'b self,
+ ) -> impl ExactSizeIterator<Item = &'b <V as ZeroMapKV<'a>>::GetType> {
+ #[allow(clippy::unwrap_used)] // index is in range
+ (0..self.len()).map(|index| self.values.zvl_get(index).unwrap())
+ }
+}
+
+impl<'a, K, V, A, B> FromIterator<(A, B)> for ZeroHashMap<'a, K, V>
+where
+ K: ZeroMapKV<'a> + ?Sized + Hash + Eq,
+ V: ZeroMapKV<'a> + ?Sized,
+ B: Borrow<V>,
+ A: Borrow<K>,
+{
+ /// Build a [`ZeroHashMap`] from an iterator returning (K, V) tuples.
+ ///
+ /// # Example
+ /// ```
+ /// use zerovec::ZeroHashMap;
+ ///
+ /// let kv: Vec<(i32, &str)> = vec![(1, "a"), (2, "b"), (3, "c"), (4, "d")];
+ /// let hashmap: ZeroHashMap<i32, str> = ZeroHashMap::from_iter(kv.into_iter());
+ /// assert_eq!(hashmap.get(&1), Some("a"));
+ /// assert_eq!(hashmap.get(&2), Some("b"));
+ /// assert_eq!(hashmap.get(&3), Some("c"));
+ /// assert_eq!(hashmap.get(&4), Some("d"));
+ /// ```
+ fn from_iter<T: IntoIterator<Item = (A, B)>>(iter: T) -> Self {
+ let iter = iter.into_iter();
+ let size_hint = match iter.size_hint() {
+ (_, Some(upper)) => upper,
+ (lower, None) => lower,
+ };
+
+ let mut key_hashes = vec![];
+ key_hashes.reserve(size_hint);
+ let mut keys = K::Container::zvl_with_capacity(size_hint);
+ let mut values = V::Container::zvl_with_capacity(size_hint);
+ for (k, v) in iter {
+ keys.zvl_push(k.borrow());
+ key_hashes.push(compute_hash(k.borrow()));
+ values.zvl_push(v.borrow());
+ }
+
+ let (displacements, mut reverse_mapping) = compute_displacements(key_hashes.into_iter());
+
+ keys.zvl_permute(&mut reverse_mapping.clone());
+ values.zvl_permute(&mut reverse_mapping);
+
+ Self {
+ displacements: ZeroVec::alloc_from_slice(&displacements),
+ values,
+ keys,
+ }
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use crate::ule::AsULE;
+ use rand::{distributions::Standard, Rng, SeedableRng};
+ use rand_pcg::Lcg64Xsh32;
+
+ #[test]
+ fn test_zhms_u64k_u64v() {
+ const N: usize = 65530;
+ let seed = u64::from_le_bytes(*b"testseed");
+ let rng = Lcg64Xsh32::seed_from_u64(seed);
+ let kv: Vec<(u64, u64)> = rng.sample_iter(&Standard).take(N).collect();
+ let hashmap: ZeroHashMap<u64, u64> =
+ ZeroHashMap::from_iter(kv.iter().map(|e| (&e.0, &e.1)));
+ for (k, v) in kv {
+ assert_eq!(
+ hashmap.get(&k).copied().map(<u64 as AsULE>::from_unaligned),
+ Some(v),
+ );
+ }
+ }
+}
diff --git a/vendor/zerovec/src/hashmap/serde.rs b/vendor/zerovec/src/hashmap/serde.rs
new file mode 100644
index 000000000..2d724ac05
--- /dev/null
+++ b/vendor/zerovec/src/hashmap/serde.rs
@@ -0,0 +1,147 @@
+// This file is part of ICU4X. For terms of use, please see the file
+// called LICENSE at the top level of the ICU4X source tree
+// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
+
+use super::ZeroHashMap;
+use crate::{
+ map::{ZeroMapKV, ZeroVecLike},
+ ZeroVec,
+};
+
+use serde::{de, Deserialize, Serialize};
+
+impl<'a, K, V> Serialize for ZeroHashMap<'a, K, V>
+where
+ K: ZeroMapKV<'a> + Serialize + ?Sized,
+ V: ZeroMapKV<'a> + Serialize + ?Sized,
+ K::Container: Serialize,
+ V::Container: Serialize,
+{
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: serde::Serializer,
+ {
+ (&self.displacements, &self.keys, &self.values).serialize(serializer)
+ }
+}
+
+impl<'de, 'a, K, V> Deserialize<'de> for ZeroHashMap<'a, K, V>
+where
+ K: ZeroMapKV<'a> + ?Sized,
+ V: ZeroMapKV<'a> + ?Sized,
+ K::Container: Deserialize<'de>,
+ V::Container: Deserialize<'de>,
+ 'de: 'a,
+{
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: serde::Deserializer<'de>,
+ {
+ let (displacements, keys, values): (ZeroVec<(u32, u32)>, K::Container, V::Container) =
+ Deserialize::deserialize(deserializer)?;
+ if keys.zvl_len() != values.zvl_len() {
+ return Err(de::Error::custom(
+ "Mismatched key and value sizes in ZeroHashMap",
+ ));
+ }
+ if displacements.zvl_len() != keys.zvl_len() {
+ return Err(de::Error::custom(
+ "Mismatched displacements and key, value sizes in ZeroHashMap",
+ ));
+ }
+ Ok(Self {
+ displacements,
+ keys,
+ values,
+ })
+ }
+}
+
+#[cfg(test)]
+mod test {
+ use crate::{VarZeroVec, ZeroHashMap, ZeroVec};
+ use serde::{Deserialize, Serialize};
+
+ const JSON_STR: &str = "[[[0,1],[0,0],[0,1]],[2,1,0],[\"c\",\"b\",\"a\"]]";
+
+ const BINCODE_BYTES: &[u8] = &[
+ 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0,
+ 3, 0, 0, 0, 0, 0, 1, 0, 2, 0, 99, 98, 97,
+ ];
+
+ #[derive(Serialize, Deserialize)]
+ struct DeriveTestZeroHashMap<'data> {
+ #[serde(borrow)]
+ _data: ZeroHashMap<'data, str, [u8]>,
+ }
+
+ fn make_zerohashmap() -> ZeroHashMap<'static, u32, str> {
+ ZeroHashMap::from_iter(vec![(0, "a"), (1, "b"), (2, "c")].into_iter())
+ }
+
+ fn build_invalid_hashmap_str(
+ displacements: Vec<(u32, u32)>,
+ keys: Vec<u32>,
+ values: Vec<&str>,
+ ) -> String {
+ let invalid_hm: ZeroHashMap<u32, str> = ZeroHashMap {
+ displacements: ZeroVec::alloc_from_slice(&displacements),
+ keys: ZeroVec::alloc_from_slice(&keys),
+ values: VarZeroVec::<str>::from(&values),
+ };
+ serde_json::to_string(&invalid_hm).expect("serialize")
+ }
+
+ #[test]
+ fn test_invalid_deser_zhm() {
+ // Invalid hashmap |keys| != |values|
+ let mut invalid_hm_str =
+ build_invalid_hashmap_str(vec![(0, 1), (0, 0)], vec![1, 2], vec!["a", "b", "c"]);
+
+ assert_eq!(
+ serde_json::from_str::<ZeroHashMap<u32, str>>(&invalid_hm_str)
+ .unwrap_err()
+ .to_string(),
+ "Mismatched key and value sizes in ZeroHashMap"
+ );
+
+ // Invalid hashmap |displacements| != |keys| == |values|
+ // |displacements| = 2, |keys| = 3, |values| = 3
+ invalid_hm_str =
+ build_invalid_hashmap_str(vec![(0, 1), (0, 0)], vec![2, 1, 0], vec!["a", "b", "c"]);
+
+ assert_eq!(
+ serde_json::from_str::<ZeroHashMap<u32, str>>(&invalid_hm_str)
+ .unwrap_err()
+ .to_string(),
+ "Mismatched displacements and key, value sizes in ZeroHashMap"
+ );
+ }
+
+ #[test]
+ fn test_serde_valid_deser_zhm() {
+ let hm = make_zerohashmap();
+ let json_str = serde_json::to_string(&hm).expect("serialize");
+ assert_eq!(json_str, JSON_STR);
+ let deserialized_hm: ZeroHashMap<u32, str> =
+ serde_json::from_str(JSON_STR).expect("deserialize");
+ assert_eq!(
+ hm.iter().collect::<Vec<_>>(),
+ deserialized_hm.iter().collect::<Vec<_>>()
+ );
+ }
+
+ #[test]
+ fn test_bincode_zhm() {
+ let hm = make_zerohashmap();
+ let bincode_bytes = bincode::serialize(&hm).expect("serialize");
+ assert_eq!(bincode_bytes, BINCODE_BYTES);
+ let deserialized_hm: ZeroHashMap<u32, str> =
+ bincode::deserialize(BINCODE_BYTES).expect("deserialize");
+ assert_eq!(
+ hm.iter().collect::<Vec<_>>(),
+ deserialized_hm.iter().collect::<Vec<_>>()
+ );
+ }
+}
diff --git a/vendor/zerovec/src/lib.rs b/vendor/zerovec/src/lib.rs
index b8b292488..add52f113 100644
--- a/vendor/zerovec/src/lib.rs
+++ b/vendor/zerovec/src/lib.rs
@@ -204,7 +204,7 @@
clippy::panic,
clippy::exhaustive_structs,
clippy::exhaustive_enums,
- // TODO(#2266): enable missing_debug_implementations,
+ missing_debug_implementations,
)
)]
// this crate does a lot of nuanced lifetime manipulation, being explicit
@@ -215,6 +215,8 @@ extern crate alloc;
mod error;
mod flexzerovec;
+#[cfg(feature = "hashmap")]
+pub mod hashmap;
mod map;
mod map2d;
#[cfg(test)]
@@ -231,6 +233,8 @@ mod yoke_impls;
mod zerofrom_impls;
pub use crate::error::ZeroVecError;
+#[cfg(feature = "hashmap")]
+pub use crate::hashmap::ZeroHashMap;
pub use crate::map::map::ZeroMap;
pub use crate::map2d::map::ZeroMap2d;
pub use crate::varzerovec::{slice::VarZeroSlice, vec::VarZeroVec};
diff --git a/vendor/zerovec/src/map/borrowed.rs b/vendor/zerovec/src/map/borrowed.rs
index 9d0854601..bc93ee497 100644
--- a/vendor/zerovec/src/map/borrowed.rs
+++ b/vendor/zerovec/src/map/borrowed.rs
@@ -277,8 +277,8 @@ where
/// to `K::ULE` and `V::ULE`, in cases when `K` and `V` are fixed-size
#[allow(clippy::needless_lifetimes)] // Lifetime is necessary in impl Trait
pub fn iter_copied<'b: 'a>(&'b self) -> impl Iterator<Item = (K, V)> + 'b {
- let keys = &*self.keys;
- let values = &*self.values;
+ let keys = &self.keys;
+ let values = &self.values;
let len = self.keys.zvl_len();
(0..len).map(move |idx| {
(
diff --git a/vendor/zerovec/src/map/databake.rs b/vendor/zerovec/src/map/databake.rs
index d98b48f9f..fceb6a966 100644
--- a/vendor/zerovec/src/map/databake.rs
+++ b/vendor/zerovec/src/map/databake.rs
@@ -43,16 +43,14 @@ fn test_baked_map() {
#[allow(unused_unsafe)]
crate::ZeroMap::from_parts_unchecked(
unsafe {
- crate::VarZeroVec::from_bytes_unchecked(&[
- 2u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 0u8, 0u8, 97u8,
- 100u8, 98u8, 99u8,
- ])
+ crate::VarZeroVec::from_bytes_unchecked(
+ b"\x02\0\0\0\0\0\0\0\x02\0\0\0adbc"
+ )
},
unsafe {
- crate::VarZeroVec::from_bytes_unchecked(&[
- 2u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 4u8, 0u8, 0u8, 0u8, 69u8, 82u8,
- 65u8, 49u8, 69u8, 82u8, 65u8, 48u8,
- ])
+ crate::VarZeroVec::from_bytes_unchecked(
+ b"\x02\0\0\0\0\0\0\0\x04\0\0\0ERA1ERA0"
+ )
},
)
},
@@ -68,16 +66,14 @@ fn test_baked_borrowed_map() {
#[allow(unused_unsafe)]
crate::maps::ZeroMapBorrowed::from_parts_unchecked(
unsafe {
- crate::VarZeroSlice::from_bytes_unchecked(&[
- 2u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 0u8, 0u8, 97u8,
- 100u8, 98u8, 99u8,
- ])
+ crate::VarZeroSlice::from_bytes_unchecked(
+ b"\x02\0\0\0\0\0\0\0\x02\0\0\0adbc"
+ )
},
unsafe {
- crate::VarZeroSlice::from_bytes_unchecked(&[
- 2u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 4u8, 0u8, 0u8, 0u8, 69u8, 82u8,
- 65u8, 49u8, 69u8, 82u8, 65u8, 48u8,
- ])
+ crate::VarZeroSlice::from_bytes_unchecked(
+ b"\x02\0\0\0\0\0\0\0\x04\0\0\0ERA1ERA0"
+ )
},
)
},
diff --git a/vendor/zerovec/src/map/vecs.rs b/vendor/zerovec/src/map/vecs.rs
index b460e5967..5ee93d3fe 100644
--- a/vendor/zerovec/src/map/vecs.rs
+++ b/vendor/zerovec/src/map/vecs.rs
@@ -195,7 +195,7 @@ where
where
T: Ord,
{
- let zs: &ZeroSlice<T> = &*self;
+ let zs: &ZeroSlice<T> = self;
zs.zvl_binary_search_in_range(k, range)
}
fn zvl_binary_search_by(
@@ -209,7 +209,7 @@ where
predicate: impl FnMut(&T) -> Ordering,
range: Range<usize>,
) -> Option<Result<usize, usize>> {
- let zs: &ZeroSlice<T> = &*self;
+ let zs: &ZeroSlice<T> = self;
zs.zvl_binary_search_in_range_by(predicate, range)
}
fn zvl_get(&self, index: usize) -> Option<&T::ULE> {
@@ -218,11 +218,9 @@ where
fn zvl_len(&self) -> usize {
ZeroSlice::len(self)
}
-
fn zvl_as_borrowed(&self) -> &ZeroSlice<T> {
- &*self
+ self
}
-
#[inline]
fn zvl_get_as_t<R>(g: &Self::GetType, f: impl FnOnce(&T) -> R) -> R {
f(&T::from_unaligned(*g))
@@ -274,7 +272,6 @@ where
fn zvl_len(&self) -> usize {
ZeroSlice::len(self)
}
-
fn zvl_as_borrowed(&self) -> &ZeroSlice<T> {
self
}
@@ -565,7 +562,7 @@ impl<'a> ZeroVecLike<usize> for FlexZeroVec<'a> {
}
fn zvl_as_borrowed(&self) -> &FlexZeroSlice {
- &*self
+ self
}
#[inline]
diff --git a/vendor/zerovec/src/map2d/databake.rs b/vendor/zerovec/src/map2d/databake.rs
index 90ab970bb..65e475c32 100644
--- a/vendor/zerovec/src/map2d/databake.rs
+++ b/vendor/zerovec/src/map2d/databake.rs
@@ -51,49 +51,24 @@ fn test_baked_map() {
#[allow(unused_unsafe)]
crate::ZeroMap2d::from_parts_unchecked(
unsafe {
- crate::VarZeroVec::from_bytes_unchecked(&[
- 97u8, 114u8, 99u8, 97u8, 122u8, 0u8, 99u8, 117u8, 0u8, 101u8, 110u8, 0u8,
- 102u8, 102u8, 0u8, 103u8, 114u8, 99u8, 107u8, 107u8, 0u8, 107u8, 117u8,
- 0u8, 107u8, 121u8, 0u8, 108u8, 105u8, 102u8, 109u8, 97u8, 110u8, 109u8,
- 110u8, 0u8, 112u8, 97u8, 0u8, 112u8, 97u8, 108u8, 115u8, 100u8, 0u8, 116u8,
- 103u8, 0u8, 117u8, 103u8, 0u8, 117u8, 110u8, 114u8, 117u8, 122u8, 0u8,
- 121u8, 117u8, 101u8, 122u8, 104u8, 0u8,
- ])
+ crate::VarZeroVec::from_bytes_unchecked(
+ b"arcaz\0cu\0en\0ff\0grckk\0ku\0ky\0lifmanmn\0pa\0palsd\0tg\0ug\0unruz\0yuezh\0"
+ )
},
unsafe {
- crate::ZeroVec::from_bytes_unchecked(&[
- 2u8, 0u8, 0u8, 0u8, 3u8, 0u8, 0u8, 0u8, 4u8, 0u8, 0u8, 0u8, 5u8, 0u8, 0u8,
- 0u8, 6u8, 0u8, 0u8, 0u8, 7u8, 0u8, 0u8, 0u8, 8u8, 0u8, 0u8, 0u8, 10u8, 0u8,
- 0u8, 0u8, 12u8, 0u8, 0u8, 0u8, 13u8, 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8,
- 15u8, 0u8, 0u8, 0u8, 16u8, 0u8, 0u8, 0u8, 17u8, 0u8, 0u8, 0u8, 20u8, 0u8,
- 0u8, 0u8, 21u8, 0u8, 0u8, 0u8, 22u8, 0u8, 0u8, 0u8, 23u8, 0u8, 0u8, 0u8,
- 24u8, 0u8, 0u8, 0u8, 25u8, 0u8, 0u8, 0u8, 28u8, 0u8, 0u8, 0u8,
- ])
+ crate::ZeroVec::from_bytes_unchecked(
+ b"\x02\0\0\0\x03\0\0\0\x04\0\0\0\x05\0\0\0\x06\0\0\0\x07\0\0\0\x08\0\0\0\n\0\0\0\x0C\0\0\0\r\0\0\0\x0E\0\0\0\x0F\0\0\0\x10\0\0\0\x11\0\0\0\x14\0\0\0\x15\0\0\0\x16\0\0\0\x17\0\0\0\x18\0\0\0\x19\0\0\0\x1C\0\0\0"
+ )
},
unsafe {
- crate::VarZeroVec::from_bytes_unchecked(&[
- 78u8, 98u8, 97u8, 116u8, 80u8, 97u8, 108u8, 109u8, 65u8, 114u8, 97u8, 98u8,
- 71u8, 108u8, 97u8, 103u8, 83u8, 104u8, 97u8, 119u8, 65u8, 100u8, 108u8,
- 109u8, 76u8, 105u8, 110u8, 98u8, 65u8, 114u8, 97u8, 98u8, 65u8, 114u8,
- 97u8, 98u8, 89u8, 101u8, 122u8, 105u8, 65u8, 114u8, 97u8, 98u8, 76u8, 97u8,
- 116u8, 110u8, 76u8, 105u8, 109u8, 98u8, 78u8, 107u8, 111u8, 111u8, 77u8,
- 111u8, 110u8, 103u8, 65u8, 114u8, 97u8, 98u8, 80u8, 104u8, 108u8, 112u8,
- 68u8, 101u8, 118u8, 97u8, 75u8, 104u8, 111u8, 106u8, 83u8, 105u8, 110u8,
- 100u8, 65u8, 114u8, 97u8, 98u8, 67u8, 121u8, 114u8, 108u8, 68u8, 101u8,
- 118u8, 97u8, 65u8, 114u8, 97u8, 98u8, 72u8, 97u8, 110u8, 115u8, 66u8,
- 111u8, 112u8, 111u8, 72u8, 97u8, 110u8, 98u8, 72u8, 97u8, 110u8, 116u8,
- ])
+ crate::VarZeroVec::from_bytes_unchecked(
+ b"NbatPalmArabGlagShawAdlmLinbArabArabYeziArabLatnLimbNkooMongArabPhlpDevaKhojSindArabCyrlDevaArabHansBopoHanbHant"
+ )
},
unsafe {
- crate::VarZeroVec::from_bytes_unchecked(&[
- 74u8, 79u8, 0u8, 83u8, 89u8, 0u8, 73u8, 82u8, 0u8, 66u8, 71u8, 0u8, 71u8,
- 66u8, 0u8, 71u8, 78u8, 0u8, 71u8, 82u8, 0u8, 67u8, 78u8, 0u8, 73u8, 81u8,
- 0u8, 71u8, 69u8, 0u8, 67u8, 78u8, 0u8, 84u8, 82u8, 0u8, 73u8, 78u8, 0u8,
- 71u8, 78u8, 0u8, 67u8, 78u8, 0u8, 80u8, 75u8, 0u8, 67u8, 78u8, 0u8, 73u8,
- 78u8, 0u8, 73u8, 78u8, 0u8, 73u8, 78u8, 0u8, 80u8, 75u8, 0u8, 75u8, 90u8,
- 0u8, 78u8, 80u8, 0u8, 65u8, 70u8, 0u8, 67u8, 78u8, 0u8, 84u8, 87u8, 0u8,
- 84u8, 87u8, 0u8, 84u8, 87u8, 0u8,
- ])
+ crate::VarZeroVec::from_bytes_unchecked(
+ b"JO\0SY\0IR\0BG\0GB\0GN\0GR\0CN\0IQ\0GE\0CN\0TR\0IN\0GN\0CN\0PK\0CN\0IN\0IN\0IN\0PK\0KZ\0NP\0AF\0CN\0TW\0TW\0TW\0"
+ )
},
)
},
@@ -109,49 +84,24 @@ fn test_baked_borrowed_map() {
#[allow(unused_unsafe)]
crate::maps::ZeroMap2dBorrowed::from_parts_unchecked(
unsafe {
- crate::VarZeroSlice::from_bytes_unchecked(&[
- 97u8, 114u8, 99u8, 97u8, 122u8, 0u8, 99u8, 117u8, 0u8, 101u8, 110u8, 0u8,
- 102u8, 102u8, 0u8, 103u8, 114u8, 99u8, 107u8, 107u8, 0u8, 107u8, 117u8,
- 0u8, 107u8, 121u8, 0u8, 108u8, 105u8, 102u8, 109u8, 97u8, 110u8, 109u8,
- 110u8, 0u8, 112u8, 97u8, 0u8, 112u8, 97u8, 108u8, 115u8, 100u8, 0u8, 116u8,
- 103u8, 0u8, 117u8, 103u8, 0u8, 117u8, 110u8, 114u8, 117u8, 122u8, 0u8,
- 121u8, 117u8, 101u8, 122u8, 104u8, 0u8,
- ])
+ crate::VarZeroSlice::from_bytes_unchecked(
+ b"arcaz\0cu\0en\0ff\0grckk\0ku\0ky\0lifmanmn\0pa\0palsd\0tg\0ug\0unruz\0yuezh\0"
+ )
},
unsafe {
- crate::ZeroSlice::from_bytes_unchecked(&[
- 2u8, 0u8, 0u8, 0u8, 3u8, 0u8, 0u8, 0u8, 4u8, 0u8, 0u8, 0u8, 5u8, 0u8, 0u8,
- 0u8, 6u8, 0u8, 0u8, 0u8, 7u8, 0u8, 0u8, 0u8, 8u8, 0u8, 0u8, 0u8, 10u8, 0u8,
- 0u8, 0u8, 12u8, 0u8, 0u8, 0u8, 13u8, 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8,
- 15u8, 0u8, 0u8, 0u8, 16u8, 0u8, 0u8, 0u8, 17u8, 0u8, 0u8, 0u8, 20u8, 0u8,
- 0u8, 0u8, 21u8, 0u8, 0u8, 0u8, 22u8, 0u8, 0u8, 0u8, 23u8, 0u8, 0u8, 0u8,
- 24u8, 0u8, 0u8, 0u8, 25u8, 0u8, 0u8, 0u8, 28u8, 0u8, 0u8, 0u8,
- ])
+ crate::ZeroSlice::from_bytes_unchecked(
+ b"\x02\0\0\0\x03\0\0\0\x04\0\0\0\x05\0\0\0\x06\0\0\0\x07\0\0\0\x08\0\0\0\n\0\0\0\x0C\0\0\0\r\0\0\0\x0E\0\0\0\x0F\0\0\0\x10\0\0\0\x11\0\0\0\x14\0\0\0\x15\0\0\0\x16\0\0\0\x17\0\0\0\x18\0\0\0\x19\0\0\0\x1C\0\0\0"
+ )
},
unsafe {
- crate::VarZeroSlice::from_bytes_unchecked(&[
- 78u8, 98u8, 97u8, 116u8, 80u8, 97u8, 108u8, 109u8, 65u8, 114u8, 97u8, 98u8,
- 71u8, 108u8, 97u8, 103u8, 83u8, 104u8, 97u8, 119u8, 65u8, 100u8, 108u8,
- 109u8, 76u8, 105u8, 110u8, 98u8, 65u8, 114u8, 97u8, 98u8, 65u8, 114u8,
- 97u8, 98u8, 89u8, 101u8, 122u8, 105u8, 65u8, 114u8, 97u8, 98u8, 76u8, 97u8,
- 116u8, 110u8, 76u8, 105u8, 109u8, 98u8, 78u8, 107u8, 111u8, 111u8, 77u8,
- 111u8, 110u8, 103u8, 65u8, 114u8, 97u8, 98u8, 80u8, 104u8, 108u8, 112u8,
- 68u8, 101u8, 118u8, 97u8, 75u8, 104u8, 111u8, 106u8, 83u8, 105u8, 110u8,
- 100u8, 65u8, 114u8, 97u8, 98u8, 67u8, 121u8, 114u8, 108u8, 68u8, 101u8,
- 118u8, 97u8, 65u8, 114u8, 97u8, 98u8, 72u8, 97u8, 110u8, 115u8, 66u8,
- 111u8, 112u8, 111u8, 72u8, 97u8, 110u8, 98u8, 72u8, 97u8, 110u8, 116u8,
- ])
+ crate::VarZeroSlice::from_bytes_unchecked(
+ b"NbatPalmArabGlagShawAdlmLinbArabArabYeziArabLatnLimbNkooMongArabPhlpDevaKhojSindArabCyrlDevaArabHansBopoHanbHant"
+ )
},
unsafe {
- crate::VarZeroSlice::from_bytes_unchecked(&[
- 74u8, 79u8, 0u8, 83u8, 89u8, 0u8, 73u8, 82u8, 0u8, 66u8, 71u8, 0u8, 71u8,
- 66u8, 0u8, 71u8, 78u8, 0u8, 71u8, 82u8, 0u8, 67u8, 78u8, 0u8, 73u8, 81u8,
- 0u8, 71u8, 69u8, 0u8, 67u8, 78u8, 0u8, 84u8, 82u8, 0u8, 73u8, 78u8, 0u8,
- 71u8, 78u8, 0u8, 67u8, 78u8, 0u8, 80u8, 75u8, 0u8, 67u8, 78u8, 0u8, 73u8,
- 78u8, 0u8, 73u8, 78u8, 0u8, 73u8, 78u8, 0u8, 80u8, 75u8, 0u8, 75u8, 90u8,
- 0u8, 78u8, 80u8, 0u8, 65u8, 70u8, 0u8, 67u8, 78u8, 0u8, 84u8, 87u8, 0u8,
- 84u8, 87u8, 0u8, 84u8, 87u8, 0u8,
- ])
+ crate::VarZeroSlice::from_bytes_unchecked(
+ b"JO\0SY\0IR\0BG\0GB\0GN\0GR\0CN\0IQ\0GE\0CN\0TR\0IN\0GN\0CN\0PK\0CN\0IN\0IN\0IN\0PK\0KZ\0NP\0AF\0CN\0TW\0TW\0TW\0"
+ )
},
)
},
diff --git a/vendor/zerovec/src/map2d/map.rs b/vendor/zerovec/src/map2d/map.rs
index e6545dfa5..8bdefe792 100644
--- a/vendor/zerovec/src/map2d/map.rs
+++ b/vendor/zerovec/src/map2d/map.rs
@@ -160,7 +160,7 @@ where
pub fn as_borrowed(&'a self) -> ZeroMap2dBorrowed<'a, K0, K1, V> {
ZeroMap2dBorrowed {
keys0: self.keys0.zvl_as_borrowed(),
- joiner: &*self.joiner,
+ joiner: &self.joiner,
keys1: self.keys1.zvl_as_borrowed(),
values: self.values.zvl_as_borrowed(),
}
@@ -710,7 +710,7 @@ mod test {
let mut zm2d = ZeroMap2d::<u16, str, str>::new();
assert_eq!(
- format!("{:?}", zm2d),
+ format!("{zm2d:?}"),
"ZeroMap2d { keys0: ZeroVec([]), joiner: ZeroVec([]), keys1: [], values: [] }"
);
assert_eq!(zm2d.get0(&0), None);
@@ -718,7 +718,7 @@ mod test {
let result = zm2d.try_append(&3, "ccc", "CCC");
assert!(matches!(result, None));
- assert_eq!(format!("{:?}", zm2d), "ZeroMap2d { keys0: ZeroVec([3]), joiner: ZeroVec([1]), keys1: [\"ccc\"], values: [\"CCC\"] }");
+ assert_eq!(format!("{zm2d:?}"), "ZeroMap2d { keys0: ZeroVec([3]), joiner: ZeroVec([1]), keys1: [\"ccc\"], values: [\"CCC\"] }");
assert_eq!(zm2d.get0(&0), None);
assert_eq!(zm2d.get0(&3).unwrap().get1(""), None);
assert_eq!(zm2d.get_2d(&3, "ccc"), Some("CCC"));
@@ -727,7 +727,7 @@ mod test {
let result = zm2d.try_append(&3, "eee", "EEE");
assert!(matches!(result, None));
- assert_eq!(format!("{:?}", zm2d), "ZeroMap2d { keys0: ZeroVec([3]), joiner: ZeroVec([2]), keys1: [\"ccc\", \"eee\"], values: [\"CCC\", \"EEE\"] }");
+ assert_eq!(format!("{zm2d:?}"), "ZeroMap2d { keys0: ZeroVec([3]), joiner: ZeroVec([2]), keys1: [\"ccc\", \"eee\"], values: [\"CCC\", \"EEE\"] }");
assert_eq!(zm2d.get0(&0), None);
assert_eq!(zm2d.get0(&3).unwrap().get1(""), None);
assert_eq!(zm2d.get_2d(&3, "ccc"), Some("CCC"));
@@ -751,7 +751,7 @@ mod test {
let result = zm2d.try_append(&9, "yyy", "YYY");
assert!(matches!(result, None));
- assert_eq!(format!("{:?}", zm2d), "ZeroMap2d { keys0: ZeroVec([3, 5, 7, 9]), joiner: ZeroVec([2, 3, 6, 7]), keys1: [\"ccc\", \"eee\", \"ddd\", \"ddd\", \"eee\", \"www\", \"yyy\"], values: [\"CCC\", \"EEE\", \"DD1\", \"DD2\", \"EEE\", \"WWW\", \"YYY\"] }");
+ assert_eq!(format!("{zm2d:?}"), "ZeroMap2d { keys0: ZeroVec([3, 5, 7, 9]), joiner: ZeroVec([2, 3, 6, 7]), keys1: [\"ccc\", \"eee\", \"ddd\", \"ddd\", \"eee\", \"www\", \"yyy\"], values: [\"CCC\", \"EEE\", \"DD1\", \"DD2\", \"EEE\", \"WWW\", \"YYY\"] }");
assert_eq!(zm2d.get0(&0), None);
assert_eq!(zm2d.get0(&3).unwrap().get1(""), None);
assert_eq!(zm2d.get_2d(&3, "ccc"), Some("CCC"));
@@ -782,7 +782,7 @@ mod test {
zm2d.insert(&6, "mmm", "MM1");
zm2d.insert(&6, "nnn", "NNN");
- assert_eq!(format!("{:?}", zm2d), "ZeroMap2d { keys0: ZeroVec([3, 5, 6, 7, 9]), joiner: ZeroVec([3, 4, 7, 10, 11]), keys1: [\"ccc\", \"eee\", \"mmm\", \"ddd\", \"ddd\", \"mmm\", \"nnn\", \"ddd\", \"eee\", \"www\", \"yyy\"], values: [\"CCC\", \"EEE\", \"MM0\", \"DD1\", \"DD3\", \"MM1\", \"NNN\", \"DD2\", \"EEE\", \"WWW\", \"YYY\"] }");
+ assert_eq!(format!("{zm2d:?}"), "ZeroMap2d { keys0: ZeroVec([3, 5, 6, 7, 9]), joiner: ZeroVec([3, 4, 7, 10, 11]), keys1: [\"ccc\", \"eee\", \"mmm\", \"ddd\", \"ddd\", \"mmm\", \"nnn\", \"ddd\", \"eee\", \"www\", \"yyy\"], values: [\"CCC\", \"EEE\", \"MM0\", \"DD1\", \"DD3\", \"MM1\", \"NNN\", \"DD2\", \"EEE\", \"WWW\", \"YYY\"] }");
assert_eq!(zm2d.get0(&0), None);
assert_eq!(zm2d.get0(&3).unwrap().get1(""), None);
assert_eq!(zm2d.get_2d(&3, "ccc"), Some("CCC"));
@@ -822,6 +822,6 @@ mod test {
let result = zm2d.remove(&9, "yyy"); // last element
assert_eq!(result.as_deref(), Some("YYY"));
- assert_eq!(format!("{:?}", zm2d), "ZeroMap2d { keys0: ZeroVec([3, 6, 7]), joiner: ZeroVec([1, 4, 7]), keys1: [\"eee\", \"ddd\", \"mmm\", \"nnn\", \"ddd\", \"eee\", \"www\"], values: [\"EEE\", \"DD3\", \"MM1\", \"NNN\", \"DD2\", \"EEE\", \"WWW\"] }");
+ assert_eq!(format!("{zm2d:?}"), "ZeroMap2d { keys0: ZeroVec([3, 6, 7]), joiner: ZeroVec([1, 4, 7]), keys1: [\"eee\", \"ddd\", \"mmm\", \"nnn\", \"ddd\", \"eee\", \"www\"], values: [\"EEE\", \"DD3\", \"MM1\", \"NNN\", \"DD2\", \"EEE\", \"WWW\"] }");
}
}
diff --git a/vendor/zerovec/src/map2d/serde.rs b/vendor/zerovec/src/map2d/serde.rs
index b5e913654..53e3284b3 100644
--- a/vendor/zerovec/src/map2d/serde.rs
+++ b/vendor/zerovec/src/map2d/serde.rs
@@ -388,7 +388,7 @@ mod test {
assert_eq!(JSON_STR, json_str);
let new_map: ZeroMap2d<u32, u16, str> =
serde_json::from_str(&json_str).expect("deserialize");
- assert_eq!(format!("{:?}", new_map), format!("{:?}", map));
+ assert_eq!(format!("{new_map:?}"), format!("{map:?}"));
}
#[test]
@@ -399,15 +399,15 @@ mod test {
let new_map: ZeroMap2d<u32, u16, str> =
bincode::deserialize(&bincode_bytes).expect("deserialize");
assert_eq!(
- format!("{:?}", new_map),
- format!("{:?}", map).replace("Owned", "Borrowed"),
+ format!("{new_map:?}"),
+ format!("{map:?}").replace("Owned", "Borrowed"),
);
let new_map: ZeroMap2dBorrowed<u32, u16, str> =
bincode::deserialize(&bincode_bytes).expect("deserialize");
assert_eq!(
- format!("{:?}", new_map),
- format!("{:?}", map)
+ format!("{new_map:?}"),
+ format!("{map:?}")
.replace("Owned", "Borrowed")
.replace("ZeroMap2d", "ZeroMap2dBorrowed")
);
diff --git a/vendor/zerovec/src/ule/chars.rs b/vendor/zerovec/src/ule/chars.rs
index 4298d7338..7a4a97a4a 100644
--- a/vendor/zerovec/src/ule/chars.rs
+++ b/vendor/zerovec/src/ule/chars.rs
@@ -37,7 +37,7 @@ use core::convert::TryFrom;
/// CharULE::parse_byte_slice(bytes).expect_err("Invalid bytes");
/// ```
#[repr(transparent)]
-#[derive(Debug, PartialEq, Eq, Clone, Copy)]
+#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
pub struct CharULE([u8; 3]);
// Safety (based on the safety checklist on the ULE trait):
diff --git a/vendor/zerovec/src/ule/encode.rs b/vendor/zerovec/src/ule/encode.rs
index 3043bbd0a..2091cf06b 100644
--- a/vendor/zerovec/src/ule/encode.rs
+++ b/vendor/zerovec/src/ule/encode.rs
@@ -121,7 +121,7 @@ where
unsafe impl<T: VarULE + ?Sized> EncodeAsVarULE<T> for Box<T> {
fn encode_var_ule_as_slices<R>(&self, cb: impl FnOnce(&[&[u8]]) -> R) -> R {
- cb(&[T::as_byte_slice(&*self)])
+ cb(&[T::as_byte_slice(self)])
}
}
@@ -138,7 +138,7 @@ where
T: ULE,
{
fn encode_var_ule_as_slices<R>(&self, cb: impl FnOnce(&[&[u8]]) -> R) -> R {
- cb(&[<[T] as VarULE>::as_byte_slice(&*self)])
+ cb(&[<[T] as VarULE>::as_byte_slice(self)])
}
}
diff --git a/vendor/zerovec/src/ule/multi.rs b/vendor/zerovec/src/ule/multi.rs
index 1eacfac69..0ba0aea89 100644
--- a/vendor/zerovec/src/ule/multi.rs
+++ b/vendor/zerovec/src/ule/multi.rs
@@ -15,7 +15,7 @@ use core::mem;
/// where `V1` etc are potentially different [`VarULE`] types.
///
/// Internally, it is represented by a VarZeroSlice.
-#[derive(PartialEq, Eq)]
+#[derive(PartialEq, Eq, Debug)]
#[repr(transparent)]
pub struct MultiFieldsULE(VarZeroSlice<[u8], Index32>);
diff --git a/vendor/zerovec/src/ule/niche.rs b/vendor/zerovec/src/ule/niche.rs
index 688357f77..ae61faca0 100644
--- a/vendor/zerovec/src/ule/niche.rs
+++ b/vendor/zerovec/src/ule/niche.rs
@@ -10,7 +10,7 @@ use super::{AsULE, ULE};
/// can never occur as a valid byte representation of the type.
///
/// Guarantees for a valid implementation.
-/// 1. N must be equal to core::mem::sizeo_of::<Self>() or else it will
+/// 1. N must be equal to `core::mem::sizeo_of::<Self>()` or else it will
/// cause panics.
/// 2. The bit pattern [`NicheBytes::NICHE_BIT_PATTERN`] must not be incorrect as it would lead to
/// weird behaviour.
@@ -54,8 +54,16 @@ pub union NichedOptionULE<U: NicheBytes<N> + ULE, const N: usize> {
valid: U,
}
+impl<U: NicheBytes<N> + ULE + core::fmt::Debug, const N: usize> core::fmt::Debug
+ for NichedOptionULE<U, N>
+{
+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+ self.get().fmt(f)
+ }
+}
+
impl<U: NicheBytes<N> + ULE, const N: usize> NichedOptionULE<U, N> {
- /// New NichedOptionULE<U, N> from Option<U>
+ /// New `NichedOptionULE<U, N>` from `Option<U>`
pub fn new(opt: Option<U>) -> Self {
assert!(N == core::mem::size_of::<U>());
match opt {
@@ -66,7 +74,7 @@ impl<U: NicheBytes<N> + ULE, const N: usize> NichedOptionULE<U, N> {
}
}
- /// Convert to an Option<U>
+ /// Convert to an `Option<U>`
pub fn get(self) -> Option<U> {
// Safety: The union stores NICHE_BIT_PATTERN when None otherwise a valid U
unsafe {
@@ -131,7 +139,7 @@ unsafe impl<U: NicheBytes<N> + ULE, const N: usize> ULE for NichedOptionULE<U, N
}
/// Optional type which uses [`NichedOptionULE<U,N>`] as ULE type.
-/// The implementors guarantee that N == core::mem::sizeo_of::<Self>()
+/// The implementors guarantee that `N == core::mem::sizeo_of::<Self>()`
/// [`repr(transparent)`] guarantees that the layout is same as [`Option<U>`]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
#[repr(transparent)]
diff --git a/vendor/zerovec/src/ule/option.rs b/vendor/zerovec/src/ule/option.rs
index a6b1966a5..50b193aac 100644
--- a/vendor/zerovec/src/ule/option.rs
+++ b/vendor/zerovec/src/ule/option.rs
@@ -32,7 +32,7 @@ use core::mem::{self, MaybeUninit};
pub struct OptionULE<U>(bool, MaybeUninit<U>);
impl<U: Copy> OptionULE<U> {
- /// Obtain this as an Option<T>
+ /// Obtain this as an `Option<T>`
pub fn get(self) -> Option<U> {
if self.0 {
unsafe {
@@ -44,7 +44,7 @@ impl<U: Copy> OptionULE<U> {
}
}
- /// Construct an OptionULE<U> from an equivalent Option<T>
+ /// Construct an `OptionULE<U>` from an equivalent `Option<T>`
pub fn new(opt: Option<U>) -> Self {
if let Some(inner) = opt {
Self(true, MaybeUninit::new(inner))
@@ -54,6 +54,12 @@ impl<U: Copy> OptionULE<U> {
}
}
+impl<U: Copy + core::fmt::Debug> core::fmt::Debug for OptionULE<U> {
+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+ self.get().fmt(f)
+ }
+}
+
// Safety (based on the safety checklist on the ULE trait):
// 1. OptionULE does not include any uninitialized or padding bytes.
// (achieved by `#[repr(packed)]` on a struct containing only ULE fields,
@@ -152,6 +158,12 @@ impl<U: VarULE + ?Sized> OptionVarULE<U> {
}
}
+impl<U: VarULE + ?Sized + core::fmt::Debug> core::fmt::Debug for OptionVarULE<U> {
+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+ self.as_ref().fmt(f)
+ }
+}
+
// Safety (based on the safety checklist on the VarULE trait):
// 1. OptionVarULE<T> does not include any uninitialized or padding bytes
// (achieved by being repr(packed) on ULE types)
diff --git a/vendor/zerovec/src/varzerovec/components.rs b/vendor/zerovec/src/varzerovec/components.rs
index bf70c83c5..ff26d9029 100644
--- a/vendor/zerovec/src/varzerovec/components.rs
+++ b/vendor/zerovec/src/varzerovec/components.rs
@@ -85,7 +85,7 @@ unsafe impl VarZeroVecFormat for Index16 {
unsafe impl VarZeroVecFormat for Index32 {
const INDEX_WIDTH: usize = 4;
- const MAX_VALUE: u32 = u32::MAX as u32;
+ const MAX_VALUE: u32 = u32::MAX;
type RawBytes = RawBytesULE<4>;
#[inline]
fn rawbytes_to_usize(raw: Self::RawBytes) -> usize {
@@ -110,6 +110,7 @@ unsafe impl VarZeroVecFormat for Index32 {
/// exist.
///
/// See [`VarZeroVecComponents::parse_byte_slice()`] for information on the internal invariants involved
+#[derive(Debug)]
pub struct VarZeroVecComponents<'a, T: ?Sized, F> {
/// The number of elements
len: u32,
@@ -197,7 +198,7 @@ impl<'a, T: VarULE + ?Sized, F: VarZeroVecFormat> VarZeroVecComponents<'a, T, F>
.ok_or(ZeroVecError::VarZeroVecFormatError)?;
let borrowed = VarZeroVecComponents {
- len: len as u32,
+ len,
indices: indices_bytes,
things,
entire_slice: slice,
@@ -392,7 +393,7 @@ impl<'a, T: VarULE + ?Sized, F: VarZeroVecFormat> VarZeroVecComponents<'a, T, F>
.copied()
.map(F::rawbytes_to_usize)
.collect::<Vec<_>>();
- format!("VarZeroVecComponents {{ indices: {:?} }}", indices)
+ format!("VarZeroVecComponents {{ indices: {indices:?} }}")
}
}
diff --git a/vendor/zerovec/src/varzerovec/databake.rs b/vendor/zerovec/src/varzerovec/databake.rs
index 2c3d506b3..8d9fc0bfc 100644
--- a/vendor/zerovec/src/varzerovec/databake.rs
+++ b/vendor/zerovec/src/varzerovec/databake.rs
@@ -8,18 +8,26 @@ use databake::*;
impl<T: VarULE + ?Sized> Bake for VarZeroVec<'_, T> {
fn bake(&self, env: &CrateEnv) -> TokenStream {
env.insert("zerovec");
- let bytes = self.as_bytes();
- // Safe because self.as_bytes is a safe input
- quote! { unsafe { ::zerovec::VarZeroVec::from_bytes_unchecked(&[#(#bytes),*]) } }
+ if self.is_empty() {
+ quote! { ::zerovec::VarZeroVec::new() }
+ } else {
+ let bytes = databake::Bake::bake(&self.as_bytes(), env);
+ // Safe because self.as_bytes is a safe input
+ quote! { unsafe { ::zerovec::VarZeroVec::from_bytes_unchecked(#bytes) } }
+ }
}
}
impl<T: VarULE + ?Sized> Bake for &VarZeroSlice<T> {
fn bake(&self, env: &CrateEnv) -> TokenStream {
env.insert("zerovec");
- let bytes = self.as_bytes();
- // Safe because self.as_bytes is a safe input
- quote! { unsafe { ::zerovec::VarZeroSlice::from_bytes_unchecked(&[#(#bytes),*]) } }
+ if self.is_empty() {
+ quote! { ::zerovec::VarZeroSlice::new_empty() }
+ } else {
+ let bytes = databake::Bake::bake(&self.as_bytes(), env);
+ // Safe because self.as_bytes is a safe input
+ quote! { unsafe { ::zerovec::VarZeroSlice::from_bytes_unchecked(#bytes) } }
+ }
}
}
@@ -27,10 +35,15 @@ impl<T: VarULE + ?Sized> Bake for &VarZeroSlice<T> {
fn test_baked_vec() {
test_bake!(
VarZeroVec<str>,
+ const: crate::VarZeroVec::new(),
+ zerovec
+ );
+ test_bake!(
+ VarZeroVec<str>,
const: unsafe {
- crate::VarZeroVec::from_bytes_unchecked(&[
- 2u8, 1u8, 0u8, 22u8, 0u8, 77u8, 1u8, 92u8, 17u8,
- ])
+ crate::VarZeroVec::from_bytes_unchecked(
+ b"\x02\x01\0\x16\0M\x01\\\x11"
+ )
},
zerovec
);
@@ -40,10 +53,15 @@ fn test_baked_vec() {
fn test_baked_slice() {
test_bake!(
&VarZeroSlice<str>,
+ const: crate::VarZeroSlice::new_empty(),
+ zerovec
+ );
+ test_bake!(
+ &VarZeroSlice<str>,
const: unsafe {
- crate::VarZeroSlice::from_bytes_unchecked(&[
- 2u8, 1u8, 0u8, 22u8, 0u8, 77u8, 1u8, 92u8, 17u8,
- ])
+ crate::VarZeroSlice::from_bytes_unchecked(
+ b"\x02\x01\0\x16\0M\x01\\\x11"
+ )
},
zerovec
);
diff --git a/vendor/zerovec/src/varzerovec/owned.rs b/vendor/zerovec/src/varzerovec/owned.rs
index af4692d48..76de48760 100644
--- a/vendor/zerovec/src/varzerovec/owned.rs
+++ b/vendor/zerovec/src/varzerovec/owned.rs
@@ -96,7 +96,7 @@ impl<T: VarULE + ?Sized, F: VarZeroVecFormat> VarZeroVecOwned<T, F> {
/// Obtain this `VarZeroVec` as a [`VarZeroSlice`]
pub fn as_slice(&self) -> &VarZeroSlice<T, F> {
- let slice: &[u8] = &*self.entire_slice;
+ let slice: &[u8] = &self.entire_slice;
unsafe {
// safety: the slice is known to come from a valid parsed VZV
VarZeroSlice::from_byte_slice_unchecked(slice)
@@ -146,7 +146,7 @@ impl<T: VarULE + ?Sized, F: VarZeroVecFormat> VarZeroVecOwned<T, F> {
unsafe fn element_range_unchecked(&self, idx: usize) -> core::ops::Range<usize> {
let start = self.element_position_unchecked(idx);
let end = self.element_position_unchecked(idx + 1);
- debug_assert!(start <= end, "{} > {}", start, end);
+ debug_assert!(start <= end, "{start} > {end}");
start..end
}
@@ -353,7 +353,7 @@ impl<T: VarULE + ?Sized, F: VarZeroVecFormat> VarZeroVecOwned<T, F> {
+ METADATA_WIDTH
+ self.len() * F::INDEX_WIDTH
+ self.element_position_unchecked(index);
- &mut self.entire_slice[element_pos..element_pos + new_size as usize]
+ &mut self.entire_slice[element_pos..element_pos + new_size]
}
/// Checks the internal invariants of the vec to ensure safe code will not cause UB.
@@ -423,10 +423,7 @@ impl<T: VarULE + ?Sized, F: VarZeroVecFormat> VarZeroVecOwned<T, F> {
pub fn insert<A: EncodeAsVarULE<T> + ?Sized>(&mut self, index: usize, element: &A) {
let len = self.len();
if index > len {
- panic!(
- "Called out-of-bounds insert() on VarZeroVec, index {} len {}",
- index, len
- );
+ panic!("Called out-of-bounds insert() on VarZeroVec, index {index} len {len}");
}
let value_len = element.encode_var_ule_len();
@@ -451,10 +448,7 @@ impl<T: VarULE + ?Sized, F: VarZeroVecFormat> VarZeroVecOwned<T, F> {
pub fn remove(&mut self, index: usize) {
let len = self.len();
if index >= len {
- panic!(
- "Called out-of-bounds remove() on VarZeroVec, index {} len {}",
- index, len
- );
+ panic!("Called out-of-bounds remove() on VarZeroVec, index {index} len {len}");
}
if len == 1 {
// This is removing the last element. Set the slice to empty to ensure all empty vecs have empty data slices.
@@ -470,10 +464,7 @@ impl<T: VarULE + ?Sized, F: VarZeroVecFormat> VarZeroVecOwned<T, F> {
pub fn replace<A: EncodeAsVarULE<T> + ?Sized>(&mut self, index: usize, element: &A) {
let len = self.len();
if index >= len {
- panic!(
- "Called out-of-bounds replace() on VarZeroVec, index {} len {}",
- index, len
- );
+ panic!("Called out-of-bounds replace() on VarZeroVec, index {index} len {len}");
}
let value_len = element.encode_var_ule_len();
diff --git a/vendor/zerovec/src/varzerovec/vec.rs b/vendor/zerovec/src/varzerovec/vec.rs
index 7edb48a96..1401a180a 100644
--- a/vendor/zerovec/src/varzerovec/vec.rs
+++ b/vendor/zerovec/src/varzerovec/vec.rs
@@ -248,7 +248,7 @@ impl<'a, T: VarULE + ?Sized, F: VarZeroVecFormat> VarZeroVec<'a, T, F> {
/// assert!(vzv.is_empty());
/// ```
#[inline]
- pub fn new() -> Self {
+ pub const fn new() -> Self {
Self::Borrowed(VarZeroSlice::new_empty())
}
@@ -354,7 +354,7 @@ impl<'a, T: VarULE + ?Sized, F: VarZeroVecFormat> VarZeroVec<'a, T, F> {
/// Obtain this `VarZeroVec` as a [`VarZeroSlice`]
pub fn as_slice(&self) -> &VarZeroSlice<T, F> {
match *self {
- VarZeroVec::Owned(ref owned) => &**owned,
+ VarZeroVec::Owned(ref owned) => owned,
VarZeroVec::Borrowed(b) => b,
}
}
@@ -413,8 +413,7 @@ where
{
#[inline]
fn from(elements: &Vec<A>) -> Self {
- #[allow(clippy::unwrap_used)] // TODO(#1410) Better story for fallibility
- VarZeroVecOwned::try_from_elements(elements).unwrap().into()
+ Self::from(elements.as_slice())
}
}
@@ -439,8 +438,7 @@ where
{
#[inline]
fn from(elements: &[A; N]) -> Self {
- #[allow(clippy::unwrap_used)] // TODO(#1410) Better story for fallibility
- VarZeroVecOwned::try_from_elements(elements).unwrap().into()
+ Self::from(elements.as_slice())
}
}
diff --git a/vendor/zerovec/src/yoke_impls.rs b/vendor/zerovec/src/yoke_impls.rs
index 0efb47a2d..a5064a554 100644
--- a/vendor/zerovec/src/yoke_impls.rs
+++ b/vendor/zerovec/src/yoke_impls.rs
@@ -4,6 +4,7 @@
// This way we can copy-paste Yokeable impls
#![allow(clippy::forget_copy)]
+#![allow(clippy::forget_non_drop)]
use crate::flexzerovec::FlexZeroVec;
use crate::map::ZeroMapBorrowed;
@@ -305,11 +306,12 @@ mod test {
}
#[test]
+ #[ignore] // https://github.com/rust-lang/rust/issues/98906
fn bake_ZeroVec() {
test_bake!(
DeriveTest_ZeroVec<'static>,
crate::yoke_impls::test::DeriveTest_ZeroVec {
- _data: unsafe { crate::ZeroVec::from_bytes_unchecked(&[]) },
+ _data: crate::ZeroVec::new(),
},
zerovec,
);
@@ -328,7 +330,7 @@ mod test {
test_bake!(
DeriveTest_ZeroSlice<'static>,
crate::yoke_impls::test::DeriveTest_ZeroSlice {
- _data: unsafe { crate::ZeroSlice::from_bytes_unchecked(&[]) },
+ _data: crate::ZeroSlice::new_empty(),
},
zerovec,
);
@@ -343,13 +345,13 @@ mod test {
}
#[test]
+ #[ignore] // https://github.com/rust-lang/rust/issues/98906
fn bake_FlexZeroVec() {
test_bake!(
DeriveTest_FlexZeroVec<'static>,
crate::yoke_impls::test::DeriveTest_FlexZeroVec {
- _data: unsafe {
- crate::vecs::FlexZeroSlice::from_byte_slice_unchecked(&[1u8]).as_flexzerovec()
- },
+ _data: unsafe { crate::vecs::FlexZeroSlice::from_byte_slice_unchecked(b"\x01") }
+ .as_flexzerovec(),
},
zerovec,
);
@@ -368,7 +370,7 @@ mod test {
test_bake!(
DeriveTest_FlexZeroSlice<'static>,
crate::yoke_impls::test::DeriveTest_FlexZeroSlice {
- _data: unsafe { crate::vecs::FlexZeroSlice::from_byte_slice_unchecked(&[1u8]) },
+ _data: unsafe { crate::vecs::FlexZeroSlice::from_byte_slice_unchecked(b"\x01\0") },
},
zerovec,
);
@@ -387,7 +389,7 @@ mod test {
test_bake!(
DeriveTest_VarZeroVec<'static>,
crate::yoke_impls::test::DeriveTest_VarZeroVec {
- _data: unsafe { crate::VarZeroVec::from_bytes_unchecked(&[]) },
+ _data: crate::VarZeroVec::new(),
},
zerovec,
);
@@ -406,7 +408,7 @@ mod test {
test_bake!(
DeriveTest_VarZeroSlice<'static>,
crate::yoke_impls::test::DeriveTest_VarZeroSlice {
- _data: unsafe { crate::VarZeroSlice::from_bytes_unchecked(&[]) }
+ _data: crate::VarZeroSlice::new_empty()
},
zerovec,
);
@@ -429,8 +431,8 @@ mod test {
_data: unsafe {
#[allow(unused_unsafe)]
crate::ZeroMap::from_parts_unchecked(
- unsafe { crate::VarZeroVec::from_bytes_unchecked(&[]) },
- unsafe { crate::VarZeroVec::from_bytes_unchecked(&[]) },
+ crate::VarZeroVec::new(),
+ crate::VarZeroVec::new(),
)
},
},
@@ -455,8 +457,8 @@ mod test {
_data: unsafe {
#[allow(unused_unsafe)]
crate::maps::ZeroMapBorrowed::from_parts_unchecked(
- unsafe { crate::VarZeroSlice::from_bytes_unchecked(&[]) },
- unsafe { crate::VarZeroSlice::from_bytes_unchecked(&[]) },
+ crate::VarZeroSlice::new_empty(),
+ crate::VarZeroSlice::new_empty(),
)
},
},
@@ -481,8 +483,8 @@ mod test {
_data: unsafe {
#[allow(unused_unsafe)]
crate::ZeroMap::from_parts_unchecked(
- unsafe { crate::VarZeroVec::from_bytes_unchecked(&[]) },
- unsafe { crate::VarZeroVec::from_bytes_unchecked(&[]) },
+ crate::VarZeroVec::new(),
+ crate::VarZeroVec::new(),
)
},
},
@@ -507,10 +509,10 @@ mod test {
_data: unsafe {
#[allow(unused_unsafe)]
crate::ZeroMap2d::from_parts_unchecked(
- unsafe { crate::ZeroVec::from_bytes_unchecked(&[]) },
- unsafe { crate::ZeroVec::from_bytes_unchecked(&[]) },
- unsafe { crate::ZeroVec::from_bytes_unchecked(&[]) },
- unsafe { crate::VarZeroVec::from_bytes_unchecked(&[]) },
+ crate::ZeroVec::new(),
+ crate::ZeroVec::new(),
+ crate::ZeroVec::new(),
+ crate::VarZeroVec::new(),
)
},
},
@@ -535,10 +537,10 @@ mod test {
_data: unsafe {
#[allow(unused_unsafe)]
crate::maps::ZeroMap2dBorrowed::from_parts_unchecked(
- unsafe { crate::ZeroSlice::from_bytes_unchecked(&[]) },
- unsafe { crate::ZeroSlice::from_bytes_unchecked(&[]) },
- unsafe { crate::ZeroSlice::from_bytes_unchecked(&[]) },
- unsafe { crate::VarZeroSlice::from_bytes_unchecked(&[]) },
+ crate::ZeroSlice::new_empty(),
+ crate::ZeroSlice::new_empty(),
+ crate::ZeroSlice::new_empty(),
+ crate::VarZeroSlice::new_empty(),
)
},
},
diff --git a/vendor/zerovec/src/zerofrom_impls.rs b/vendor/zerovec/src/zerofrom_impls.rs
index dfb3da187..d17e432c4 100644
--- a/vendor/zerovec/src/zerofrom_impls.rs
+++ b/vendor/zerovec/src/zerofrom_impls.rs
@@ -41,14 +41,14 @@ where
impl<'zf> ZeroFrom<'zf, FlexZeroVec<'_>> for FlexZeroVec<'zf> {
#[inline]
fn zero_from(other: &'zf FlexZeroVec<'_>) -> Self {
- FlexZeroVec::Borrowed(&*other)
+ FlexZeroVec::Borrowed(other)
}
}
impl<'zf> ZeroFrom<'zf, FlexZeroSlice> for FlexZeroVec<'zf> {
#[inline]
fn zero_from(other: &'zf FlexZeroSlice) -> Self {
- FlexZeroVec::Borrowed(&*other)
+ FlexZeroVec::Borrowed(other)
}
}
diff --git a/vendor/zerovec/src/zerovec/databake.rs b/vendor/zerovec/src/zerovec/databake.rs
index 0643ddb40..e46065c38 100644
--- a/vendor/zerovec/src/zerovec/databake.rs
+++ b/vendor/zerovec/src/zerovec/databake.rs
@@ -12,8 +12,12 @@ where
{
fn bake(&self, env: &CrateEnv) -> TokenStream {
env.insert("zerovec");
- let bytes = self.as_bytes();
- quote! { unsafe { ::zerovec::ZeroVec::from_bytes_unchecked(&[#(#bytes),*]) } }
+ if self.is_empty() {
+ quote! { ::zerovec::ZeroVec::new() }
+ } else {
+ let bytes = databake::Bake::bake(&self.as_bytes(), env);
+ quote! { unsafe { ::zerovec::ZeroVec::from_bytes_unchecked(#bytes) } }
+ }
}
}
@@ -23,8 +27,12 @@ where
{
fn bake(&self, env: &CrateEnv) -> TokenStream {
env.insert("zerovec");
- let bytes = self.as_bytes();
- quote! { unsafe { ::zerovec::ZeroSlice::from_bytes_unchecked(&[#(#bytes),*]) } }
+ if self.is_empty() {
+ quote! { ::zerovec::ZeroSlice::new_empty() }
+ } else {
+ let bytes = databake::Bake::bake(&self.as_bytes(), env);
+ quote! { unsafe { ::zerovec::ZeroSlice::from_bytes_unchecked(#bytes) } }
+ }
}
}
@@ -32,8 +40,13 @@ where
fn test_baked_vec() {
test_bake!(
ZeroVec<u32>,
+ const: crate::ZeroVec::new(),
+ zerovec
+ );
+ test_bake!(
+ ZeroVec<u32>,
const: unsafe {
- crate::ZeroVec::from_bytes_unchecked(&[2u8, 1u8, 0u8, 22u8, 0u8, 77u8, 1u8, 92u8])
+ crate::ZeroVec::from_bytes_unchecked(b"\x02\x01\0\x16\0M\x01\\")
},
zerovec
);
@@ -43,8 +56,13 @@ fn test_baked_vec() {
fn test_baked_slice() {
test_bake!(
&ZeroSlice<u32>,
+ const: crate::ZeroSlice::new_empty(),
+ zerovec
+ );
+ test_bake!(
+ &ZeroSlice<u32>,
const: unsafe {
- crate::ZeroSlice::from_bytes_unchecked(&[2u8, 1u8, 0u8, 22u8, 0u8, 77u8, 1u8, 92u8])
+ crate::ZeroSlice::from_bytes_unchecked(b"\x02\x01\0\x16\0M\x01\\")
},
zerovec
);
diff --git a/vendor/zerovec/src/zerovec/mod.rs b/vendor/zerovec/src/zerovec/mod.rs
index 371450e21..e7c87f68e 100644
--- a/vendor/zerovec/src/zerovec/mod.rs
+++ b/vendor/zerovec/src/zerovec/mod.rs
@@ -284,7 +284,7 @@ where
// Deconstruct the vector into parts
// This is the only part of the code that goes from Vec
// to ZeroVec, all other such operations should use this function
- let slice: &[T::ULE] = &*vec;
+ let slice: &[T::ULE] = &vec;
let slice = slice as *const [_] as *mut [_];
let capacity = vec.capacity();
mem::forget(vec);
diff --git a/vendor/zerovec/src/zerovec/slice.rs b/vendor/zerovec/src/zerovec/slice.rs
index 847705304..52ddc184b 100644
--- a/vendor/zerovec/src/zerovec/slice.rs
+++ b/vendor/zerovec/src/zerovec/slice.rs
@@ -191,6 +191,27 @@ where
.map(T::from_unaligned)
}
+ /// Gets the entire slice as an array of length `N`. Returns None if the slice
+ /// does not have exactly `N` elements.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use zerovec::ZeroVec;
+ ///
+ /// let bytes: &[u8] = &[0xD3, 0x00, 0x19, 0x01, 0xA5, 0x01, 0xCD, 0x80];
+ /// let zerovec: ZeroVec<u16> =
+ /// ZeroVec::parse_byte_slice(bytes).expect("infallible");
+ /// let array: [u16; 4] =
+ /// zerovec.get_as_array().expect("should be 4 items in array");
+ ///
+ /// assert_eq!(array[2], 421);
+ /// ```
+ pub fn get_as_array<const N: usize>(&self) -> Option<[T; N]> {
+ let ule_array = <&[T::ULE; N]>::try_from(self.as_ule_slice()).ok()?;
+ Some(ule_array.map(|u| T::from_unaligned(u)))
+ }
+
/// Gets a subslice of elements within a certain range. Returns None if the range
/// is out of bounds of this `ZeroSlice`.
///
@@ -510,7 +531,7 @@ where
}
}
-impl<'a, T: AsULE + PartialOrd> PartialOrd for ZeroSlice<T> {
+impl<T: AsULE + PartialOrd> PartialOrd for ZeroSlice<T> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.iter().partial_cmp(other.iter())
}
@@ -524,13 +545,13 @@ impl<T: AsULE + Ord> Ord for ZeroSlice<T> {
impl<T: AsULE> AsRef<ZeroSlice<T>> for Vec<T::ULE> {
fn as_ref(&self) -> &ZeroSlice<T> {
- ZeroSlice::<T>::from_ule_slice(&**self)
+ ZeroSlice::<T>::from_ule_slice(self)
}
}
impl<T: AsULE> AsRef<ZeroSlice<T>> for &[T::ULE] {
fn as_ref(&self) -> &ZeroSlice<T> {
- ZeroSlice::<T>::from_ule_slice(&**self)
+ ZeroSlice::<T>::from_ule_slice(self)
}
}