• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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         $PublicBitFlags:ident: $T:ty, $InternalBitFlags:ident
30     ) => {
31         $crate::__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]
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         $crate::__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                         $crate::__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                         $crate::__bitflags_flag!({
189                             name: $Flag,
190                             named: {
191                                 $crate::__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]
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]
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                 let inner = self.0;
325                 $crate::__private::core::fmt::Binary::fmt(&inner, f)
326             }
327         }
328 
329         impl $crate::__private::core::fmt::Octal for $PublicBitFlags {
330             fn fmt(
331                 &self,
332                 f: &mut $crate::__private::core::fmt::Formatter,
333             ) -> $crate::__private::core::fmt::Result {
334                 let inner = self.0;
335                 $crate::__private::core::fmt::Octal::fmt(&inner, f)
336             }
337         }
338 
339         impl $crate::__private::core::fmt::LowerHex for $PublicBitFlags {
340             fn fmt(
341                 &self,
342                 f: &mut $crate::__private::core::fmt::Formatter,
343             ) -> $crate::__private::core::fmt::Result {
344                 let inner = self.0;
345                 $crate::__private::core::fmt::LowerHex::fmt(&inner, f)
346             }
347         }
348 
349         impl $crate::__private::core::fmt::UpperHex for $PublicBitFlags {
350             fn fmt(
351                 &self,
352                 f: &mut $crate::__private::core::fmt::Formatter,
353             ) -> $crate::__private::core::fmt::Result {
354                 let inner = self.0;
355                 $crate::__private::core::fmt::UpperHex::fmt(&inner, f)
356             }
357         }
358 
359         impl $crate::__private::core::ops::BitOr for $PublicBitFlags {
360             type Output = Self;
361 
362             /// The bitwise or (`|`) of the bits in two flags values.
363             #[inline]
364             fn bitor(self, other: $PublicBitFlags) -> Self {
365                 self.union(other)
366             }
367         }
368 
369         impl $crate::__private::core::ops::BitOrAssign for $PublicBitFlags {
370             /// The bitwise or (`|`) of the bits in two flags values.
371             #[inline]
372             fn bitor_assign(&mut self, other: Self) {
373                 self.insert(other);
374             }
375         }
376 
377         impl $crate::__private::core::ops::BitXor for $PublicBitFlags {
378             type Output = Self;
379 
380             /// The bitwise exclusive-or (`^`) of the bits in two flags values.
381             #[inline]
382             fn bitxor(self, other: Self) -> Self {
383                 self.symmetric_difference(other)
384             }
385         }
386 
387         impl $crate::__private::core::ops::BitXorAssign for $PublicBitFlags {
388             /// The bitwise exclusive-or (`^`) of the bits in two flags values.
389             #[inline]
390             fn bitxor_assign(&mut self, other: Self) {
391                 self.toggle(other);
392             }
393         }
394 
395         impl $crate::__private::core::ops::BitAnd for $PublicBitFlags {
396             type Output = Self;
397 
398             /// The bitwise and (`&`) of the bits in two flags values.
399             #[inline]
400             fn bitand(self, other: Self) -> Self {
401                 self.intersection(other)
402             }
403         }
404 
405         impl $crate::__private::core::ops::BitAndAssign for $PublicBitFlags {
406             /// The bitwise and (`&`) of the bits in two flags values.
407             #[inline]
408             fn bitand_assign(&mut self, other: Self) {
409                 *self = Self::from_bits_retain(self.bits()).intersection(other);
410             }
411         }
412 
413         impl $crate::__private::core::ops::Sub for $PublicBitFlags {
414             type Output = Self;
415 
416             /// The intersection of a source flags value with the complement of a target flags value (`&!`).
417             ///
418             /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
419             /// `difference` won't truncate `other`, but the `!` operator will.
420             #[inline]
421             fn sub(self, other: Self) -> Self {
422                 self.difference(other)
423             }
424         }
425 
426         impl $crate::__private::core::ops::SubAssign for $PublicBitFlags {
427             /// The intersection of a source flags value with the complement of a target flags value (`&!`).
428             ///
429             /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
430             /// `difference` won't truncate `other`, but the `!` operator will.
431             #[inline]
432             fn sub_assign(&mut self, other: Self) {
433                 self.remove(other);
434             }
435         }
436 
437         impl $crate::__private::core::ops::Not for $PublicBitFlags {
438             type Output = Self;
439 
440             /// The bitwise negation (`!`) of the bits in a flags value, truncating the result.
441             #[inline]
442             fn not(self) -> Self {
443                 self.complement()
444             }
445         }
446 
447         impl $crate::__private::core::iter::Extend<$PublicBitFlags> for $PublicBitFlags {
448             /// The bitwise or (`|`) of the bits in each flags value.
449             fn extend<T: $crate::__private::core::iter::IntoIterator<Item = Self>>(
450                 &mut self,
451                 iterator: T,
452             ) {
453                 for item in iterator {
454                     self.insert(item)
455                 }
456             }
457         }
458 
459         impl $crate::__private::core::iter::FromIterator<$PublicBitFlags> for $PublicBitFlags {
460             /// The bitwise or (`|`) of the bits in each flags value.
461             fn from_iter<T: $crate::__private::core::iter::IntoIterator<Item = Self>>(
462                 iterator: T,
463             ) -> Self {
464                 use $crate::__private::core::iter::Extend;
465 
466                 let mut result = Self::empty();
467                 result.extend(iterator);
468                 result
469             }
470         }
471     };
472 }
473 
474 /// Implement constants on the public (user-facing) bitflags type.
475 #[macro_export]
476 #[doc(hidden)]
477 macro_rules! __impl_public_bitflags_consts {
478     (
479         $PublicBitFlags:ident: $T:ty {
480             $(
481                 $(#[$inner:ident $($args:tt)*])*
482                 const $Flag:tt = $value:expr;
483             )*
484         }
485     ) => {
486         impl $PublicBitFlags {
487             $(
488                 $crate::__bitflags_flag!({
489                     name: $Flag,
490                     named: {
491                         $(#[$inner $($args)*])*
492                         #[allow(
493                             deprecated,
494                             non_upper_case_globals,
495                         )]
496                         pub const $Flag: Self = Self::from_bits_retain($value);
497                     },
498                     unnamed: {},
499                 });
500             )*
501         }
502 
503         impl $crate::Flags for $PublicBitFlags {
504             const FLAGS: &'static [$crate::Flag<$PublicBitFlags>] = &[
505                 $(
506                     $crate::__bitflags_flag!({
507                         name: $Flag,
508                         named: {
509                             $crate::__bitflags_expr_safe_attrs!(
510                                 $(#[$inner $($args)*])*
511                                 {
512                                     #[allow(
513                                         deprecated,
514                                         non_upper_case_globals,
515                                     )]
516                                     $crate::Flag::new($crate::__private::core::stringify!($Flag), $PublicBitFlags::$Flag)
517                                 }
518                             )
519                         },
520                         unnamed: {
521                             $crate::__bitflags_expr_safe_attrs!(
522                                 $(#[$inner $($args)*])*
523                                 {
524                                     #[allow(
525                                         deprecated,
526                                         non_upper_case_globals,
527                                     )]
528                                     $crate::Flag::new("", $PublicBitFlags::from_bits_retain($value))
529                                 }
530                             )
531                         },
532                     }),
533                 )*
534             ];
535 
536             type Bits = $T;
537 
538             fn bits(&self) -> $T {
539                 $PublicBitFlags::bits(self)
540             }
541 
542             fn from_bits_retain(bits: $T) -> $PublicBitFlags {
543                 $PublicBitFlags::from_bits_retain(bits)
544             }
545         }
546     };
547 }
548