type_sets/
lib.rs

1#![doc = include_str!("../README.md")]
2
3use std::any::TypeId;
4
5mod set;
6pub use set::*;
7
8/// Sets from 0 to 10 elements.
9pub mod sets;
10
11//-------------------------------------
12// Contains
13//-------------------------------------
14
15/// Implemented if a set contains the element `E`.
16///
17/// # Safety
18/// Implementing this is unsafe, for custom set-types, implement [`AsSet`] instead.
19pub unsafe trait Contains<E> {}
20
21// Implement Contains for `Set<dyn ..>`
22unsafe impl<T: ?Sized, E> Contains<E> for Set<T> where T: Contains<E> {}
23
24// Implement Contains for `impl AsSet`
25unsafe impl<T, E> Contains<E> for T
26where
27    T: AsSet,
28    T::Set: Contains<E>,
29{
30}
31
32//-------------------------------------
33// Members
34//-------------------------------------
35
36/// Trait to get the members (type-ids) of a set.
37///
38/// # Safety
39/// Implementing this is unsafe, for custom set-types, implement [`AsSet`] instead.
40pub unsafe trait Members {
41    /// Get the members (type-ids) of this set.
42    fn members() -> Vec<TypeId>;
43}
44
45// Implement Members for `impl AsSet`
46unsafe impl<T> Members for T
47where
48    T: AsSet,
49{
50    fn members() -> Vec<TypeId> {
51        <T::Set as Members>::members()
52    }
53}
54
55//-------------------------------------
56// SubsetOf
57//-------------------------------------
58
59/// Implemented a set is a subset of `S`.
60///
61/// # Safety
62/// Implementing this is unsafe, for custom set-types, implement [`AsSet`] instead.
63pub unsafe trait SubsetOf<S> {}
64
65// Implement SubsetOf for `impl AsSet`
66unsafe impl<T, S> SubsetOf<S> for T
67where
68    T: AsSet,
69    T::Set: SubsetOf<S>,
70{
71}
72
73//-------------------------------------
74// SupersetOf
75//-------------------------------------
76
77/// Implemented if a set is a superset of `S`.
78///
79/// # Safety
80/// Implementing this is unsafe, for custom set-types, implement [`AsSet`] instead.
81pub unsafe trait SupersetOf<S> {}
82
83// Implement SupersetOf for `impl AsSet`
84unsafe impl<T, S> SupersetOf<S> for T where S: SubsetOf<T> {}
85
86//-------------------------------------
87// AsSet
88//-------------------------------------
89
90/// Trait that allows usage of custom types instead of [`Set`].
91pub trait AsSet {
92    /// The [`struct@Set`] type.
93    type Set: Members;
94}
95
96#[cfg(test)]
97mod tests {
98    use super::*;
99
100    struct MySet;
101
102    impl AsSet for MySet {
103        type Set = Set![u32, u64];
104    }
105
106    #[test]
107    fn test() {
108        contains_string::<Set![String]>();
109        contains_string::<Set![String, u32]>();
110        contains_string::<Set![String, u32, u64]>();
111        contains_string::<Set![u32, u64, u128, String]>();
112        // contains_string::<MySet>(); // does not compile
113        // contains_string::<Set![u32]>(); // does not compile
114
115        is_subset::<Set![u32, u64, u32, u32]>();
116        is_subset::<Set![u32, u64]>();
117        is_subset2::<Set![u32]>();
118        is_subset::<Set![]>();
119        is_subset::<MySet>();
120        // is_subset::<Set![u32, u64, u128]>(); // does not compile
121        // is_subset2::<MySet>(); // does not compile
122        // is_subset::<Set![u32, u64, u128]>(); // does not compile
123
124        is_superset1::<Set![u32, u64]>();
125        is_superset2::<Set![u32, u64, u128]>();
126        is_superset1::<MySet>();
127        // is_superset1::<Set![u32]>(); // does not compile
128        // is_superset2::<MySet>(); // does not compile
129
130        let _: Set![];
131        let _: Set![u32];
132        let _: Set![u32, u64];
133        let _: Set![u32, u64, u128];
134        let _: Set![u32, u64, u128, u32];
135        let _: Set![u32, u64, u128, u32, u64];
136        let _: Set![u32, u64, u128, u32, u64, u128];
137        let _: Set![u32, u64, u128, u32, u64, u128, u32];
138        let _: Set![u32, u64, u128, u32, u64, u128, u32, u64];
139        let _: Set![u32, u64, u128, u32, u64, u128, u32, u64, u128];
140        let _: Set![u32, u64, u128, u32, u64, u128, u32, u64, u128, u32];
141        let _: Set![u32, u64, u128, u32, u64, u128, u32, u64, u128, u32, u64];
142        let _: Set![u32, u64, u128, u32, u64, u128, u32, u64, u128, u32, u64, u128];
143    }
144
145    fn contains_string<T>()
146    where
147        T: Contains<String>,
148    {
149    }
150
151    fn is_subset<T>()
152    where
153        T: SubsetOf<Set![u32, u64]>,
154    {
155    }
156
157    fn is_subset2<T>()
158    where
159        T: SubsetOf<Set![u32]>,
160    {
161    }
162
163    fn is_superset1<T>()
164    where
165        T: SupersetOf<Set![u32, u64]>,
166    {
167    }
168
169    fn is_superset2<T>()
170    where
171        T: SupersetOf<Set![u32, u64, u128]>,
172    {
173    }
174}