1use super::*;
2use alloc::{borrow::Borrow, collections::BTreeSet};
3use codec::Error as DecodeError;
4use core::fmt;
5
6pub trait SetLike<T> {
9 fn insert(&mut self, t: T) -> bool;
15 fn extend(&mut self, iter: impl Iterator<Item = T>);
17 fn contains(&self, t: &T) -> bool;
21 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#[derive(Clone, Encode, Eq, PartialEq, Ord, PartialOrd)]
65pub struct VecSet<T>(Vec<T>);
66impl<T: Eq + PartialEq + Ord + PartialOrd> VecSet<T> {
67 pub const fn new() -> Self {
69 Self(Vec::new())
70 }
71 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 pub fn len(&self) -> usize {
84 self.0.len()
85 }
86 pub fn is_empty(&self) -> bool {
88 self.0.is_empty()
89 }
90 pub fn is_disjoint(&self, other: &Self) -> bool {
94 is_disjoint(&self.0, &other.0)
95 }
96 pub fn iter(&self) -> core::slice::Iter<'_, T> {
98 self.0.iter()
99 }
100 pub fn map<U>(self, f: impl FnMut(T) -> U) -> Vec<U> {
105 self.0.into_iter().map(f).collect::<Vec<_>>()
106 }
107 pub fn map_ref<U>(&self, f: impl FnMut(&T) -> U) -> Vec<U> {
112 self.0.iter().map(f).collect::<Vec<_>>()
113 }
114 pub fn to_vec(&self) -> Vec<T>
116 where
117 T: Clone,
118 {
119 self.0.clone()
120 }
121 pub fn into_vec(self) -> Vec<T> {
123 self.0
124 }
125 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 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 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 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 pub fn retain(&mut self, f: impl FnMut(&T) -> bool) {
174 self.0.retain(f);
175 }
176 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}