1use alloc::vec::Vec;
10use core::marker::PhantomData;
11use impl_trait_for_tuples::impl_for_tuples;
12use subsoil::arithmetic::traits::AtLeast16BitUnsigned;
13use subsoil::runtime::DispatchResult;
14
15pub trait Contains<T> {
17 fn contains(t: &T) -> bool;
19}
20
21#[cfg_attr(all(not(feature = "tuples-96"), not(feature = "tuples-128")), impl_for_tuples(64))]
22#[cfg_attr(all(feature = "tuples-96", not(feature = "tuples-128")), impl_for_tuples(96))]
23#[cfg_attr(feature = "tuples-128", impl_for_tuples(128))]
24impl<T> Contains<T> for Tuple {
25 fn contains(t: &T) -> bool {
26 for_tuples!( #(
27 if Tuple::contains(t) { return true }
28 )* );
29 false
30 }
31}
32
33pub trait ContainsPair<A, B> {
35 fn contains(a: &A, b: &B) -> bool;
37}
38
39#[cfg_attr(all(not(feature = "tuples-96"), not(feature = "tuples-128")), impl_for_tuples(64))]
40#[cfg_attr(all(feature = "tuples-96", not(feature = "tuples-128")), impl_for_tuples(96))]
41#[cfg_attr(feature = "tuples-128", impl_for_tuples(128))]
42impl<A, B> ContainsPair<A, B> for Tuple {
43 fn contains(a: &A, b: &B) -> bool {
44 for_tuples!( #(
45 if Tuple::contains(a, b) { return true }
46 )* );
47 false
48 }
49}
50
51pub struct FromContainsPair<CP>(PhantomData<CP>);
53impl<A, B, CP: ContainsPair<A, B>> Contains<(A, B)> for FromContainsPair<CP> {
54 fn contains((ref a, ref b): &(A, B)) -> bool {
55 CP::contains(a, b)
56 }
57}
58
59pub struct FromContains<CA, CB>(PhantomData<(CA, CB)>);
62impl<A, B, CA: Contains<A>, CB: Contains<B>> ContainsPair<A, B> for FromContains<CA, CB> {
63 fn contains(a: &A, b: &B) -> bool {
64 CA::contains(a) && CB::contains(b)
65 }
66}
67
68pub enum Everything {}
70impl<T> Contains<T> for Everything {
71 fn contains(_: &T) -> bool {
72 true
73 }
74}
75impl<A, B> ContainsPair<A, B> for Everything {
76 fn contains(_: &A, _: &B) -> bool {
77 true
78 }
79}
80
81pub enum Nothing {}
83impl<T> Contains<T> for Nothing {
84 fn contains(_: &T) -> bool {
85 false
86 }
87}
88impl<A, B> ContainsPair<A, B> for Nothing {
89 fn contains(_: &A, _: &B) -> bool {
90 false
91 }
92}
93
94pub struct EverythingBut<Exclude>(PhantomData<Exclude>);
96impl<T, Exclude: Contains<T>> Contains<T> for EverythingBut<Exclude> {
97 fn contains(t: &T) -> bool {
98 !Exclude::contains(t)
99 }
100}
101impl<A, B, Exclude: ContainsPair<A, B>> ContainsPair<A, B> for EverythingBut<Exclude> {
102 fn contains(a: &A, b: &B) -> bool {
103 !Exclude::contains(a, b)
104 }
105}
106
107pub struct TheseExcept<These, Except>(PhantomData<(These, Except)>);
110impl<T, These: Contains<T>, Except: Contains<T>> Contains<T> for TheseExcept<These, Except> {
111 fn contains(t: &T) -> bool {
112 These::contains(t) && !Except::contains(t)
113 }
114}
115impl<A, B, These: ContainsPair<A, B>, Except: ContainsPair<A, B>> ContainsPair<A, B>
116 for TheseExcept<These, Except>
117{
118 fn contains(a: &A, b: &B) -> bool {
119 These::contains(a, b) && !Except::contains(a, b)
120 }
121}
122
123pub struct InsideBoth<These, Those>(PhantomData<(These, Those)>);
126impl<T, These: Contains<T>, Those: Contains<T>> Contains<T> for InsideBoth<These, Those> {
127 fn contains(t: &T) -> bool {
128 These::contains(t) && Those::contains(t)
129 }
130}
131impl<A, B, These: ContainsPair<A, B>, Those: ContainsPair<A, B>> ContainsPair<A, B>
132 for InsideBoth<These, Those>
133{
134 fn contains(a: &A, b: &B) -> bool {
135 These::contains(a, b) && Those::contains(a, b)
136 }
137}
138
139pub struct Equals<T>(PhantomData<T>);
141impl<X: PartialEq, T: super::Get<X>> Contains<X> for Equals<T> {
142 fn contains(t: &X) -> bool {
143 t == &T::get()
144 }
145}
146
147#[macro_export]
150macro_rules! match_types {
151 (
152 pub type $n:ident: impl Contains<$t:ty> = {
153 $phead:pat_param $( | $ptail:pat )*
154 };
155 $( $rest:tt )*
156 ) => {
157 pub struct $n;
158 impl $crate::traits::Contains<$t> for $n {
159 fn contains(l: &$t) -> bool {
160 matches!(l, $phead $( | $ptail )* )
161 }
162 }
163 $crate::match_types!( $( $rest )* );
164 };
165 (
166 pub type $n:ident: impl ContainsPair<$a:ty, $b:ty> = {
167 $phead:pat_param $( | $ptail:pat )*
168 };
169 $( $rest:tt )*
170 ) => {
171 pub struct $n;
172 impl $crate::traits::ContainsPair<$a, $b> for $n {
173 fn contains(a: &$a, b: &$b) -> bool {
174 matches!((a, b), $phead $( | $ptail )* )
175 }
176 }
177 $crate::match_types!( $( $rest )* );
178 };
179 () => {}
180}
181
182#[macro_export]
185#[deprecated = "Use `match_types!` instead"]
186macro_rules! match_type {
187 ($( $x:tt )*) => { $crate::match_types!( $( $x )* ); }
188}
189
190#[deprecated = "Use `Everything` instead"]
191pub type AllowAll = Everything;
192#[deprecated = "Use `Nothing` instead"]
193pub type DenyAll = Nothing;
194#[deprecated = "Use `Contains` instead"]
195pub trait Filter<T> {
196 fn filter(t: &T) -> bool;
197}
198#[allow(deprecated)]
199impl<T, C: Contains<T>> Filter<T> for C {
200 fn filter(t: &T) -> bool {
201 Self::contains(t)
202 }
203}
204
205#[cfg(test)]
206mod tests {
207 use super::*;
208
209 match_types! {
210 pub type OneOrTenToTwenty: impl Contains<u8> = { 1 | 10..=20 };
211 }
212
213 #[test]
214 fn match_types_works() {
215 for i in 0..=255 {
216 assert_eq!(OneOrTenToTwenty::contains(&i), i == 1 || i >= 10 && i <= 20);
217 }
218 }
219}
220
221pub trait SortedMembers<T: Ord> {
223 fn sorted_members() -> Vec<T>;
225
226 fn contains(t: &T) -> bool {
228 Self::sorted_members().binary_search(t).is_ok()
229 }
230
231 fn count() -> usize {
233 Self::sorted_members().len()
234 }
235
236 #[cfg(feature = "runtime-benchmarks")]
241 fn add(_t: &T) {
242 unimplemented!()
243 }
244}
245
246pub struct AsContains<OM>(PhantomData<(OM,)>);
248impl<T: Ord + Eq, OM: SortedMembers<T>> Contains<T> for AsContains<OM> {
249 fn contains(t: &T) -> bool {
250 OM::contains(t)
251 }
252}
253
254pub struct IsInVec<T>(PhantomData<T>);
256impl<X: Eq, T: super::Get<Vec<X>>> Contains<X> for IsInVec<T> {
257 fn contains(t: &X) -> bool {
258 T::get().contains(t)
259 }
260}
261impl<X: Ord + PartialOrd, T: super::Get<Vec<X>>> SortedMembers<X> for IsInVec<T> {
262 fn sorted_members() -> Vec<X> {
263 let mut r = T::get();
264 r.sort();
265 r
266 }
267}
268
269pub trait ContainsLengthBound {
271 fn min_len() -> usize;
273 fn max_len() -> usize;
275}
276
277pub trait RankedMembers {
279 type AccountId;
280 type Rank: AtLeast16BitUnsigned;
281
282 fn min_rank() -> Self::Rank;
284
285 fn rank_of(who: &Self::AccountId) -> Option<Self::Rank>;
287
288 fn induct(who: &Self::AccountId) -> DispatchResult;
290
291 fn promote(who: &Self::AccountId) -> DispatchResult;
293
294 fn demote(who: &Self::AccountId) -> DispatchResult;
297}
298
299#[impl_trait_for_tuples::impl_for_tuples(16)]
301pub trait RankedMembersSwapHandler<AccountId, Rank> {
302 fn swapped(who: &AccountId, new_who: &AccountId, rank: Rank);
304}
305
306pub trait InitializeMembers<AccountId> {
308 fn initialize_members(members: &[AccountId]);
310}
311
312impl<T> InitializeMembers<T> for () {
313 fn initialize_members(_: &[T]) {}
314}
315
316pub trait ChangeMembers<AccountId: Clone + Ord> {
318 fn change_members(incoming: &[AccountId], outgoing: &[AccountId], mut new: Vec<AccountId>) {
323 new.sort();
324 Self::change_members_sorted(incoming, outgoing, &new[..]);
325 }
326
327 fn change_members_sorted(
334 incoming: &[AccountId],
335 outgoing: &[AccountId],
336 sorted_new: &[AccountId],
337 );
338
339 fn set_members_sorted(new_members: &[AccountId], old_members: &[AccountId]) {
344 let (incoming, outgoing) = Self::compute_members_diff_sorted(new_members, old_members);
345 Self::change_members_sorted(&incoming[..], &outgoing[..], new_members);
346 }
347
348 fn compute_members_diff_sorted(
352 new_members: &[AccountId],
353 old_members: &[AccountId],
354 ) -> (Vec<AccountId>, Vec<AccountId>) {
355 let mut old_iter = old_members.iter();
356 let mut new_iter = new_members.iter();
357 let mut incoming = Vec::new();
358 let mut outgoing = Vec::new();
359 let mut old_i = old_iter.next();
360 let mut new_i = new_iter.next();
361 loop {
362 match (old_i, new_i) {
363 (None, None) => break,
364 (Some(old), Some(new)) if old == new => {
365 old_i = old_iter.next();
366 new_i = new_iter.next();
367 },
368 (Some(old), Some(new)) if old < new => {
369 outgoing.push(old.clone());
370 old_i = old_iter.next();
371 },
372 (Some(old), None) => {
373 outgoing.push(old.clone());
374 old_i = old_iter.next();
375 },
376 (_, Some(new)) => {
377 incoming.push(new.clone());
378 new_i = new_iter.next();
379 },
380 }
381 }
382 (incoming, outgoing)
383 }
384
385 fn set_prime(_prime: Option<AccountId>) {}
387
388 fn get_prime() -> Option<AccountId> {
390 None
391 }
392}
393
394impl<T: Clone + Ord> ChangeMembers<T> for () {
395 fn change_members(_: &[T], _: &[T], _: Vec<T>) {}
396 fn change_members_sorted(_: &[T], _: &[T], _: &[T]) {}
397 fn set_members_sorted(_: &[T], _: &[T]) {}
398 fn set_prime(_: Option<T>) {}
399}