bitflags/
lib.rs

1// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2// file at the top-level directory of this distribution and at
3// http://rust-lang.org/COPYRIGHT.
4//
5// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8// option. This file may not be copied, modified, or distributed
9// except according to those terms.
10
11/*!
12Generate types for C-style flags with ergonomic APIs.
13
14# Getting started
15
16Add `bitflags` to your `Cargo.toml`:
17
18```toml
19[dependencies.bitflags]
20version = "2.8.0"
21```
22
23## Generating flags types
24
25Use the [`bitflags`] macro to generate flags types:
26
27```rust
28use bitflags::bitflags;
29
30bitflags! {
31    pub struct Flags: u32 {
32        const A = 0b00000001;
33        const B = 0b00000010;
34        const C = 0b00000100;
35    }
36}
37```
38
39See the docs for the `bitflags` macro for the full syntax.
40
41Also see the [`example_generated`](./example_generated/index.html) module for an example of what the `bitflags` macro generates for a flags type.
42
43### Externally defined flags
44
45If you're generating flags types for an external source, such as a C API, you can define
46an extra unnamed flag as a mask of all bits the external source may ever set. Usually this would be all bits (`!0`):
47
48```rust
49# use bitflags::bitflags;
50bitflags! {
51    pub struct Flags: u32 {
52        const A = 0b00000001;
53        const B = 0b00000010;
54        const C = 0b00000100;
55
56        // The source may set any bits
57        const _ = !0;
58    }
59}
60```
61
62Why should you do this? Generated methods like `all` and truncating operators like `!` only consider
63bits in defined flags. Adding an unnamed flag makes those methods consider additional bits,
64without generating additional constants for them. It helps compatibility when the external source
65may start setting additional bits at any time. The [known and unknown bits](#known-and-unknown-bits)
66section has more details on this behavior.
67
68### Custom derives
69
70You can derive some traits on generated flags types if you enable Cargo features. The following
71libraries are currently supported:
72
73- `serde`: Support `#[derive(Serialize, Deserialize)]`, using text for human-readable formats,
74  and a raw number for binary formats.
75- `arbitrary`: Support `#[derive(Arbitrary)]`, only generating flags values with known bits.
76- `bytemuck`: Support `#[derive(Pod, Zeroable)]`, for casting between flags values and their
77  underlying bits values.
78
79You can also define your own flags type outside of the [`bitflags`] macro and then use it to generate methods.
80This can be useful if you need a custom `#[derive]` attribute for a library that `bitflags` doesn't
81natively support:
82
83```rust
84# use std::fmt::Debug as SomeTrait;
85# use bitflags::bitflags;
86#[derive(SomeTrait)]
87pub struct Flags(u32);
88
89bitflags! {
90    impl Flags: u32 {
91        const A = 0b00000001;
92        const B = 0b00000010;
93        const C = 0b00000100;
94    }
95}
96```
97
98### Adding custom methods
99
100The [`bitflags`] macro supports attributes on generated flags types within the macro itself, while
101`impl` blocks can be added outside of it:
102
103```rust
104# use bitflags::bitflags;
105bitflags! {
106    // Attributes can be applied to flags types
107    #[repr(transparent)]
108    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
109    pub struct Flags: u32 {
110        const A = 0b00000001;
111        const B = 0b00000010;
112        const C = 0b00000100;
113    }
114}
115
116// Impl blocks can be added to flags types
117impl Flags {
118    pub fn as_u64(&self) -> u64 {
119        self.bits() as u64
120    }
121}
122```
123
124## Working with flags values
125
126Use generated constants and standard bitwise operators to interact with flags values:
127
128```rust
129# use bitflags::bitflags;
130# bitflags! {
131#     #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
132#     pub struct Flags: u32 {
133#         const A = 0b00000001;
134#         const B = 0b00000010;
135#         const C = 0b00000100;
136#     }
137# }
138// union
139let ab = Flags::A | Flags::B;
140
141// intersection
142let a = ab & Flags::A;
143
144// difference
145let b = ab - Flags::A;
146
147// complement
148let c = !ab;
149```
150
151See the docs for the [`Flags`] trait for more details on operators and how they behave.
152
153# Formatting and parsing
154
155`bitflags` defines a text format that can be used to convert any flags value to and from strings.
156
157See the [`parser`] module for more details.
158
159# Specification
160
161The terminology and behavior of generated flags types is
162[specified in the source repository](https://github.com/bitflags/bitflags/blob/main/spec.md).
163Details are repeated in these docs where appropriate, but is exhaustively listed in the spec. Some
164things are worth calling out explicitly here.
165
166## Flags types, flags values, flags
167
168The spec and these docs use consistent terminology to refer to things in the bitflags domain:
169
170- **Bits type**: A type that defines a fixed number of bits at specific locations.
171- **Flag**: A set of bits in a bits type that may have a unique name.
172- **Flags type**: A set of defined flags over a specific bits type.
173- **Flags value**: An instance of a flags type using its specific bits value for storage.
174
175```
176# use bitflags::bitflags;
177bitflags! {
178    struct FlagsType: u8 {
179//                    -- Bits type
180//         --------- Flags type
181        const A = 1;
182//            ----- Flag
183    }
184}
185
186let flag = FlagsType::A;
187//  ---- Flags value
188```
189
190## Known and unknown bits
191
192Any bits in a flag you define are called _known bits_. Any other bits are _unknown bits_.
193In the following flags type:
194
195```
196# use bitflags::bitflags;
197bitflags! {
198    struct Flags: u8 {
199        const A = 1;
200        const B = 1 << 1;
201        const C = 1 << 2;
202    }
203}
204```
205
206The known bits are `0b0000_0111` and the unknown bits are `0b1111_1000`.
207
208`bitflags` doesn't guarantee that a flags value will only ever have known bits set, but some operators
209will unset any unknown bits they encounter. In a future version of `bitflags`, all operators will
210unset unknown bits.
211
212If you're using `bitflags` for flags types defined externally, such as from C, you probably want all
213bits to be considered known, in case that external source changes. You can do this using an unnamed
214flag, as described in [externally defined flags](#externally-defined-flags).
215
216## Zero-bit flags
217
218Flags with no bits set should be avoided because they interact strangely with [`Flags::contains`]
219and [`Flags::intersects`]. A zero-bit flag is always contained, but is never intersected. The
220names of zero-bit flags can be parsed, but are never formatted.
221
222## Multi-bit flags
223
224Flags that set multiple bits should be avoided unless each bit is also in a single-bit flag.
225Take the following flags type as an example:
226
227```
228# use bitflags::bitflags;
229bitflags! {
230    struct Flags: u8 {
231        const A = 1;
232        const B = 1 | 1 << 1;
233    }
234}
235```
236
237The result of `Flags::A ^ Flags::B` is `0b0000_0010`, which doesn't correspond to either
238`Flags::A` or `Flags::B` even though it's still a known bit.
239*/
240
241#![cfg_attr(not(any(feature = "std", test)), no_std)]
242#![cfg_attr(not(test), forbid(unsafe_code))]
243#![cfg_attr(test, allow(mixed_script_confusables))]
244
245#[doc(inline)]
246pub use traits::{Bits, Flag, Flags};
247
248pub mod iter;
249pub mod parser;
250
251mod traits;
252
253#[doc(hidden)]
254pub mod __private {
255    #[allow(unused_imports)]
256    // Easier than conditionally checking any optional external dependencies
257    pub use crate::{external::__private::*, traits::__private::*};
258
259    pub use core;
260}
261
262#[allow(unused_imports)]
263pub use external::*;
264
265#[allow(deprecated)]
266pub use traits::BitFlags;
267
268/*
269How does the bitflags crate work?
270
271This library generates a `struct` in the end-user's crate with a bunch of constants on it that represent flags.
272The difference between `bitflags` and a lot of other libraries is that we don't actually control the generated `struct` in the end.
273It's part of the end-user's crate, so it belongs to them. That makes it difficult to extend `bitflags` with new functionality
274because we could end up breaking valid code that was already written.
275
276Our solution is to split the type we generate into two: the public struct owned by the end-user, and an internal struct owned by `bitflags` (us).
277To give you an example, let's say we had a crate that called `bitflags!`:
278
279```rust
280bitflags! {
281    pub struct MyFlags: u32 {
282        const A = 1;
283        const B = 2;
284    }
285}
286```
287
288What they'd end up with looks something like this:
289
290```rust
291pub struct MyFlags(<MyFlags as PublicFlags>::InternalBitFlags);
292
293const _: () = {
294    #[repr(transparent)]
295    #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
296    pub struct MyInternalBitFlags {
297        bits: u32,
298    }
299
300    impl PublicFlags for MyFlags {
301        type Internal = InternalBitFlags;
302    }
303};
304```
305
306If we want to expose something like a new trait impl for generated flags types, we add it to our generated `MyInternalBitFlags`,
307and let `#[derive]` on `MyFlags` pick up that implementation, if an end-user chooses to add one.
308
309The public API is generated in the `__impl_public_flags!` macro, and the internal API is generated in
310the `__impl_internal_flags!` macro.
311
312The macros are split into 3 modules:
313
314- `public`: where the user-facing flags types are generated.
315- `internal`: where the `bitflags`-facing flags types are generated.
316- `external`: where external library traits are implemented conditionally.
317*/
318
319/**
320Generate a flags type.
321
322# `struct` mode
323
324A declaration that begins with `$vis struct` will generate a `struct` for a flags type, along with
325methods and trait implementations for it. The body of the declaration defines flags as constants,
326where each constant is a flags value of the generated flags type.
327
328## Examples
329
330Generate a flags type using `u8` as the bits type:
331
332```
333# use bitflags::bitflags;
334bitflags! {
335    struct Flags: u8 {
336        const A = 1;
337        const B = 1 << 1;
338        const C = 0b0000_0100;
339    }
340}
341```
342
343Flags types are private by default and accept standard visibility modifiers. Flags themselves
344are always public:
345
346```
347# use bitflags::bitflags;
348bitflags! {
349    pub struct Flags: u8 {
350        // Constants are always `pub`
351        const A = 1;
352    }
353}
354```
355
356Flags may refer to other flags using their [`Flags::bits`] value:
357
358```
359# use bitflags::bitflags;
360bitflags! {
361    struct Flags: u8 {
362        const A = 1;
363        const B = 1 << 1;
364        const AB = Flags::A.bits() | Flags::B.bits();
365    }
366}
367```
368
369A single `bitflags` invocation may include zero or more flags type declarations:
370
371```
372# use bitflags::bitflags;
373bitflags! {}
374
375bitflags! {
376    struct Flags1: u8 {
377        const A = 1;
378    }
379
380    struct Flags2: u8 {
381        const A = 1;
382    }
383}
384```
385
386# `impl` mode
387
388A declaration that begins with `impl` will only generate methods and trait implementations for the
389`struct` defined outside of the `bitflags` macro.
390
391The struct itself must be a newtype using the bits type as its field.
392
393The syntax for `impl` mode is identical to `struct` mode besides the starting token.
394
395## Examples
396
397Implement flags methods and traits for a custom flags type using `u8` as its underlying bits type:
398
399```
400# use bitflags::bitflags;
401struct Flags(u8);
402
403bitflags! {
404    impl Flags: u8 {
405        const A = 1;
406        const B = 1 << 1;
407        const C = 0b0000_0100;
408    }
409}
410```
411
412# Named and unnamed flags
413
414Constants in the body of a declaration are flags. The identifier of the constant is the name of
415the flag. If the identifier is `_`, then the flag is unnamed. Unnamed flags don't appear in the
416generated API, but affect how bits are truncated.
417
418## Examples
419
420Adding an unnamed flag that makes all bits known:
421
422```
423# use bitflags::bitflags;
424bitflags! {
425    struct Flags: u8 {
426        const A = 1;
427        const B = 1 << 1;
428
429        const _ = !0;
430    }
431}
432```
433
434Flags types may define multiple unnamed flags:
435
436```
437# use bitflags::bitflags;
438bitflags! {
439    struct Flags: u8 {
440        const _ = 1;
441        const _ = 1 << 1;
442    }
443}
444```
445*/
446#[macro_export]
447macro_rules! bitflags {
448    (
449        $(#[$outer:meta])*
450        $vis:vis struct $BitFlags:ident: $T:ty {
451            $(
452                $(#[$inner:ident $($args:tt)*])*
453                const $Flag:tt = $value:expr;
454            )*
455        }
456
457        $($t:tt)*
458    ) => {
459        // Declared in the scope of the `bitflags!` call
460        // This type appears in the end-user's API
461        $crate::__declare_public_bitflags! {
462            $(#[$outer])*
463            $vis struct $BitFlags
464        }
465
466        // Workaround for: https://github.com/bitflags/bitflags/issues/320
467        $crate::__impl_public_bitflags_consts! {
468            $BitFlags: $T {
469                $(
470                    $(#[$inner $($args)*])*
471                    const $Flag = $value;
472                )*
473            }
474        }
475
476        #[allow(
477            dead_code,
478            deprecated,
479            unused_doc_comments,
480            unused_attributes,
481            unused_mut,
482            unused_imports,
483            non_upper_case_globals,
484            clippy::assign_op_pattern,
485            clippy::indexing_slicing,
486            clippy::same_name_method,
487            clippy::iter_without_into_iter,
488        )]
489        const _: () = {
490            // Declared in a "hidden" scope that can't be reached directly
491            // These types don't appear in the end-user's API
492            $crate::__declare_internal_bitflags! {
493                $vis struct InternalBitFlags: $T
494            }
495
496            $crate::__impl_internal_bitflags! {
497                InternalBitFlags: $T, $BitFlags {
498                    $(
499                        $(#[$inner $($args)*])*
500                        const $Flag = $value;
501                    )*
502                }
503            }
504
505            // This is where new library trait implementations can be added
506            $crate::__impl_external_bitflags! {
507                InternalBitFlags: $T, $BitFlags {
508                    $(
509                        $(#[$inner $($args)*])*
510                        const $Flag;
511                    )*
512                }
513            }
514
515            $crate::__impl_public_bitflags_forward! {
516                $BitFlags: $T, InternalBitFlags
517            }
518
519            $crate::__impl_public_bitflags_ops! {
520                $BitFlags
521            }
522
523            $crate::__impl_public_bitflags_iter! {
524                $BitFlags: $T, $BitFlags
525            }
526        };
527
528        $crate::bitflags! {
529            $($t)*
530        }
531    };
532    (
533        $(#[$outer:meta])*
534        impl $BitFlags:ident: $T:ty {
535            $(
536                $(#[$inner:ident $($args:tt)*])*
537                const $Flag:tt = $value:expr;
538            )*
539        }
540
541        $($t:tt)*
542    ) => {
543        $crate::__impl_public_bitflags_consts! {
544            $BitFlags: $T {
545                $(
546                    $(#[$inner $($args)*])*
547                    const $Flag = $value;
548                )*
549            }
550        }
551
552        #[allow(
553            dead_code,
554            deprecated,
555            unused_doc_comments,
556            unused_attributes,
557            unused_mut,
558            unused_imports,
559            non_upper_case_globals,
560            clippy::assign_op_pattern,
561            clippy::iter_without_into_iter,
562        )]
563        const _: () = {
564            $crate::__impl_public_bitflags! {
565                $(#[$outer])*
566                $BitFlags: $T, $BitFlags {
567                    $(
568                        $(#[$inner $($args)*])*
569                        const $Flag = $value;
570                    )*
571                }
572            }
573
574            $crate::__impl_public_bitflags_ops! {
575                $BitFlags
576            }
577
578            $crate::__impl_public_bitflags_iter! {
579                $BitFlags: $T, $BitFlags
580            }
581        };
582
583        $crate::bitflags! {
584            $($t)*
585        }
586    };
587    () => {};
588}
589
590/// Implement functions on bitflags types.
591///
592/// We need to be careful about adding new methods and trait implementations here because they
593/// could conflict with items added by the end-user.
594#[macro_export]
595#[doc(hidden)]
596macro_rules! __impl_bitflags {
597    (
598        $(#[$outer:meta])*
599        $PublicBitFlags:ident: $T:ty {
600            fn empty() $empty:block
601            fn all() $all:block
602            fn bits($bits0:ident) $bits:block
603            fn from_bits($from_bits0:ident) $from_bits:block
604            fn from_bits_truncate($from_bits_truncate0:ident) $from_bits_truncate:block
605            fn from_bits_retain($from_bits_retain0:ident) $from_bits_retain:block
606            fn from_name($from_name0:ident) $from_name:block
607            fn is_empty($is_empty0:ident) $is_empty:block
608            fn is_all($is_all0:ident) $is_all:block
609            fn intersects($intersects0:ident, $intersects1:ident) $intersects:block
610            fn contains($contains0:ident, $contains1:ident) $contains:block
611            fn insert($insert0:ident, $insert1:ident) $insert:block
612            fn remove($remove0:ident, $remove1:ident) $remove:block
613            fn toggle($toggle0:ident, $toggle1:ident) $toggle:block
614            fn set($set0:ident, $set1:ident, $set2:ident) $set:block
615            fn intersection($intersection0:ident, $intersection1:ident) $intersection:block
616            fn union($union0:ident, $union1:ident) $union:block
617            fn difference($difference0:ident, $difference1:ident) $difference:block
618            fn symmetric_difference($symmetric_difference0:ident, $symmetric_difference1:ident) $symmetric_difference:block
619            fn complement($complement0:ident) $complement:block
620        }
621    ) => {
622        #[allow(dead_code, deprecated, unused_attributes)]
623        $(#[$outer])*
624        impl $PublicBitFlags {
625            /// Get a flags value with all bits unset.
626            #[inline]
627            pub const fn empty() -> Self {
628                $empty
629            }
630
631            /// Get a flags value with all known bits set.
632            #[inline]
633            pub const fn all() -> Self {
634                $all
635            }
636
637            /// Get the underlying bits value.
638            ///
639            /// The returned value is exactly the bits set in this flags value.
640            #[inline]
641            pub const fn bits(&self) -> $T {
642                let $bits0 = self;
643                $bits
644            }
645
646            /// Convert from a bits value.
647            ///
648            /// This method will return `None` if any unknown bits are set.
649            #[inline]
650            pub const fn from_bits(bits: $T) -> $crate::__private::core::option::Option<Self> {
651                let $from_bits0 = bits;
652                $from_bits
653            }
654
655            /// Convert from a bits value, unsetting any unknown bits.
656            #[inline]
657            pub const fn from_bits_truncate(bits: $T) -> Self {
658                let $from_bits_truncate0 = bits;
659                $from_bits_truncate
660            }
661
662            /// Convert from a bits value exactly.
663            #[inline]
664            pub const fn from_bits_retain(bits: $T) -> Self {
665                let $from_bits_retain0 = bits;
666                $from_bits_retain
667            }
668
669            /// Get a flags value with the bits of a flag with the given name set.
670            ///
671            /// This method will return `None` if `name` is empty or doesn't
672            /// correspond to any named flag.
673            #[inline]
674            pub fn from_name(name: &str) -> $crate::__private::core::option::Option<Self> {
675                let $from_name0 = name;
676                $from_name
677            }
678
679            /// Whether all bits in this flags value are unset.
680            #[inline]
681            pub const fn is_empty(&self) -> bool {
682                let $is_empty0 = self;
683                $is_empty
684            }
685
686            /// Whether all known bits in this flags value are set.
687            #[inline]
688            pub const fn is_all(&self) -> bool {
689                let $is_all0 = self;
690                $is_all
691            }
692
693            /// Whether any set bits in a source flags value are also set in a target flags value.
694            #[inline]
695            pub const fn intersects(&self, other: Self) -> bool {
696                let $intersects0 = self;
697                let $intersects1 = other;
698                $intersects
699            }
700
701            /// Whether all set bits in a source flags value are also set in a target flags value.
702            #[inline]
703            pub const fn contains(&self, other: Self) -> bool {
704                let $contains0 = self;
705                let $contains1 = other;
706                $contains
707            }
708
709            /// The bitwise or (`|`) of the bits in two flags values.
710            #[inline]
711            pub fn insert(&mut self, other: Self) {
712                let $insert0 = self;
713                let $insert1 = other;
714                $insert
715            }
716
717            /// The intersection of a source flags value with the complement of a target flags value (`&!`).
718            ///
719            /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
720            /// `remove` won't truncate `other`, but the `!` operator will.
721            #[inline]
722            pub fn remove(&mut self, other: Self) {
723                let $remove0 = self;
724                let $remove1 = other;
725                $remove
726            }
727
728            /// The bitwise exclusive-or (`^`) of the bits in two flags values.
729            #[inline]
730            pub fn toggle(&mut self, other: Self) {
731                let $toggle0 = self;
732                let $toggle1 = other;
733                $toggle
734            }
735
736            /// Call `insert` when `value` is `true` or `remove` when `value` is `false`.
737            #[inline]
738            pub fn set(&mut self, other: Self, value: bool) {
739                let $set0 = self;
740                let $set1 = other;
741                let $set2 = value;
742                $set
743            }
744
745            /// The bitwise and (`&`) of the bits in two flags values.
746            #[inline]
747            #[must_use]
748            pub const fn intersection(self, other: Self) -> Self {
749                let $intersection0 = self;
750                let $intersection1 = other;
751                $intersection
752            }
753
754            /// The bitwise or (`|`) of the bits in two flags values.
755            #[inline]
756            #[must_use]
757            pub const fn union(self, other: Self) -> Self {
758                let $union0 = self;
759                let $union1 = other;
760                $union
761            }
762
763            /// The intersection of a source flags value with the complement of a target flags value (`&!`).
764            ///
765            /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
766            /// `difference` won't truncate `other`, but the `!` operator will.
767            #[inline]
768            #[must_use]
769            pub const fn difference(self, other: Self) -> Self {
770                let $difference0 = self;
771                let $difference1 = other;
772                $difference
773            }
774
775            /// The bitwise exclusive-or (`^`) of the bits in two flags values.
776            #[inline]
777            #[must_use]
778            pub const fn symmetric_difference(self, other: Self) -> Self {
779                let $symmetric_difference0 = self;
780                let $symmetric_difference1 = other;
781                $symmetric_difference
782            }
783
784            /// The bitwise negation (`!`) of the bits in a flags value, truncating the result.
785            #[inline]
786            #[must_use]
787            pub const fn complement(self) -> Self {
788                let $complement0 = self;
789                $complement
790            }
791        }
792    };
793}
794
795/// A macro that matches flags values, similar to Rust's `match` statement.
796///
797/// In a regular `match` statement, the syntax `Flag::A | Flag::B` is interpreted as an or-pattern,
798/// instead of the bitwise-or of `Flag::A` and `Flag::B`. This can be surprising when combined with flags types
799/// because `Flag::A | Flag::B` won't match the pattern `Flag::A | Flag::B`. This macro is an alternative to
800/// `match` for flags values that doesn't have this issue.
801///
802/// # Syntax
803///
804/// ```ignore
805/// bitflags_match!(expression, {
806///     pattern1 => result1,
807///     pattern2 => result2,
808///     ..
809///     _ => default_result,
810/// })
811/// ```
812///
813/// The final `_ => default_result` arm is required, otherwise the macro will fail to compile.
814///
815/// # Examples
816///
817/// ```rust
818/// use bitflags::{bitflags, bitflags_match};
819///
820/// bitflags! {
821///     #[derive(PartialEq)]
822///     struct Flags: u8 {
823///         const A = 1 << 0;
824///         const B = 1 << 1;
825///         const C = 1 << 2;
826///     }
827/// }
828///
829/// let flags = Flags::A | Flags::B;
830///
831/// bitflags_match!(flags, {
832///     Flags::A | Flags::B => println!("A and/or B are set"),
833///     _ => println!("neither A nor B are set"),
834/// })
835/// ```
836///
837/// # How it works
838///
839/// The macro expands to a series of `if` statements, checking equality between the input expression
840/// and each pattern. This allows for correct matching of bitflag combinations, which is not possible
841/// with a regular match expression due to the way bitflags are implemented.
842///
843/// Patterns are evaluated in order.
844#[macro_export]
845macro_rules! bitflags_match {
846    ($operation:expr, {
847        $($t:tt)*
848    }) => {
849        // Expand to a closure so we can use `return`
850        // This makes it possible to apply attributes to the "match arms"
851        (|| {
852            $crate::__bitflags_match!($operation, { $($t)* })
853        })()
854    };
855}
856
857/// Expand the `bitflags_match` macro
858#[macro_export]
859#[doc(hidden)]
860macro_rules! __bitflags_match {
861    // Eat an optional `,` following a block match arm
862    ($operation:expr, { $pattern:expr => { $($body:tt)* } , $($t:tt)+ }) => {
863        $crate::__bitflags_match!($operation, { $pattern => { $($body)* } $($t)+ })
864    };
865    // Expand a block match arm `A => { .. }`
866    ($operation:expr, { $pattern:expr => { $($body:tt)* } $($t:tt)+ }) => {
867        {
868            if $operation == $pattern {
869                return {
870                    $($body)*
871                };
872            }
873
874            $crate::__bitflags_match!($operation, { $($t)+ })
875        }
876    };
877    // Expand an expression match arm `A => x,`
878    ($operation:expr, { $pattern:expr => $body:expr , $($t:tt)+ }) => {
879        {
880            if $operation == $pattern {
881                return $body;
882            }
883
884            $crate::__bitflags_match!($operation, { $($t)+ })
885        }
886    };
887    // Expand the default case
888    ($operation:expr, { _ => $default:expr $(,)? }) => {
889        $default
890    }
891}
892
893/// A macro that processed the input to `bitflags!` and shuffles attributes around
894/// based on whether or not they're "expression-safe".
895///
896/// This macro is a token-tree muncher that works on 2 levels:
897///
898/// For each attribute, we explicitly match on its identifier, like `cfg` to determine
899/// whether or not it should be considered expression-safe.
900///
901/// If you find yourself with an attribute that should be considered expression-safe
902/// and isn't, it can be added here.
903#[macro_export]
904#[doc(hidden)]
905macro_rules! __bitflags_expr_safe_attrs {
906    // Entrypoint: Move all flags and all attributes into `unprocessed` lists
907    // where they'll be munched one-at-a-time
908    (
909        $(#[$inner:ident $($args:tt)*])*
910        { $e:expr }
911    ) => {
912        $crate::__bitflags_expr_safe_attrs! {
913            expr: { $e },
914            attrs: {
915                // All attributes start here
916                unprocessed: [$(#[$inner $($args)*])*],
917                // Attributes that are safe on expressions go here
918                processed: [],
919            },
920        }
921    };
922    // Process the next attribute on the current flag
923    // `cfg`: The next flag should be propagated to expressions
924    // NOTE: You can copy this rules block and replace `cfg` with
925    // your attribute name that should be considered expression-safe
926    (
927        expr: { $e:expr },
928            attrs: {
929            unprocessed: [
930                // cfg matched here
931                #[cfg $($args:tt)*]
932                $($attrs_rest:tt)*
933            ],
934            processed: [$($expr:tt)*],
935        },
936    ) => {
937        $crate::__bitflags_expr_safe_attrs! {
938            expr: { $e },
939            attrs: {
940                unprocessed: [
941                    $($attrs_rest)*
942                ],
943                processed: [
944                    $($expr)*
945                    // cfg added here
946                    #[cfg $($args)*]
947                ],
948            },
949        }
950    };
951    // Process the next attribute on the current flag
952    // `$other`: The next flag should not be propagated to expressions
953    (
954        expr: { $e:expr },
955            attrs: {
956            unprocessed: [
957                // $other matched here
958                #[$other:ident $($args:tt)*]
959                $($attrs_rest:tt)*
960            ],
961            processed: [$($expr:tt)*],
962        },
963    ) => {
964        $crate::__bitflags_expr_safe_attrs! {
965            expr: { $e },
966                attrs: {
967                unprocessed: [
968                    $($attrs_rest)*
969                ],
970                processed: [
971                    // $other not added here
972                    $($expr)*
973                ],
974            },
975        }
976    };
977    // Once all attributes on all flags are processed, generate the actual code
978    (
979        expr: { $e:expr },
980        attrs: {
981            unprocessed: [],
982            processed: [$(#[$expr:ident $($exprargs:tt)*])*],
983        },
984    ) => {
985        $(#[$expr $($exprargs)*])*
986        { $e }
987    }
988}
989
990/// Implement a flag, which may be a wildcard `_`.
991#[macro_export]
992#[doc(hidden)]
993macro_rules! __bitflags_flag {
994    (
995        {
996            name: _,
997            named: { $($named:tt)* },
998            unnamed: { $($unnamed:tt)* },
999        }
1000    ) => {
1001        $($unnamed)*
1002    };
1003    (
1004        {
1005            name: $Flag:ident,
1006            named: { $($named:tt)* },
1007            unnamed: { $($unnamed:tt)* },
1008        }
1009    ) => {
1010        $($named)*
1011    };
1012}
1013
1014#[macro_use]
1015mod public;
1016#[macro_use]
1017mod internal;
1018#[macro_use]
1019mod external;
1020
1021#[cfg(feature = "example_generated")]
1022pub mod example_generated;
1023
1024#[cfg(test)]
1025mod tests;