1use alloc::vec::Vec;
21use core::marker::PhantomData;
22use impl_trait_for_tuples::impl_for_tuples;
23use sp_arithmetic::traits::AtLeast16BitUnsigned;
24use sp_runtime::DispatchResult;
25
26pub trait Contains<T> {
28 fn contains(t: &T) -> bool;
30}
31
32#[cfg_attr(all(not(feature = "tuples-96"), not(feature = "tuples-128")), impl_for_tuples(64))]
33#[cfg_attr(all(feature = "tuples-96", not(feature = "tuples-128")), impl_for_tuples(96))]
34#[cfg_attr(feature = "tuples-128", impl_for_tuples(128))]
35impl<T> Contains<T> for Tuple {
36 fn contains(t: &T) -> bool {
37 for_tuples!( #(
38 if Tuple::contains(t) { return true }
39 )* );
40 false
41 }
42}
43
44pub trait ContainsPair<A, B> {
46 fn contains(a: &A, b: &B) -> bool;
48}
49
50#[cfg_attr(all(not(feature = "tuples-96"), not(feature = "tuples-128")), impl_for_tuples(64))]
51#[cfg_attr(all(feature = "tuples-96", not(feature = "tuples-128")), impl_for_tuples(96))]
52#[cfg_attr(feature = "tuples-128", impl_for_tuples(128))]
53impl<A, B> ContainsPair<A, B> for Tuple {
54 fn contains(a: &A, b: &B) -> bool {
55 for_tuples!( #(
56 if Tuple::contains(a, b) { return true }
57 )* );
58 false
59 }
60}
61
62pub struct FromContainsPair<CP>(PhantomData<CP>);
64impl<A, B, CP: ContainsPair<A, B>> Contains<(A, B)> for FromContainsPair<CP> {
65 fn contains((ref a, ref b): &(A, B)) -> bool {
66 CP::contains(a, b)
67 }
68}
69
70pub struct FromContains<CA, CB>(PhantomData<(CA, CB)>);
73impl<A, B, CA: Contains<A>, CB: Contains<B>> ContainsPair<A, B> for FromContains<CA, CB> {
74 fn contains(a: &A, b: &B) -> bool {
75 CA::contains(a) && CB::contains(b)
76 }
77}
78
79pub enum Everything {}
81impl<T> Contains<T> for Everything {
82 fn contains(_: &T) -> bool {
83 true
84 }
85}
86impl<A, B> ContainsPair<A, B> for Everything {
87 fn contains(_: &A, _: &B) -> bool {
88 true
89 }
90}
91
92pub enum Nothing {}
94impl<T> Contains<T> for Nothing {
95 fn contains(_: &T) -> bool {
96 false
97 }
98}
99impl<A, B> ContainsPair<A, B> for Nothing {
100 fn contains(_: &A, _: &B) -> bool {
101 false
102 }
103}
104
105pub struct EverythingBut<Exclude>(PhantomData<Exclude>);
107impl<T, Exclude: Contains<T>> Contains<T> for EverythingBut<Exclude> {
108 fn contains(t: &T) -> bool {
109 !Exclude::contains(t)
110 }
111}
112impl<A, B, Exclude: ContainsPair<A, B>> ContainsPair<A, B> for EverythingBut<Exclude> {
113 fn contains(a: &A, b: &B) -> bool {
114 !Exclude::contains(a, b)
115 }
116}
117
118pub struct TheseExcept<These, Except>(PhantomData<(These, Except)>);
121impl<T, These: Contains<T>, Except: Contains<T>> Contains<T> for TheseExcept<These, Except> {
122 fn contains(t: &T) -> bool {
123 These::contains(t) && !Except::contains(t)
124 }
125}
126impl<A, B, These: ContainsPair<A, B>, Except: ContainsPair<A, B>> ContainsPair<A, B>
127 for TheseExcept<These, Except>
128{
129 fn contains(a: &A, b: &B) -> bool {
130 These::contains(a, b) && !Except::contains(a, b)
131 }
132}
133
134pub struct InsideBoth<These, Those>(PhantomData<(These, Those)>);
137impl<T, These: Contains<T>, Those: Contains<T>> Contains<T> for InsideBoth<These, Those> {
138 fn contains(t: &T) -> bool {
139 These::contains(t) && Those::contains(t)
140 }
141}
142impl<A, B, These: ContainsPair<A, B>, Those: ContainsPair<A, B>> ContainsPair<A, B>
143 for InsideBoth<These, Those>
144{
145 fn contains(a: &A, b: &B) -> bool {
146 These::contains(a, b) && Those::contains(a, b)
147 }
148}
149
150pub struct Equals<T>(PhantomData<T>);
152impl<X: PartialEq, T: super::Get<X>> Contains<X> for Equals<T> {
153 fn contains(t: &X) -> bool {
154 t == &T::get()
155 }
156}
157
158#[macro_export]
161macro_rules! match_types {
162 (
163 pub type $n:ident: impl Contains<$t:ty> = {
164 $phead:pat_param $( | $ptail:pat )*
165 };
166 $( $rest:tt )*
167 ) => {
168 pub struct $n;
169 impl $crate::traits::Contains<$t> for $n {
170 fn contains(l: &$t) -> bool {
171 matches!(l, $phead $( | $ptail )* )
172 }
173 }
174 $crate::match_types!( $( $rest )* );
175 };
176 (
177 pub type $n:ident: impl ContainsPair<$a:ty, $b:ty> = {
178 $phead:pat_param $( | $ptail:pat )*
179 };
180 $( $rest:tt )*
181 ) => {
182 pub struct $n;
183 impl $crate::traits::ContainsPair<$a, $b> for $n {
184 fn contains(a: &$a, b: &$b) -> bool {
185 matches!((a, b), $phead $( | $ptail )* )
186 }
187 }
188 $crate::match_types!( $( $rest )* );
189 };
190 () => {}
191}
192
193#[cfg(test)]
194mod tests {
195 use super::*;
196
197 match_types! {
198 pub type OneOrTenToTwenty: impl Contains<u8> = { 1 | 10..=20 };
199 }
200
201 #[test]
202 fn match_types_works() {
203 for i in 0..=255 {
204 assert_eq!(OneOrTenToTwenty::contains(&i), i == 1 || i >= 10 && i <= 20);
205 }
206 }
207}
208
209pub trait SortedMembers<T: Ord> {
211 fn sorted_members() -> Vec<T>;
213
214 fn contains(t: &T) -> bool {
216 Self::sorted_members().binary_search(t).is_ok()
217 }
218
219 fn count() -> usize {
221 Self::sorted_members().len()
222 }
223
224 #[cfg(feature = "runtime-benchmarks")]
229 fn add(_t: &T) {
230 unimplemented!()
231 }
232}
233
234pub struct AsContains<OM>(PhantomData<(OM,)>);
236impl<T: Ord + Eq, OM: SortedMembers<T>> Contains<T> for AsContains<OM> {
237 fn contains(t: &T) -> bool {
238 OM::contains(t)
239 }
240}
241
242pub struct IsInVec<T>(PhantomData<T>);
244impl<X: Eq, T: super::Get<Vec<X>>> Contains<X> for IsInVec<T> {
245 fn contains(t: &X) -> bool {
246 T::get().contains(t)
247 }
248}
249impl<X: Ord + PartialOrd, T: super::Get<Vec<X>>> SortedMembers<X> for IsInVec<T> {
250 fn sorted_members() -> Vec<X> {
251 let mut r = T::get();
252 r.sort();
253 r
254 }
255}
256
257pub trait ContainsLengthBound {
259 fn min_len() -> usize;
261 fn max_len() -> usize;
263}
264
265pub trait RankedMembers {
267 type AccountId;
268 type Rank: AtLeast16BitUnsigned;
269
270 fn min_rank() -> Self::Rank;
272
273 fn rank_of(who: &Self::AccountId) -> Option<Self::Rank>;
275
276 fn induct(who: &Self::AccountId) -> DispatchResult;
278
279 fn promote(who: &Self::AccountId) -> DispatchResult;
281
282 fn demote(who: &Self::AccountId) -> DispatchResult;
285}
286
287#[impl_trait_for_tuples::impl_for_tuples(16)]
289pub trait RankedMembersSwapHandler<AccountId, Rank> {
290 fn swapped(who: &AccountId, new_who: &AccountId, rank: Rank);
292}
293
294pub trait InitializeMembers<AccountId> {
296 fn initialize_members(members: &[AccountId]);
298}
299
300impl<T> InitializeMembers<T> for () {
301 fn initialize_members(_: &[T]) {}
302}
303
304pub trait ChangeMembers<AccountId: Clone + Ord> {
306 fn change_members(incoming: &[AccountId], outgoing: &[AccountId], mut new: Vec<AccountId>) {
311 new.sort();
312 Self::change_members_sorted(incoming, outgoing, &new[..]);
313 }
314
315 fn change_members_sorted(
322 incoming: &[AccountId],
323 outgoing: &[AccountId],
324 sorted_new: &[AccountId],
325 );
326
327 fn set_members_sorted(new_members: &[AccountId], old_members: &[AccountId]) {
332 let (incoming, outgoing) = Self::compute_members_diff_sorted(new_members, old_members);
333 Self::change_members_sorted(&incoming[..], &outgoing[..], new_members);
334 }
335
336 fn compute_members_diff_sorted(
340 new_members: &[AccountId],
341 old_members: &[AccountId],
342 ) -> (Vec<AccountId>, Vec<AccountId>) {
343 let mut old_iter = old_members.iter();
344 let mut new_iter = new_members.iter();
345 let mut incoming = Vec::new();
346 let mut outgoing = Vec::new();
347 let mut old_i = old_iter.next();
348 let mut new_i = new_iter.next();
349 loop {
350 match (old_i, new_i) {
351 (None, None) => break,
352 (Some(old), Some(new)) if old == new => {
353 old_i = old_iter.next();
354 new_i = new_iter.next();
355 },
356 (Some(old), Some(new)) if old < new => {
357 outgoing.push(old.clone());
358 old_i = old_iter.next();
359 },
360 (Some(old), None) => {
361 outgoing.push(old.clone());
362 old_i = old_iter.next();
363 },
364 (_, Some(new)) => {
365 incoming.push(new.clone());
366 new_i = new_iter.next();
367 },
368 }
369 }
370 (incoming, outgoing)
371 }
372
373 fn set_prime(_prime: Option<AccountId>) {}
375
376 fn get_prime() -> Option<AccountId> {
378 None
379 }
380}
381
382impl<T: Clone + Ord> ChangeMembers<T> for () {
383 fn change_members(_: &[T], _: &[T], _: Vec<T>) {}
384 fn change_members_sorted(_: &[T], _: &[T], _: &[T]) {}
385 fn set_members_sorted(_: &[T], _: &[T]) {}
386 fn set_prime(_: Option<T>) {}
387}