//! Ordered collections that guarantee sorted, deduplicated items. #[cfg(not(feature = "std"))] use alloc::vec::Vec; use bytes::BufMut; use commonware_codec::{ Buf, EncodeSize, MaxEncodeSize, RangeCfg, Read, Write, util::max_items_size, }; use core::{ fmt, hash::Hash, ops::{Deref, Index, Range}, }; use hashbrown::HashSet; use thiserror::Error; type Hasher = ahash::RandomState; #[cfg(not(feature = "std"))] type VecIntoIter = alloc::vec::IntoIter; #[cfg(feature = "std")] type VecIntoIter = std::vec::IntoIter; /// Errors that can occur when interacting with ordered collections. #[derive(Error, Debug, PartialEq, Eq)] pub enum Error { /// A key was duplicated. #[error("duplicate key")] DuplicateKey, /// A value was duplicated. #[error("duplicate value")] DuplicateValue, } use crate::{Faults, Participant, TryFromIterator}; /// An ordered, deduplicated collection of items. #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct Set(Vec); impl fmt::Debug for Set { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple("Set").field(&self.0).finish() } } impl Default for Set { fn default() -> Self { Self(Vec::new()) } } impl Set { /// Creates a new [`Set`] from an iterator, removing duplicates. /// /// Unlike [`FromIterator`] and [`From`], this method tolerates duplicate /// items by silently discarding them. pub fn from_iter_dedup>(iter: I) -> Self { let mut items: Vec = iter.into_iter().collect(); items.sort(); items.dedup(); Self(items) } } impl Set { /// Returns the size of the ordered collection. pub const fn len(&self) -> usize { self.0.len() } /// Returns `true` if the collection is empty. pub const fn is_empty(&self) -> bool { self.0.is_empty() } /// Returns an item by index, if it exists. pub fn get(&self, index: usize) -> Option<&T> { self.0.get(index) } /// Returns the position of a given item in the collection, if it exists. pub fn position(&self, item: &T) -> Option where T: Ord, { self.0.binary_search(item).ok() } /// Returns an iterator over the items in the collection. pub fn iter(&self) -> core::slice::Iter<'_, T> { self.into_iter() } } impl Write for Set { fn write(&self, buf: &mut impl BufMut) { self.0.write(buf); } } impl EncodeSize for Set { fn encode_size(&self) -> usize { self.0.encode_size() } } impl Set { /// Returns an upper bound on the encoded size of a set of at most `len` items. pub fn max_encode_size(len: usize) -> usize { max_items_size(len, T::MAX_ENCODE_SIZE) } } impl Read for Set { type Cfg = (RangeCfg, T::Cfg); fn read_cfg(buf: &mut impl Buf, cfg: &Self::Cfg) -> Result { let items = Vec::::read_cfg(buf, cfg)?; for i in 1..items.len() { if items[i - 1] >= items[i] { return Err(commonware_codec::Error::Invalid( "Set", "items must be sorted and unique", )); } } Ok(Self(items)) } } impl TryFromIterator for Set { type Error = Error; /// Attempts to create a [`Set`] from an iterator. /// /// Returns an error if there are duplicate items. fn try_from_iter>(iter: I) -> Result { let mut items: Vec = iter.into_iter().collect(); items.sort(); let len = items.len(); items.dedup(); if items.len() != len { return Err(Error::DuplicateKey); } Ok(Self(items)) } } impl TryFrom> for Set { type Error = Error; fn try_from(items: Vec) -> Result { Self::try_from_iter(items) } } impl TryFrom<&[T]> for Set { type Error = Error; fn try_from(items: &[T]) -> Result { Self::try_from_iter(items.iter().cloned()) } } impl TryFrom<[T; N]> for Set { type Error = Error; fn try_from(items: [T; N]) -> Result { Self::try_from_iter(items) } } impl TryFrom<&[T; N]> for Set { type Error = Error; fn try_from(items: &[T; N]) -> Result { Self::try_from(items.as_slice()) } } impl IntoIterator for Set { type Item = T; type IntoIter = VecIntoIter; fn into_iter(self) -> Self::IntoIter { self.0.into_iter() } } impl<'a, T> IntoIterator for &'a Set { type Item = &'a T; type IntoIter = core::slice::Iter<'a, T>; fn into_iter(self) -> Self::IntoIter { self.0.iter() } } impl Index for Set { type Output = T; fn index(&self, index: usize) -> &Self::Output { &self.0[index] } } impl Index> for Set { type Output = [T]; fn index(&self, index: Range) -> &Self::Output { &self.0[index] } } impl AsRef<[T]> for Set { fn as_ref(&self) -> &[T] { &self.0 } } impl fmt::Display for Set { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { write!(f, "[")?; for (i, item) in self.0.iter().enumerate() { if i > 0 { write!(f, ", ")?; } write!(f, "{item}")?; } write!(f, "]") } } impl From> for Vec { fn from(set: Set) -> Self { set.0 } } #[cfg(feature = "arbitrary")] impl arbitrary::Arbitrary<'_> for Set where T: for<'a> arbitrary::Arbitrary<'a> + Ord, { fn arbitrary(u: &mut arbitrary::Unstructured<'_>) -> arbitrary::Result { let vec = Vec::::arbitrary(u)?; Ok(Self::from_iter_dedup(vec)) } } /// Extension trait for [`Set`] participant sets providing quorum and index utilities. pub trait Quorum { /// The type of items in this set. type Item: Ord; /// Returns the quorum value for this participant set using the given fault model. /// /// ## Panics /// /// Panics if the number of participants exceeds `u32::MAX`. fn quorum(&self) -> u32; /// Returns the maximum number of faults tolerated by this participant set. /// /// ## Panics /// /// Panics if the number of participants exceeds `u32::MAX`. fn max_faults(&self) -> u32; /// Returns the participant key at the given index. fn key(&self, index: Participant) -> Option<&Self::Item>; /// Returns the index for the given participant key, if present. /// /// ## Panics /// /// Panics if the participant index exceeds `u32::MAX`. fn index(&self, key: &Self::Item) -> Option; } impl Quorum for Set { type Item = T; fn quorum(&self) -> u32 { M::quorum(u32::try_from(self.len()).expect("too many participants")) } fn max_faults(&self) -> u32 { M::max_faults(self.len()) } fn key(&self, index: Participant) -> Option<&Self::Item> { self.get(index.into()) } fn index(&self, key: &Self::Item) -> Option { self.position(key).map(Participant::from_usize) } } /// An ordered, deduplicated collection of key-value pairs. #[derive(Clone, PartialEq, Eq, Hash)] pub struct Map { keys: Set, values: Vec, } impl Map { /// Creates a new [`Map`] from an iterator, removing duplicate keys. /// /// Unlike [`FromIterator`] and [`From`], this method tolerates duplicate /// keys by silently discarding them (keeping the first occurrence). pub fn from_iter_dedup>(iter: I) -> Self { let mut items: Vec<(K, V)> = iter.into_iter().collect(); items.sort_by(|(lk, _), (rk, _)| lk.cmp(rk)); items.dedup_by(|l, r| l.0 == r.0); let mut keys = Vec::with_capacity(items.len()); let mut values = Vec::with_capacity(items.len()); for (key, value) in items { keys.push(key); values.push(value); } Self { keys: Set(keys), values, } } } impl Default for Map { fn default() -> Self { Self { keys: Set::default(), values: Vec::new(), } } } impl Map { /// Creates a map from ordered keys and corresponding values, reusing both allocations. /// /// Each value is paired with the key at the same index. Returns `None` if /// the lengths differ. /// /// # Examples /// /// ``` /// use commonware_utils::ordered::{Map, Set}; /// /// let keys = Set::try_from([3, 1, 2]).unwrap(); /// let map = Map::from_parts(keys, vec!["one", "two", "three"]).unwrap(); /// assert_eq!(map.get_value(&2), Some(&"two")); /// ``` pub fn from_parts(keys: Set, values: Vec) -> Option { if keys.len() != values.len() { return None; } Some(Self { keys, values }) } /// Returns the number of entries in the map. pub const fn len(&self) -> usize { self.keys.len() } /// Returns `true` if the map is empty. pub const fn is_empty(&self) -> bool { self.keys.is_empty() } /// Returns a key by index, if it exists. pub fn get(&self, index: usize) -> Option<&K> { self.keys.get(index) } /// Returns the position of the provided key, if it exists. pub fn position(&self, key: &K) -> Option where K: Ord, { self.keys.position(key) } /// Returns the ordered keys as a [`Set`] reference. pub const fn keys(&self) -> &Set { &self.keys } /// Consumes the map and returns the ordered keys. pub fn into_keys(self) -> Set { self.keys } /// Returns the associated value at `index`, if it exists. pub fn value(&self, index: usize) -> Option<&V> { self.values.get(index) } /// Returns the associated value for `key`, if it exists. pub fn get_value(&self, key: &K) -> Option<&V> where K: Ord, { self.position(key).and_then(|index| self.values.get(index)) } /// Returns a mutable reference to the associated value for `key`, if it exists. pub fn get_value_mut(&mut self, key: &K) -> Option<&mut V> where K: Ord, { self.position(key) .and_then(|index| self.values.get_mut(index)) } /// Returns the associated values. pub fn values(&self) -> &[V] { &self.values } /// Returns a mutable reference to the associated values pub fn values_mut(&mut self) -> &mut [V] { &mut self.values } /// Maps each value in key order, cloning the keys without sorting or validating them. /// /// The closure receives references to the key and value. The new values may /// borrow from this map. /// /// # Examples /// /// ``` /// use commonware_utils::ordered::Map; /// /// let map = Map::try_from([(4, "four"), (1, "one")]).unwrap(); /// let lengths = map.map_values(|_, value| value.len()); /// assert_eq!(lengths.keys(), map.keys()); /// assert_eq!(lengths.values(), &[3, 4]); /// ``` pub fn map_values<'a, U, F>(&'a self, mut f: F) -> Map where K: Clone, F: FnMut(&'a K, &'a V) -> U, { let values = self .iter_pairs() .map(|(key, value)| f(key, value)) .collect(); Map { keys: self.keys.clone(), values, } } /// Fallible version of [`Self::map_values`]. /// /// Returns the first error without calling the closure for subsequent entries. /// Clones the keys only on success. /// /// # Examples /// /// ``` /// use commonware_utils::ordered::Map; /// /// let map = Map::try_from([(2, "invalid"), (1, "10")]).unwrap(); /// let result = map.try_map_values(|_, value| value.parse::()); /// assert!(result.is_err()); /// assert_eq!(map.values(), &["10", "invalid"]); /// ``` pub fn try_map_values<'a, U, E, F>(&'a self, mut f: F) -> Result, E> where K: Clone, F: FnMut(&'a K, &'a V) -> Result, { let mut values = Vec::with_capacity(self.len()); for (key, value) in self.iter_pairs() { values.push(f(key, value)?); } Ok(Map { keys: self.keys.clone(), values, }) } /// Consumes the map and maps each value in key order, reusing the key allocation. /// /// The closure receives a reference to the key and the owned value. Keys are /// not cloned, sorted, or validated. /// /// # Examples /// /// ``` /// use commonware_utils::ordered::Map; /// /// let map = Map::try_from([(2, String::from("two")), (1, String::from("one"))]).unwrap(); /// let bytes = map.map_values_into(|_, value| value.into_bytes()); /// assert_eq!(bytes.keys().as_ref(), &[1, 2]); /// assert_eq!(bytes.values(), &[b"one".to_vec(), b"two".to_vec()]); /// ``` pub fn map_values_into(self, mut f: F) -> Map where F: FnMut(&K, V) -> U, { let Self { keys, values } = self; let values = keys .iter() .zip(values) .map(|(key, value)| f(key, value)) .collect(); Map { keys, values } } /// Fallible version of [`Self::map_values_into`]. /// /// Returns the first error without calling the closure for subsequent entries. /// /// # Examples /// /// ``` /// use commonware_utils::ordered::Map; /// /// let map = Map::try_from([(2, String::from("20")), (1, String::from("10"))]).unwrap(); /// let parsed = map.try_map_values_into(|_, value| value.parse::()).unwrap(); /// assert_eq!(parsed.keys().as_ref(), &[1, 2]); /// assert_eq!(parsed.values(), &[10, 20]); /// ``` pub fn try_map_values_into(self, mut f: F) -> Result, E> where F: FnMut(&K, V) -> Result, { let Self { keys, values } = self; let mut mapped = Vec::with_capacity(keys.len()); for (key, value) in keys.iter().zip(values) { mapped.push(f(key, value)?); } Ok(Map { keys, values: mapped, }) } /// Truncates the map to at most `len` entries. pub fn truncate(&mut self, len: usize) { self.keys.0.truncate(len); self.values.truncate(len); } /// Returns a zipped iterator over keys and values. pub fn iter_pairs(&self) -> impl ExactSizeIterator + DoubleEndedIterator { self.keys.iter().zip(self.values.iter()) } /// Returns a zipped iterator over keys and mutable references to values. /// /// This is provided because the borrow checker does not let you combine /// the other functions yourself. pub fn iter_pairs_mut( &mut self, ) -> impl ExactSizeIterator + DoubleEndedIterator { self.keys.iter().zip(self.values.iter_mut()) } /// Returns an iterator over the ordered keys. pub fn iter(&self) -> core::slice::Iter<'_, K> { self.keys.iter() } } impl fmt::Debug for Map { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple("Map") .field(&self.iter_pairs().collect::>()) .finish() } } impl fmt::Display for Map { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { write!(f, "[")?; for (i, (key, value)) in self.iter_pairs().enumerate() { if i > 0 { write!(f, ", ")?; } write!(f, "({key}, {value})")?; } write!(f, "]") } } impl AsRef<[K]> for Map { fn as_ref(&self) -> &[K] { self.keys.as_ref() } } impl AsRef> for Map { fn as_ref(&self) -> &Set { &self.keys } } impl Deref for Map { type Target = Set; fn deref(&self) -> &Self::Target { &self.keys } } impl TryFromIterator<(K, V)> for Map { type Error = Error; /// Attempts to create a [`Map`] from an iterator. /// /// Returns an error if there are duplicate keys. fn try_from_iter>(iter: I) -> Result { let mut items: Vec<(K, V)> = iter.into_iter().collect(); items.sort_by(|(lk, _), (rk, _)| lk.cmp(rk)); let len = items.len(); items.dedup_by(|l, r| l.0 == r.0); if items.len() != len { return Err(Error::DuplicateKey); } let mut keys = Vec::with_capacity(items.len()); let mut values = Vec::with_capacity(items.len()); for (key, value) in items { keys.push(key); values.push(value); } Ok(Self { keys: Set(keys), values, }) } } impl TryFrom> for Map { type Error = Error; fn try_from(items: Vec<(K, V)>) -> Result { Self::try_from_iter(items) } } impl TryFrom<&[(K, V)]> for Map { type Error = Error; fn try_from(items: &[(K, V)]) -> Result { Self::try_from_iter(items.iter().cloned()) } } impl TryFrom<[(K, V); N]> for Map { type Error = Error; fn try_from(items: [(K, V); N]) -> Result { Self::try_from_iter(items) } } impl TryFrom<&[(K, V); N]> for Map { type Error = Error; fn try_from(items: &[(K, V); N]) -> Result { Self::try_from(items.as_slice()) } } impl From> for Vec<(K, V)> { fn from(wrapped: Map) -> Self { wrapped.into_iter().collect() } } impl Write for Map { fn write(&self, buf: &mut impl BufMut) { self.keys.write(buf); self.values.write(buf); } } impl EncodeSize for Map { fn encode_size(&self) -> usize { self.keys.encode_size() + self.values.encode_size() } } impl Map { /// Returns an upper bound on the encoded size of a map of at most `len` entries whose values /// encode to at most `value` bytes each. pub fn max_encode_size(len: usize, value: usize) -> usize { Set::::max_encode_size(len) + max_items_size(len, value) } } impl Read for Map { type Cfg = (RangeCfg, K::Cfg, V::Cfg); fn read_cfg(buf: &mut impl Buf, cfg: &Self::Cfg) -> Result { let (range_cfg, key_cfg, value_cfg) = cfg; let keys = Set::::read_cfg(buf, &(*range_cfg, key_cfg.clone()))?; let values = Vec::::read_cfg(buf, &(RangeCfg::exact(keys.len()), value_cfg.clone()))?; Ok(Self { keys, values }) } } impl IntoIterator for Map { type Item = (K, V); type IntoIter = MapIntoIter; fn into_iter(self) -> Self::IntoIter { MapIntoIter { keys: self.keys.into_iter(), values: self.values.into_iter(), } } } impl<'a, K, V> IntoIterator for &'a Map { type Item = (&'a K, &'a V); type IntoIter = core::iter::Zip, core::slice::Iter<'a, V>>; fn into_iter(self) -> Self::IntoIter { self.keys.iter().zip(self.values.iter()) } } /// An iterator over owned key-value pairs. pub struct MapIntoIter { keys: VecIntoIter, values: VecIntoIter, } impl Iterator for MapIntoIter { type Item = (K, V); fn next(&mut self) -> Option { let key = self.keys.next()?; let value = self.values.next()?; Some((key, value)) } fn size_hint(&self) -> (usize, Option) { self.keys.size_hint() } } impl ExactSizeIterator for MapIntoIter {} impl DoubleEndedIterator for MapIntoIter { fn next_back(&mut self) -> Option { let key = self.keys.next_back()?; let value = self.values.next_back()?; Some((key, value)) } } #[cfg(feature = "arbitrary")] impl arbitrary::Arbitrary<'_> for Map where K: for<'a> arbitrary::Arbitrary<'a> + Ord, V: for<'a> arbitrary::Arbitrary<'a>, { fn arbitrary(u: &mut arbitrary::Unstructured<'_>) -> arbitrary::Result { let vec = Vec::<(K, V)>::arbitrary(u)?; Ok(Self::from_iter_dedup(vec)) } } /// An ordered, deduplicated collection of key-value pairs with unique values. #[derive(Clone, PartialEq, Eq, Hash)] pub struct BiMap { inner: Map, } impl Default for BiMap { fn default() -> Self { Self { inner: Map::default(), } } } impl BiMap { /// Returns the number of entries in the map. pub const fn len(&self) -> usize { self.inner.len() } /// Returns `true` if the map is empty. pub const fn is_empty(&self) -> bool { self.inner.is_empty() } /// Returns a key by index, if it exists. pub fn get(&self, index: usize) -> Option<&K> { self.inner.get(index) } /// Returns the position of the provided key, if it exists. pub fn position(&self, key: &K) -> Option where K: Ord, { self.inner.position(key) } /// Returns the ordered keys as a [`Set`] reference. pub const fn keys(&self) -> &Set { self.inner.keys() } /// Consumes the map and returns the ordered keys. pub fn into_keys(self) -> Set { self.inner.into_keys() } /// Returns the associated value at `index`, if it exists. pub fn value(&self, index: usize) -> Option<&V> { self.inner.value(index) } /// Returns the associated value for `key`, if it exists. pub fn get_value(&self, key: &K) -> Option<&V> where K: Ord, { self.inner.get_value(key) } /// Returns the associated key for `value`, if it exists. pub fn get_key(&self, value: &V) -> Option<&K> where V: PartialEq, { self.inner .values() .iter() .position(|v| v == value) .map(|idx| &self.inner.keys()[idx]) } /// Returns the associated values. pub fn values(&self) -> &[V] { self.inner.values() } /// Returns a zipped iterator over keys and values. pub fn iter_pairs(&self) -> impl ExactSizeIterator + DoubleEndedIterator { self.inner.iter_pairs() } /// Returns an iterator over the ordered keys. pub fn iter(&self) -> core::slice::Iter<'_, K> { self.inner.iter() } } impl TryFromIterator<(K, V)> for BiMap { type Error = Error; /// Attempts to create a [`BiMap`] from an iterator of key-value pairs. /// /// Returns an error if any key or value is duplicated. fn try_from_iter>(iter: I) -> Result { let map = as TryFromIterator<(K, V)>>::try_from_iter(iter)?; Self::try_from(map) } } impl TryFrom> for BiMap { type Error = Error; fn try_from(map: Map) -> Result { { let mut seen = HashSet::with_capacity_and_hasher(map.values.len(), Hasher::default()); for value in map.values.iter() { if !seen.insert(value) { return Err(Error::DuplicateValue); } } } Ok(Self { inner: map }) } } impl fmt::Debug for BiMap { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple("BiMap") .field(&self.inner.iter_pairs().collect::>()) .finish() } } impl fmt::Display for BiMap { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { write!(f, "[")?; for (i, (key, value)) in self.iter_pairs().enumerate() { if i > 0 { write!(f, ", ")?; } write!(f, "({key}, {value})")?; } write!(f, "]") } } impl AsRef<[K]> for BiMap { fn as_ref(&self) -> &[K] { self.inner.as_ref() } } impl AsRef> for BiMap { fn as_ref(&self) -> &Set { self.inner.as_ref() } } impl Deref for BiMap { type Target = Set; fn deref(&self) -> &Self::Target { &self.inner } } impl TryFrom<&[(K, V)]> for BiMap { type Error = Error; fn try_from(items: &[(K, V)]) -> Result { Self::try_from_iter(items.iter().cloned()) } } impl TryFrom> for BiMap { type Error = Error; fn try_from(items: Vec<(K, V)>) -> Result { Self::try_from_iter(items) } } impl TryFrom<[(K, V); N]> for BiMap { type Error = Error; fn try_from(items: [(K, V); N]) -> Result { Self::try_from_iter(items) } } impl TryFrom<&[(K, V); N]> for BiMap { type Error = Error; fn try_from(items: &[(K, V); N]) -> Result { Self::try_from(items.as_slice()) } } impl From> for Vec<(K, V)> { fn from(wrapped: BiMap) -> Self { wrapped.inner.into() } } impl Write for BiMap { fn write(&self, buf: &mut impl BufMut) { self.inner.write(buf); } } impl EncodeSize for BiMap { fn encode_size(&self) -> usize { self.inner.encode_size() } } impl Read for BiMap { type Cfg = (RangeCfg, K::Cfg, V::Cfg); fn read_cfg(buf: &mut impl Buf, cfg: &Self::Cfg) -> Result { let inner = Map::::read_cfg(buf, cfg)?; Self::try_from(inner).map_err(|_| { commonware_codec::Error::Invalid( "BiMap", "duplicate value detected during deserialization", ) }) } } impl IntoIterator for BiMap { type Item = (K, V); type IntoIter = MapIntoIter; fn into_iter(self) -> Self::IntoIter { self.inner.into_iter() } } impl<'a, K, V> IntoIterator for &'a BiMap { type Item = (&'a K, &'a V); type IntoIter = core::iter::Zip, core::slice::Iter<'a, V>>; fn into_iter(self) -> Self::IntoIter { self.inner.iter().zip(self.inner.values().iter()) } } #[cfg(feature = "arbitrary")] impl arbitrary::Arbitrary<'_> for BiMap where K: for<'a> arbitrary::Arbitrary<'a> + Ord, V: for<'a> arbitrary::Arbitrary<'a> + Ord + Hash, { fn arbitrary(u: &mut arbitrary::Unstructured<'_>) -> arbitrary::Result { let mut vec = Vec::<(K, V)>::arbitrary(u)?; vec.sort_by(|(lk, _), (rk, _)| lk.cmp(rk)); vec.dedup_by(|l, r| l.0 == r.0); vec.sort_by(|(_, lv), (_, rv)| lv.cmp(rv)); vec.dedup_by(|l, r| l.1 == r.1); Self::try_from_iter(vec).map_err(|_| arbitrary::Error::IncorrectFormat) } } #[cfg(test)] mod test { use super::*; use core::cell::Cell; use rstest::rstest; #[test] fn test_sorted_unique_construct_unseal() { const CASE: [u8; 12] = [1, 3, 2, 5, 4, 3, 1, 7, 9, 6, 8, 4]; const EXPECTED: [u8; 9] = [1, 2, 3, 4, 5, 6, 7, 8, 9]; let sorted = Set::from_iter_dedup(CASE); assert_eq!(sorted.iter().copied().collect::>(), EXPECTED); let unsealed: Vec<_> = sorted.into(); assert_eq!(unsealed, EXPECTED); } #[test] fn test_sorted_unique_codec_roundtrip() { const CASE: [u8; 9] = [1, 2, 3, 4, 5, 6, 7, 8, 9]; let sorted: Set<_> = CASE.try_into().unwrap(); let mut buf = Vec::with_capacity(sorted.encode_size()); sorted.write(&mut buf); let decoded = Set::::read_cfg(&mut bytes::Bytes::from(buf), &(RangeCfg::from(0..=9), ())) .unwrap(); assert_eq!(sorted, decoded); } #[test] fn test_sorted_unique_display() { const CASE: [u8; 9] = [1, 2, 3, 4, 5, 6, 7, 8, 9]; #[derive(Ord, PartialOrd, Eq, PartialEq)] struct Example(u8); impl fmt::Display for Example { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "ex({})", self.0) } } let sorted: Set<_> = Set::try_from_iter(CASE.into_iter().map(Example)).unwrap(); assert_eq!( sorted.to_string(), "[ex(1), ex(2), ex(3), ex(4), ex(5), ex(6), ex(7), ex(8), ex(9)]" ); } #[test] fn test_set_from_iter_dedup() { let items = [3u8, 1u8, 2u8, 2u8]; let set = Set::from_iter_dedup(items); assert_eq!(set.iter().copied().collect::>(), vec![1, 2, 3]); } #[test] fn test_set_try_from_duplicate() { let result: Result, _> = vec![3u8, 1u8, 2u8, 2u8].try_into(); assert_eq!(result, Err(Error::DuplicateKey)); } #[test] fn test_set_try_from_iter_duplicate() { let items = vec![3u8, 1u8, 2u8, 2u8]; let result = Set::try_from_iter(items); assert_eq!(result, Err(Error::DuplicateKey)); } #[test] fn test_map_from_iter_dedup() { let items = vec![(3u8, "c"), (1u8, "a"), (2u8, "b"), (1u8, "duplicate")]; let map = Map::from_iter_dedup(items); assert_eq!(map.len(), 3); assert_eq!(map.iter().copied().collect::>(), vec![1, 2, 3]); assert_eq!(map.get_value(&1), Some(&"a")); assert_eq!(map.get_value(&4), None); assert_eq!(map.value(1), Some(&"b")); } #[test] fn test_map_try_from() { let pairs = vec![(3u8, "c"), (1u8, "a"), (2u8, "b")]; let wrapped: Map<_, _> = pairs.try_into().unwrap(); assert_eq!(wrapped.iter().copied().collect::>(), vec![1, 2, 3]); assert_eq!(wrapped.get_value(&2), Some(&"b")); } #[test] fn test_map_try_from_duplicate() { let result: Result, _> = vec![(3u8, "c"), (1u8, "a"), (2u8, "b"), (1u8, "duplicate")].try_into(); assert_eq!(result, Err(Error::DuplicateKey)); } #[test] fn test_map_try_from_iter_duplicate() { let pairs = vec![(3u8, "c"), (1u8, "a"), (2u8, "b"), (1u8, "duplicate")]; let result = Map::try_from_iter(pairs); assert_eq!(result, Err(Error::DuplicateKey)); } #[test] fn test_map_deref_to_set() { fn sum(set: &Set) -> u32 { set.iter().map(|v| *v as u32).sum() } let map: Map<_, _> = vec![(2u8, "b"), (1u8, "a")].try_into().unwrap(); assert_eq!(sum(&map), 3); } #[test] fn test_map_from_set() { let set: Set<_> = vec![(3u8, 'a'), (1u8, 'b'), (2u8, 'c')].try_into().unwrap(); let wrapped: Map<_, _> = Map::try_from_iter(set.clone()).unwrap(); assert_eq!( set.iter().map(|(k, _)| *k).collect::>(), wrapped.keys().iter().copied().collect::>(), ); } #[test] fn test_map_from_parts_reuses_allocations() { #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)] struct Key(u8); #[derive(Debug, PartialEq, Eq)] struct Value(u8); let keys = Set::try_from([Key(3), Key(1), Key(2)]).unwrap(); let values = vec![Value(30), Value(10), Value(10)]; let keys_ptr = keys.as_ref().as_ptr(); let values_ptr = values.as_ptr(); let map = Map::from_parts(keys, values).unwrap(); assert_eq!(map.keys().as_ref().as_ptr(), keys_ptr); assert_eq!(map.values().as_ptr(), values_ptr); assert_eq!(map.keys().as_ref(), &[Key(1), Key(2), Key(3)]); assert_eq!(map.values(), &[Value(30), Value(10), Value(10)]); } #[rstest] fn test_map_from_parts_lengths( #[values(0, 1, 3)] keys_len: usize, #[values(0, 1, 3)] values_len: usize, ) { let keys = Set::try_from_iter(0..keys_len).unwrap(); let map = Map::from_parts(keys, vec![(); values_len]); assert_eq!(map.is_some(), keys_len == values_len); if let Some(map) = map { assert_eq!(map.len(), keys_len); assert_eq!(map.values().len(), values_len); } } #[test] fn test_map_into_keys() { let map: Map<_, _> = vec![(3u8, "c"), (1u8, "a"), (2u8, "b")].try_into().unwrap(); let keys = map.into_keys(); assert_eq!(keys.iter().copied().collect::>(), vec![1, 2, 3]); } #[test] fn test_values_mut() { let mut map: Map = vec![(1u8, 10u8), (2, 20)].try_into().unwrap(); for value in map.values_mut() { *value += 1; } assert_eq!(map.values(), &[11, 21]); } #[test] fn test_map_values_borrowed() { struct Value(u8); let map = Map::try_from([(3, Value(30)), (1, Value(10)), (2, Value(20))]).unwrap(); let mapped = map.map_values(|key, value| (key, &value.0)); let tried = map .try_map_values(|key, value| Ok::<_, ()>((key, &value.0))) .unwrap(); for result in [mapped, tried] { assert_eq!(result.keys(), map.keys()); assert_eq!(result.values(), &[(&1, &10), (&2, &20), (&3, &30)]); } assert_eq!(map.get_value(&2).unwrap().0, 20); } #[rstest] #[case::infallible(false)] #[case::fallible(true)] fn test_map_values_into_reuses_keys(#[case] fallible: bool) { #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)] struct Key(u8); struct Value(u8); let map = Map::try_from([ (Key(3), Value(30)), (Key(1), Value(10)), (Key(2), Value(20)), ]) .unwrap(); let keys_ptr = map.keys().as_ref().as_ptr(); let mut visited = Vec::new(); let mut transform = |key: &Key, value: Value| { visited.push(key.0); key.0 + value.0 }; let mapped = if fallible { map.try_map_values_into(|key, value| Ok::<_, ()>(transform(key, value))) .unwrap() } else { map.map_values_into(transform) }; assert_eq!(visited, [1, 2, 3]); assert_eq!(mapped.keys().as_ref().as_ptr(), keys_ptr); assert_eq!(mapped.keys().as_ref(), &[Key(1), Key(2), Key(3)]); assert_eq!(mapped.values(), &[11, 22, 33]); } #[test] fn test_map_values_empty() { let map = Map::::default(); let mapped: Map<_, u32> = map.map_values(|_, _| unreachable!()); assert!(mapped.is_empty()); let mapped: Result, ()> = map.try_map_values(|_, _| unreachable!()); assert!(mapped.unwrap().is_empty()); let mapped: Map<_, u32> = map.clone().map_values_into(|_, _| unreachable!()); assert!(mapped.is_empty()); let mapped: Result, ()> = map.try_map_values_into(|_, _| unreachable!()); assert!(mapped.unwrap().is_empty()); } #[rstest] #[case::borrowed(false)] #[case::owned(true)] fn test_try_map_values_error(#[case] owned: bool, #[values(1, 2, 3)] failed_key: usize) { struct Tracked<'a>(&'a Cell); impl Drop for Tracked<'_> { fn drop(&mut self) { self.0.set(self.0.get() + 1); } } let input_drops = Cell::new(0); let output_drops = Cell::new(0); let map = Map::try_from_iter((1..=3).map(|key| (key, Tracked(&input_drops)))).unwrap(); let mut visited = Vec::new(); let mut transform = |key: &usize| { visited.push(*key); if *key == failed_key { Err(*key) } else { Ok(Tracked(&output_drops)) } }; let result = if owned { map.try_map_values_into(|key, _| transform(key)) } else { map.try_map_values(|key, _| transform(key)) }; assert_eq!(result.err(), Some(failed_key)); assert_eq!(visited, (1..=failed_key).collect::>()); assert_eq!(input_drops.get(), if owned { 3 } else { 0 }); assert_eq!(output_drops.get(), failed_key - 1); } #[test] fn test_pair_iterators() { fn check(mut pairs: impl ExactSizeIterator + DoubleEndedIterator) { assert_eq!(pairs.len(), 3); assert_eq!(pairs.next(), Some((1, 10))); assert_eq!(pairs.len(), 2); assert_eq!(pairs.next_back(), Some((3, 30))); assert_eq!(pairs.len(), 1); assert_eq!(pairs.next_back(), Some((2, 20))); assert_eq!(pairs.len(), 0); assert_eq!(pairs.next(), None); assert_eq!(pairs.next_back(), None); } let mut map = Map::try_from([(3, 30), (1, 10), (2, 20)]).unwrap(); check(map.iter_pairs().map(|(&key, &value)| (key, value))); check(map.iter_pairs_mut().map(|(&key, value)| { let previous = *value; *value += key; (key, previous) })); assert_eq!(map.values(), &[11, 22, 33]); let bimap = BiMap::try_from([(3, 30), (1, 10), (2, 20)]).unwrap(); check(bimap.iter_pairs().map(|(&key, &value)| (key, value))); } #[test] fn test_map_allows_duplicate_values() { let items = vec![(1u8, "a"), (2u8, "b"), (3u8, "a")]; let map: Map<_, _> = items.try_into().unwrap(); assert_eq!(map.len(), 3); assert_eq!(map.get_value(&1), Some(&"a")); assert_eq!(map.get_value(&3), Some(&"a")); } #[test] fn test_bimap_duplicate_value_error() { let items = vec![(1u8, "a"), (2u8, "b"), (3u8, "a")]; let result = BiMap::try_from_iter(items); assert_eq!(result, Err(Error::DuplicateValue)); } #[test] fn test_bimap_no_duplicate_values() { let items = vec![(1u8, "a"), (2u8, "b"), (3u8, "c")]; let result = BiMap::try_from_iter(items); assert!(result.is_ok()); let map = result.unwrap(); assert_eq!(map.len(), 3); assert_eq!(map.get_value(&1), Some(&"a")); assert_eq!(map.get_value(&2), Some(&"b")); assert_eq!(map.get_value(&3), Some(&"c")); } #[test] fn test_bimap_try_from_map() { let items = vec![(1u8, "a"), (2u8, "b"), (3u8, "c")]; let map: Map<_, _> = items.try_into().unwrap(); let bimap = BiMap::try_from(map).unwrap(); assert_eq!(bimap.len(), 3); assert_eq!(bimap.get_value(&1), Some(&"a")); } #[test] fn test_bimap_get_key() { let items = vec![(1u8, "a"), (2u8, "b"), (3u8, "c")]; let bimap: BiMap<_, _> = items.try_into().unwrap(); assert_eq!(bimap.get_key(&"a"), Some(&1)); assert_eq!(bimap.get_key(&"b"), Some(&2)); assert_eq!(bimap.get_key(&"c"), Some(&3)); assert_eq!(bimap.get_key(&"d"), None); } #[test] fn test_bimap_try_from_map_duplicate() { let items = vec![(1u8, "a"), (2u8, "b"), (3u8, "a")]; let map: Map<_, _> = items.try_into().unwrap(); let result = BiMap::try_from(map); assert_eq!(result, Err(Error::DuplicateValue)); } #[test] fn test_bimap_decode_rejects_duplicate_values() { let items = vec![(1u8, 10u8), (2, 20), (3, 10)]; let map: Map<_, _> = items.try_into().unwrap(); let mut buf = Vec::with_capacity(map.encode_size()); map.write(&mut buf); let cfg = (RangeCfg::from(0..=10), (), ()); let result = BiMap::::read_cfg(&mut bytes::Bytes::from(buf), &cfg); assert!(result.is_err()); } #[test] fn test_set_decode_rejects_duplicates() { let items: Vec = vec![1, 2, 2, 3]; let mut buf = Vec::new(); items.write(&mut buf); let cfg = (RangeCfg::from(0..=10), ()); let result = Set::::read_cfg(&mut bytes::Bytes::from(buf), &cfg); assert!(result.is_err()); } #[test] fn test_set_decode_rejects_unsorted() { let items: Vec = vec![1, 3, 2, 4]; let mut buf = Vec::new(); items.write(&mut buf); let cfg = (RangeCfg::from(0..=10), ()); let result = Set::::read_cfg(&mut bytes::Bytes::from(buf), &cfg); assert!(result.is_err()); } #[test] fn test_set_decode_accepts_valid() { let items: Vec = vec![1, 2, 3, 4]; let mut buf = Vec::new(); items.write(&mut buf); let cfg = (RangeCfg::from(0..=10), ()); let result = Set::::read_cfg(&mut bytes::Bytes::from(buf), &cfg); assert!(result.is_ok()); assert_eq!(result.unwrap().iter().copied().collect::>(), items); } #[test] fn test_map_decode_rejects_duplicate_keys() { let keys: Vec = vec![1, 2, 2, 3]; let values: Vec = vec![10, 20, 30, 40]; let mut buf = Vec::new(); keys.write(&mut buf); values.write(&mut buf); let cfg = (RangeCfg::from(0..=10), (), ()); let result = Map::::read_cfg(&mut bytes::Bytes::from(buf), &cfg); assert!(result.is_err()); } #[test] fn test_map_decode_rejects_unsorted_keys() { let keys: Vec = vec![1, 3, 2, 4]; let values: Vec = vec![10, 20, 30, 40]; let mut buf = Vec::new(); keys.write(&mut buf); values.write(&mut buf); let cfg = (RangeCfg::from(0..=10), (), ()); let result = Map::::read_cfg(&mut bytes::Bytes::from(buf), &cfg); assert!(result.is_err()); } #[test] fn test_map_decode_accepts_valid() { let keys: Vec = vec![1, 2, 3, 4]; let values: Vec = vec![10, 20, 30, 40]; let mut buf = Vec::new(); keys.write(&mut buf); values.write(&mut buf); let cfg = (RangeCfg::from(0..=10), (), ()); let result = Map::::read_cfg(&mut bytes::Bytes::from(buf), &cfg); assert!(result.is_ok()); let map = result.unwrap(); assert_eq!(map.keys().iter().copied().collect::>(), keys); assert_eq!(map.values(), values.as_slice()); } #[cfg(feature = "arbitrary")] mod conformance { use super::*; use commonware_codec::conformance::CodecConformance; commonware_conformance::conformance_tests! { CodecConformance>, CodecConformance>, CodecConformance>, } } }