1#![no_std]
2
3#[ghost::phantom]
5#[derive(Debug, Default)]
6pub struct Or<A, B>;
7
8impl<A: SetMember + Default, B: SetMember<Set = A::Set> + Default> Or<A, B> {
9 pub fn contains(&self, other: impl SetMember<Set=Self>) -> bool {
10 other.in_set(self)
11 }
12
13 pub fn equals(&self, other: impl SetMember<Set=Self>) -> bool {
14 other.eq_set(self)
15 }
16}
17
18impl<A: SetMember + Default, B: SetMember<Set = A::Set> + Default> SetMember for Or<A, B> {
19 type Set = A::Set;
20
21 fn to_set(&self) -> Self::Set {
22 A::default_set() | B::default_set()
23 }
24
25 fn eq_set(&self, set: &Self::Set) -> bool {
26 &Self::default_set() == set
27 }
28
29 fn in_set(&self, set: &Self::Set) -> bool {
30 A::default().in_set(set) || B::default().in_set(set)
31 }
32}
33
34pub trait SetMember: Sized{
36 type Set: PartialEq + core::ops::BitOr<Self::Set, Output = Self::Set>;
37 fn to_set(&self) -> Self::Set;
38 fn eq_set(&self, set: &Self::Set) -> bool;
39 fn in_set(&self, set: &Self::Set) -> bool;
40 fn and_set(self, other: impl SetMember<Set = Self::Set>) -> Self::Set {
41 self.to_set() | other.to_set()
42 }
43 fn default_set() -> Self::Set where Self: Default {
44 Self::to_set(&Default::default())
45 }
46}
47
48#[macro_export]
69macro_rules! tlbf {
70 (
71 $(#[$($flags_args: tt)*])*
72 $vis: vis $flags_name: ident: $repr: ty {
73 $(
74 $(#[$($branch_args: tt)*])*
75 $vis2: vis $name: ident
76 ),* $(,)?
77 }
78 ) => {
79 $crate::tlbf! (
80 $(#[$($flags_args)*])*
81 $vis $flags_name: $repr {
82 $(
83 $(#[$($branch_args)*])*
84 $vis2 $name
85 ),*
86 }
87 {} (0)
88 );
89 };
90 (
91 $(#[$($flags_args: tt)*])*
92 $vis: vis $flags_name: ident: $repr: ty {
93 $(#[$($first_args: tt)*])*
94 $vis0: vis $first: ident
95 $(
96 ,$(#[$($branch_args: tt)*])*
97 $vis2: vis $name: ident
98 )* $(,)?
99 }
100 {$($(#[$($a: tt)*])* $v: vis $x: ident = $y: expr),*} ($value: expr)
101 ) => {
102 $crate::tlbf! (
103 $(#[$($flags_args)*])*
104 $vis $flags_name: $repr {
105 $(
106 $(#[$($branch_args)*])*
107 $vis2 $name
108 ),*
109 }
110 {
111 $($(#[$($a)*])* $v $x = $y,)*
112 $(#[$($first_args)*])*
113 $vis0 $first = $value
114 } ($value + 1)
115 );
116 };
117 (
118 $(#[$($flags_args: tt)*])*
119 $vis: vis $flags_name: ident: $repr: ty {$(,)?}
120 {$($(#[$($a: tt)*])* $vis2: vis $x: ident = $y: expr),*} ($value: expr)
121 ) => {
122 $crate::tlbf! (
123 $(#[$($flags_args)*])*
124 $vis $flags_name: $repr
125 {$($vis2 $x = $y),*}
126 );
127 };
128 (
129 $(#[$($flags_args: tt)*])*
130 $vis: vis $flags_name: ident: $repr: ty {
131 $(
132 $(#[$($branch_args: tt)*])*
133 $vis2: vis $name: ident = $value: expr
134 ),* $(,)?
135 }
136 ) => {
137 #[repr(transparent)]
138 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
139 $(#[$($flags_args)*])*
140 $vis struct $flags_name($repr);
141
142 const _: () = {
143 #[allow(non_upper_case_globals)]
144 impl $flags_name {
145 $($vis const $name: Self = Self(1 << ($value));)*
146
147 pub fn is_empty(&self) -> bool {
148 self.0 == 0
149 }
150
151 pub fn contains(&self, other: impl $crate::SetMember<Set=Self>) -> bool {
152 other.in_set(self)
153 }
154
155 pub fn equals(&self, other: impl $crate::SetMember<Set=Self>) -> bool {
156 other.eq_set(self)
157 }
158
159 pub fn intersects(&self, other: impl $crate::SetMember<Set=Self>) -> bool {
160 self.0 & other.to_set().0 > 0
161 }
162
163 pub const fn all() -> Self {
164 Self($(Self::$name.0)|*)
165 }
166 }
167
168 impl $crate::SetMember for $flags_name {
169 type Set = $flags_name;
170 fn to_set(&self) -> Self::Set {
171 (*self).into()
172 }
173 fn eq_set(&self, set: &Self::Set) -> bool {
174 self == set
175 }
176 fn in_set(&self, set: &Self::Set) -> bool {
177 set.0 & self.0 == self.0
178 }
179 }
180
181 impl<T> ::core::ops::BitAnd<T> for $flags_name where T: $crate::SetMember<Set = Self> {
182 type Output = Self;
183 fn bitand(self, rhs: T) -> Self {
184 Self(self.0 & rhs.to_set().0)
185 }
186 }
187
188 impl<T> ::core::ops::BitOr<T> for $flags_name where T: $crate::SetMember<Set = Self> {
189 type Output = Self;
190 fn bitor(self, rhs: T) -> Self {
191 Self(self.0 | rhs.to_set().0)
192 }
193 }
194
195 impl<T> ::core::ops::BitXor<T> for $flags_name where T: $crate::SetMember<Set = Self> {
196 type Output = Self;
197 fn bitxor(self, rhs: T) -> Self {
198 Self(self.0 ^ rhs.to_set().0)
199 }
200 }
201
202 impl<T> ::core::ops::BitAndAssign<T> for $flags_name where T: $crate::SetMember<Set = Self> {
203 fn bitand_assign(&mut self, rhs: T) {
204 self.0 &= rhs.to_set().0
205 }
206 }
207
208 impl<T> ::core::ops::BitOrAssign<T> for $flags_name where T: $crate::SetMember<Set = Self> {
209 fn bitor_assign(&mut self, rhs: T) {
210 self.0 |= rhs.to_set().0
211 }
212 }
213
214 impl<T> ::core::ops::BitXorAssign<T> for $flags_name where T: $crate::SetMember<Set = Self> {
215 fn bitxor_assign(&mut self, rhs: T) {
216 self.0 ^= rhs.to_set().0
217 }
218 }
219 };
220
221
222 $(
223 $(#[$($branch_args)*])*
224 #[derive(Debug, Default, Clone, Copy, Eq, Hash)]
225 $vis2 struct $name;
226
227 const _: () = {
228 use $crate::SetMember;
229 impl ::core::fmt::Display for $name {
230 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
231 f.write_str(stringify!($name))
232 }
233 }
234
235 impl ::core::convert::From<$name> for $flags_name {
236 fn from(_: $name) -> Self {
237 Self::$name
238 }
239 }
240
241 impl ::core::convert::From<&$name> for $flags_name {
242 fn from(_: &$name) -> Self {
243 Self::$name
244 }
245 }
246
247 impl $crate::SetMember for $name {
248 type Set = $flags_name;
249 fn to_set(&self) -> Self::Set {
250 self.into()
251 }
252 fn eq_set(&self, set: &Self::Set) -> bool {
253 set == &Self::Set::$name
254 }
255 fn in_set(&self, set: &Self::Set) -> bool {
256 *set & Self::Set::$name == Self::Set::$name
257 }
258 }
259
260 impl<T> ::core::ops::BitOr<T> for $name where T: SetMember<Set=$flags_name>{
261 type Output = $flags_name;
262 fn bitor(self, rhs: T) -> $flags_name {
263 $flags_name::$name | rhs.to_set()
264 }
265 }
266
267 impl<T> ::core::cmp::PartialEq<T> for $name where T: $crate::SetMember<Set=$flags_name>{
268 fn eq(&self, other: &T) -> bool {
269 $flags_name::$name == other.to_set()
270 }
271 }
272 };
273 )*
274 };
275}
276
277
278#[macro_export]
293macro_rules! tyflags {
294 ($expr: expr $(,)?) => {
295 $expr
296 };
297 ($first: expr $(,$expr: expr)* $(,)?) => {
298 $crate::Or<$first, $crate::type_join!($($expr),*)>
299 };
300}
301
302#[cfg(test)]
303mod test {
304
305 tlbf!(
306 pub Unit1: u8 {
307 Hello
308 }
309 );
310 tlbf!(
311 pub Unit2: u8 {
312 Hiii,
313 }
314 );
315 #[test]
316 pub fn test(){
317 tlbf!(
318 pub Mascot: u8 {
319 pub Ferris
320 }
321 );
322 tlbf!(
323 #[derive(Default)]
324 LesserMascots: u8 {
325 #[repr(C)]
326 Gopher
327 }
328 );
329 assert_eq!(Mascot::all(), Mascot::Ferris);
330
331 tlbf!(
332 pub Colors: u8 {
333 pub Red,
334 pub Blue,
335 pub Green,
336 }
337 );
338 assert_eq!(Colors::all(), Colors::Red|Colors::Blue|Colors::Green);
339 }
340}