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