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