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