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 /*! 12 Generate types for C-style flags with ergonomic APIs. 13 14 # Getting started 15 16 Add `bitflags` to your `Cargo.toml`: 17 18 ```toml 19 [dependencies.bitflags] 20 version = "2.5.0" 21 ``` 22 23 ## Generating flags types 24 25 Use the [`bitflags`] macro to generate flags types: 26 27 ```rust 28 use bitflags::bitflags; 29 30 bitflags! { 31 pub struct Flags: u32 { 32 const A = 0b00000001; 33 const B = 0b00000010; 34 const C = 0b00000100; 35 } 36 } 37 ``` 38 39 See the docs for the `bitflags` macro for the full syntax. 40 41 Also see the [`example_generated`] module for an example of what the `bitflags` macro generates for a flags type. 42 43 ### Externally defined flags 44 45 If you're generating flags types for an external source, such as a C API, you can define 46 an 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; 50 bitflags! { 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 62 Why should you do this? Generated methods like `all` and truncating operators like `!` only consider 63 bits in defined flags. Adding an unnamed flag makes those methods consider additional bits, 64 without generating additional constants for them. It helps compatibility when the external source 65 may start setting additional bits at any time. The [known and unknown bits](#known-and-unknown-bits) 66 section has more details on this behavior. 67 68 ### Custom derives 69 70 You can derive some traits on generated flags types if you enable Cargo features. The following 71 libraries 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 79 You can also define your own flags type outside of the [`bitflags`] macro and then use it to generate methods. 80 This can be useful if you need a custom `#[derive]` attribute for a library that `bitflags` doesn't 81 natively support: 82 83 ```rust 84 # use std::fmt::Debug as SomeTrait; 85 # use bitflags::bitflags; 86 #[derive(SomeTrait)] 87 pub struct Flags(u32); 88 89 bitflags! { 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 100 The [`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; 105 bitflags! { 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 117 impl Flags { 118 pub fn as_u64(&self) -> u64 { 119 self.bits() as u64 120 } 121 } 122 ``` 123 124 ## Working with flags values 125 126 Use 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 139 let ab = Flags::A | Flags::B; 140 141 // intersection 142 let a = ab & Flags::A; 143 144 // difference 145 let b = ab - Flags::A; 146 147 // complement 148 let c = !ab; 149 ``` 150 151 See 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 157 See the [`parser`] module for more details. 158 159 # Specification 160 161 The terminology and behavior of generated flags types is 162 [specified in the source repository](https://github.com/bitflags/bitflags/blob/main/spec.md). 163 Details are repeated in these docs where appropriate, but is exhaustively listed in the spec. Some 164 things are worth calling out explicitly here. 165 166 ## Flags types, flags values, flags 167 168 The 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; 177 bitflags! { 178 struct FlagsType: u8 { 179 // -- Bits type 180 // --------- Flags type 181 const A = 1; 182 // ----- Flag 183 } 184 } 185 186 let flag = FlagsType::A; 187 // ---- Flags value 188 ``` 189 190 ## Known and unknown bits 191 192 Any bits in a flag you define are called _known bits_. Any other bits are _unknown bits_. 193 In the following flags type: 194 195 ``` 196 # use bitflags::bitflags; 197 bitflags! { 198 struct Flags: u8 { 199 const A = 1; 200 const B = 1 << 1; 201 const C = 1 << 2; 202 } 203 } 204 ``` 205 206 The 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 209 will unset any unknown bits they encounter. In a future version of `bitflags`, all operators will 210 unset unknown bits. 211 212 If you're using `bitflags` for flags types defined externally, such as from C, you probably want all 213 bits to be considered known, in case that external source changes. You can do this using an unnamed 214 flag, as described in [externally defined flags](#externally-defined-flags). 215 216 ## Zero-bit flags 217 218 Flags with no bits set should be avoided because they interact strangely with [`Flags::contains`] 219 and [`Flags::intersects`]. A zero-bit flag is always contained, but is never intersected. The 220 names of zero-bit flags can be parsed, but are never formatted. 221 222 ## Multi-bit flags 223 224 Flags that set multiple bits should be avoided unless each bit is also in a single-bit flag. 225 Take the following flags type as an example: 226 227 ``` 228 # use bitflags::bitflags; 229 bitflags! { 230 struct Flags: u8 { 231 const A = 1; 232 const B = 1 | 1 << 1; 233 } 234 } 235 ``` 236 237 The 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)] 246 pub use traits::{Bits, Flag, Flags}; 247 248 pub mod iter; 249 pub mod parser; 250 251 mod traits; 252 253 #[doc(hidden)] 254 pub 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)] 263 pub use external::*; 264 265 #[allow(deprecated)] 266 pub use traits::BitFlags; 267 268 /* 269 How does the bitflags crate work? 270 271 This library generates a `struct` in the end-user's crate with a bunch of constants on it that represent flags. 272 The difference between `bitflags` and a lot of other libraries is that we don't actually control the generated `struct` in the end. 273 It's part of the end-user's crate, so it belongs to them. That makes it difficult to extend `bitflags` with new functionality 274 because we could end up breaking valid code that was already written. 275 276 Our 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). 277 To give you an example, let's say we had a crate that called `bitflags!`: 278 279 ```rust 280 bitflags! { 281 pub struct MyFlags: u32 { 282 const A = 1; 283 const B = 2; 284 } 285 } 286 ``` 287 288 What they'd end up with looks something like this: 289 290 ```rust 291 pub struct MyFlags(<MyFlags as PublicFlags>::InternalBitFlags); 292 293 const _: () = { 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 306 If we want to expose something like a new trait impl for generated flags types, we add it to our generated `MyInternalBitFlags`, 307 and let `#[derive]` on `MyFlags` pick up that implementation, if an end-user chooses to add one. 308 309 The public API is generated in the `__impl_public_flags!` macro, and the internal API is generated in 310 the `__impl_internal_flags!` macro. 311 312 The 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 /** 320 Generate a flags type. 321 322 # `struct` mode 323 324 A declaration that begins with `$vis struct` will generate a `struct` for a flags type, along with 325 methods and trait implementations for it. The body of the declaration defines flags as constants, 326 where each constant is a flags value of the generated flags type. 327 328 ## Examples 329 330 Generate a flags type using `u8` as the bits type: 331 332 ``` 333 # use bitflags::bitflags; 334 bitflags! { 335 struct Flags: u8 { 336 const A = 1; 337 const B = 1 << 1; 338 const C = 0b0000_0100; 339 } 340 } 341 ``` 342 343 Flags types are private by default and accept standard visibility modifiers. Flags themselves 344 are always public: 345 346 ``` 347 # use bitflags::bitflags; 348 bitflags! { 349 pub struct Flags: u8 { 350 // Constants are always `pub` 351 const A = 1; 352 } 353 } 354 ``` 355 356 Flags may refer to other flags using their [`Flags::bits`] value: 357 358 ``` 359 # use bitflags::bitflags; 360 bitflags! { 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 369 A single `bitflags` invocation may include zero or more flags type declarations: 370 371 ``` 372 # use bitflags::bitflags; 373 bitflags! {} 374 375 bitflags! { 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 388 A declaration that begins with `impl` will only generate methods and trait implementations for the 389 `struct` defined outside of the `bitflags` macro. 390 391 The struct itself must be a newtype using the bits type as its field. 392 393 The syntax for `impl` mode is identical to `struct` mode besides the starting token. 394 395 ## Examples 396 397 Implement flags methods and traits for a custom flags type using `u8` as its underlying bits type: 398 399 ``` 400 # use bitflags::bitflags; 401 struct Flags(u8); 402 403 bitflags! { 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 414 Constants in the body of a declaration are flags. The identifier of the constant is the name of 415 the flag. If the identifier is `_`, then the flag is unnamed. Unnamed flags don't appear in the 416 generated API, but affect how bits are truncated. 417 418 ## Examples 419 420 Adding an unnamed flag that makes all bits known: 421 422 ``` 423 # use bitflags::bitflags; 424 bitflags! { 425 struct Flags: u8 { 426 const A = 1; 427 const B = 1 << 1; 428 429 const _ = !0; 430 } 431 } 432 ``` 433 434 Flags types may define multiple unnamed flags: 435 436 ``` 437 # use bitflags::bitflags; 438 bitflags! { 439 struct Flags: u8 { 440 const _ = 1; 441 const _ = 1 << 1; 442 } 443 } 444 ``` 445 */ 446 #[macro_export] 447 macro_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 impl $BitFlags:ident: $T:ty { 534 $( 535 $(#[$inner:ident $($args:tt)*])* 536 const $Flag:tt = $value:expr; 537 )* 538 } 539 540 $($t:tt)* 541 ) => { 542 $crate::__impl_public_bitflags_consts! { 543 $BitFlags: $T { 544 $( 545 $(#[$inner $($args)*])* 546 const $Flag = $value; 547 )* 548 } 549 } 550 551 #[allow( 552 dead_code, 553 deprecated, 554 unused_doc_comments, 555 unused_attributes, 556 unused_mut, 557 unused_imports, 558 non_upper_case_globals, 559 clippy::assign_op_pattern, 560 clippy::iter_without_into_iter, 561 )] 562 const _: () = { 563 $crate::__impl_public_bitflags! { 564 $BitFlags: $T, $BitFlags { 565 $( 566 $(#[$inner $($args)*])* 567 const $Flag = $value; 568 )* 569 } 570 } 571 572 $crate::__impl_public_bitflags_ops! { 573 $BitFlags 574 } 575 576 $crate::__impl_public_bitflags_iter! { 577 $BitFlags: $T, $BitFlags 578 } 579 }; 580 581 $crate::bitflags! { 582 $($t)* 583 } 584 }; 585 () => {}; 586 } 587 588 /// Implement functions on bitflags types. 589 /// 590 /// We need to be careful about adding new methods and trait implementations here because they 591 /// could conflict with items added by the end-user. 592 #[macro_export] 593 #[doc(hidden)] 594 macro_rules! __impl_bitflags { 595 ( 596 $PublicBitFlags:ident: $T:ty { 597 fn empty() $empty:block 598 fn all() $all:block 599 fn bits($bits0:ident) $bits:block 600 fn from_bits($from_bits0:ident) $from_bits:block 601 fn from_bits_truncate($from_bits_truncate0:ident) $from_bits_truncate:block 602 fn from_bits_retain($from_bits_retain0:ident) $from_bits_retain:block 603 fn from_name($from_name0:ident) $from_name:block 604 fn is_empty($is_empty0:ident) $is_empty:block 605 fn is_all($is_all0:ident) $is_all:block 606 fn intersects($intersects0:ident, $intersects1:ident) $intersects:block 607 fn contains($contains0:ident, $contains1:ident) $contains:block 608 fn insert($insert0:ident, $insert1:ident) $insert:block 609 fn remove($remove0:ident, $remove1:ident) $remove:block 610 fn toggle($toggle0:ident, $toggle1:ident) $toggle:block 611 fn set($set0:ident, $set1:ident, $set2:ident) $set:block 612 fn intersection($intersection0:ident, $intersection1:ident) $intersection:block 613 fn union($union0:ident, $union1:ident) $union:block 614 fn difference($difference0:ident, $difference1:ident) $difference:block 615 fn symmetric_difference($symmetric_difference0:ident, $symmetric_difference1:ident) $symmetric_difference:block 616 fn complement($complement0:ident) $complement:block 617 } 618 ) => { 619 #[allow(dead_code, deprecated, unused_attributes)] 620 impl $PublicBitFlags { 621 /// Get a flags value with all bits unset. 622 #[inline] 623 pub const fn empty() -> Self { 624 $empty 625 } 626 627 /// Get a flags value with all known bits set. 628 #[inline] 629 pub const fn all() -> Self { 630 $all 631 } 632 633 /// Get the underlying bits value. 634 /// 635 /// The returned value is exactly the bits set in this flags value. 636 #[inline] 637 pub const fn bits(&self) -> $T { 638 let $bits0 = self; 639 $bits 640 } 641 642 /// Convert from a bits value. 643 /// 644 /// This method will return `None` if any unknown bits are set. 645 #[inline] 646 pub const fn from_bits(bits: $T) -> $crate::__private::core::option::Option<Self> { 647 let $from_bits0 = bits; 648 $from_bits 649 } 650 651 /// Convert from a bits value, unsetting any unknown bits. 652 #[inline] 653 pub const fn from_bits_truncate(bits: $T) -> Self { 654 let $from_bits_truncate0 = bits; 655 $from_bits_truncate 656 } 657 658 /// Convert from a bits value exactly. 659 #[inline] 660 pub const fn from_bits_retain(bits: $T) -> Self { 661 let $from_bits_retain0 = bits; 662 $from_bits_retain 663 } 664 665 /// Get a flags value with the bits of a flag with the given name set. 666 /// 667 /// This method will return `None` if `name` is empty or doesn't 668 /// correspond to any named flag. 669 #[inline] 670 pub fn from_name(name: &str) -> $crate::__private::core::option::Option<Self> { 671 let $from_name0 = name; 672 $from_name 673 } 674 675 /// Whether all bits in this flags value are unset. 676 #[inline] 677 pub const fn is_empty(&self) -> bool { 678 let $is_empty0 = self; 679 $is_empty 680 } 681 682 /// Whether all known bits in this flags value are set. 683 #[inline] 684 pub const fn is_all(&self) -> bool { 685 let $is_all0 = self; 686 $is_all 687 } 688 689 /// Whether any set bits in a source flags value are also set in a target flags value. 690 #[inline] 691 pub const fn intersects(&self, other: Self) -> bool { 692 let $intersects0 = self; 693 let $intersects1 = other; 694 $intersects 695 } 696 697 /// Whether all set bits in a source flags value are also set in a target flags value. 698 #[inline] 699 pub const fn contains(&self, other: Self) -> bool { 700 let $contains0 = self; 701 let $contains1 = other; 702 $contains 703 } 704 705 /// The bitwise or (`|`) of the bits in two flags values. 706 #[inline] 707 pub fn insert(&mut self, other: Self) { 708 let $insert0 = self; 709 let $insert1 = other; 710 $insert 711 } 712 713 /// The intersection of a source flags value with the complement of a target flags value (`&!`). 714 /// 715 /// This method is not equivalent to `self & !other` when `other` has unknown bits set. 716 /// `remove` won't truncate `other`, but the `!` operator will. 717 #[inline] 718 pub fn remove(&mut self, other: Self) { 719 let $remove0 = self; 720 let $remove1 = other; 721 $remove 722 } 723 724 /// The bitwise exclusive-or (`^`) of the bits in two flags values. 725 #[inline] 726 pub fn toggle(&mut self, other: Self) { 727 let $toggle0 = self; 728 let $toggle1 = other; 729 $toggle 730 } 731 732 /// Call `insert` when `value` is `true` or `remove` when `value` is `false`. 733 #[inline] 734 pub fn set(&mut self, other: Self, value: bool) { 735 let $set0 = self; 736 let $set1 = other; 737 let $set2 = value; 738 $set 739 } 740 741 /// The bitwise and (`&`) of the bits in two flags values. 742 #[inline] 743 #[must_use] 744 pub const fn intersection(self, other: Self) -> Self { 745 let $intersection0 = self; 746 let $intersection1 = other; 747 $intersection 748 } 749 750 /// The bitwise or (`|`) of the bits in two flags values. 751 #[inline] 752 #[must_use] 753 pub const fn union(self, other: Self) -> Self { 754 let $union0 = self; 755 let $union1 = other; 756 $union 757 } 758 759 /// The intersection of a source flags value with the complement of a target flags value (`&!`). 760 /// 761 /// This method is not equivalent to `self & !other` when `other` has unknown bits set. 762 /// `difference` won't truncate `other`, but the `!` operator will. 763 #[inline] 764 #[must_use] 765 pub const fn difference(self, other: Self) -> Self { 766 let $difference0 = self; 767 let $difference1 = other; 768 $difference 769 } 770 771 /// The bitwise exclusive-or (`^`) of the bits in two flags values. 772 #[inline] 773 #[must_use] 774 pub const fn symmetric_difference(self, other: Self) -> Self { 775 let $symmetric_difference0 = self; 776 let $symmetric_difference1 = other; 777 $symmetric_difference 778 } 779 780 /// The bitwise negation (`!`) of the bits in a flags value, truncating the result. 781 #[inline] 782 #[must_use] 783 pub const fn complement(self) -> Self { 784 let $complement0 = self; 785 $complement 786 } 787 } 788 }; 789 } 790 791 /// A macro that processed the input to `bitflags!` and shuffles attributes around 792 /// based on whether or not they're "expression-safe". 793 /// 794 /// This macro is a token-tree muncher that works on 2 levels: 795 /// 796 /// For each attribute, we explicitly match on its identifier, like `cfg` to determine 797 /// whether or not it should be considered expression-safe. 798 /// 799 /// If you find yourself with an attribute that should be considered expression-safe 800 /// and isn't, it can be added here. 801 #[macro_export] 802 #[doc(hidden)] 803 macro_rules! __bitflags_expr_safe_attrs { 804 // Entrypoint: Move all flags and all attributes into `unprocessed` lists 805 // where they'll be munched one-at-a-time 806 ( 807 $(#[$inner:ident $($args:tt)*])* 808 { $e:expr } 809 ) => { 810 $crate::__bitflags_expr_safe_attrs! { 811 expr: { $e }, 812 attrs: { 813 // All attributes start here 814 unprocessed: [$(#[$inner $($args)*])*], 815 // Attributes that are safe on expressions go here 816 processed: [], 817 }, 818 } 819 }; 820 // Process the next attribute on the current flag 821 // `cfg`: The next flag should be propagated to expressions 822 // NOTE: You can copy this rules block and replace `cfg` with 823 // your attribute name that should be considered expression-safe 824 ( 825 expr: { $e:expr }, 826 attrs: { 827 unprocessed: [ 828 // cfg matched here 829 #[cfg $($args:tt)*] 830 $($attrs_rest:tt)* 831 ], 832 processed: [$($expr:tt)*], 833 }, 834 ) => { 835 $crate::__bitflags_expr_safe_attrs! { 836 expr: { $e }, 837 attrs: { 838 unprocessed: [ 839 $($attrs_rest)* 840 ], 841 processed: [ 842 $($expr)* 843 // cfg added here 844 #[cfg $($args)*] 845 ], 846 }, 847 } 848 }; 849 // Process the next attribute on the current flag 850 // `$other`: The next flag should not be propagated to expressions 851 ( 852 expr: { $e:expr }, 853 attrs: { 854 unprocessed: [ 855 // $other matched here 856 #[$other:ident $($args:tt)*] 857 $($attrs_rest:tt)* 858 ], 859 processed: [$($expr:tt)*], 860 }, 861 ) => { 862 $crate::__bitflags_expr_safe_attrs! { 863 expr: { $e }, 864 attrs: { 865 unprocessed: [ 866 $($attrs_rest)* 867 ], 868 processed: [ 869 // $other not added here 870 $($expr)* 871 ], 872 }, 873 } 874 }; 875 // Once all attributes on all flags are processed, generate the actual code 876 ( 877 expr: { $e:expr }, 878 attrs: { 879 unprocessed: [], 880 processed: [$(#[$expr:ident $($exprargs:tt)*])*], 881 }, 882 ) => { 883 $(#[$expr $($exprargs)*])* 884 { $e } 885 } 886 } 887 888 /// Implement a flag, which may be a wildcard `_`. 889 #[macro_export] 890 #[doc(hidden)] 891 macro_rules! __bitflags_flag { 892 ( 893 { 894 name: _, 895 named: { $($named:tt)* }, 896 unnamed: { $($unnamed:tt)* }, 897 } 898 ) => { 899 $($unnamed)* 900 }; 901 ( 902 { 903 name: $Flag:ident, 904 named: { $($named:tt)* }, 905 unnamed: { $($unnamed:tt)* }, 906 } 907 ) => { 908 $($named)* 909 }; 910 } 911 912 #[macro_use] 913 mod public; 914 #[macro_use] 915 mod internal; 916 #[macro_use] 917 mod external; 918 919 #[cfg(feature = "example_generated")] 920 pub mod example_generated; 921 922 #[cfg(test)] 923 mod tests; 924