type_sets/
sets.rs

1use crate::*;
2use std::{any::TypeId, sync::OnceLock};
3
4macro_rules! create_sets {
5    ($(
6        $n:literal $set:ident<$($gen:ident),*> $(:)? $($sub_sets:path),*;
7    )*) => {
8        $(
9            // Create the sets as auto-traits
10            #[doc = concat!("A set containing ", $n, " types.")]
11            ///
12            /// This should not be implemented manually.
13            ///
14            /// For easy usage, see the macro [`macro@Set`].
15            pub trait $set<$($gen),*>: $($sub_sets +)* {}
16            impl<$($gen,)* S: ?Sized> $set<$($gen),*> for S where S: $($sub_sets +)* {}
17
18            // Implement the correct IsSubsetOf implementations
19            unsafe impl<$($gen,)* S> SubsetOf<S> for Set<dyn $set<$($gen),*>>
20            where
21                S: $set<$($gen),*>
22            {}
23
24            unsafe impl<$($gen: 'static,)*> Members for Set<dyn $set<$($gen),*>>
25            {
26                fn members() -> Vec<TypeId> {
27                    vec![ $(TypeId::of::<$gen>()),* ]
28                }
29            }
30        )*
31    };
32}
33
34create_sets!(
35    0 Zero<>;
36    1 One<T1>: Zero, Contains<T1>;
37    2 Two<T1, T2>: One<T1>, Contains<T2>;
38    3 Three<T1, T2, T3>: Two<T1, T2>, Contains<T3>;
39    4 Four<T1, T2, T3, T4>: Three<T1, T2, T3>, Contains<T4>;
40    5 Five<T1, T2, T3, T4, T5>: Four<T1, T2, T3, T4>, Contains<T5>;
41    6 Six<T1, T2, T3, T4, T5, T6>: Five<T1, T2, T3, T4, T5>, Contains<T6>;
42    7 Seven<T1, T2, T3, T4, T5, T6, T7>: Six<T1, T2, T3, T4, T5, T6>, Contains<T7>;
43    8 Eight<T1, T2, T3, T4, T5, T6, T7, T8>: Seven<T1, T2, T3, T4, T5, T6, T7>, Contains<T8>;
44    9 Nine<T1, T2, T3, T4, T5, T6, T7, T8, T9>: Eight<T1, T2, T3, T4, T5, T6, T7, T8>, Contains<T9>;
45    10 Ten<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>: Nine<T1, T2, T3, T4, T5, T6, T7, T8, T9>, Contains<T10>;
46    11 Eleven<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>: Ten<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>, Contains<T11>;
47    12 Twelve<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>: Eleven<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>, Contains<T12>;
48);
49
50#[cfg(test)]
51mod tests {
52    use super::*;
53
54    #[test]
55    fn members() {
56        assert_eq!(<Set![]>::members(), &[]);
57        assert_eq!(<Set![u8]>::members(), &[TypeId::of::<u8>()]);
58        assert_eq!(
59            <Set![u8, u16]>::members(),
60            &[TypeId::of::<u8>(), TypeId::of::<u16>()]
61        );
62        assert_eq!(
63            <Set![u8, u16, u32]>::members(),
64            &[TypeId::of::<u8>(), TypeId::of::<u16>(), TypeId::of::<u32>()]
65        );
66    }
67
68    #[test]
69    fn consequtive_members() {
70        assert_eq!(<Set![u32]>::members(), &[TypeId::of::<u32>()]);
71        assert_eq!(<Set![u8]>::members(), &[TypeId::of::<u8>()]);
72    }
73}