jam_types/
vec_set.rs

1use super::*;
2use alloc::{borrow::Borrow, 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 const 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<Q>(&self, t: &Q) -> bool
149	where
150		T: Borrow<Q>,
151		Q: Ord + ?Sized,
152	{
153		self.0.binary_search_by(|x| x.borrow().cmp(t)).is_ok()
154	}
155	/// Remove an item from the set.
156	///
157	/// Removes the item equal to `t` from the set.
158	///
159	/// Returns [Some] with the removed item if it was previously in the set.
160	pub fn remove<Q>(&mut self, t: &Q) -> Option<T>
161	where
162		T: Borrow<Q>,
163		Q: Ord + ?Sized,
164	{
165		match self.0.binary_search_by(|x| x.borrow().cmp(t)) {
166			Ok(i) => Some(self.0.remove(i)),
167			Err(_) => None,
168		}
169	}
170	/// Filter items from the set.
171	///
172	/// Removes all items from the set for which `f` returns `false`.
173	pub fn retain(&mut self, f: impl FnMut(&T) -> bool) {
174		self.0.retain(f);
175	}
176	/// Remove all elements.
177	pub fn clear(&mut self) {
178		self.0.clear();
179	}
180}
181
182impl<T: Eq + PartialEq + Ord + PartialOrd> SetLike<T> for VecSet<T> {
183	fn insert(&mut self, t: T) -> bool {
184		VecSet::<T>::insert(self, t)
185	}
186	fn extend(&mut self, iter: impl Iterator<Item = T>) {
187		VecSet::<T>::extend(self, iter)
188	}
189	fn contains(&self, t: &T) -> bool {
190		VecSet::<T>::contains(self, t)
191	}
192	fn remove(&mut self, t: &T) -> bool {
193		VecSet::<T>::remove(self, t).is_some()
194	}
195}
196
197impl<T: fmt::Debug> fmt::Debug for VecSet<T> {
198	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
199		match self.0.len() {
200			0 => write!(f, "[]"),
201			_ => {
202				write!(f, "[{:?}", self.0[0])?;
203				for i in 1..self.0.len() {
204					write!(f, ", {:?}", self.0[i])?;
205				}
206				write!(f, "]")
207			},
208		}
209	}
210}
211
212impl<T: fmt::Display> fmt::Display for VecSet<T> {
213	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
214		match self.0.len() {
215			0 => write!(f, "[]"),
216			_ => {
217				write!(f, "[{}", self.0[0])?;
218				for i in 1..self.0.len() {
219					write!(f, ", {}", self.0[i])?;
220				}
221				write!(f, "]")
222			},
223		}
224	}
225}
226
227impl<T: Decode + Eq + PartialEq + Ord + PartialOrd> Decode for VecSet<T> {
228	fn decode<I: codec::Input>(input: &mut I) -> Result<Self, DecodeError> {
229		Ok(Self::from_sorted(Vec::<T>::decode(input)?).map_err(|()| "set out-of-order")?)
230	}
231}
232
233impl<T: Eq + PartialEq + Ord + PartialOrd> Default for VecSet<T> {
234	fn default() -> Self {
235		Self::new()
236	}
237}
238impl<T> AsRef<[T]> for VecSet<T> {
239	fn as_ref(&self) -> &[T] {
240		&self.0[..]
241	}
242}
243impl<T> AsMut<[T]> for VecSet<T> {
244	fn as_mut(&mut self) -> &mut [T] {
245		&mut self.0[..]
246	}
247}
248
249impl<T> From<VecSet<T>> for Vec<T> {
250	fn from(s: VecSet<T>) -> Vec<T> {
251		s.0
252	}
253}
254impl<T: Eq + PartialEq + Ord + PartialOrd> From<Vec<T>> for VecSet<T> {
255	fn from(mut v: Vec<T>) -> Self {
256		v.sort_unstable();
257		v.dedup();
258		Self(v)
259	}
260}
261impl<T: Eq + PartialEq + Ord + PartialOrd> FromIterator<T> for VecSet<T> {
262	fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
263		Vec::<T>::from_iter(iter).into()
264	}
265}
266impl<T: Eq + PartialEq + Ord + PartialOrd> Extend<T> for VecSet<T> {
267	fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
268		VecSet::<T>::extend(self, iter)
269	}
270}
271impl<T: Eq + PartialEq + Ord + PartialOrd> IntoIterator for VecSet<T> {
272	type Item = T;
273	type IntoIter = <Vec<T> as IntoIterator>::IntoIter;
274
275	fn into_iter(self) -> Self::IntoIter {
276		self.0.into_iter()
277	}
278}
279
280pub(crate) fn is_disjoint<X: Ord + PartialOrd>(
281	a: impl IntoIterator<Item = X>,
282	b: impl IntoIterator<Item = X>,
283) -> bool {
284	let mut ordered_a = a.into_iter();
285	let mut ordered_b = b.into_iter();
286	let mut a_next = ordered_a.next();
287	let mut b_next = ordered_b.next();
288	while let (Some(a), Some(b)) = (a_next.as_ref(), b_next.as_ref()) {
289		if a == b {
290			return false
291		}
292		if a < b {
293			a_next = ordered_a.next();
294		} else {
295			b_next = ordered_b.next();
296		}
297	}
298	true
299}