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