Skip to main content

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.13.2"
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### Renaming flags
134
135The [`bitflags`] macro recognizes a special `#[bitflags(flag_name = "<value>")]` attribute on flags values to rename them:
136
137```rust
138# use bitflags::bitflags;
139bitflags! {
140    pub struct Flags: u32 {
141        // Add the attribute to a flag to change its name
142        #[bitflags(flag_name = "a")]
143        const A = 0b00000001;
144        #[bitflags(flag_name = "b")]
145        const B = 0b00000010;
146        #[bitflags(flag_name = "c")]
147        const C = 0b00000100;
148    }
149}
150```
151
152When applied to a flag value, instead of using its identifier, like `A` as the name, it'll use the given string. This
153doesn't affect the identifier of the constant itself, just the name recognized when parsing and formatting.
154
155## Working with flags values
156
157Use generated constants and standard bitwise operators to interact with flags values:
158
159```rust
160# use bitflags::bitflags;
161# bitflags! {
162#     #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
163#     pub struct Flags: u32 {
164#         const A = 0b00000001;
165#         const B = 0b00000010;
166#         const C = 0b00000100;
167#     }
168# }
169// union
170let ab = Flags::A | Flags::B;
171
172// intersection
173let a = ab & Flags::A;
174
175// difference
176let b = ab - Flags::A;
177
178// complement
179let c = !ab;
180```
181
182See the docs for the [`Flags`] trait for more details on operators and how they behave.
183
184# Formatting and parsing
185
186`bitflags` defines a text format that can be used to convert any flags value to and from strings.
187
188See the [`parser`] module for more details.
189
190# Specification
191
192The terminology and behavior of generated flags types is
193[specified in the source repository](https://github.com/bitflags/bitflags/blob/main/spec.md).
194Details are repeated in these docs where appropriate, but is exhaustively listed in the spec. Some
195things are worth calling out explicitly here.
196
197## Flags types, flags values, flags
198
199The spec and these docs use consistent terminology to refer to things in the bitflags domain:
200
201- **Bits type**: A type that defines a fixed number of bits at specific locations.
202- **Flag**: A set of bits in a bits type that may have a unique name.
203- **Flags type**: A set of defined flags over a specific bits type.
204- **Flags value**: An instance of a flags type using its specific bits value for storage.
205
206```
207# use bitflags::bitflags;
208bitflags! {
209    struct FlagsType: u8 {
210//                    -- Bits type
211//         --------- Flags type
212        const A = 1;
213//            ----- Flag
214    }
215}
216
217let flag = FlagsType::A;
218//  ---- Flags value
219```
220
221## Known and unknown bits
222
223Any bits in a flag you define are called _known bits_. Any other bits are _unknown bits_.
224In the following flags type:
225
226```
227# use bitflags::bitflags;
228bitflags! {
229    struct Flags: u8 {
230        const A = 1;
231        const B = 1 << 1;
232        const C = 1 << 2;
233    }
234}
235```
236
237The known bits are `0b0000_0111` and the unknown bits are `0b1111_1000`.
238
239`bitflags` doesn't guarantee that a flags value will only ever have known bits set, but some operators
240will unset any unknown bits they encounter. In a future version of `bitflags`, all operators will
241unset unknown bits.
242
243If you're using `bitflags` for flags types defined externally, such as from C, you probably want all
244bits to be considered known, in case that external source changes. You can do this using an unnamed
245flag, as described in [externally defined flags](#externally-defined-flags).
246
247## Zero-bit flags
248
249Flags with no bits set should be avoided because they interact strangely with [`Flags::contains`]
250and [`Flags::intersects`]. A zero-bit flag is always contained, but is never intersected. The
251names of zero-bit flags can be parsed, but are never formatted.
252
253## Multi-bit flags
254
255Flags that set multiple bits should be avoided unless each bit is also in a single-bit flag.
256Take the following flags type as an example:
257
258```
259# use bitflags::bitflags;
260bitflags! {
261    struct Flags: u8 {
262        const A = 1;
263        const B = 1 | 1 << 1;
264    }
265}
266```
267
268The result of `Flags::A ^ Flags::B` is `0b0000_0010`, which doesn't correspond to either
269`Flags::A` or `Flags::B` even though it's still a known bit.
270*/
271
272#![cfg_attr(not(any(feature = "std", test)), no_std)]
273#![cfg_attr(not(test), forbid(unsafe_code))]
274#![cfg_attr(test, allow(mixed_script_confusables))]
275
276#[doc(inline)]
277pub use traits::{Bits, Flag, Flags};
278
279pub mod iter;
280pub mod parser;
281
282mod traits;
283
284#[doc(hidden)]
285pub mod __private {
286    #[allow(unused_imports)]
287    // Easier than conditionally checking any optional external dependencies
288    pub use crate::{external::__private::*, traits::__private::*};
289
290    pub use core;
291}
292
293#[allow(unused_imports)]
294pub use external::*;
295
296#[allow(deprecated)]
297pub use traits::BitFlags;
298
299/*
300How does the bitflags crate work?
301
302This library generates a `struct` in the end-user's crate with a bunch of constants on it that represent flags.
303The difference between `bitflags` and a lot of other libraries is that we don't actually control the generated `struct` in the end.
304It's part of the end-user's crate, so it belongs to them. That makes it difficult to extend `bitflags` with new functionality
305because we could end up breaking valid code that was already written.
306
307Our 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).
308To give you an example, let's say we had a crate that called `bitflags!`:
309
310```rust
311bitflags! {
312    pub struct MyFlags: u32 {
313        const A = 1;
314        const B = 2;
315    }
316}
317```
318
319What they'd end up with looks something like this:
320
321```rust
322pub struct MyFlags(<MyFlags as PublicFlags>::InternalBitFlags);
323
324const _: () = {
325    #[repr(transparent)]
326    #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
327    pub struct MyInternalBitFlags {
328        bits: u32,
329    }
330
331    impl PublicFlags for MyFlags {
332        type Internal = InternalBitFlags;
333    }
334};
335```
336
337If we want to expose something like a new trait impl for generated flags types, we add it to our generated `MyInternalBitFlags`,
338and let `#[derive]` on `MyFlags` pick up that implementation, if an end-user chooses to add one.
339
340The public API is generated in the `__impl_public_flags!` macro, and the internal API is generated in
341the `__impl_internal_flags!` macro.
342
343The macros are split into 3 modules:
344
345- `public`: where the user-facing flags types are generated.
346- `internal`: where the `bitflags`-facing flags types are generated.
347- `external`: where external library traits are implemented conditionally.
348*/
349
350/**
351Generate a flags type.
352
353# `struct` mode
354
355A declaration that begins with `$vis struct` will generate a `struct` for a flags type, along with
356methods and trait implementations for it. The body of the declaration defines flags as constants,
357where each constant is a flags value of the generated flags type.
358
359## Examples
360
361Generate a flags type using `u8` as the bits type:
362
363```
364# use bitflags::bitflags;
365bitflags! {
366    struct Flags: u8 {
367        const A = 1;
368        const B = 1 << 1;
369        const C = 0b0000_0100;
370    }
371}
372```
373
374Flags types are private by default and accept standard visibility modifiers. Flags themselves
375are always public:
376
377```
378# use bitflags::bitflags;
379bitflags! {
380    pub struct Flags: u8 {
381        // Constants are always `pub`
382        const A = 1;
383    }
384}
385```
386
387Flags may refer to other flags using their [`Flags::bits`] value:
388
389```
390# use bitflags::bitflags;
391bitflags! {
392    struct Flags: u8 {
393        const A = 1;
394        const B = 1 << 1;
395        const AB = Flags::A.bits() | Flags::B.bits();
396    }
397}
398```
399
400A single `bitflags` invocation may include zero or more flags type declarations:
401
402```
403# use bitflags::bitflags;
404bitflags! {}
405
406bitflags! {
407    struct Flags1: u8 {
408        const A = 1;
409    }
410
411    struct Flags2: u8 {
412        const A = 1;
413    }
414}
415```
416
417# `impl` mode
418
419A declaration that begins with `impl` will only generate methods and trait implementations for the
420`struct` defined outside of the `bitflags` macro.
421
422The struct itself must be a newtype using the bits type as its field.
423
424The syntax for `impl` mode is identical to `struct` mode besides the starting token.
425
426## Examples
427
428Implement flags methods and traits for a custom flags type using `u8` as its underlying bits type:
429
430```
431# use bitflags::bitflags;
432struct Flags(u8);
433
434bitflags! {
435    impl Flags: u8 {
436        const A = 1;
437        const B = 1 << 1;
438        const C = 0b0000_0100;
439    }
440}
441```
442
443# Named and unnamed flags
444
445Constants in the body of a declaration are flags. The identifier of the constant is the name of
446the flag. If the identifier is `_`, then the flag is unnamed. Unnamed flags don't appear in the
447generated API, but affect how bits are truncated.
448
449## Examples
450
451Adding an unnamed flag that makes all bits known:
452
453```
454# use bitflags::bitflags;
455bitflags! {
456    struct Flags: u8 {
457        const A = 1;
458        const B = 1 << 1;
459
460        const _ = !0;
461    }
462}
463```
464
465Flags types may define multiple unnamed flags:
466
467```
468# use bitflags::bitflags;
469bitflags! {
470    struct Flags: u8 {
471        const _ = 1;
472        const _ = 1 << 1;
473    }
474}
475```
476*/
477#[macro_export]
478macro_rules! bitflags {
479    (
480        $(#[$outer:meta])*
481        $vis:vis struct $BitFlags:ident: $T:ty {
482            $(
483                $(#[$inner:ident $($args:tt)*])*
484                const $Flag:tt = $value:expr;
485            )*
486        }
487
488        $($t:tt)*
489    ) => {
490        // Declared in the scope of the `bitflags!` call
491        // This type appears in the end-user's API
492        $crate::__declare_public_bitflags! {
493            $(#[$outer])*
494            $vis struct $BitFlags
495        }
496
497        // Workaround for: https://github.com/bitflags/bitflags/issues/320
498        // Pulled outside of the `const _: () = {}` block to avoid triggering an ICE
499        $crate::__impl_public_bitflags_consts! {
500            #[allow(
501                dead_code,
502                deprecated,
503                unused_doc_comments,
504                unused_attributes,
505                unused_mut,
506                unused_imports,
507                non_upper_case_globals,
508                clippy::min_ident_chars,
509                clippy::assign_op_pattern,
510                clippy::indexing_slicing,
511                clippy::same_name_method,
512                clippy::iter_without_into_iter,
513            )]
514            $BitFlags: $T {
515                $(
516                    $(#[$inner $($args)*])*
517                    const $Flag = $value;
518                )*
519            }
520        }
521
522        #[allow(
523            dead_code,
524            deprecated,
525            unused_doc_comments,
526            unused_attributes,
527            unused_mut,
528            unused_imports,
529            non_upper_case_globals,
530            clippy::min_ident_chars,
531            clippy::assign_op_pattern,
532            clippy::indexing_slicing,
533            clippy::same_name_method,
534            clippy::iter_without_into_iter,
535        )]
536        const _: () = {
537            // Declared in a "hidden" scope that can't be reached directly
538            // These types don't appear in the end-user's API
539            $crate::__declare_internal_bitflags! {
540                $vis struct InternalBitFlags: $T
541            }
542
543            $crate::__impl_internal_bitflags! {
544                InternalBitFlags: $T, $BitFlags {
545                    $(
546                        $(#[$inner $($args)*])*
547                        const $Flag = $value;
548                    )*
549                }
550            }
551
552            // This is where new library trait implementations can be added
553            $crate::__impl_external_bitflags! {
554                InternalBitFlags: $T, $BitFlags {
555                    $(
556                        $(#[$inner $($args)*])*
557                        const $Flag;
558                    )*
559                }
560            }
561
562            $crate::__impl_public_bitflags_forward! {
563                $BitFlags: $T, InternalBitFlags
564            }
565
566            $crate::__impl_public_bitflags_ops! {
567                $BitFlags
568            }
569
570            $crate::__impl_public_bitflags_iter! {
571                $BitFlags: $T, $BitFlags
572            }
573        };
574
575        $crate::bitflags! {
576            $($t)*
577        }
578    };
579    (
580        $(#[$outer:meta])*
581        impl $BitFlags:ident: $T:ty {
582            $(
583                $(#[$inner:ident $($args:tt)*])*
584                const $Flag:tt = $value:expr;
585            )*
586        }
587
588        $($t:tt)*
589    ) => {
590        // Workaround for: https://github.com/bitflags/bitflags/issues/320
591        // Pulled outside of the `const _: () = {}` block to avoid triggering an ICE
592        $crate::__impl_public_bitflags_consts! {
593            #[allow(
594                dead_code,
595                deprecated,
596                unused_doc_comments,
597                unused_attributes,
598                unused_mut,
599                unused_imports,
600                non_upper_case_globals,
601                clippy::min_ident_chars,
602                clippy::assign_op_pattern,
603                clippy::iter_without_into_iter,
604            )]
605            $BitFlags: $T {
606                $(
607                    $(#[$inner $($args)*])*
608                    const $Flag = $value;
609                )*
610            }
611        }
612
613        #[allow(
614            dead_code,
615            deprecated,
616            unused_doc_comments,
617            unused_attributes,
618            unused_mut,
619            unused_imports,
620            non_upper_case_globals,
621            clippy::min_ident_chars,
622            clippy::assign_op_pattern,
623            clippy::iter_without_into_iter,
624        )]
625        const _: () = {
626            $crate::__impl_public_bitflags! {
627                $(#[$outer])*
628                $BitFlags: $T, $BitFlags {
629                    $(
630                        $(#[$inner $($args)*])*
631                        const $Flag = $value;
632                    )*
633                }
634            }
635
636            $crate::__impl_public_bitflags_ops! {
637                $BitFlags
638            }
639
640            $crate::__impl_public_bitflags_iter! {
641                $BitFlags: $T, $BitFlags
642            }
643        };
644
645        $crate::bitflags! {
646            $($t)*
647        }
648    };
649    () => {};
650}
651
652/// Implement functions on bitflags types.
653///
654/// We need to be careful about adding new methods and trait implementations here because they
655/// could conflict with items added by the end-user.
656#[macro_export]
657#[doc(hidden)]
658macro_rules! __impl_bitflags {
659    (
660        // These param names must be passed in to make the macro work.
661        // Just use `params: self, bits, name, other, value;`.
662        params: $self:ident, $bits:ident, $name:ident, $other:ident, $value:ident;
663        $(#[$outer:meta])*
664        $PublicBitFlags:ident: $T:ty {
665            fn empty() $empty_body:block
666            fn all() $all_body:block
667            fn bits(&self) $bits_body:block
668            fn from_bits(bits) $from_bits_body:block
669            fn from_bits_truncate(bits) $from_bits_truncate_body:block
670            fn from_bits_retain(bits) $from_bits_retain_body:block
671            fn from_name(name) $from_name_body:block
672            fn is_empty(&self) $is_empty_body:block
673            fn is_all(&self) $is_all_body:block
674            fn intersects(&self, other) $intersects_body:block
675            fn contains(&self, other) $contains_body:block
676            fn insert(&mut self, other) $insert_body:block
677            fn remove(&mut self, other) $remove_body:block
678            fn toggle(&mut self, other) $toggle_body:block
679            fn set(&mut self, other, value) $set_body:block
680            fn intersection(self, other) $intersection_body:block
681            fn union(self, other) $union_body:block
682            fn difference(self, other) $difference_body:block
683            fn symmetric_difference(self, other) $symmetric_difference_body:block
684            fn complement(self) $complement_body:block
685        }
686    ) => {
687        $(#[$outer])*
688        impl $PublicBitFlags {
689            /// Get a flags value with all bits unset.
690            #[inline]
691            pub const fn empty() -> Self
692                $empty_body
693
694            /// Get a flags value with all known bits set.
695            #[inline]
696            pub const fn all() -> Self
697                $all_body
698
699            /// Get the underlying bits value.
700            ///
701            /// The returned value is exactly the bits set in this flags value.
702            #[inline]
703            pub const fn bits(&$self) -> $T
704                $bits_body
705
706            /// Convert from a bits value.
707            ///
708            /// This method will return `None` if any unknown bits are set.
709            #[inline]
710            pub const fn from_bits($bits: $T) -> $crate::__private::core::option::Option<Self>
711                $from_bits_body
712
713            /// Convert from a bits value, unsetting any unknown bits.
714            #[inline]
715            pub const fn from_bits_truncate($bits: $T) -> Self
716                $from_bits_truncate_body
717
718            /// Convert from a bits value exactly.
719            #[inline]
720            pub const fn from_bits_retain($bits: $T) -> Self
721                $from_bits_retain_body
722
723            /// Get a flags value with the bits of a flag with the given name set.
724            ///
725            /// This method will return `None` if `name` is empty or doesn't
726            /// correspond to any named flag.
727            #[inline]
728            pub fn from_name($name: &str) -> $crate::__private::core::option::Option<Self>
729                $from_name_body
730
731            /// Whether all bits in `self` are unset.
732            #[inline]
733            pub const fn is_empty(&$self) -> bool
734                $is_empty_body
735
736            /// Whether all known bits in this flags value are set.
737            #[inline]
738            pub const fn is_all(&$self) -> bool
739                $is_all_body
740
741            /// Whether any set bits in `other` are also set in `self`.
742            #[inline]
743            pub const fn intersects(&$self, $other: Self) -> bool
744                $intersects_body
745
746            /// Whether all set bits in `other` are also set in `self`.
747            #[inline]
748            pub const fn contains(&$self, $other: Self) -> bool
749                $contains_body
750
751            /// The bitwise or (`|`) of the bits in `self` and `other`.
752            #[inline]
753            pub fn insert(&mut $self, $other: Self)
754                $insert_body
755
756            /// The intersection of `self` with the complement of `other` (`&!`).
757            ///
758            /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
759            /// `remove` won't truncate `other`, but the `!` operator will.
760            #[inline]
761            pub fn remove(&mut $self, $other: Self)
762                $remove_body
763
764            /// The bitwise exclusive-or (`^`) of the bits in `self` and `other`.
765            #[inline]
766            pub fn toggle(&mut $self, $other: Self)
767                $toggle_body
768
769            /// Call `insert` when `value` is `true` or `remove` when `value` is `false`.
770            #[inline]
771            pub fn set(&mut $self, $other: Self, $value: bool)
772                $set_body
773
774            /// The bitwise and (`&`) of the bits in `self` and `other`.
775            #[inline]
776            #[must_use]
777            pub const fn intersection($self, $other: Self) -> Self
778                $intersection_body
779
780            /// The bitwise or (`|`) of the bits in `self` and `other`.
781            #[inline]
782            #[must_use]
783            pub const fn union($self, $other: Self) -> Self
784                $union_body
785
786            /// The intersection of `self` with the complement of `other` (`&!`).
787            ///
788            /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
789            /// `difference` won't truncate `other`, but the `!` operator will.
790            #[inline]
791            #[must_use]
792            pub const fn difference($self, $other: Self) -> Self
793                $difference_body
794
795            /// The bitwise exclusive-or (`^`) of the bits in `self` and `other`.
796            #[inline]
797            #[must_use]
798            pub const fn symmetric_difference($self, $other: Self) -> Self
799                $symmetric_difference_body
800
801            /// The bitwise negation (`!`) of the bits in `self`, truncating the result.
802            #[inline]
803            #[must_use]
804            pub const fn complement($self) -> Self
805                $complement_body
806        }
807    };
808}
809
810/// A macro that matches flags values, similar to Rust's `match` statement.
811///
812/// In a regular `match` statement, the syntax `Flag::A | Flag::B` is interpreted as an or-pattern,
813/// instead of the bitwise-or of `Flag::A` and `Flag::B`. This can be surprising when combined with flags types
814/// because `Flag::A | Flag::B` won't match the pattern `Flag::A | Flag::B`. This macro is an alternative to
815/// `match` for flags values that doesn't have this issue.
816///
817/// # Syntax
818///
819/// ```ignore
820/// bitflags_match!(expression, {
821///     pattern1 => result1,
822///     pattern2 => result2,
823///     ..
824///     _ => default_result,
825/// })
826/// ```
827///
828/// The final `_ => default_result` arm is required, otherwise the macro will fail to compile.
829///
830/// # Examples
831///
832/// ```rust
833/// use bitflags::{bitflags, bitflags_match};
834///
835/// bitflags! {
836///     #[derive(PartialEq)]
837///     struct Flags: u8 {
838///         const A = 1 << 0;
839///         const B = 1 << 1;
840///         const C = 1 << 2;
841///     }
842/// }
843///
844/// let flags = Flags::A | Flags::B;
845///
846/// // Prints `the value is A and B`
847/// bitflags_match!(flags, {
848///     Flags::A | Flags::B => println!("the value is A and B"),
849///     _ => println!("the value is not A and B"),
850/// });
851///
852/// // Prints `the value is not A`
853/// bitflags_match!(flags, {
854///     Flags::A => println!("the value is A"),
855///     _ => println!("the value is not A"),
856/// });
857/// ```
858///
859/// # How it works
860///
861/// The macro expands to a series of `if` statements, **checking equality** between the input expression
862/// and each pattern. This allows for correct matching of bitflag combinations, which is not possible
863/// with a regular match expression due to the way bitflags are implemented.
864///
865/// Patterns are evaluated in the order they appear in the macro.
866#[macro_export]
867macro_rules! bitflags_match {
868    ($operation:expr, {
869        $($t:tt)*
870    }) => {
871        // Expand to a closure so we can use `return`
872        // This makes it possible to apply attributes to the "match arms"
873        (|| {
874            $crate::__bitflags_match!($operation, { $($t)* })
875        })()
876    };
877}
878
879/// Expand the `bitflags_match` macro
880#[macro_export]
881#[doc(hidden)]
882macro_rules! __bitflags_match {
883    // Eat an optional `,` following a block match arm
884    ($operation:expr, { $pattern:expr => { $($body:tt)* } , $($t:tt)+ }) => {
885        $crate::__bitflags_match!($operation, { $pattern => { $($body)* } $($t)+ })
886    };
887    // Expand a block match arm `A => { .. }`
888    ($operation:expr, { $pattern:expr => { $($body:tt)* } $($t:tt)+ }) => {
889        {
890            if $operation == $pattern {
891                return {
892                    $($body)*
893                };
894            }
895
896            $crate::__bitflags_match!($operation, { $($t)+ })
897        }
898    };
899    // Expand an expression match arm `A => x,`
900    ($operation:expr, { $pattern:expr => $body:expr , $($t:tt)+ }) => {
901        {
902            if $operation == $pattern {
903                return $body;
904            }
905
906            $crate::__bitflags_match!($operation, { $($t)+ })
907        }
908    };
909    // Expand the default case
910    ($operation:expr, { _ => $default:expr $(,)? }) => {
911        $default
912    }
913}
914
915/// Implement a flag, which may be a wildcard `_`.
916///
917/// Named flags will emit the `named` block, and unnamed flags will emit the `unnamed` block.
918#[macro_export]
919#[doc(hidden)]
920macro_rules! __bitflags_flag {
921    (
922        {
923            name: _,
924            named: { $($named:tt)* },
925            unnamed: { $($unnamed:tt)* },
926        }
927    ) => {
928        $($unnamed)*
929    };
930    (
931        {
932            name: $Flag:ident,
933            named: { $($named:tt)* },
934            unnamed: { $($unnamed:tt)* },
935        }
936    ) => {
937        $($named)*
938    };
939}
940
941/*
942Attribute inspection macros
943
944The following macros all use the same pattern for searching for specific attributes and transforming
945a target token tree. They're implementations of _token-tree munchers_, where each token from a source
946set is matched one-at-a-time until the input is exhausted, at which point the final result is emitted.
947
948The first match is the entrypoint for the macro with user syntax.
949
950Subsequent matches pull tokens from `unprocessed` and do something with them. That might be moving
951them into `processed` to be emitted later, or manipulating a target item/expression. The logic of
952the macro is implemented in these middle matches.
953
954The final match is the exitpoint, where `unprocessed` is empty.
955*/
956
957/// A macro that processes the input to `bitflags!` and shuffles attributes around
958/// based on whether or not they're "expression-safe".
959///
960/// This macro is a token-tree muncher that works on 2 levels:
961///
962/// For each attribute, we explicitly match on its identifier, like `cfg` to determine
963/// whether or not it should be considered expression-safe.
964///
965/// If you find yourself with an attribute that should be considered expression-safe
966/// and isn't, it can be added here.
967#[macro_export]
968#[doc(hidden)]
969macro_rules! __bitflags_expr_safe_attrs {
970    (
971        $(#[$inner:ident $($args:tt)*])*
972        { $e:expr }
973    ) => {
974        $crate::__bitflags_expr_safe_attrs! {
975            expr: { $e },
976            attrs: {
977                // All attributes start here
978                unprocessed: [$(#[$inner $($args)*])*],
979                // Attributes that are safe on expressions go here
980                processed: [],
981            },
982        }
983    };
984    // `cfg`: propagate
985    (
986        expr: { $e:expr },
987        attrs: {
988            unprocessed: [
989                #[cfg $($args:tt)*]
990                $($attrs_rest:tt)*
991            ],
992            processed: [$($expr:tt)*],
993        },
994    ) => {
995        $crate::__bitflags_expr_safe_attrs! {
996            expr: { $e },
997            attrs: {
998                unprocessed: [
999                    $($attrs_rest)*
1000                ],
1001                processed: [
1002                    $($expr)*
1003                    #[cfg $($args)*]
1004                ],
1005            },
1006        }
1007    };
1008    // Other: discard
1009    (
1010        expr: { $e:expr },
1011        attrs: {
1012            unprocessed: [
1013                #[$other:ident $($args:tt)*]
1014                $($attrs_rest:tt)*
1015            ],
1016            processed: [$($expr:tt)*],
1017        },
1018    ) => {
1019        $crate::__bitflags_expr_safe_attrs! {
1020            expr: { $e },
1021                attrs: {
1022                unprocessed: [
1023                    $($attrs_rest)*
1024                ],
1025                processed: [
1026                    $($expr)*
1027                ],
1028            },
1029        }
1030    };
1031    // Finished
1032    (
1033        expr: { $e:expr },
1034        attrs: {
1035            unprocessed: [],
1036            processed: [$(#[$expr:ident $($exprargs:tt)*])*],
1037        },
1038    ) => {
1039        $(#[$expr $($exprargs)*])*
1040        { $e }
1041    }
1042}
1043
1044/// A macro that processes the input to `bitflags!` and shuffles attributes around
1045/// based on whether or not they're "item-safe".
1046///
1047/// This macro follows the same pattern as expr-safe above, but assumes all attributes
1048/// are safe on items. It only filters out any `bitflags`-defined attributes.
1049#[macro_export]
1050#[doc(hidden)]
1051macro_rules! __bitflags_item_safe_attrs {
1052    (
1053        $(#[$inner:ident $($args:tt)*])*
1054        { $i:item }
1055    ) => {
1056        $crate::__bitflags_item_safe_attrs! {
1057            item: { $i },
1058            attrs: {
1059                // All attributes start here
1060                unprocessed: [$(#[$inner $($args)*])*],
1061                // Attributes that are safe on items go here
1062                processed: [],
1063            },
1064        }
1065    };
1066    // `bitflags`: discard
1067    (
1068        item: { $i:item },
1069        attrs: {
1070            unprocessed: [
1071                #[bitflags $($args:tt)*]
1072                $($attrs_rest:tt)*
1073            ],
1074            processed: [$($item:tt)*],
1075        },
1076    ) => {
1077        $crate::__bitflags_item_safe_attrs! {
1078            item: { $i },
1079            attrs: {
1080                unprocessed: [
1081                    $($attrs_rest)*
1082                ],
1083                processed: [
1084                    $($item)*
1085                ],
1086            },
1087        }
1088    };
1089    // Other: propagate
1090    (
1091        item: { $i:item },
1092        attrs: {
1093            unprocessed: [
1094                // $other matched here
1095                #[$other:ident $($args:tt)*]
1096                $($attrs_rest:tt)*
1097            ],
1098            processed: [$($item:tt)*],
1099        },
1100    ) => {
1101        $crate::__bitflags_item_safe_attrs! {
1102            item: { $i },
1103                attrs: {
1104                unprocessed: [
1105                    $($attrs_rest)*
1106                ],
1107                processed: [
1108                    $($item)*
1109                    #[$other $($args)*]
1110                ],
1111            },
1112        }
1113    };
1114    // Finished
1115    (
1116        item: { $i:item },
1117        attrs: {
1118            unprocessed: [],
1119            processed: [$(#[$item:ident $($itemargs:tt)*])*],
1120        },
1121    ) => {
1122        $(#[$item $($itemargs)*])*
1123        $i
1124    }
1125}
1126
1127/// Determine the name to assign to a flag.
1128#[macro_export]
1129#[doc(hidden)]
1130macro_rules! __bitflags_flag_name {
1131    // Unnamed
1132    (
1133        $(#[$inner:ident $($args:tt)*])*
1134        { $vis:vis const _ = _ }
1135    ) => {
1136
1137    };
1138    (
1139        $(#[$inner:ident $($args:tt)*])*
1140        { $vis:vis const $binding:ident = $name:expr }
1141    ) => {
1142        $crate::__bitflags_flag_name! {
1143            item: { $vis const $binding = $crate::__private::core::stringify!($name) },
1144            attrs: {
1145                // All attributes start here
1146                unprocessed: [$(#[$inner $($args)*])*],
1147                // Attributes that are safe on the flag name go here
1148                processed: [],
1149            },
1150        }
1151    };
1152    // `bitflags(flag_name)`: set the name
1153    (
1154        item: { $vis:vis const $binding:ident = $name:expr },
1155        attrs: {
1156            unprocessed: [
1157                #[bitflags(flag_name = $flag_name:expr)]
1158                $($attrs_rest:tt)*
1159            ],
1160            processed: [$($item:tt)*],
1161        },
1162    ) => {
1163        $crate::__bitflags_flag_name! {
1164            item: { $vis const $binding = $flag_name },
1165            attrs: {
1166                unprocessed: [
1167                    $($attrs_rest)*
1168                ],
1169                processed: [
1170                    $($item)*
1171                ],
1172            },
1173        }
1174    };
1175    // `cfg`: propagate
1176    (
1177        item: { $vis:vis const $binding:ident = $name:expr },
1178        attrs: {
1179            unprocessed: [
1180                #[cfg $($args:tt)*]
1181                $($attrs_rest:tt)*
1182            ],
1183            processed: [$($item:tt)*],
1184        },
1185    ) => {
1186        $crate::__bitflags_flag_name! {
1187            item: { $vis const $binding = $name },
1188            attrs: {
1189                unprocessed: [
1190                    $($attrs_rest)*
1191                ],
1192                processed: [
1193                    $($item)*
1194                    #[cfg $($args)*]
1195                ],
1196            },
1197        }
1198    };
1199    // Other: discard
1200    (
1201        item: { $vis:vis const $binding:ident = $name:expr },
1202        attrs: {
1203            unprocessed: [
1204                #[$other:ident $($args:tt)*]
1205                $($attrs_rest:tt)*
1206            ],
1207            processed: [$($item:tt)*],
1208        },
1209    ) => {
1210        $crate::__bitflags_flag_name! {
1211            item: { $vis const $binding = $name },
1212            attrs: {
1213                unprocessed: [
1214                    $($attrs_rest)*
1215                ],
1216                processed: [$($item)*],
1217            },
1218        }
1219    };
1220    // Finished
1221    (
1222        item: { $vis:vis const $binding:ident = $name:expr },
1223        attrs: {
1224            unprocessed: [],
1225            processed: [$(#[$item:ident $($itemargs:tt)*])*],
1226        },
1227    ) => {
1228        $(#[$item $($itemargs)*])*
1229        $vis const $binding: &'static str = $name;
1230    }
1231}
1232
1233#[macro_use]
1234mod public;
1235#[macro_use]
1236mod internal;
1237#[macro_use]
1238mod external;
1239
1240#[cfg(feature = "example_generated")]
1241pub mod example_generated;
1242
1243#[cfg(test)]
1244mod tests;