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 // 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 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 $BitFlags: $T, $BitFlags { 566 $( 567 $(#[$inner $($args)*])* 568 const $Flag = $value; 569 )* 570 } 571 } 572 573 $crate::__impl_public_bitflags_ops! { 574 $BitFlags 575 } 576 577 $crate::__impl_public_bitflags_iter! { 578 $BitFlags: $T, $BitFlags 579 } 580 }; 581 582 $crate::bitflags! { 583 $($t)* 584 } 585 }; 586 () => {}; 587 } 588 589 /// Implement functions on bitflags types. 590 /// 591 /// We need to be careful about adding new methods and trait implementations here because they 592 /// could conflict with items added by the end-user. 593 #[macro_export] 594 #[doc(hidden)] 595 macro_rules! __impl_bitflags { 596 ( 597 $PublicBitFlags:ident: $T:ty { 598 fn empty() $empty:block 599 fn all() $all:block 600 fn bits($bits0:ident) $bits:block 601 fn from_bits($from_bits0:ident) $from_bits:block 602 fn from_bits_truncate($from_bits_truncate0:ident) $from_bits_truncate:block 603 fn from_bits_retain($from_bits_retain0:ident) $from_bits_retain:block 604 fn from_name($from_name0:ident) $from_name:block 605 fn is_empty($is_empty0:ident) $is_empty:block 606 fn is_all($is_all0:ident) $is_all:block 607 fn intersects($intersects0:ident, $intersects1:ident) $intersects:block 608 fn contains($contains0:ident, $contains1:ident) $contains:block 609 fn insert($insert0:ident, $insert1:ident) $insert:block 610 fn remove($remove0:ident, $remove1:ident) $remove:block 611 fn toggle($toggle0:ident, $toggle1:ident) $toggle:block 612 fn set($set0:ident, $set1:ident, $set2:ident) $set:block 613 fn intersection($intersection0:ident, $intersection1:ident) $intersection:block 614 fn union($union0:ident, $union1:ident) $union:block 615 fn difference($difference0:ident, $difference1:ident) $difference:block 616 fn symmetric_difference($symmetric_difference0:ident, $symmetric_difference1:ident) $symmetric_difference:block 617 fn complement($complement0:ident) $complement:block 618 } 619 ) => { 620 #[allow(dead_code, deprecated, unused_attributes)] 621 impl $PublicBitFlags { 622 /// Get a flags value with all bits unset. 623 #[inline] 624 pub const fn empty() -> Self { 625 $empty 626 } 627 628 /// Get a flags value with all known bits set. 629 #[inline] 630 pub const fn all() -> Self { 631 $all 632 } 633 634 /// Get the underlying bits value. 635 /// 636 /// The returned value is exactly the bits set in this flags value. 637 #[inline] 638 pub const fn bits(&self) -> $T { 639 let $bits0 = self; 640 $bits 641 } 642 643 /// Convert from a bits value. 644 /// 645 /// This method will return `None` if any unknown bits are set. 646 #[inline] 647 pub const fn from_bits(bits: $T) -> $crate::__private::core::option::Option<Self> { 648 let $from_bits0 = bits; 649 $from_bits 650 } 651 652 /// Convert from a bits value, unsetting any unknown bits. 653 #[inline] 654 pub const fn from_bits_truncate(bits: $T) -> Self { 655 let $from_bits_truncate0 = bits; 656 $from_bits_truncate 657 } 658 659 /// Convert from a bits value exactly. 660 #[inline] 661 pub const fn from_bits_retain(bits: $T) -> Self { 662 let $from_bits_retain0 = bits; 663 $from_bits_retain 664 } 665 666 /// Get a flags value with the bits of a flag with the given name set. 667 /// 668 /// This method will return `None` if `name` is empty or doesn't 669 /// correspond to any named flag. 670 #[inline] 671 pub fn from_name(name: &str) -> $crate::__private::core::option::Option<Self> { 672 let $from_name0 = name; 673 $from_name 674 } 675 676 /// Whether all bits in this flags value are unset. 677 #[inline] 678 pub const fn is_empty(&self) -> bool { 679 let $is_empty0 = self; 680 $is_empty 681 } 682 683 /// Whether all known bits in this flags value are set. 684 #[inline] 685 pub const fn is_all(&self) -> bool { 686 let $is_all0 = self; 687 $is_all 688 } 689 690 /// Whether any set bits in a source flags value are also set in a target flags value. 691 #[inline] 692 pub const fn intersects(&self, other: Self) -> bool { 693 let $intersects0 = self; 694 let $intersects1 = other; 695 $intersects 696 } 697 698 /// Whether all set bits in a source flags value are also set in a target flags value. 699 #[inline] 700 pub const fn contains(&self, other: Self) -> bool { 701 let $contains0 = self; 702 let $contains1 = other; 703 $contains 704 } 705 706 /// The bitwise or (`|`) of the bits in two flags values. 707 #[inline] 708 pub fn insert(&mut self, other: Self) { 709 let $insert0 = self; 710 let $insert1 = other; 711 $insert 712 } 713 714 /// The intersection of a source flags value with the complement of a target flags value (`&!`). 715 /// 716 /// This method is not equivalent to `self & !other` when `other` has unknown bits set. 717 /// `remove` won't truncate `other`, but the `!` operator will. 718 #[inline] 719 pub fn remove(&mut self, other: Self) { 720 let $remove0 = self; 721 let $remove1 = other; 722 $remove 723 } 724 725 /// The bitwise exclusive-or (`^`) of the bits in two flags values. 726 #[inline] 727 pub fn toggle(&mut self, other: Self) { 728 let $toggle0 = self; 729 let $toggle1 = other; 730 $toggle 731 } 732 733 /// Call `insert` when `value` is `true` or `remove` when `value` is `false`. 734 #[inline] 735 pub fn set(&mut self, other: Self, value: bool) { 736 let $set0 = self; 737 let $set1 = other; 738 let $set2 = value; 739 $set 740 } 741 742 /// The bitwise and (`&`) of the bits in two flags values. 743 #[inline] 744 #[must_use] 745 pub const fn intersection(self, other: Self) -> Self { 746 let $intersection0 = self; 747 let $intersection1 = other; 748 $intersection 749 } 750 751 /// The bitwise or (`|`) of the bits in two flags values. 752 #[inline] 753 #[must_use] 754 pub const fn union(self, other: Self) -> Self { 755 let $union0 = self; 756 let $union1 = other; 757 $union 758 } 759 760 /// The intersection of a source flags value with the complement of a target flags value (`&!`). 761 /// 762 /// This method is not equivalent to `self & !other` when `other` has unknown bits set. 763 /// `difference` won't truncate `other`, but the `!` operator will. 764 #[inline] 765 #[must_use] 766 pub const fn difference(self, other: Self) -> Self { 767 let $difference0 = self; 768 let $difference1 = other; 769 $difference 770 } 771 772 /// The bitwise exclusive-or (`^`) of the bits in two flags values. 773 #[inline] 774 #[must_use] 775 pub const fn symmetric_difference(self, other: Self) -> Self { 776 let $symmetric_difference0 = self; 777 let $symmetric_difference1 = other; 778 $symmetric_difference 779 } 780 781 /// The bitwise negation (`!`) of the bits in a flags value, truncating the result. 782 #[inline] 783 #[must_use] 784 pub const fn complement(self) -> Self { 785 let $complement0 = self; 786 $complement 787 } 788 } 789 }; 790 } 791 792 /// A macro that processed the input to `bitflags!` and shuffles attributes around 793 /// based on whether or not they're "expression-safe". 794 /// 795 /// This macro is a token-tree muncher that works on 2 levels: 796 /// 797 /// For each attribute, we explicitly match on its identifier, like `cfg` to determine 798 /// whether or not it should be considered expression-safe. 799 /// 800 /// If you find yourself with an attribute that should be considered expression-safe 801 /// and isn't, it can be added here. 802 #[macro_export] 803 #[doc(hidden)] 804 macro_rules! __bitflags_expr_safe_attrs { 805 // Entrypoint: Move all flags and all attributes into `unprocessed` lists 806 // where they'll be munched one-at-a-time 807 ( 808 $(#[$inner:ident $($args:tt)*])* 809 { $e:expr } 810 ) => { 811 $crate::__bitflags_expr_safe_attrs! { 812 expr: { $e }, 813 attrs: { 814 // All attributes start here 815 unprocessed: [$(#[$inner $($args)*])*], 816 // Attributes that are safe on expressions go here 817 processed: [], 818 }, 819 } 820 }; 821 // Process the next attribute on the current flag 822 // `cfg`: The next flag should be propagated to expressions 823 // NOTE: You can copy this rules block and replace `cfg` with 824 // your attribute name that should be considered expression-safe 825 ( 826 expr: { $e:expr }, 827 attrs: { 828 unprocessed: [ 829 // cfg matched here 830 #[cfg $($args:tt)*] 831 $($attrs_rest:tt)* 832 ], 833 processed: [$($expr:tt)*], 834 }, 835 ) => { 836 $crate::__bitflags_expr_safe_attrs! { 837 expr: { $e }, 838 attrs: { 839 unprocessed: [ 840 $($attrs_rest)* 841 ], 842 processed: [ 843 $($expr)* 844 // cfg added here 845 #[cfg $($args)*] 846 ], 847 }, 848 } 849 }; 850 // Process the next attribute on the current flag 851 // `$other`: The next flag should not be propagated to expressions 852 ( 853 expr: { $e:expr }, 854 attrs: { 855 unprocessed: [ 856 // $other matched here 857 #[$other:ident $($args:tt)*] 858 $($attrs_rest:tt)* 859 ], 860 processed: [$($expr:tt)*], 861 }, 862 ) => { 863 $crate::__bitflags_expr_safe_attrs! { 864 expr: { $e }, 865 attrs: { 866 unprocessed: [ 867 $($attrs_rest)* 868 ], 869 processed: [ 870 // $other not added here 871 $($expr)* 872 ], 873 }, 874 } 875 }; 876 // Once all attributes on all flags are processed, generate the actual code 877 ( 878 expr: { $e:expr }, 879 attrs: { 880 unprocessed: [], 881 processed: [$(#[$expr:ident $($exprargs:tt)*])*], 882 }, 883 ) => { 884 $(#[$expr $($exprargs)*])* 885 { $e } 886 } 887 } 888 889 /// Implement a flag, which may be a wildcard `_`. 890 #[macro_export] 891 #[doc(hidden)] 892 macro_rules! __bitflags_flag { 893 ( 894 { 895 name: _, 896 named: { $($named:tt)* }, 897 unnamed: { $($unnamed:tt)* }, 898 } 899 ) => { 900 $($unnamed)* 901 }; 902 ( 903 { 904 name: $Flag:ident, 905 named: { $($named:tt)* }, 906 unnamed: { $($unnamed:tt)* }, 907 } 908 ) => { 909 $($named)* 910 }; 911 } 912 913 #[macro_use] 914 mod public; 915 #[macro_use] 916 mod internal; 917 #[macro_use] 918 mod external; 919 920 #[cfg(feature = "example_generated")] 921 pub mod example_generated; 922 923 #[cfg(test)] 924 mod tests; 925