Skip to main content

type_sets/
generate_sets.rs

1#![allow(unused)]
2use super::*;
3use std::{any::TypeId, marker::PhantomData, sync::OnceLock};
4
5macro_rules! generate_sets {
6    ($(
7        for<$($el:ident),*> $n:literal $($true:literal)? = {
8            pub struct $struct:ident;
9
10            trait $contains_n:ident:
11                $sub_contains:ident <$($sub_el:ident),*> +
12                $add_contains:ident <$add_el:ident>
13            {}
14        }
15    )*) => {
16        // Trait definitions
17        pub(crate) mod _priv {
18            use super::*;
19            $(
20                /// A private trait that defines the set of types contained in a type set.
21                pub trait $contains_n<$($el),*>:
22                    $sub_contains <$($sub_el),*>
23                    + $add_contains <$add_el>
24                {}
25            )*
26        }
27        pub(crate) use _priv::*;
28
29        $(
30            // Subset implementations for `dyn ContainsN`
31            #[diagnostic::do_not_recommend]
32            impl<S: ?Sized, $($el),*> Subset<S> for dyn $contains_n<$($el),*>
33                // where S: $contains_n<$($el),*>
34                where S: $(
35                    Contains1<$el> +
36                )*
37            {}
38
39            // Members implementations for `dyn ContainsN`
40            #[diagnostic::do_not_recommend]
41            impl<$($el),*> Members for dyn $contains_n<$($el),*>
42                where Self: 'static
43            {
44                fn members() -> &'static [TypeId]
45                where
46                    Self: 'static,
47                {
48                    static MEMBERS: OnceLock<[TypeId; $n]> = OnceLock::new();
49                    MEMBERS.get_or_init(|| [$(
50                        TypeId::of::<$el>()
51                    ),*])
52                }
53            }
54
55            // AsTypeSet implementations for tuples
56            #[diagnostic::do_not_recommend]
57            impl<$($el),*> AsTypeSet for ($($el,)*)
58            {
59                type Set = dyn $contains_n<$($el),*>;
60            }
61
62            // Contains implementations for `impl AsTypeSet`
63            #[diagnostic::do_not_recommend]
64            impl<S: ?Sized, $($el),*> $contains_n<$($el),*> for S
65            where
66                S: AsTypeSet<Set: $contains_n<$($el),*>>
67            {}
68
69            // AddMember implementations for tuples
70            #[diagnostic::do_not_recommend]
71            impl<$($el),*> Push for ($($el,)*) {
72                type Output<E> = ($($el,)* E);
73            }
74
75            // // Shrink implementations for tuples
76            // #[diagnostic::do_not_recommend]
77            // impl<$($el),*> Shrink for ($($el,)*) {
78            //     type Output = ($($sub_el,)*);
79            //     type Popped = $add_el;
80            // }
81        )*
82    };
83}
84
85mod _priv_0 {
86    use super::*;
87
88    pub trait Contains0 {}
89
90    impl AsTypeSet for () {
91        type Set = dyn Contains0;
92    }
93
94    #[diagnostic::do_not_recommend]
95    impl Members for dyn Contains0 {
96        fn members() -> &'static [TypeId] {
97            static MEMBERS: OnceLock<[TypeId; 0]> = OnceLock::new();
98            MEMBERS.get_or_init(|| [])
99        }
100    }
101
102    #[diagnostic::do_not_recommend]
103    impl<S: ?Sized> Subset<S> for dyn Contains0 {}
104
105    #[diagnostic::do_not_recommend]
106    impl<S: ?Sized> Contains0 for S {}
107
108    impl Push for () {
109        type Output<E> = (E,);
110    }
111
112    // impl Shrink for () {
113    //     type Output = ();
114    //     type Popped =
115    // }
116
117    pub trait Contains1<E>: Contains0 {}
118
119    #[diagnostic::do_not_recommend]
120    impl<E1> AsTypeSet for (E1,) {
121        type Set = dyn Contains1<E1>;
122    }
123
124    impl<S: ?Sized, E1> Contains1<E1> for S where S: AsTypeSet<Set: Contains1<E1>> {}
125
126    #[diagnostic::do_not_recommend]
127    impl<S: ?Sized, E1> Subset<S> for dyn Contains1<E1> where S: Contains1<E1> {}
128
129    #[diagnostic::do_not_recommend]
130    impl<E1: 'static> Members for dyn Contains1<E1> {
131        fn members() -> &'static [TypeId] {
132            static MEMBERS: OnceLock<[TypeId; 1]> = OnceLock::new();
133            MEMBERS.get_or_init(|| [TypeId::of::<E1>()])
134        }
135    }
136
137    impl<E1> Push for (E1,) {
138        type Output<E> = (E1, E);
139    }
140
141    // impl<E1> Shrink for (E1,) {
142    //     type Output = ();
143    //     type Popped = E1;
144    // }
145}
146pub(crate) use _priv_0::*;
147
148// #[diagnostic::do_not_recommend]
149// impl<S: ?Sized, E1> Contains1<E1> for S where S: Contains0 + Contains1<E1> {}
150
151impl AsTypeSet for Infallible {
152    type Set = dyn Contains0;
153}
154
155#[cfg(test)]
156mod test {
157    use super::*;
158
159    fn is_superset<T: ?Sized, R: ?Sized>()
160    where
161        T: Superset<R>,
162    {
163    }
164
165    fn is_subset<T: ?Sized, R: ?Sized>()
166    where
167        T: Subset<R>,
168    {
169    }
170
171    fn test() {
172        is_subset::<dyn Contains3<u8, u16, u32>, dyn Contains4<u8, u16, u64, u32>>();
173
174        is_subset::<(u8, u32), (u8, u16, u64, u32)>();
175    }
176}
177
178generate_sets! {
179    // Set0 / Contains0 is implemented manually below, because it has no constraints
180
181    // for<E1> 1 = {
182    //     pub struct Set1;
183    //     trait Contains1: Contains0<> + Contains0<> {}
184    // }
185
186    for<E1, E2> 2 = {
187        pub struct Set2;
188        trait Contains2: Contains1<E1> + Contains1<E2> {}
189    }
190
191    for<E1, E2, E3> 3 = {
192        pub struct Set3;
193        trait Contains3: Contains2<E1, E2> + Contains1<E3> {}
194    }
195
196    for<E1, E2, E3, E4> 4 = {
197        pub struct Set4;
198        trait Contains4: Contains3<E1, E2, E3> + Contains1<E4> {}
199    }
200
201    for<E1, E2, E3, E4, E5> 5 = {
202        pub struct Set5;
203        trait Contains5: Contains4<E1, E2, E3, E4> + Contains1<E5> {}
204    }
205
206    for<E1, E2, E3, E4, E5, E6> 6 = {
207        pub struct Set6;
208        trait Contains6: Contains5<E1, E2, E3, E4, E5> + Contains1<E6> {}
209    }
210
211    for<E1, E2, E3, E4, E5, E6, E7> 7 = {
212        pub struct Set7;
213        trait Contains7: Contains6<E1, E2, E3, E4, E5, E6> + Contains1<E7> {}
214    }
215
216    for<E1, E2, E3, E4, E5, E6, E7, E8> 8 = {
217        pub struct Set8;
218        trait Contains8: Contains7<E1, E2, E3, E4, E5, E6, E7> + Contains1<E8> {}
219    }
220
221    for<E1, E2, E3, E4, E5, E6, E7, E8, E9> 9 = {
222        pub struct Set9;
223        trait Contains9: Contains8<E1, E2, E3, E4, E5, E6, E7, E8> + Contains1<E9> {}
224    }
225
226    for<E1, E2, E3, E4, E5, E6, E7, E8, E9, E10> 10 = {
227        pub struct Set10;
228        trait Contains10: Contains9<E1, E2, E3, E4, E5, E6, E7, E8, E9> + Contains1<E10> {}
229    }
230
231    for<E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11> 11 = {
232        pub struct Set11;
233        trait Contains11: Contains10<E1, E2, E3, E4, E5, E6, E7, E8, E9, E10> + Contains1<E11> {}
234    }
235
236    for<E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11, E12> 12 = {
237        pub struct Set12;
238        trait Contains12: Contains11<E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11> + Contains1<E12> {}
239    }
240
241    for<E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11, E12, E13> 13 = {
242        pub struct Set13;
243        trait Contains13: Contains12<E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11, E12> + Contains1<E13> {}
244    }
245
246    for<E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11, E12, E13, E14> 14 = {
247        pub struct Set14;
248        trait Contains14: Contains13<E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11, E12, E13> + Contains1<E14> {}
249    }
250
251    for<E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11, E12, E13, E14, E15> 15 = {
252        pub struct Set15;
253        trait Contains15: Contains14<E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11, E12, E13, E14> + Contains1<E15> {}
254    }
255
256    for<E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11, E12, E13, E14, E15, E16> 16 = {
257        pub struct Set16;
258        trait Contains16: Contains15<E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11, E12, E13, E14, E15> + Contains1<E16> {}
259    }
260
261    for<E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11, E12, E13, E14, E15, E16, E17> 17 = {
262        pub struct Set17;
263        trait Contains17: Contains16<E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11, E12, E13, E14, E15, E16> + Contains1<E17> {}
264    }
265
266    for<E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11, E12, E13, E14, E15, E16, E17, E18> 18 = {
267        pub struct Set18;
268        trait Contains18: Contains17<E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11, E12, E13, E14, E15, E16, E17> + Contains1<E18> {}
269    }
270
271    for<E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11, E12, E13, E14, E15, E16, E17, E18, E19> 19 = {
272        pub struct Set19;
273        trait Contains19: Contains18<E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11, E12, E13, E14, E15, E16, E17, E18> + Contains1<E19> {}
274    }
275
276    for<E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11, E12, E13, E14, E15, E16, E17, E18, E19, E20> 20 = {
277        pub struct Set20;
278        trait Contains20: Contains19<E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11, E12, E13, E14, E15, E16, E17, E18, E19> + Contains1<E20> {}
279    }
280
281    for<E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11, E12, E13, E14, E15, E16, E17, E18, E19, E20, E21> 21 = {
282        pub struct Set21;
283        trait Contains21: Contains20<E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11, E12, E13, E14, E15, E16, E17, E18, E19, E20> + Contains1<E21> {}
284    }
285
286    for<E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11, E12, E13, E14, E15, E16, E17, E18, E19, E20, E21, E22> 22 = {
287        pub struct Set22;
288        trait Contains22: Contains21<E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11, E12, E13, E14, E15, E16, E17, E18, E19, E20, E21> + Contains1<E22> {}
289    }
290
291    for<E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11, E12, E13, E14, E15, E16, E17, E18, E19, E20, E21, E22, E23> 23 = {
292        pub struct Set23;
293        trait Contains23: Contains22<E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11, E12, E13, E14, E15, E16, E17, E18, E19, E20, E21, E22> + Contains1<E23> {}
294    }
295
296    for<E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11, E12, E13, E14, E15, E16, E17, E18, E19, E20, E21, E22, E23, E24> 24 = {
297        pub struct Set24;
298        trait Contains24: Contains23<E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11, E12, E13, E14, E15, E16, E17, E18, E19, E20, E21, E22, E23> + Contains1<E24> {}
299    }
300}