bitflags/
public.rs

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)]
11macro_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)]
27macro_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)]
131macro_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)]
277macro_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)]
326macro_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)]
505macro_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}