1 | //! Generate the user-facing flags type. |
2 | //! |
3 | //! The code here belongs to the end-user, so new trait implementations and methods can't be |
4 | //! added without potentially breaking users. |
5 | |
6 | /// Declare the user-facing bitflags struct. |
7 | /// |
8 | /// This type is guaranteed to be a newtype with a `bitflags`-facing type as its single field. |
9 | #[macro_export (local_inner_macros)] |
10 | #[doc (hidden)] |
11 | macro_rules! __declare_public_bitflags { |
12 | ( |
13 | $(#[$outer:meta])* |
14 | $vis:vis struct $PublicBitFlags:ident |
15 | ) => { |
16 | $(#[$outer])* |
17 | $vis struct $PublicBitFlags(<$PublicBitFlags as $crate::__private::PublicFlags>::Internal); |
18 | }; |
19 | } |
20 | |
21 | /// Implement functions on the public (user-facing) bitflags type. |
22 | /// |
23 | /// We need to be careful about adding new methods and trait implementations here because they |
24 | /// could conflict with items added by the end-user. |
25 | #[macro_export (local_inner_macros)] |
26 | #[doc (hidden)] |
27 | macro_rules! __impl_public_bitflags_forward { |
28 | ( |
29 | $PublicBitFlags:ident: $T:ty, $InternalBitFlags:ident |
30 | ) => { |
31 | __impl_bitflags! { |
32 | $PublicBitFlags: $T { |
33 | fn empty() { |
34 | Self($InternalBitFlags::empty()) |
35 | } |
36 | |
37 | fn all() { |
38 | Self($InternalBitFlags::all()) |
39 | } |
40 | |
41 | fn bits(f) { |
42 | f.0.bits() |
43 | } |
44 | |
45 | fn from_bits(bits) { |
46 | match $InternalBitFlags::from_bits(bits) { |
47 | $crate::__private::core::option::Option::Some(bits) => $crate::__private::core::option::Option::Some(Self(bits)), |
48 | $crate::__private::core::option::Option::None => $crate::__private::core::option::Option::None, |
49 | } |
50 | } |
51 | |
52 | fn from_bits_truncate(bits) { |
53 | Self($InternalBitFlags::from_bits_truncate(bits)) |
54 | } |
55 | |
56 | fn from_bits_retain(bits) { |
57 | Self($InternalBitFlags::from_bits_retain(bits)) |
58 | } |
59 | |
60 | fn from_name(name) { |
61 | match $InternalBitFlags::from_name(name) { |
62 | $crate::__private::core::option::Option::Some(bits) => $crate::__private::core::option::Option::Some(Self(bits)), |
63 | $crate::__private::core::option::Option::None => $crate::__private::core::option::Option::None, |
64 | } |
65 | } |
66 | |
67 | fn is_empty(f) { |
68 | f.0.is_empty() |
69 | } |
70 | |
71 | fn is_all(f) { |
72 | f.0.is_all() |
73 | } |
74 | |
75 | fn intersects(f, other) { |
76 | f.0.intersects(other.0) |
77 | } |
78 | |
79 | fn contains(f, other) { |
80 | f.0.contains(other.0) |
81 | } |
82 | |
83 | fn insert(f, other) { |
84 | f.0.insert(other.0) |
85 | } |
86 | |
87 | fn remove(f, other) { |
88 | f.0.remove(other.0) |
89 | } |
90 | |
91 | fn toggle(f, other) { |
92 | f.0.toggle(other.0) |
93 | } |
94 | |
95 | fn set(f, other, value) { |
96 | f.0.set(other.0, value) |
97 | } |
98 | |
99 | fn intersection(f, other) { |
100 | Self(f.0.intersection(other.0)) |
101 | } |
102 | |
103 | fn union(f, other) { |
104 | Self(f.0.union(other.0)) |
105 | } |
106 | |
107 | fn difference(f, other) { |
108 | Self(f.0.difference(other.0)) |
109 | } |
110 | |
111 | fn symmetric_difference(f, other) { |
112 | Self(f.0.symmetric_difference(other.0)) |
113 | } |
114 | |
115 | fn complement(f) { |
116 | Self(f.0.complement()) |
117 | } |
118 | } |
119 | } |
120 | }; |
121 | } |
122 | |
123 | /// Implement functions on the public (user-facing) bitflags type. |
124 | /// |
125 | /// We need to be careful about adding new methods and trait implementations here because they |
126 | /// could conflict with items added by the end-user. |
127 | #[macro_export (local_inner_macros)] |
128 | #[doc (hidden)] |
129 | macro_rules! __impl_public_bitflags { |
130 | ( |
131 | $BitFlags:ident: $T:ty, $PublicBitFlags:ident { |
132 | $( |
133 | $(#[$inner:ident $($args:tt)*])* |
134 | const $Flag:tt = $value:expr; |
135 | )* |
136 | } |
137 | ) => { |
138 | __impl_bitflags! { |
139 | $BitFlags: $T { |
140 | fn empty() { |
141 | Self(<$T as $crate::Bits>::EMPTY) |
142 | } |
143 | |
144 | fn all() { |
145 | let mut truncated = <$T as $crate::Bits>::EMPTY; |
146 | let mut i = 0; |
147 | |
148 | $( |
149 | __bitflags_expr_safe_attrs!( |
150 | $(#[$inner $($args)*])* |
151 | {{ |
152 | let flag = <$PublicBitFlags as $crate::Flags>::FLAGS[i].value().bits(); |
153 | |
154 | truncated = truncated | flag; |
155 | i += 1; |
156 | }} |
157 | ); |
158 | )* |
159 | |
160 | let _ = i; |
161 | Self::from_bits_retain(truncated) |
162 | } |
163 | |
164 | fn bits(f) { |
165 | f.0 |
166 | } |
167 | |
168 | fn from_bits(bits) { |
169 | let truncated = Self::from_bits_truncate(bits).0; |
170 | |
171 | if truncated == bits { |
172 | $crate::__private::core::option::Option::Some(Self(bits)) |
173 | } else { |
174 | $crate::__private::core::option::Option::None |
175 | } |
176 | } |
177 | |
178 | fn from_bits_truncate(bits) { |
179 | Self(bits & Self::all().bits()) |
180 | } |
181 | |
182 | fn from_bits_retain(bits) { |
183 | Self(bits) |
184 | } |
185 | |
186 | fn from_name(name) { |
187 | $( |
188 | __bitflags_flag!({ |
189 | name: $Flag, |
190 | named: { |
191 | __bitflags_expr_safe_attrs!( |
192 | $(#[$inner $($args)*])* |
193 | { |
194 | if name == $crate::__private::core::stringify!($Flag) { |
195 | return $crate::__private::core::option::Option::Some(Self($PublicBitFlags::$Flag.bits())); |
196 | } |
197 | } |
198 | ); |
199 | }, |
200 | unnamed: {}, |
201 | }); |
202 | )* |
203 | |
204 | let _ = name; |
205 | $crate::__private::core::option::Option::None |
206 | } |
207 | |
208 | fn is_empty(f) { |
209 | f.bits() == <$T as $crate::Bits>::EMPTY |
210 | } |
211 | |
212 | fn is_all(f) { |
213 | // NOTE: We check against `Self::all` here, not `Self::Bits::ALL` |
214 | // because the set of all flags may not use all bits |
215 | Self::all().bits() | f.bits() == f.bits() |
216 | } |
217 | |
218 | fn intersects(f, other) { |
219 | f.bits() & other.bits() != <$T as $crate::Bits>::EMPTY |
220 | } |
221 | |
222 | fn contains(f, other) { |
223 | f.bits() & other.bits() == other.bits() |
224 | } |
225 | |
226 | fn insert(f, other) { |
227 | *f = Self::from_bits_retain(f.bits()).union(other); |
228 | } |
229 | |
230 | fn remove(f, other) { |
231 | *f = Self::from_bits_retain(f.bits()).difference(other); |
232 | } |
233 | |
234 | fn toggle(f, other) { |
235 | *f = Self::from_bits_retain(f.bits()).symmetric_difference(other); |
236 | } |
237 | |
238 | fn set(f, other, value) { |
239 | if value { |
240 | f.insert(other); |
241 | } else { |
242 | f.remove(other); |
243 | } |
244 | } |
245 | |
246 | fn intersection(f, other) { |
247 | Self::from_bits_retain(f.bits() & other.bits()) |
248 | } |
249 | |
250 | fn union(f, other) { |
251 | Self::from_bits_retain(f.bits() | other.bits()) |
252 | } |
253 | |
254 | fn difference(f, other) { |
255 | Self::from_bits_retain(f.bits() & !other.bits()) |
256 | } |
257 | |
258 | fn symmetric_difference(f, other) { |
259 | Self::from_bits_retain(f.bits() ^ other.bits()) |
260 | } |
261 | |
262 | fn complement(f) { |
263 | Self::from_bits_truncate(!f.bits()) |
264 | } |
265 | } |
266 | } |
267 | }; |
268 | } |
269 | |
270 | /// Implement iterators on the public (user-facing) bitflags type. |
271 | #[macro_export (local_inner_macros)] |
272 | #[doc (hidden)] |
273 | macro_rules! __impl_public_bitflags_iter { |
274 | ($BitFlags:ident: $T:ty, $PublicBitFlags:ident) => { |
275 | impl $BitFlags { |
276 | /// Yield a set of contained flags values. |
277 | /// |
278 | /// Each yielded flags value will correspond to a defined named flag. Any unknown bits |
279 | /// will be yielded together as a final flags value. |
280 | #[inline] |
281 | pub const fn iter(&self) -> $crate::iter::Iter<$PublicBitFlags> { |
282 | $crate::iter::Iter::__private_const_new( |
283 | <$PublicBitFlags as $crate::Flags>::FLAGS, |
284 | $PublicBitFlags::from_bits_retain(self.bits()), |
285 | $PublicBitFlags::from_bits_retain(self.bits()), |
286 | ) |
287 | } |
288 | |
289 | /// Yield a set of contained named flags values. |
290 | /// |
291 | /// This method is like [`iter`](#method.iter), except only yields bits in contained named flags. |
292 | /// Any unknown bits, or bits not corresponding to a contained flag will not be yielded. |
293 | #[inline] |
294 | pub const fn iter_names(&self) -> $crate::iter::IterNames<$PublicBitFlags> { |
295 | $crate::iter::IterNames::__private_const_new( |
296 | <$PublicBitFlags as $crate::Flags>::FLAGS, |
297 | $PublicBitFlags::from_bits_retain(self.bits()), |
298 | $PublicBitFlags::from_bits_retain(self.bits()), |
299 | ) |
300 | } |
301 | } |
302 | |
303 | impl $crate::__private::core::iter::IntoIterator for $BitFlags { |
304 | type Item = $PublicBitFlags; |
305 | type IntoIter = $crate::iter::Iter<$PublicBitFlags>; |
306 | |
307 | fn into_iter(self) -> Self::IntoIter { |
308 | self.iter() |
309 | } |
310 | } |
311 | }; |
312 | } |
313 | |
314 | /// Implement traits on the public (user-facing) bitflags type. |
315 | #[macro_export (local_inner_macros)] |
316 | #[doc (hidden)] |
317 | macro_rules! __impl_public_bitflags_ops { |
318 | ($PublicBitFlags:ident) => { |
319 | impl $crate::__private::core::fmt::Binary for $PublicBitFlags { |
320 | fn fmt( |
321 | &self, |
322 | f: &mut $crate::__private::core::fmt::Formatter, |
323 | ) -> $crate::__private::core::fmt::Result { |
324 | $crate::__private::core::fmt::Binary::fmt(&self.0, f) |
325 | } |
326 | } |
327 | |
328 | impl $crate::__private::core::fmt::Octal for $PublicBitFlags { |
329 | fn fmt( |
330 | &self, |
331 | f: &mut $crate::__private::core::fmt::Formatter, |
332 | ) -> $crate::__private::core::fmt::Result { |
333 | $crate::__private::core::fmt::Octal::fmt(&self.0, f) |
334 | } |
335 | } |
336 | |
337 | impl $crate::__private::core::fmt::LowerHex for $PublicBitFlags { |
338 | fn fmt( |
339 | &self, |
340 | f: &mut $crate::__private::core::fmt::Formatter, |
341 | ) -> $crate::__private::core::fmt::Result { |
342 | $crate::__private::core::fmt::LowerHex::fmt(&self.0, f) |
343 | } |
344 | } |
345 | |
346 | impl $crate::__private::core::fmt::UpperHex for $PublicBitFlags { |
347 | fn fmt( |
348 | &self, |
349 | f: &mut $crate::__private::core::fmt::Formatter, |
350 | ) -> $crate::__private::core::fmt::Result { |
351 | $crate::__private::core::fmt::UpperHex::fmt(&self.0, f) |
352 | } |
353 | } |
354 | |
355 | impl $crate::__private::core::ops::BitOr for $PublicBitFlags { |
356 | type Output = Self; |
357 | |
358 | /// The bitwise or (`|`) of the bits in two flags values. |
359 | #[inline] |
360 | fn bitor(self, other: $PublicBitFlags) -> Self { |
361 | self.union(other) |
362 | } |
363 | } |
364 | |
365 | impl $crate::__private::core::ops::BitOrAssign for $PublicBitFlags { |
366 | /// The bitwise or (`|`) of the bits in two flags values. |
367 | #[inline] |
368 | fn bitor_assign(&mut self, other: Self) { |
369 | self.insert(other); |
370 | } |
371 | } |
372 | |
373 | impl $crate::__private::core::ops::BitXor for $PublicBitFlags { |
374 | type Output = Self; |
375 | |
376 | /// The bitwise exclusive-or (`^`) of the bits in two flags values. |
377 | #[inline] |
378 | fn bitxor(self, other: Self) -> Self { |
379 | self.symmetric_difference(other) |
380 | } |
381 | } |
382 | |
383 | impl $crate::__private::core::ops::BitXorAssign for $PublicBitFlags { |
384 | /// The bitwise exclusive-or (`^`) of the bits in two flags values. |
385 | #[inline] |
386 | fn bitxor_assign(&mut self, other: Self) { |
387 | self.toggle(other); |
388 | } |
389 | } |
390 | |
391 | impl $crate::__private::core::ops::BitAnd for $PublicBitFlags { |
392 | type Output = Self; |
393 | |
394 | /// The bitwise and (`&`) of the bits in two flags values. |
395 | #[inline] |
396 | fn bitand(self, other: Self) -> Self { |
397 | self.intersection(other) |
398 | } |
399 | } |
400 | |
401 | impl $crate::__private::core::ops::BitAndAssign for $PublicBitFlags { |
402 | /// The bitwise and (`&`) of the bits in two flags values. |
403 | #[inline] |
404 | fn bitand_assign(&mut self, other: Self) { |
405 | *self = Self::from_bits_retain(self.bits()).intersection(other); |
406 | } |
407 | } |
408 | |
409 | impl $crate::__private::core::ops::Sub for $PublicBitFlags { |
410 | type Output = Self; |
411 | |
412 | /// The intersection of a source flags value with the complement of a target flags value (`&!`). |
413 | /// |
414 | /// This method is not equivalent to `self & !other` when `other` has unknown bits set. |
415 | /// `difference` won't truncate `other`, but the `!` operator will. |
416 | #[inline] |
417 | fn sub(self, other: Self) -> Self { |
418 | self.difference(other) |
419 | } |
420 | } |
421 | |
422 | impl $crate::__private::core::ops::SubAssign for $PublicBitFlags { |
423 | /// The intersection of a source flags value with the complement of a target flags value (`&!`). |
424 | /// |
425 | /// This method is not equivalent to `self & !other` when `other` has unknown bits set. |
426 | /// `difference` won't truncate `other`, but the `!` operator will. |
427 | #[inline] |
428 | fn sub_assign(&mut self, other: Self) { |
429 | self.remove(other); |
430 | } |
431 | } |
432 | |
433 | impl $crate::__private::core::ops::Not for $PublicBitFlags { |
434 | type Output = Self; |
435 | |
436 | /// The bitwise negation (`!`) of the bits in a flags value, truncating the result. |
437 | #[inline] |
438 | fn not(self) -> Self { |
439 | self.complement() |
440 | } |
441 | } |
442 | |
443 | impl $crate::__private::core::iter::Extend<$PublicBitFlags> for $PublicBitFlags { |
444 | /// The bitwise or (`|`) of the bits in each flags value. |
445 | fn extend<T: $crate::__private::core::iter::IntoIterator<Item = Self>>( |
446 | &mut self, |
447 | iterator: T, |
448 | ) { |
449 | for item in iterator { |
450 | self.insert(item) |
451 | } |
452 | } |
453 | } |
454 | |
455 | impl $crate::__private::core::iter::FromIterator<$PublicBitFlags> for $PublicBitFlags { |
456 | /// The bitwise or (`|`) of the bits in each flags value. |
457 | fn from_iter<T: $crate::__private::core::iter::IntoIterator<Item = Self>>( |
458 | iterator: T, |
459 | ) -> Self { |
460 | use $crate::__private::core::iter::Extend; |
461 | |
462 | let mut result = Self::empty(); |
463 | result.extend(iterator); |
464 | result |
465 | } |
466 | } |
467 | }; |
468 | } |
469 | |
470 | /// Implement constants on the public (user-facing) bitflags type. |
471 | #[macro_export (local_inner_macros)] |
472 | #[doc (hidden)] |
473 | macro_rules! __impl_public_bitflags_consts { |
474 | ( |
475 | $PublicBitFlags:ident: $T:ty { |
476 | $( |
477 | $(#[$inner:ident $($args:tt)*])* |
478 | const $Flag:tt = $value:expr; |
479 | )* |
480 | } |
481 | ) => { |
482 | impl $PublicBitFlags { |
483 | $( |
484 | __bitflags_flag!({ |
485 | name: $Flag, |
486 | named: { |
487 | $(#[$inner $($args)*])* |
488 | #[allow( |
489 | deprecated, |
490 | non_upper_case_globals, |
491 | )] |
492 | pub const $Flag: Self = Self::from_bits_retain($value); |
493 | }, |
494 | unnamed: {}, |
495 | }); |
496 | )* |
497 | } |
498 | |
499 | impl $crate::Flags for $PublicBitFlags { |
500 | const FLAGS: &'static [$crate::Flag<$PublicBitFlags>] = &[ |
501 | $( |
502 | __bitflags_flag!({ |
503 | name: $Flag, |
504 | named: { |
505 | __bitflags_expr_safe_attrs!( |
506 | $(#[$inner $($args)*])* |
507 | { |
508 | #[allow( |
509 | deprecated, |
510 | non_upper_case_globals, |
511 | )] |
512 | $crate::Flag::new($crate::__private::core::stringify!($Flag), $PublicBitFlags::$Flag) |
513 | } |
514 | ) |
515 | }, |
516 | unnamed: { |
517 | __bitflags_expr_safe_attrs!( |
518 | $(#[$inner $($args)*])* |
519 | { |
520 | #[allow( |
521 | deprecated, |
522 | non_upper_case_globals, |
523 | )] |
524 | $crate::Flag::new("" , $PublicBitFlags::from_bits_retain($value)) |
525 | } |
526 | ) |
527 | }, |
528 | }), |
529 | )* |
530 | ]; |
531 | |
532 | type Bits = $T; |
533 | |
534 | fn bits(&self) -> $T { |
535 | $PublicBitFlags::bits(self) |
536 | } |
537 | |
538 | fn from_bits_retain(bits: $T) -> $PublicBitFlags { |
539 | $PublicBitFlags::from_bits_retain(bits) |
540 | } |
541 | } |
542 | }; |
543 | } |
544 | |