1use std::{any::TypeId, convert::Infallible, fmt::Debug, marker::PhantomData};
2
3pub struct Set<T>(PhantomData<fn() -> T>);
9
10impl<T> TypeSet for Set<T>
11where
12 T: TypeSet,
13{
14 type Set = T::Set;
15
16 fn members() -> &'static [TypeId]
17 where
18 Self: 'static,
19 {
20 T::members()
21 }
22}
23
24impl<T> Debug for Set<T> {
25 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
26 write!(f, "Set<{}>", std::any::type_name::<T>())
27 }
28}
29
30#[diagnostic::on_unimplemented(
32 message = "`{Self}` does not contain `{E}`",
33 label = "type does not contain this element",
34 note = "a type implements `Contains<E>` when `E` is one of its set members"
35)]
36pub trait Contains<E>: Contains0 {}
37
38#[diagnostic::do_not_recommend]
39impl<E, T: ?Sized> Contains<E> for T where T: Contains1<E> {}
40
41#[diagnostic::on_unimplemented(
43 message = "`{Self}` is not a subset of `{S}`",
44 label = "this set is not a subset of the required set",
45 note = "every member of the left-hand set must also be present in the right-hand set"
46)]
47pub trait SubsetOf<S: ?Sized> {}
48
49#[diagnostic::do_not_recommend]
50impl<T: TypeSet, R: TypeSet> SubsetOf<R> for T where T::Set: SubsetOf<R::Set> {}
51
52#[diagnostic::on_unimplemented(
54 message = "`{Self}` is not a superset of `{S}`",
55 label = "this set does not contain all required members",
56 note = "every member of the right-hand set must also be present in the left-hand set"
57)]
58pub trait SupersetOf<S: ?Sized> {}
59
60#[diagnostic::do_not_recommend]
61impl<S1: ?Sized, S2: ?Sized> SupersetOf<S2> for S1 where S2: SubsetOf<S1> {}
62
63pub trait TypeSet {
67 type Set: ?Sized;
69
70 fn members() -> &'static [TypeId]
72 where
73 Self: 'static;
74}
75
76#[diagnostic::on_unimplemented(
78 message = "`{Self}` and `{R}` do not represent the same set",
79 label = "the sets contain different members",
80 note = "two sets are equal when every member of one is also a member of the other"
81)]
82pub trait SetEqual<R: ?Sized> {}
83
84#[diagnostic::do_not_recommend]
85impl<T: TypeSet, R: TypeSet> SetEqual<R> for T where T: SubsetOf<R> + SupersetOf<R> {}
86
87mod generate_sets;
88use generate_sets::*;
89
90mod set_macro;
91
92impl TypeSet for Infallible {
93 type Set = ();
94
95 fn members() -> &'static [TypeId]
96 where
97 Self: 'static,
98 {
99 &[]
100 }
101}