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.4.1"
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`] 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,
74and 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
77underlying 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 pub use crate::{external::__private::*, traits::__private::*};
256
257 pub use core;
258}
259
260#[allow(unused_imports)]
261pub use external::*;
262
263#[allow(deprecated)]
264pub use traits::BitFlags;
265
266/*
267How does the bitflags crate work?
268
269This library generates a `struct` in the end-user's crate with a bunch of constants on it that represent flags.
270The difference between `bitflags` and a lot of other libraries is that we don't actually control the generated `struct` in the end.
271It's part of the end-user's crate, so it belongs to them. That makes it difficult to extend `bitflags` with new functionality
272because we could end up breaking valid code that was already written.
273
274Our 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).
275To give you an example, let's say we had a crate that called `bitflags!`:
276
277```rust
278bitflags! {
279 pub struct MyFlags: u32 {
280 const A = 1;
281 const B = 2;
282 }
283}
284```
285
286What they'd end up with looks something like this:
287
288```rust
289pub struct MyFlags(<MyFlags as PublicFlags>::InternalBitFlags);
290
291const _: () = {
292 #[repr(transparent)]
293 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
294 pub struct MyInternalBitFlags {
295 bits: u32,
296 }
297
298 impl PublicFlags for MyFlags {
299 type Internal = InternalBitFlags;
300 }
301};
302```
303
304If we want to expose something like a new trait impl for generated flags types, we add it to our generated `MyInternalBitFlags`,
305and let `#[derive]` on `MyFlags` pick up that implementation, if an end-user chooses to add one.
306
307The public API is generated in the `__impl_public_flags!` macro, and the internal API is generated in
308the `__impl_internal_flags!` macro.
309
310The macros are split into 3 modules:
311
312- `public`: where the user-facing flags types are generated.
313- `internal`: where the `bitflags`-facing flags types are generated.
314- `external`: where external library traits are implemented conditionally.
315*/
316
317/**
318Generate a flags type.
319
320# `struct` mode
321
322A declaration that begins with `$vis struct` will generate a `struct` for a flags type, along with
323methods and trait implementations for it. The body of the declaration defines flags as constants,
324where each constant is a flags value of the generated flags type.
325
326## Examples
327
328Generate a flags type using `u8` as the bits type:
329
330```
331# use bitflags::bitflags;
332bitflags! {
333 struct Flags: u8 {
334 const A = 1;
335 const B = 1 << 1;
336 const C = 0b0000_0100;
337 }
338}
339```
340
341Flags types are private by default and accept standard visibility modifiers. Flags themselves
342are always public:
343
344```
345# use bitflags::bitflags;
346bitflags! {
347 pub struct Flags: u8 {
348 // Constants are always `pub`
349 const A = 1;
350 }
351}
352```
353
354Flags may refer to other flags using their [`Flags::bits`] value:
355
356```
357# use bitflags::bitflags;
358bitflags! {
359 struct Flags: u8 {
360 const A = 1;
361 const B = 1 << 1;
362 const AB = Flags::A.bits() | Flags::B.bits();
363 }
364}
365```
366
367A single `bitflags` invocation may include zero or more flags type declarations:
368
369```
370# use bitflags::bitflags;
371bitflags! {}
372
373bitflags! {
374 struct Flags1: u8 {
375 const A = 1;
376 }
377
378 struct Flags2: u8 {
379 const A = 1;
380 }
381}
382```
383
384# `impl` mode
385
386A declaration that begins with `impl` will only generate methods and trait implementations for the
387`struct` defined outside of the `bitflags` macro.
388
389The struct itself must be a newtype using the bits type as its field.
390
391The syntax for `impl` mode is identical to `struct` mode besides the starting token.
392
393## Examples
394
395Implement flags methods and traits for a custom flags type using `u8` as its underlying bits type:
396
397```
398# use bitflags::bitflags;
399struct Flags(u8);
400
401bitflags! {
402 impl Flags: u8 {
403 const A = 1;
404 const B = 1 << 1;
405 const C = 0b0000_0100;
406 }
407}
408```
409
410# Named and unnamed flags
411
412Constants in the body of a declaration are flags. The identifier of the constant is the name of
413the flag. If the identifier is `_`, then the flag is unnamed. Unnamed flags don't appear in the
414generated API, but affect how bits are truncated.
415
416## Examples
417
418Adding an unnamed flag that makes all bits known:
419
420```
421# use bitflags::bitflags;
422bitflags! {
423 struct Flags: u8 {
424 const A = 1;
425 const B = 1 << 1;
426
427 const _ = !0;
428 }
429}
430```
431
432Flags types may define multiple unnamed flags:
433
434```
435# use bitflags::bitflags;
436bitflags! {
437 struct Flags: u8 {
438 const _ = 1;
439 const _ = 1 << 1;
440 }
441}
442```
443*/
444#[macro_export(local_inner_macros)]
445macro_rules! bitflags {
446 (
447 $(#[$outer:meta])*
448 $vis:vis struct $BitFlags:ident: $T:ty {
449 $(
450 $(#[$inner:ident $($args:tt)*])*
451 const $Flag:tt = $value:expr;
452 )*
453 }
454
455 $($t:tt)*
456 ) => {
457 // Declared in the scope of the `bitflags!` call
458 // This type appears in the end-user's API
459 __declare_public_bitflags! {
460 $(#[$outer])*
461 $vis struct $BitFlags
462 }
463
464 // Workaround for: https://github.com/bitflags/bitflags/issues/320
465 __impl_public_bitflags_consts! {
466 $BitFlags: $T {
467 $(
468 $(#[$inner $($args)*])*
469 const $Flag = $value;
470 )*
471 }
472 }
473
474 #[allow(
475 dead_code,
476 deprecated,
477 unused_doc_comments,
478 unused_attributes,
479 unused_mut,
480 unused_imports,
481 non_upper_case_globals,
482 clippy::assign_op_pattern,
483 clippy::indexing_slicing,
484 clippy::same_name_method,
485 clippy::iter_without_into_iter,
486 )]
487 const _: () = {
488 // Declared in a "hidden" scope that can't be reached directly
489 // These types don't appear in the end-user's API
490 __declare_internal_bitflags! {
491 $vis struct InternalBitFlags: $T
492 }
493
494 __impl_internal_bitflags! {
495 InternalBitFlags: $T, $BitFlags {
496 $(
497 $(#[$inner $($args)*])*
498 const $Flag = $value;
499 )*
500 }
501 }
502
503 // This is where new library trait implementations can be added
504 __impl_external_bitflags! {
505 InternalBitFlags: $T, $BitFlags {
506 $(
507 $(#[$inner $($args)*])*
508 const $Flag;
509 )*
510 }
511 }
512
513 __impl_public_bitflags_forward! {
514 $BitFlags: $T, InternalBitFlags
515 }
516
517 __impl_public_bitflags_ops! {
518 $BitFlags
519 }
520
521 __impl_public_bitflags_iter! {
522 $BitFlags: $T, $BitFlags
523 }
524 };
525
526 bitflags! {
527 $($t)*
528 }
529 };
530 (
531 impl $BitFlags:ident: $T:ty {
532 $(
533 $(#[$inner:ident $($args:tt)*])*
534 const $Flag:tt = $value:expr;
535 )*
536 }
537
538 $($t:tt)*
539 ) => {
540 __impl_public_bitflags_consts! {
541 $BitFlags: $T {
542 $(
543 $(#[$inner $($args)*])*
544 const $Flag = $value;
545 )*
546 }
547 }
548
549 #[allow(
550 dead_code,
551 deprecated,
552 unused_doc_comments,
553 unused_attributes,
554 unused_mut,
555 unused_imports,
556 non_upper_case_globals,
557 clippy::assign_op_pattern,
558 clippy::iter_without_into_iter,
559 )]
560 const _: () = {
561 __impl_public_bitflags! {
562 $BitFlags: $T, $BitFlags {
563 $(
564 $(#[$inner $($args)*])*
565 const $Flag = $value;
566 )*
567 }
568 }
569
570 __impl_public_bitflags_ops! {
571 $BitFlags
572 }
573
574 __impl_public_bitflags_iter! {
575 $BitFlags: $T, $BitFlags
576 }
577 };
578
579 bitflags! {
580 $($t)*
581 }
582 };
583 () => {};
584}
585
586/// Implement functions on bitflags types.
587///
588/// We need to be careful about adding new methods and trait implementations here because they
589/// could conflict with items added by the end-user.
590#[macro_export(local_inner_macros)]
591#[doc(hidden)]
592macro_rules! __impl_bitflags {
593 (
594 $PublicBitFlags:ident: $T:ty {
595 fn empty() $empty:block
596 fn all() $all:block
597 fn bits($bits0:ident) $bits:block
598 fn from_bits($from_bits0:ident) $from_bits:block
599 fn from_bits_truncate($from_bits_truncate0:ident) $from_bits_truncate:block
600 fn from_bits_retain($from_bits_retain0:ident) $from_bits_retain:block
601 fn from_name($from_name0:ident) $from_name:block
602 fn is_empty($is_empty0:ident) $is_empty:block
603 fn is_all($is_all0:ident) $is_all:block
604 fn intersects($intersects0:ident, $intersects1:ident) $intersects:block
605 fn contains($contains0:ident, $contains1:ident) $contains:block
606 fn insert($insert0:ident, $insert1:ident) $insert:block
607 fn remove($remove0:ident, $remove1:ident) $remove:block
608 fn toggle($toggle0:ident, $toggle1:ident) $toggle:block
609 fn set($set0:ident, $set1:ident, $set2:ident) $set:block
610 fn intersection($intersection0:ident, $intersection1:ident) $intersection:block
611 fn union($union0:ident, $union1:ident) $union:block
612 fn difference($difference0:ident, $difference1:ident) $difference:block
613 fn symmetric_difference($symmetric_difference0:ident, $symmetric_difference1:ident) $symmetric_difference:block
614 fn complement($complement0:ident) $complement:block
615 }
616 ) => {
617 #[allow(dead_code, deprecated, unused_attributes)]
618 impl $PublicBitFlags {
619 /// Get a flags value with all bits unset.
620 #[inline]
621 pub const fn empty() -> Self {
622 $empty
623 }
624
625 /// Get a flags value with all known bits set.
626 #[inline]
627 pub const fn all() -> Self {
628 $all
629 }
630
631 /// Get the underlying bits value.
632 ///
633 /// The returned value is exactly the bits set in this flags value.
634 #[inline]
635 pub const fn bits(&self) -> $T {
636 let $bits0 = self;
637 $bits
638 }
639
640 /// Convert from a bits value.
641 ///
642 /// This method will return `None` if any unknown bits are set.
643 #[inline]
644 pub const fn from_bits(bits: $T) -> $crate::__private::core::option::Option<Self> {
645 let $from_bits0 = bits;
646 $from_bits
647 }
648
649 /// Convert from a bits value, unsetting any unknown bits.
650 #[inline]
651 pub const fn from_bits_truncate(bits: $T) -> Self {
652 let $from_bits_truncate0 = bits;
653 $from_bits_truncate
654 }
655
656 /// Convert from a bits value exactly.
657 #[inline]
658 pub const fn from_bits_retain(bits: $T) -> Self {
659 let $from_bits_retain0 = bits;
660 $from_bits_retain
661 }
662
663 /// Get a flags value with the bits of a flag with the given name set.
664 ///
665 /// This method will return `None` if `name` is empty or doesn't
666 /// correspond to any named flag.
667 #[inline]
668 pub fn from_name(name: &str) -> $crate::__private::core::option::Option<Self> {
669 let $from_name0 = name;
670 $from_name
671 }
672
673 /// Whether all bits in this flags value are unset.
674 #[inline]
675 pub const fn is_empty(&self) -> bool {
676 let $is_empty0 = self;
677 $is_empty
678 }
679
680 /// Whether all known bits in this flags value are set.
681 #[inline]
682 pub const fn is_all(&self) -> bool {
683 let $is_all0 = self;
684 $is_all
685 }
686
687 /// Whether any set bits in a source flags value are also set in a target flags value.
688 #[inline]
689 pub const fn intersects(&self, other: Self) -> bool {
690 let $intersects0 = self;
691 let $intersects1 = other;
692 $intersects
693 }
694
695 /// Whether all set bits in a source flags value are also set in a target flags value.
696 #[inline]
697 pub const fn contains(&self, other: Self) -> bool {
698 let $contains0 = self;
699 let $contains1 = other;
700 $contains
701 }
702
703 /// The bitwise or (`|`) of the bits in two flags values.
704 #[inline]
705 pub fn insert(&mut self, other: Self) {
706 let $insert0 = self;
707 let $insert1 = other;
708 $insert
709 }
710
711 /// The intersection of a source flags value with the complement of a target flags value (`&!`).
712 ///
713 /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
714 /// `remove` won't truncate `other`, but the `!` operator will.
715 #[inline]
716 pub fn remove(&mut self, other: Self) {
717 let $remove0 = self;
718 let $remove1 = other;
719 $remove
720 }
721
722 /// The bitwise exclusive-or (`^`) of the bits in two flags values.
723 #[inline]
724 pub fn toggle(&mut self, other: Self) {
725 let $toggle0 = self;
726 let $toggle1 = other;
727 $toggle
728 }
729
730 /// Call `insert` when `value` is `true` or `remove` when `value` is `false`.
731 #[inline]
732 pub fn set(&mut self, other: Self, value: bool) {
733 let $set0 = self;
734 let $set1 = other;
735 let $set2 = value;
736 $set
737 }
738
739 /// The bitwise and (`&`) of the bits in two flags values.
740 #[inline]
741 #[must_use]
742 pub const fn intersection(self, other: Self) -> Self {
743 let $intersection0 = self;
744 let $intersection1 = other;
745 $intersection
746 }
747
748 /// The bitwise or (`|`) of the bits in two flags values.
749 #[inline]
750 #[must_use]
751 pub const fn union(self, other: Self) -> Self {
752 let $union0 = self;
753 let $union1 = other;
754 $union
755 }
756
757 /// The intersection of a source flags value with the complement of a target flags value (`&!`).
758 ///
759 /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
760 /// `difference` won't truncate `other`, but the `!` operator will.
761 #[inline]
762 #[must_use]
763 pub const fn difference(self, other: Self) -> Self {
764 let $difference0 = self;
765 let $difference1 = other;
766 $difference
767 }
768
769 /// The bitwise exclusive-or (`^`) of the bits in two flags values.
770 #[inline]
771 #[must_use]
772 pub const fn symmetric_difference(self, other: Self) -> Self {
773 let $symmetric_difference0 = self;
774 let $symmetric_difference1 = other;
775 $symmetric_difference
776 }
777
778 /// The bitwise negation (`!`) of the bits in a flags value, truncating the result.
779 #[inline]
780 #[must_use]
781 pub const fn complement(self) -> Self {
782 let $complement0 = self;
783 $complement
784 }
785 }
786 };
787}
788
789/// A macro that processed the input to `bitflags!` and shuffles attributes around
790/// based on whether or not they're "expression-safe".
791///
792/// This macro is a token-tree muncher that works on 2 levels:
793///
794/// For each attribute, we explicitly match on its identifier, like `cfg` to determine
795/// whether or not it should be considered expression-safe.
796///
797/// If you find yourself with an attribute that should be considered expression-safe
798/// and isn't, it can be added here.
799#[macro_export(local_inner_macros)]
800#[doc(hidden)]
801macro_rules! __bitflags_expr_safe_attrs {
802 // Entrypoint: Move all flags and all attributes into `unprocessed` lists
803 // where they'll be munched one-at-a-time
804 (
805 $(#[$inner:ident $($args:tt)*])*
806 { $e:expr }
807 ) => {
808 __bitflags_expr_safe_attrs! {
809 expr: { $e },
810 attrs: {
811 // All attributes start here
812 unprocessed: [$(#[$inner $($args)*])*],
813 // Attributes that are safe on expressions go here
814 processed: [],
815 },
816 }
817 };
818 // Process the next attribute on the current flag
819 // `cfg`: The next flag should be propagated to expressions
820 // NOTE: You can copy this rules block and replace `cfg` with
821 // your attribute name that should be considered expression-safe
822 (
823 expr: { $e:expr },
824 attrs: {
825 unprocessed: [
826 // cfg matched here
827 #[cfg $($args:tt)*]
828 $($attrs_rest:tt)*
829 ],
830 processed: [$($expr:tt)*],
831 },
832 ) => {
833 __bitflags_expr_safe_attrs! {
834 expr: { $e },
835 attrs: {
836 unprocessed: [
837 $($attrs_rest)*
838 ],
839 processed: [
840 $($expr)*
841 // cfg added here
842 #[cfg $($args)*]
843 ],
844 },
845 }
846 };
847 // Process the next attribute on the current flag
848 // `$other`: The next flag should not be propagated to expressions
849 (
850 expr: { $e:expr },
851 attrs: {
852 unprocessed: [
853 // $other matched here
854 #[$other:ident $($args:tt)*]
855 $($attrs_rest:tt)*
856 ],
857 processed: [$($expr:tt)*],
858 },
859 ) => {
860 __bitflags_expr_safe_attrs! {
861 expr: { $e },
862 attrs: {
863 unprocessed: [
864 $($attrs_rest)*
865 ],
866 processed: [
867 // $other not added here
868 $($expr)*
869 ],
870 },
871 }
872 };
873 // Once all attributes on all flags are processed, generate the actual code
874 (
875 expr: { $e:expr },
876 attrs: {
877 unprocessed: [],
878 processed: [$(#[$expr:ident $($exprargs:tt)*])*],
879 },
880 ) => {
881 $(#[$expr $($exprargs)*])*
882 { $e }
883 }
884}
885
886/// Implement a flag, which may be a wildcard `_`.
887#[macro_export(local_inner_macros)]
888#[doc(hidden)]
889macro_rules! __bitflags_flag {
890 (
891 {
892 name: _,
893 named: { $($named:tt)* },
894 unnamed: { $($unnamed:tt)* },
895 }
896 ) => {
897 $($unnamed)*
898 };
899 (
900 {
901 name: $Flag:ident,
902 named: { $($named:tt)* },
903 unnamed: { $($unnamed:tt)* },
904 }
905 ) => {
906 $($named)*
907 };
908}
909
910#[macro_use]
911mod public;
912#[macro_use]
913mod internal;
914#[macro_use]
915mod external;
916
917#[cfg(feature = "example_generated")]
918pub mod example_generated;
919
920#[cfg(test)]
921mod tests;
922