jam_types/
vec_set.rs

1use super::*;
2use alloc::collections::BTreeSet;
3use codec::Error as DecodeError;
4use core::fmt;
5
6/// A data-structure providing the storage of non-duplicated items and the querying of their
7/// inclusion.
8pub trait SetLike<T> {
9	/// Insert item into the set.
10	///
11	/// Inserts some item `t` into the set.
12	///
13	/// Returns `true` iff the item was not already in the set.
14	fn insert(&mut self, t: T) -> bool;
15	/// Insert multiple items from an iterator.
16	fn extend(&mut self, iter: impl Iterator<Item = T>);
17	/// Check if a value is in the set.
18	///
19	/// Returns `true` iff the set contains a value equal to `t`.
20	fn contains(&self, t: &T) -> bool;
21	/// Remove an item from the set.
22	///
23	/// Removes the item equal to `t` from the set.
24	///
25	/// Returns `true` iff the item was previously in the set.
26	fn remove(&mut self, t: &T) -> bool;
27}
28
29#[cfg(feature = "std")]
30impl<T: Eq + std::hash::Hash> SetLike<T> for std::collections::HashSet<T> {
31	fn insert(&mut self, t: T) -> bool {
32		std::collections::HashSet::<T>::insert(self, t)
33	}
34	fn extend(&mut self, iter: impl Iterator<Item = T>) {
35		<std::collections::HashSet<T> as Extend<T>>::extend(self, iter)
36	}
37	fn contains(&self, t: &T) -> bool {
38		std::collections::HashSet::<T>::contains(self, t)
39	}
40	fn remove(&mut self, t: &T) -> bool {
41		std::collections::HashSet::<T>::remove(self, t)
42	}
43}
44
45impl<T: Eq + PartialEq + Ord + PartialOrd> SetLike<T> for BTreeSet<T> {
46	fn insert(&mut self, t: T) -> bool {
47		BTreeSet::<T>::insert(self, t)
48	}
49	fn extend(&mut self, iter: impl Iterator<Item = T>) {
50		<BTreeSet<T> as Extend<T>>::extend(self, iter)
51	}
52	fn contains(&self, t: &T) -> bool {
53		BTreeSet::<T>::contains(self, t)
54	}
55	fn remove(&mut self, t: &T) -> bool {
56		BTreeSet::<T>::remove(self, t)
57	}
58}
59
60/// An set of items stored in order in a [Vec].
61///
62/// This is always efficient for small sizes of sets, and efficient for large sizes when
63/// insertion is not needed (i.e. items are placed into the set in bulk).
64#[derive(Clone, Encode, Eq, PartialEq, Ord, PartialOrd)]
65pub struct VecSet<T>(Vec<T>);
66impl<T: Eq + PartialEq + Ord + PartialOrd> VecSet<T> {
67	/// Create a new, empty instance.
68	pub fn new() -> Self {
69		Self(Vec::new())
70	}
71	/// Create a new instance from a sorted [Vec].
72	///
73	/// Returns [Ok] with an instance containing the same items as `v`, or [Err] if `v` is unsorted.
74	pub fn from_sorted(v: Vec<T>) -> Result<Self, ()> {
75		let Some(first) = v.first() else { return Ok(Self::new()) };
76		v.iter()
77			.skip(1)
78			.try_fold(first, |a, e| if a < e { Some(e) } else { None })
79			.ok_or(())?;
80		Ok(Self(v))
81	}
82	/// Return the number of items this set contains.
83	pub fn len(&self) -> usize {
84		self.0.len()
85	}
86	/// Return `true` if this set is empty.
87	pub fn is_empty(&self) -> bool {
88		self.0.is_empty()
89	}
90	/// Compares the items in two sets.
91	///
92	/// Returns `true` iff every item in the set is not found in `other`.
93	pub fn is_disjoint(&self, other: &Self) -> bool {
94		is_disjoint(&self.0, &other.0)
95	}
96	/// Return an iterator over the items in this set in order.
97	pub fn iter(&self) -> core::slice::Iter<T> {
98		self.0.iter()
99	}
100	/// Consume this set and return a [Vec] of transformed items.
101	///
102	/// Returns the [Vec] of the resultant values of applying `f` to each item in the set in
103	/// order.
104	pub fn map<U>(self, f: impl FnMut(T) -> U) -> Vec<U> {
105		self.0.into_iter().map(f).collect::<Vec<_>>()
106	}
107	/// Transform all items by reference and return a [Vec] with the results.
108	///
109	/// Returns the [Vec] of the resultant values of applying `f` to each item by reference in the
110	/// set in order.
111	pub fn map_ref<U>(&self, f: impl FnMut(&T) -> U) -> Vec<U> {
112		self.0.iter().map(f).collect::<Vec<_>>()
113	}
114	/// Return a [Vec] of sorted items by cloning this set.
115	pub fn to_vec(&self) -> Vec<T>
116	where
117		T: Clone,
118	{
119		self.0.clone()
120	}
121	/// Return a [Vec] of sorted items by consuming this set.
122	pub fn into_vec(self) -> Vec<T> {
123		self.0
124	}
125	/// Insert item into the set.
126	///
127	/// Inserts some item `t` into the set.
128	///
129	/// Returns `true` iff the item was not already in the set.
130	pub fn insert(&mut self, t: T) -> bool {
131		match self.0.binary_search(&t) {
132			Ok(_) => false,
133			Err(i) => {
134				self.0.insert(i, t);
135				true
136			},
137		}
138	}
139	/// Insert multiple items from an iterator.
140	pub fn extend(&mut self, iter: impl IntoIterator<Item = T>) {
141		self.0.extend(iter);
142		self.0.sort_unstable();
143		self.0.dedup();
144	}
145	/// Check if a value is in the set.
146	///
147	/// Returns `true` iff the set contains a value equal to `t`.
148	pub fn contains(&self, t: &T) -> bool {
149		self.0.binary_search(t).is_ok()
150	}
151	/// Remove an item from the set.
152	///
153	/// Removes the item equal to `t` from the set.
154	///
155	/// Returns [Some] with the removed item if it was previously in the set.
156	pub fn remove(&mut self, t: &T) -> Option<T> {
157		match self.0.binary_search(t) {
158			Ok(i) => Some(self.0.remove(i)),
159			Err(_) => None,
160		}
161	}
162	/// Filter items from the set.
163	///
164	/// Removes all items from the set for which `f` returns `false`.
165	pub fn retain(&mut self, f: impl FnMut(&T) -> bool) {
166		self.0.retain(f);
167	}
168}
169
170impl<T: Eq + PartialEq + Ord + PartialOrd> SetLike<T> for VecSet<T> {
171	fn insert(&mut self, t: T) -> bool {
172		VecSet::<T>::insert(self, t)
173	}
174	fn extend(&mut self, iter: impl Iterator<Item = T>) {
175		VecSet::<T>::extend(self, iter)
176	}
177	fn contains(&self, t: &T) -> bool {
178		VecSet::<T>::contains(self, t)
179	}
180	fn remove(&mut self, t: &T) -> bool {
181		VecSet::<T>::remove(self, t).is_some()
182	}
183}
184
185impl<T: fmt::Debug> fmt::Debug for VecSet<T> {
186	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
187		match self.0.len() {
188			0 => write!(f, "[]"),
189			_ => {
190				write!(f, "[{:?}", self.0[0])?;
191				for i in 1..self.0.len() {
192					write!(f, ", {:?}", self.0[i])?;
193				}
194				write!(f, "]")
195			},
196		}
197	}
198}
199
200impl<T: fmt::Display> fmt::Display for VecSet<T> {
201	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
202		match self.0.len() {
203			0 => write!(f, "[]"),
204			_ => {
205				write!(f, "[{}", self.0[0])?;
206				for i in 1..self.0.len() {
207					write!(f, ", {}", self.0[i])?;
208				}
209				write!(f, "]")
210			},
211		}
212	}
213}
214
215impl<T: Decode + Eq + PartialEq + Ord + PartialOrd> Decode for VecSet<T> {
216	fn decode<I: codec::Input>(input: &mut I) -> Result<Self, DecodeError> {
217		Ok(Self::from_sorted(Vec::<T>::decode(input)?).map_err(|()| "set out-of-order")?)
218	}
219}
220
221impl<T: Default + Eq + PartialEq + Ord + PartialOrd> Default for VecSet<T> {
222	fn default() -> Self {
223		Self::new()
224	}
225}
226impl<T> AsRef<[T]> for VecSet<T> {
227	fn as_ref(&self) -> &[T] {
228		&self.0[..]
229	}
230}
231impl<T> AsMut<[T]> for VecSet<T> {
232	fn as_mut(&mut self) -> &mut [T] {
233		&mut self.0[..]
234	}
235}
236
237impl<T> From<VecSet<T>> for Vec<T> {
238	fn from(s: VecSet<T>) -> Vec<T> {
239		s.0
240	}
241}
242impl<T: Eq + PartialEq + Ord + PartialOrd> From<Vec<T>> for VecSet<T> {
243	fn from(mut v: Vec<T>) -> Self {
244		v.sort_unstable();
245		Self(v)
246	}
247}
248impl<T: Eq + PartialEq + Ord + PartialOrd> FromIterator<T> for VecSet<T> {
249	fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
250		Vec::<T>::from_iter(iter).into()
251	}
252}
253impl<T: Eq + PartialEq + Ord + PartialOrd> Extend<T> for VecSet<T> {
254	fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
255		VecSet::<T>::extend(self, iter)
256	}
257}
258impl<T: Eq + PartialEq + Ord + PartialOrd> IntoIterator for VecSet<T> {
259	type Item = T;
260	type IntoIter = <Vec<T> as IntoIterator>::IntoIter;
261
262	fn into_iter(self) -> Self::IntoIter {
263		self.0.into_iter()
264	}
265}
266
267pub(crate) fn is_disjoint<X: Ord + PartialOrd>(
268	a: impl IntoIterator<Item = X>,
269	b: impl IntoIterator<Item = X>,
270) -> bool {
271	let mut ordered_a = a.into_iter();
272	let mut ordered_b = b.into_iter();
273	let mut a_next = ordered_a.next();
274	let mut b_next = ordered_b.next();
275	while let (Some(a), Some(b)) = (a_next.as_ref(), b_next.as_ref()) {
276		if a == b {
277			return false
278		}
279		if a < b {
280			a_next = ordered_a.next();
281		} else {
282			b_next = ordered_b.next();
283		}
284	}
285	true
286}