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