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 //! A typesafe bitmask flag generator useful for sets of C-style bitmask flags. 12 //! It can be used for creating typesafe wrappers around C APIs. 13 //! 14 //! The `bitflags!` macro generates `struct`s that manage a set of flags. The 15 //! flags should only be defined for integer types, otherwise unexpected type 16 //! errors may occur at compile time. 17 //! 18 //! # Example 19 //! 20 //! ``` 21 //! use bitflags::bitflags; 22 //! 23 //! bitflags! { 24 //! struct Flags: u32 { 25 //! const A = 0b00000001; 26 //! const B = 0b00000010; 27 //! const C = 0b00000100; 28 //! const ABC = Self::A.bits | Self::B.bits | Self::C.bits; 29 //! } 30 //! } 31 //! 32 //! fn main() { 33 //! let e1 = Flags::A | Flags::C; 34 //! let e2 = Flags::B | Flags::C; 35 //! assert_eq!((e1 | e2), Flags::ABC); // union 36 //! assert_eq!((e1 & e2), Flags::C); // intersection 37 //! assert_eq!((e1 - e2), Flags::A); // set difference 38 //! assert_eq!(!e2, Flags::A); // set complement 39 //! } 40 //! ``` 41 //! 42 //! See [`example_generated::Flags`](./example_generated/struct.Flags.html) for documentation of code 43 //! generated by the above `bitflags!` expansion. 44 //! 45 //! The generated `struct`s can also be extended with type and trait 46 //! implementations: 47 //! 48 //! ``` 49 //! use std::fmt; 50 //! 51 //! use bitflags::bitflags; 52 //! 53 //! bitflags! { 54 //! struct Flags: u32 { 55 //! const A = 0b00000001; 56 //! const B = 0b00000010; 57 //! } 58 //! } 59 //! 60 //! impl Flags { 61 //! pub fn clear(&mut self) { 62 //! self.bits = 0; // The `bits` field can be accessed from within the 63 //! // same module where the `bitflags!` macro was invoked. 64 //! } 65 //! } 66 //! 67 //! impl fmt::Display for Flags { 68 //! fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 69 //! write!(f, "hi!") 70 //! } 71 //! } 72 //! 73 //! fn main() { 74 //! let mut flags = Flags::A | Flags::B; 75 //! flags.clear(); 76 //! assert!(flags.is_empty()); 77 //! assert_eq!(format!("{}", flags), "hi!"); 78 //! assert_eq!(format!("{:?}", Flags::A | Flags::B), "A | B"); 79 //! assert_eq!(format!("{:?}", Flags::B), "B"); 80 //! } 81 //! ``` 82 //! 83 //! # Visibility 84 //! 85 //! The generated structs and their associated flag constants are not exported 86 //! out of the current module by default. A definition can be exported out of 87 //! the current module by adding `pub` before `struct`: 88 //! 89 //! ``` 90 //! mod example { 91 //! use bitflags::bitflags; 92 //! 93 //! bitflags! { 94 //! pub struct Flags1: u32 { 95 //! const A = 0b00000001; 96 //! } 97 //! 98 //! # pub 99 //! struct Flags2: u32 { 100 //! const B = 0b00000010; 101 //! } 102 //! } 103 //! } 104 //! 105 //! fn main() { 106 //! let flag1 = example::Flags1::A; 107 //! let flag2 = example::Flags2::B; // error: const `B` is private 108 //! } 109 //! ``` 110 //! 111 //! # Attributes 112 //! 113 //! Attributes can be attached to the generated `struct`s by placing them 114 //! before the `struct` keyword. 115 //! 116 //! ## Representations 117 //! 118 //! It's valid to add a `#[repr(C)]` or `#[repr(transparent)]` attribute to a type 119 //! generated by `bitflags!`. In these cases, the type is guaranteed to be a newtype. 120 //! 121 //! ``` 122 //! use bitflags::bitflags; 123 //! 124 //! bitflags! { 125 //! #[repr(transparent)] 126 //! struct Flags: u32 { 127 //! const A = 0b00000001; 128 //! const B = 0b00000010; 129 //! const C = 0b00000100; 130 //! } 131 //! } 132 //! ``` 133 //! 134 //! # Trait implementations 135 //! 136 //! The `Copy`, `Clone`, `PartialEq`, `Eq`, `PartialOrd`, `Ord` and `Hash` 137 //! traits are automatically derived for the `struct`s using the `derive` attribute. 138 //! Additional traits can be derived by providing an explicit `derive` 139 //! attribute on `struct`. 140 //! 141 //! The `Extend` and `FromIterator` traits are implemented for the `struct`s, 142 //! too: `Extend` adds the union of the instances of the `struct` iterated over, 143 //! while `FromIterator` calculates the union. 144 //! 145 //! The `Binary`, `Debug`, `LowerHex`, `Octal` and `UpperHex` traits are also 146 //! implemented by displaying the bits value of the internal struct. 147 //! 148 //! ## Operators 149 //! 150 //! The following operator traits are implemented for the generated `struct`s: 151 //! 152 //! - `BitOr` and `BitOrAssign`: union 153 //! - `BitAnd` and `BitAndAssign`: intersection 154 //! - `BitXor` and `BitXorAssign`: toggle 155 //! - `Sub` and `SubAssign`: set difference 156 //! - `Not`: set complement 157 //! 158 //! # Methods 159 //! 160 //! The following methods are defined for the generated `struct`s: 161 //! 162 //! - `empty`: an empty set of flags 163 //! - `all`: the set of all defined flags 164 //! - `bits`: the raw value of the flags currently stored 165 //! - `from_bits`: convert from underlying bit representation, unless that 166 //! representation contains bits that do not correspond to a 167 //! defined flag 168 //! - `from_bits_truncate`: convert from underlying bit representation, dropping 169 //! any bits that do not correspond to defined flags 170 //! - `from_bits_unchecked`: convert from underlying bit representation, keeping 171 //! all bits (even those not corresponding to defined 172 //! flags) 173 //! - `is_empty`: `true` if no flags are currently stored 174 //! - `is_all`: `true` if currently set flags exactly equal all defined flags 175 //! - `intersects`: `true` if there are flags common to both `self` and `other` 176 //! - `contains`: `true` if all of the flags in `other` are contained within `self` 177 //! - `insert`: inserts the specified flags in-place 178 //! - `remove`: removes the specified flags in-place 179 //! - `toggle`: the specified flags will be inserted if not present, and removed 180 //! if they are. 181 //! - `set`: inserts or removes the specified flags depending on the passed value 182 //! - `intersection`: returns a new set of flags, containing only the flags present 183 //! in both `self` and `other` (the argument to the function). 184 //! - `union`: returns a new set of flags, containing any flags present in 185 //! either `self` or `other` (the argument to the function). 186 //! - `difference`: returns a new set of flags, containing all flags present in 187 //! `self` without any of the flags present in `other` (the 188 //! argument to the function). 189 //! - `symmetric_difference`: returns a new set of flags, containing all flags 190 //! present in either `self` or `other` (the argument 191 //! to the function), but not both. 192 //! - `complement`: returns a new set of flags, containing all flags which are 193 //! not set in `self`, but which are allowed for this type. 194 //! 195 //! ## Default 196 //! 197 //! The `Default` trait is not automatically implemented for the generated structs. 198 //! 199 //! If your default value is equal to `0` (which is the same value as calling `empty()` 200 //! on the generated struct), you can simply derive `Default`: 201 //! 202 //! ``` 203 //! use bitflags::bitflags; 204 //! 205 //! bitflags! { 206 //! // Results in default value with bits: 0 207 //! #[derive(Default)] 208 //! struct Flags: u32 { 209 //! const A = 0b00000001; 210 //! const B = 0b00000010; 211 //! const C = 0b00000100; 212 //! } 213 //! } 214 //! 215 //! fn main() { 216 //! let derived_default: Flags = Default::default(); 217 //! assert_eq!(derived_default.bits(), 0); 218 //! } 219 //! ``` 220 //! 221 //! If your default value is not equal to `0` you need to implement `Default` yourself: 222 //! 223 //! ``` 224 //! use bitflags::bitflags; 225 //! 226 //! bitflags! { 227 //! struct Flags: u32 { 228 //! const A = 0b00000001; 229 //! const B = 0b00000010; 230 //! const C = 0b00000100; 231 //! } 232 //! } 233 //! 234 //! // explicit `Default` implementation 235 //! impl Default for Flags { 236 //! fn default() -> Flags { 237 //! Flags::A | Flags::C 238 //! } 239 //! } 240 //! 241 //! fn main() { 242 //! let implemented_default: Flags = Default::default(); 243 //! assert_eq!(implemented_default, (Flags::A | Flags::C)); 244 //! } 245 //! ``` 246 //! 247 //! # Zero Flags 248 //! 249 //! Flags with a value equal to zero will have some strange behavior that one should be aware of. 250 //! 251 //! ``` 252 //! use bitflags::bitflags; 253 //! 254 //! bitflags! { 255 //! struct Flags: u32 { 256 //! const NONE = 0b00000000; 257 //! const SOME = 0b00000001; 258 //! } 259 //! } 260 //! 261 //! fn main() { 262 //! let empty = Flags::empty(); 263 //! let none = Flags::NONE; 264 //! let some = Flags::SOME; 265 //! 266 //! // Zero flags are treated as always present 267 //! assert!(empty.contains(Flags::NONE)); 268 //! assert!(none.contains(Flags::NONE)); 269 //! assert!(some.contains(Flags::NONE)); 270 //! 271 //! // Zero flags will be ignored when testing for emptiness 272 //! assert!(none.is_empty()); 273 //! } 274 //! ``` 275 //! 276 //! Users should generally avoid defining a flag with a value of zero. 277 278 // ANDROID: Use std to allow building as a dylib. 279 #![cfg_attr(not(any(test, android_dylib)), no_std)] 280 #![doc(html_root_url = "https://docs.rs/bitflags/1.3.2")] 281 282 #[doc(hidden)] 283 pub extern crate core as _core; 284 285 /// The macro used to generate the flag structures. 286 /// 287 /// See the [crate level docs](../bitflags/index.html) for complete documentation. 288 /// 289 /// # Example 290 /// 291 /// ``` 292 /// use bitflags::bitflags; 293 /// 294 /// bitflags! { 295 /// struct Flags: u32 { 296 /// const A = 0b00000001; 297 /// const B = 0b00000010; 298 /// const C = 0b00000100; 299 /// const ABC = Self::A.bits | Self::B.bits | Self::C.bits; 300 /// } 301 /// } 302 /// 303 /// fn main() { 304 /// let e1 = Flags::A | Flags::C; 305 /// let e2 = Flags::B | Flags::C; 306 /// assert_eq!((e1 | e2), Flags::ABC); // union 307 /// assert_eq!((e1 & e2), Flags::C); // intersection 308 /// assert_eq!((e1 - e2), Flags::A); // set difference 309 /// assert_eq!(!e2, Flags::A); // set complement 310 /// } 311 /// ``` 312 /// 313 /// The generated `struct`s can also be extended with type and trait 314 /// implementations: 315 /// 316 /// ``` 317 /// use std::fmt; 318 /// 319 /// use bitflags::bitflags; 320 /// 321 /// bitflags! { 322 /// struct Flags: u32 { 323 /// const A = 0b00000001; 324 /// const B = 0b00000010; 325 /// } 326 /// } 327 /// 328 /// impl Flags { 329 /// pub fn clear(&mut self) { 330 /// self.bits = 0; // The `bits` field can be accessed from within the 331 /// // same module where the `bitflags!` macro was invoked. 332 /// } 333 /// } 334 /// 335 /// impl fmt::Display for Flags { 336 /// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 337 /// write!(f, "hi!") 338 /// } 339 /// } 340 /// 341 /// fn main() { 342 /// let mut flags = Flags::A | Flags::B; 343 /// flags.clear(); 344 /// assert!(flags.is_empty()); 345 /// assert_eq!(format!("{}", flags), "hi!"); 346 /// assert_eq!(format!("{:?}", Flags::A | Flags::B), "A | B"); 347 /// assert_eq!(format!("{:?}", Flags::B), "B"); 348 /// } 349 /// ``` 350 #[macro_export(local_inner_macros)] 351 macro_rules! bitflags { 352 ( 353 $(#[$outer:meta])* 354 $vis:vis struct $BitFlags:ident: $T:ty { 355 $( 356 $(#[$inner:ident $($args:tt)*])* 357 const $Flag:ident = $value:expr; 358 )* 359 } 360 361 $($t:tt)* 362 ) => { 363 $(#[$outer])* 364 #[derive(Copy, PartialEq, Eq, Clone, PartialOrd, Ord, Hash)] 365 $vis struct $BitFlags { 366 bits: $T, 367 } 368 369 __impl_bitflags! { 370 $BitFlags: $T { 371 $( 372 $(#[$inner $($args)*])* 373 $Flag = $value; 374 )* 375 } 376 } 377 378 bitflags! { 379 $($t)* 380 } 381 }; 382 () => {}; 383 } 384 385 // A helper macro to implement the `all` function. 386 #[macro_export(local_inner_macros)] 387 #[doc(hidden)] 388 macro_rules! __impl_all_bitflags { 389 ( 390 $BitFlags:ident: $T:ty { 391 $( 392 $(#[$attr:ident $($args:tt)*])* 393 $Flag:ident = $value:expr; 394 )+ 395 } 396 ) => { 397 // See `Debug::fmt` for why this approach is taken. 398 #[allow(non_snake_case)] 399 trait __BitFlags { 400 $( 401 const $Flag: $T = 0; 402 )+ 403 } 404 #[allow(non_snake_case)] 405 impl __BitFlags for $BitFlags { 406 $( 407 __impl_bitflags! { 408 #[allow(deprecated)] 409 $(? #[$attr $($args)*])* 410 const $Flag: $T = Self::$Flag.bits; 411 } 412 )+ 413 } 414 Self { bits: $(<Self as __BitFlags>::$Flag)|+ } 415 }; 416 ( 417 $BitFlags:ident: $T:ty { } 418 ) => { 419 Self { bits: 0 } 420 }; 421 } 422 423 #[macro_export(local_inner_macros)] 424 #[doc(hidden)] 425 macro_rules! __impl_bitflags { 426 ( 427 $BitFlags:ident: $T:ty { 428 $( 429 $(#[$attr:ident $($args:tt)*])* 430 $Flag:ident = $value:expr; 431 )* 432 } 433 ) => { 434 impl $crate::_core::fmt::Debug for $BitFlags { 435 fn fmt(&self, f: &mut $crate::_core::fmt::Formatter) -> $crate::_core::fmt::Result { 436 // This convoluted approach is to handle #[cfg]-based flag 437 // omission correctly. For example it needs to support: 438 // 439 // #[cfg(unix)] const A: Flag = /* ... */; 440 // #[cfg(windows)] const B: Flag = /* ... */; 441 442 // Unconditionally define a check for every flag, even disabled 443 // ones. 444 #[allow(non_snake_case)] 445 trait __BitFlags { 446 $( 447 #[inline] 448 fn $Flag(&self) -> bool { false } 449 )* 450 } 451 452 // Conditionally override the check for just those flags that 453 // are not #[cfg]ed away. 454 #[allow(non_snake_case)] 455 impl __BitFlags for $BitFlags { 456 $( 457 __impl_bitflags! { 458 #[allow(deprecated)] 459 #[inline] 460 $(? #[$attr $($args)*])* 461 fn $Flag(&self) -> bool { 462 if Self::$Flag.bits == 0 && self.bits != 0 { 463 false 464 } else { 465 self.bits & Self::$Flag.bits == Self::$Flag.bits 466 } 467 } 468 } 469 )* 470 } 471 472 let mut first = true; 473 $( 474 if <Self as __BitFlags>::$Flag(self) { 475 if !first { 476 f.write_str(" | ")?; 477 } 478 first = false; 479 f.write_str($crate::_core::stringify!($Flag))?; 480 } 481 )* 482 let extra_bits = self.bits & !Self::all().bits(); 483 if extra_bits != 0 { 484 if !first { 485 f.write_str(" | ")?; 486 } 487 first = false; 488 f.write_str("0x")?; 489 $crate::_core::fmt::LowerHex::fmt(&extra_bits, f)?; 490 } 491 if first { 492 f.write_str("(empty)")?; 493 } 494 Ok(()) 495 } 496 } 497 impl $crate::_core::fmt::Binary for $BitFlags { 498 fn fmt(&self, f: &mut $crate::_core::fmt::Formatter) -> $crate::_core::fmt::Result { 499 $crate::_core::fmt::Binary::fmt(&self.bits, f) 500 } 501 } 502 impl $crate::_core::fmt::Octal for $BitFlags { 503 fn fmt(&self, f: &mut $crate::_core::fmt::Formatter) -> $crate::_core::fmt::Result { 504 $crate::_core::fmt::Octal::fmt(&self.bits, f) 505 } 506 } 507 impl $crate::_core::fmt::LowerHex for $BitFlags { 508 fn fmt(&self, f: &mut $crate::_core::fmt::Formatter) -> $crate::_core::fmt::Result { 509 $crate::_core::fmt::LowerHex::fmt(&self.bits, f) 510 } 511 } 512 impl $crate::_core::fmt::UpperHex for $BitFlags { 513 fn fmt(&self, f: &mut $crate::_core::fmt::Formatter) -> $crate::_core::fmt::Result { 514 $crate::_core::fmt::UpperHex::fmt(&self.bits, f) 515 } 516 } 517 518 #[allow(dead_code)] 519 impl $BitFlags { 520 $( 521 $(#[$attr $($args)*])* 522 pub const $Flag: Self = Self { bits: $value }; 523 )* 524 525 /// Returns an empty set of flags. 526 #[inline] 527 pub const fn empty() -> Self { 528 Self { bits: 0 } 529 } 530 531 /// Returns the set containing all flags. 532 #[inline] 533 pub const fn all() -> Self { 534 __impl_all_bitflags! { 535 $BitFlags: $T { 536 $( 537 $(#[$attr $($args)*])* 538 $Flag = $value; 539 )* 540 } 541 } 542 } 543 544 /// Returns the raw value of the flags currently stored. 545 #[inline] 546 pub const fn bits(&self) -> $T { 547 self.bits 548 } 549 550 /// Convert from underlying bit representation, unless that 551 /// representation contains bits that do not correspond to a flag. 552 #[inline] 553 pub const fn from_bits(bits: $T) -> $crate::_core::option::Option<Self> { 554 if (bits & !Self::all().bits()) == 0 { 555 $crate::_core::option::Option::Some(Self { bits }) 556 } else { 557 $crate::_core::option::Option::None 558 } 559 } 560 561 /// Convert from underlying bit representation, dropping any bits 562 /// that do not correspond to flags. 563 #[inline] 564 pub const fn from_bits_truncate(bits: $T) -> Self { 565 Self { bits: bits & Self::all().bits } 566 } 567 568 /// Convert from underlying bit representation, preserving all 569 /// bits (even those not corresponding to a defined flag). 570 /// 571 /// # Safety 572 /// 573 /// The caller of the `bitflags!` macro can chose to allow or 574 /// disallow extra bits for their bitflags type. 575 /// 576 /// The caller of `from_bits_unchecked()` has to ensure that 577 /// all bits correspond to a defined flag or that extra bits 578 /// are valid for this bitflags type. 579 #[inline] 580 pub const unsafe fn from_bits_unchecked(bits: $T) -> Self { 581 Self { bits } 582 } 583 584 /// Returns `true` if no flags are currently stored. 585 #[inline] 586 pub const fn is_empty(&self) -> bool { 587 self.bits() == Self::empty().bits() 588 } 589 590 /// Returns `true` if all flags are currently set. 591 #[inline] 592 pub const fn is_all(&self) -> bool { 593 Self::all().bits | self.bits == self.bits 594 } 595 596 /// Returns `true` if there are flags common to both `self` and `other`. 597 #[inline] 598 pub const fn intersects(&self, other: Self) -> bool { 599 !(Self { bits: self.bits & other.bits}).is_empty() 600 } 601 602 /// Returns `true` if all of the flags in `other` are contained within `self`. 603 #[inline] 604 pub const fn contains(&self, other: Self) -> bool { 605 (self.bits & other.bits) == other.bits 606 } 607 608 /// Inserts the specified flags in-place. 609 #[inline] 610 pub fn insert(&mut self, other: Self) { 611 self.bits |= other.bits; 612 } 613 614 /// Removes the specified flags in-place. 615 #[inline] 616 pub fn remove(&mut self, other: Self) { 617 self.bits &= !other.bits; 618 } 619 620 /// Toggles the specified flags in-place. 621 #[inline] 622 pub fn toggle(&mut self, other: Self) { 623 self.bits ^= other.bits; 624 } 625 626 /// Inserts or removes the specified flags depending on the passed value. 627 #[inline] 628 pub fn set(&mut self, other: Self, value: bool) { 629 if value { 630 self.insert(other); 631 } else { 632 self.remove(other); 633 } 634 } 635 636 /// Returns the intersection between the flags in `self` and 637 /// `other`. 638 /// 639 /// Specifically, the returned set contains only the flags which are 640 /// present in *both* `self` *and* `other`. 641 /// 642 /// This is equivalent to using the `&` operator (e.g. 643 /// [`ops::BitAnd`]), as in `flags & other`. 644 /// 645 /// [`ops::BitAnd`]: https://doc.rust-lang.org/std/ops/trait.BitAnd.html 646 #[inline] 647 #[must_use] 648 pub const fn intersection(self, other: Self) -> Self { 649 Self { bits: self.bits & other.bits } 650 } 651 652 /// Returns the union of between the flags in `self` and `other`. 653 /// 654 /// Specifically, the returned set contains all flags which are 655 /// present in *either* `self` *or* `other`, including any which are 656 /// present in both (see [`Self::symmetric_difference`] if that 657 /// is undesirable). 658 /// 659 /// This is equivalent to using the `|` operator (e.g. 660 /// [`ops::BitOr`]), as in `flags | other`. 661 /// 662 /// [`ops::BitOr`]: https://doc.rust-lang.org/std/ops/trait.BitOr.html 663 #[inline] 664 #[must_use] 665 pub const fn union(self, other: Self) -> Self { 666 Self { bits: self.bits | other.bits } 667 } 668 669 /// Returns the difference between the flags in `self` and `other`. 670 /// 671 /// Specifically, the returned set contains all flags present in 672 /// `self`, except for the ones present in `other`. 673 /// 674 /// It is also conceptually equivalent to the "bit-clear" operation: 675 /// `flags & !other` (and this syntax is also supported). 676 /// 677 /// This is equivalent to using the `-` operator (e.g. 678 /// [`ops::Sub`]), as in `flags - other`. 679 /// 680 /// [`ops::Sub`]: https://doc.rust-lang.org/std/ops/trait.Sub.html 681 #[inline] 682 #[must_use] 683 pub const fn difference(self, other: Self) -> Self { 684 Self { bits: self.bits & !other.bits } 685 } 686 687 /// Returns the [symmetric difference][sym-diff] between the flags 688 /// in `self` and `other`. 689 /// 690 /// Specifically, the returned set contains the flags present which 691 /// are present in `self` or `other`, but that are not present in 692 /// both. Equivalently, it contains the flags present in *exactly 693 /// one* of the sets `self` and `other`. 694 /// 695 /// This is equivalent to using the `^` operator (e.g. 696 /// [`ops::BitXor`]), as in `flags ^ other`. 697 /// 698 /// [sym-diff]: https://en.wikipedia.org/wiki/Symmetric_difference 699 /// [`ops::BitXor`]: https://doc.rust-lang.org/std/ops/trait.BitXor.html 700 #[inline] 701 #[must_use] 702 pub const fn symmetric_difference(self, other: Self) -> Self { 703 Self { bits: self.bits ^ other.bits } 704 } 705 706 /// Returns the complement of this set of flags. 707 /// 708 /// Specifically, the returned set contains all the flags which are 709 /// not set in `self`, but which are allowed for this type. 710 /// 711 /// Alternatively, it can be thought of as the set difference 712 /// between [`Self::all()`] and `self` (e.g. `Self::all() - self`) 713 /// 714 /// This is equivalent to using the `!` operator (e.g. 715 /// [`ops::Not`]), as in `!flags`. 716 /// 717 /// [`Self::all()`]: Self::all 718 /// [`ops::Not`]: https://doc.rust-lang.org/std/ops/trait.Not.html 719 #[inline] 720 #[must_use] 721 pub const fn complement(self) -> Self { 722 Self::from_bits_truncate(!self.bits) 723 } 724 725 } 726 727 impl $crate::_core::ops::BitOr for $BitFlags { 728 type Output = Self; 729 730 /// Returns the union of the two sets of flags. 731 #[inline] 732 fn bitor(self, other: $BitFlags) -> Self { 733 Self { bits: self.bits | other.bits } 734 } 735 } 736 737 impl $crate::_core::ops::BitOrAssign for $BitFlags { 738 /// Adds the set of flags. 739 #[inline] 740 fn bitor_assign(&mut self, other: Self) { 741 self.bits |= other.bits; 742 } 743 } 744 745 impl $crate::_core::ops::BitXor for $BitFlags { 746 type Output = Self; 747 748 /// Returns the left flags, but with all the right flags toggled. 749 #[inline] 750 fn bitxor(self, other: Self) -> Self { 751 Self { bits: self.bits ^ other.bits } 752 } 753 } 754 755 impl $crate::_core::ops::BitXorAssign for $BitFlags { 756 /// Toggles the set of flags. 757 #[inline] 758 fn bitxor_assign(&mut self, other: Self) { 759 self.bits ^= other.bits; 760 } 761 } 762 763 impl $crate::_core::ops::BitAnd for $BitFlags { 764 type Output = Self; 765 766 /// Returns the intersection between the two sets of flags. 767 #[inline] 768 fn bitand(self, other: Self) -> Self { 769 Self { bits: self.bits & other.bits } 770 } 771 } 772 773 impl $crate::_core::ops::BitAndAssign for $BitFlags { 774 /// Disables all flags disabled in the set. 775 #[inline] 776 fn bitand_assign(&mut self, other: Self) { 777 self.bits &= other.bits; 778 } 779 } 780 781 impl $crate::_core::ops::Sub for $BitFlags { 782 type Output = Self; 783 784 /// Returns the set difference of the two sets of flags. 785 #[inline] 786 fn sub(self, other: Self) -> Self { 787 Self { bits: self.bits & !other.bits } 788 } 789 } 790 791 impl $crate::_core::ops::SubAssign for $BitFlags { 792 /// Disables all flags enabled in the set. 793 #[inline] 794 fn sub_assign(&mut self, other: Self) { 795 self.bits &= !other.bits; 796 } 797 } 798 799 impl $crate::_core::ops::Not for $BitFlags { 800 type Output = Self; 801 802 /// Returns the complement of this set of flags. 803 #[inline] 804 fn not(self) -> Self { 805 Self { bits: !self.bits } & Self::all() 806 } 807 } 808 809 impl $crate::_core::iter::Extend<$BitFlags> for $BitFlags { 810 fn extend<T: $crate::_core::iter::IntoIterator<Item=Self>>(&mut self, iterator: T) { 811 for item in iterator { 812 self.insert(item) 813 } 814 } 815 } 816 817 impl $crate::_core::iter::FromIterator<$BitFlags> for $BitFlags { 818 fn from_iter<T: $crate::_core::iter::IntoIterator<Item=Self>>(iterator: T) -> Self { 819 let mut result = Self::empty(); 820 result.extend(iterator); 821 result 822 } 823 } 824 }; 825 826 // Every attribute that the user writes on a const is applied to the 827 // corresponding const that we generate, but within the implementation of 828 // Debug and all() we want to ignore everything but #[cfg] attributes. In 829 // particular, including a #[deprecated] attribute on those items would fail 830 // to compile. 831 // https://github.com/bitflags/bitflags/issues/109 832 // 833 // Input: 834 // 835 // ? #[cfg(feature = "advanced")] 836 // ? #[deprecated(note = "Use something else.")] 837 // ? #[doc = r"High quality documentation."] 838 // fn f() -> i32 { /* ... */ } 839 // 840 // Output: 841 // 842 // #[cfg(feature = "advanced")] 843 // fn f() -> i32 { /* ... */ } 844 ( 845 $(#[$filtered:meta])* 846 ? #[cfg $($cfgargs:tt)*] 847 $(? #[$rest:ident $($restargs:tt)*])* 848 fn $($item:tt)* 849 ) => { 850 __impl_bitflags! { 851 $(#[$filtered])* 852 #[cfg $($cfgargs)*] 853 $(? #[$rest $($restargs)*])* 854 fn $($item)* 855 } 856 }; 857 ( 858 $(#[$filtered:meta])* 859 // $next != `cfg` 860 ? #[$next:ident $($nextargs:tt)*] 861 $(? #[$rest:ident $($restargs:tt)*])* 862 fn $($item:tt)* 863 ) => { 864 __impl_bitflags! { 865 $(#[$filtered])* 866 // $next filtered out 867 $(? #[$rest $($restargs)*])* 868 fn $($item)* 869 } 870 }; 871 ( 872 $(#[$filtered:meta])* 873 fn $($item:tt)* 874 ) => { 875 $(#[$filtered])* 876 fn $($item)* 877 }; 878 879 // Every attribute that the user writes on a const is applied to the 880 // corresponding const that we generate, but within the implementation of 881 // Debug and all() we want to ignore everything but #[cfg] attributes. In 882 // particular, including a #[deprecated] attribute on those items would fail 883 // to compile. 884 // https://github.com/bitflags/bitflags/issues/109 885 // 886 // const version 887 // 888 // Input: 889 // 890 // ? #[cfg(feature = "advanced")] 891 // ? #[deprecated(note = "Use something else.")] 892 // ? #[doc = r"High quality documentation."] 893 // const f: i32 { /* ... */ } 894 // 895 // Output: 896 // 897 // #[cfg(feature = "advanced")] 898 // const f: i32 { /* ... */ } 899 ( 900 $(#[$filtered:meta])* 901 ? #[cfg $($cfgargs:tt)*] 902 $(? #[$rest:ident $($restargs:tt)*])* 903 const $($item:tt)* 904 ) => { 905 __impl_bitflags! { 906 $(#[$filtered])* 907 #[cfg $($cfgargs)*] 908 $(? #[$rest $($restargs)*])* 909 const $($item)* 910 } 911 }; 912 ( 913 $(#[$filtered:meta])* 914 // $next != `cfg` 915 ? #[$next:ident $($nextargs:tt)*] 916 $(? #[$rest:ident $($restargs:tt)*])* 917 const $($item:tt)* 918 ) => { 919 __impl_bitflags! { 920 $(#[$filtered])* 921 // $next filtered out 922 $(? #[$rest $($restargs)*])* 923 const $($item)* 924 } 925 }; 926 ( 927 $(#[$filtered:meta])* 928 const $($item:tt)* 929 ) => { 930 $(#[$filtered])* 931 const $($item)* 932 }; 933 } 934 935 #[cfg(feature = "example_generated")] 936 pub mod example_generated; 937 938 #[cfg(test)] 939 mod tests { 940 use std::collections::hash_map::DefaultHasher; 941 use std::hash::{Hash, Hasher}; 942 943 bitflags! { 944 #[doc = "> The first principle is that you must not fool yourself — and"] 945 #[doc = "> you are the easiest person to fool."] 946 #[doc = "> "] 947 #[doc = "> - Richard Feynman"] 948 #[derive(Default)] 949 struct Flags: u32 { 950 const A = 0b00000001; 951 #[doc = "<pcwalton> macros are way better at generating code than trans is"] 952 const B = 0b00000010; 953 const C = 0b00000100; 954 #[doc = "* cmr bed"] 955 #[doc = "* strcat table"] 956 #[doc = "<strcat> wait what?"] 957 const ABC = Self::A.bits | Self::B.bits | Self::C.bits; 958 } 959 960 struct _CfgFlags: u32 { 961 #[cfg(unix)] 962 const _CFG_A = 0b01; 963 #[cfg(windows)] 964 const _CFG_B = 0b01; 965 #[cfg(unix)] 966 const _CFG_C = Self::_CFG_A.bits | 0b10; 967 } 968 969 struct AnotherSetOfFlags: i8 { 970 const ANOTHER_FLAG = -1_i8; 971 } 972 973 struct LongFlags: u32 { 974 const LONG_A = 0b1111111111111111; 975 } 976 } 977 978 bitflags! { 979 struct EmptyFlags: u32 { 980 } 981 } 982 983 #[test] test_bits()984 fn test_bits() { 985 assert_eq!(Flags::empty().bits(), 0b00000000); 986 assert_eq!(Flags::A.bits(), 0b00000001); 987 assert_eq!(Flags::ABC.bits(), 0b00000111); 988 989 assert_eq!(AnotherSetOfFlags::empty().bits(), 0b00); 990 assert_eq!(AnotherSetOfFlags::ANOTHER_FLAG.bits(), !0_i8); 991 992 assert_eq!(EmptyFlags::empty().bits(), 0b00000000); 993 } 994 995 #[test] test_from_bits()996 fn test_from_bits() { 997 assert_eq!(Flags::from_bits(0), Some(Flags::empty())); 998 assert_eq!(Flags::from_bits(0b1), Some(Flags::A)); 999 assert_eq!(Flags::from_bits(0b10), Some(Flags::B)); 1000 assert_eq!(Flags::from_bits(0b11), Some(Flags::A | Flags::B)); 1001 assert_eq!(Flags::from_bits(0b1000), None); 1002 1003 assert_eq!( 1004 AnotherSetOfFlags::from_bits(!0_i8), 1005 Some(AnotherSetOfFlags::ANOTHER_FLAG) 1006 ); 1007 1008 assert_eq!(EmptyFlags::from_bits(0), Some(EmptyFlags::empty())); 1009 assert_eq!(EmptyFlags::from_bits(0b1), None); 1010 } 1011 1012 #[test] test_from_bits_truncate()1013 fn test_from_bits_truncate() { 1014 assert_eq!(Flags::from_bits_truncate(0), Flags::empty()); 1015 assert_eq!(Flags::from_bits_truncate(0b1), Flags::A); 1016 assert_eq!(Flags::from_bits_truncate(0b10), Flags::B); 1017 assert_eq!(Flags::from_bits_truncate(0b11), (Flags::A | Flags::B)); 1018 assert_eq!(Flags::from_bits_truncate(0b1000), Flags::empty()); 1019 assert_eq!(Flags::from_bits_truncate(0b1001), Flags::A); 1020 1021 assert_eq!( 1022 AnotherSetOfFlags::from_bits_truncate(0_i8), 1023 AnotherSetOfFlags::empty() 1024 ); 1025 1026 assert_eq!(EmptyFlags::from_bits_truncate(0), EmptyFlags::empty()); 1027 assert_eq!(EmptyFlags::from_bits_truncate(0b1), EmptyFlags::empty()); 1028 } 1029 1030 #[test] test_from_bits_unchecked()1031 fn test_from_bits_unchecked() { 1032 let extra = unsafe { Flags::from_bits_unchecked(0b1000) }; 1033 assert_eq!(unsafe { Flags::from_bits_unchecked(0) }, Flags::empty()); 1034 assert_eq!(unsafe { Flags::from_bits_unchecked(0b1) }, Flags::A); 1035 assert_eq!(unsafe { Flags::from_bits_unchecked(0b10) }, Flags::B); 1036 1037 assert_eq!( 1038 unsafe { Flags::from_bits_unchecked(0b11) }, 1039 (Flags::A | Flags::B) 1040 ); 1041 assert_eq!( 1042 unsafe { Flags::from_bits_unchecked(0b1000) }, 1043 (extra | Flags::empty()) 1044 ); 1045 assert_eq!( 1046 unsafe { Flags::from_bits_unchecked(0b1001) }, 1047 (extra | Flags::A) 1048 ); 1049 1050 let extra = unsafe { EmptyFlags::from_bits_unchecked(0b1000) }; 1051 assert_eq!( 1052 unsafe { EmptyFlags::from_bits_unchecked(0b1000) }, 1053 (extra | EmptyFlags::empty()) 1054 ); 1055 } 1056 1057 #[test] test_is_empty()1058 fn test_is_empty() { 1059 assert!(Flags::empty().is_empty()); 1060 assert!(!Flags::A.is_empty()); 1061 assert!(!Flags::ABC.is_empty()); 1062 1063 assert!(!AnotherSetOfFlags::ANOTHER_FLAG.is_empty()); 1064 1065 assert!(EmptyFlags::empty().is_empty()); 1066 assert!(EmptyFlags::all().is_empty()); 1067 } 1068 1069 #[test] test_is_all()1070 fn test_is_all() { 1071 assert!(Flags::all().is_all()); 1072 assert!(!Flags::A.is_all()); 1073 assert!(Flags::ABC.is_all()); 1074 1075 let extra = unsafe { Flags::from_bits_unchecked(0b1000) }; 1076 assert!(!extra.is_all()); 1077 assert!(!(Flags::A | extra).is_all()); 1078 assert!((Flags::ABC | extra).is_all()); 1079 1080 assert!(AnotherSetOfFlags::ANOTHER_FLAG.is_all()); 1081 1082 assert!(EmptyFlags::all().is_all()); 1083 assert!(EmptyFlags::empty().is_all()); 1084 } 1085 1086 #[test] test_two_empties_do_not_intersect()1087 fn test_two_empties_do_not_intersect() { 1088 let e1 = Flags::empty(); 1089 let e2 = Flags::empty(); 1090 assert!(!e1.intersects(e2)); 1091 1092 assert!(AnotherSetOfFlags::ANOTHER_FLAG.intersects(AnotherSetOfFlags::ANOTHER_FLAG)); 1093 } 1094 1095 #[test] test_empty_does_not_intersect_with_full()1096 fn test_empty_does_not_intersect_with_full() { 1097 let e1 = Flags::empty(); 1098 let e2 = Flags::ABC; 1099 assert!(!e1.intersects(e2)); 1100 } 1101 1102 #[test] test_disjoint_intersects()1103 fn test_disjoint_intersects() { 1104 let e1 = Flags::A; 1105 let e2 = Flags::B; 1106 assert!(!e1.intersects(e2)); 1107 } 1108 1109 #[test] test_overlapping_intersects()1110 fn test_overlapping_intersects() { 1111 let e1 = Flags::A; 1112 let e2 = Flags::A | Flags::B; 1113 assert!(e1.intersects(e2)); 1114 } 1115 1116 #[test] test_contains()1117 fn test_contains() { 1118 let e1 = Flags::A; 1119 let e2 = Flags::A | Flags::B; 1120 assert!(!e1.contains(e2)); 1121 assert!(e2.contains(e1)); 1122 assert!(Flags::ABC.contains(e2)); 1123 1124 assert!(AnotherSetOfFlags::ANOTHER_FLAG.contains(AnotherSetOfFlags::ANOTHER_FLAG)); 1125 1126 assert!(EmptyFlags::empty().contains(EmptyFlags::empty())); 1127 } 1128 1129 #[test] test_insert()1130 fn test_insert() { 1131 let mut e1 = Flags::A; 1132 let e2 = Flags::A | Flags::B; 1133 e1.insert(e2); 1134 assert_eq!(e1, e2); 1135 1136 let mut e3 = AnotherSetOfFlags::empty(); 1137 e3.insert(AnotherSetOfFlags::ANOTHER_FLAG); 1138 assert_eq!(e3, AnotherSetOfFlags::ANOTHER_FLAG); 1139 } 1140 1141 #[test] test_remove()1142 fn test_remove() { 1143 let mut e1 = Flags::A | Flags::B; 1144 let e2 = Flags::A | Flags::C; 1145 e1.remove(e2); 1146 assert_eq!(e1, Flags::B); 1147 1148 let mut e3 = AnotherSetOfFlags::ANOTHER_FLAG; 1149 e3.remove(AnotherSetOfFlags::ANOTHER_FLAG); 1150 assert_eq!(e3, AnotherSetOfFlags::empty()); 1151 } 1152 1153 #[test] test_operators()1154 fn test_operators() { 1155 let e1 = Flags::A | Flags::C; 1156 let e2 = Flags::B | Flags::C; 1157 assert_eq!((e1 | e2), Flags::ABC); // union 1158 assert_eq!((e1 & e2), Flags::C); // intersection 1159 assert_eq!((e1 - e2), Flags::A); // set difference 1160 assert_eq!(!e2, Flags::A); // set complement 1161 assert_eq!(e1 ^ e2, Flags::A | Flags::B); // toggle 1162 let mut e3 = e1; 1163 e3.toggle(e2); 1164 assert_eq!(e3, Flags::A | Flags::B); 1165 1166 let mut m4 = AnotherSetOfFlags::empty(); 1167 m4.toggle(AnotherSetOfFlags::empty()); 1168 assert_eq!(m4, AnotherSetOfFlags::empty()); 1169 } 1170 1171 #[test] test_operators_unchecked()1172 fn test_operators_unchecked() { 1173 let extra = unsafe { Flags::from_bits_unchecked(0b1000) }; 1174 let e1 = Flags::A | Flags::C | extra; 1175 let e2 = Flags::B | Flags::C; 1176 assert_eq!((e1 | e2), (Flags::ABC | extra)); // union 1177 assert_eq!((e1 & e2), Flags::C); // intersection 1178 assert_eq!((e1 - e2), (Flags::A | extra)); // set difference 1179 assert_eq!(!e2, Flags::A); // set complement 1180 assert_eq!(!e1, Flags::B); // set complement 1181 assert_eq!(e1 ^ e2, Flags::A | Flags::B | extra); // toggle 1182 let mut e3 = e1; 1183 e3.toggle(e2); 1184 assert_eq!(e3, Flags::A | Flags::B | extra); 1185 } 1186 1187 #[test] test_set_ops_basic()1188 fn test_set_ops_basic() { 1189 let ab = Flags::A.union(Flags::B); 1190 let ac = Flags::A.union(Flags::C); 1191 let bc = Flags::B.union(Flags::C); 1192 assert_eq!(ab.bits, 0b011); 1193 assert_eq!(bc.bits, 0b110); 1194 assert_eq!(ac.bits, 0b101); 1195 1196 assert_eq!(ab, Flags::B.union(Flags::A)); 1197 assert_eq!(ac, Flags::C.union(Flags::A)); 1198 assert_eq!(bc, Flags::C.union(Flags::B)); 1199 1200 assert_eq!(ac, Flags::A | Flags::C); 1201 assert_eq!(bc, Flags::B | Flags::C); 1202 assert_eq!(ab.union(bc), Flags::ABC); 1203 1204 assert_eq!(ac, Flags::A | Flags::C); 1205 assert_eq!(bc, Flags::B | Flags::C); 1206 1207 assert_eq!(ac.union(bc), ac | bc); 1208 assert_eq!(ac.union(bc), Flags::ABC); 1209 assert_eq!(bc.union(ac), Flags::ABC); 1210 1211 assert_eq!(ac.intersection(bc), ac & bc); 1212 assert_eq!(ac.intersection(bc), Flags::C); 1213 assert_eq!(bc.intersection(ac), Flags::C); 1214 1215 assert_eq!(ac.difference(bc), ac - bc); 1216 assert_eq!(bc.difference(ac), bc - ac); 1217 assert_eq!(ac.difference(bc), Flags::A); 1218 assert_eq!(bc.difference(ac), Flags::B); 1219 1220 assert_eq!(bc.complement(), !bc); 1221 assert_eq!(bc.complement(), Flags::A); 1222 assert_eq!(ac.symmetric_difference(bc), Flags::A.union(Flags::B)); 1223 assert_eq!(bc.symmetric_difference(ac), Flags::A.union(Flags::B)); 1224 } 1225 1226 #[test] test_set_ops_const()1227 fn test_set_ops_const() { 1228 // These just test that these compile and don't cause use-site panics 1229 // (would be possible if we had some sort of UB) 1230 const INTERSECT: Flags = Flags::all().intersection(Flags::C); 1231 const UNION: Flags = Flags::A.union(Flags::C); 1232 const DIFFERENCE: Flags = Flags::all().difference(Flags::A); 1233 const COMPLEMENT: Flags = Flags::C.complement(); 1234 const SYM_DIFFERENCE: Flags = UNION.symmetric_difference(DIFFERENCE); 1235 assert_eq!(INTERSECT, Flags::C); 1236 assert_eq!(UNION, Flags::A | Flags::C); 1237 assert_eq!(DIFFERENCE, Flags::all() - Flags::A); 1238 assert_eq!(COMPLEMENT, !Flags::C); 1239 assert_eq!(SYM_DIFFERENCE, (Flags::A | Flags::C) ^ (Flags::all() - Flags::A)); 1240 } 1241 1242 #[test] test_set_ops_unchecked()1243 fn test_set_ops_unchecked() { 1244 let extra = unsafe { Flags::from_bits_unchecked(0b1000) }; 1245 let e1 = Flags::A.union(Flags::C).union(extra); 1246 let e2 = Flags::B.union(Flags::C); 1247 assert_eq!(e1.bits, 0b1101); 1248 assert_eq!(e1.union(e2), (Flags::ABC | extra)); 1249 assert_eq!(e1.intersection(e2), Flags::C); 1250 assert_eq!(e1.difference(e2), Flags::A | extra); 1251 assert_eq!(e2.difference(e1), Flags::B); 1252 assert_eq!(e2.complement(), Flags::A); 1253 assert_eq!(e1.complement(), Flags::B); 1254 assert_eq!(e1.symmetric_difference(e2), Flags::A | Flags::B | extra); // toggle 1255 } 1256 1257 #[test] test_set_ops_exhaustive()1258 fn test_set_ops_exhaustive() { 1259 // Define a flag that contains gaps to help exercise edge-cases, 1260 // especially around "unknown" flags (e.g. ones outside of `all()` 1261 // `from_bits_unchecked`). 1262 // - when lhs and rhs both have different sets of unknown flags. 1263 // - unknown flags at both ends, and in the middle 1264 // - cases with "gaps". 1265 bitflags! { 1266 struct Test: u16 { 1267 // Intentionally no `A` 1268 const B = 0b000000010; 1269 // Intentionally no `C` 1270 const D = 0b000001000; 1271 const E = 0b000010000; 1272 const F = 0b000100000; 1273 const G = 0b001000000; 1274 // Intentionally no `H` 1275 const I = 0b100000000; 1276 } 1277 } 1278 let iter_test_flags = 1279 || (0..=0b111_1111_1111).map(|bits| unsafe { Test::from_bits_unchecked(bits) }); 1280 1281 for a in iter_test_flags() { 1282 assert_eq!( 1283 a.complement(), 1284 Test::from_bits_truncate(!a.bits), 1285 "wrong result: !({:?})", 1286 a, 1287 ); 1288 assert_eq!(a.complement(), !a, "named != op: !({:?})", a); 1289 for b in iter_test_flags() { 1290 // Check that the named operations produce the expected bitwise 1291 // values. 1292 assert_eq!( 1293 a.union(b).bits, 1294 a.bits | b.bits, 1295 "wrong result: `{:?}` | `{:?}`", 1296 a, 1297 b, 1298 ); 1299 assert_eq!( 1300 a.intersection(b).bits, 1301 a.bits & b.bits, 1302 "wrong result: `{:?}` & `{:?}`", 1303 a, 1304 b, 1305 ); 1306 assert_eq!( 1307 a.symmetric_difference(b).bits, 1308 a.bits ^ b.bits, 1309 "wrong result: `{:?}` ^ `{:?}`", 1310 a, 1311 b, 1312 ); 1313 assert_eq!( 1314 a.difference(b).bits, 1315 a.bits & !b.bits, 1316 "wrong result: `{:?}` - `{:?}`", 1317 a, 1318 b, 1319 ); 1320 // Note: Difference is checked as both `a - b` and `b - a` 1321 assert_eq!( 1322 b.difference(a).bits, 1323 b.bits & !a.bits, 1324 "wrong result: `{:?}` - `{:?}`", 1325 b, 1326 a, 1327 ); 1328 // Check that the named set operations are equivalent to the 1329 // bitwise equivalents 1330 assert_eq!(a.union(b), a | b, "named != op: `{:?}` | `{:?}`", a, b,); 1331 assert_eq!( 1332 a.intersection(b), 1333 a & b, 1334 "named != op: `{:?}` & `{:?}`", 1335 a, 1336 b, 1337 ); 1338 assert_eq!( 1339 a.symmetric_difference(b), 1340 a ^ b, 1341 "named != op: `{:?}` ^ `{:?}`", 1342 a, 1343 b, 1344 ); 1345 assert_eq!(a.difference(b), a - b, "named != op: `{:?}` - `{:?}`", a, b,); 1346 // Note: Difference is checked as both `a - b` and `b - a` 1347 assert_eq!(b.difference(a), b - a, "named != op: `{:?}` - `{:?}`", b, a,); 1348 // Verify that the operations which should be symmetric are 1349 // actually symmetric. 1350 assert_eq!(a.union(b), b.union(a), "asymmetry: `{:?}` | `{:?}`", a, b,); 1351 assert_eq!( 1352 a.intersection(b), 1353 b.intersection(a), 1354 "asymmetry: `{:?}` & `{:?}`", 1355 a, 1356 b, 1357 ); 1358 assert_eq!( 1359 a.symmetric_difference(b), 1360 b.symmetric_difference(a), 1361 "asymmetry: `{:?}` ^ `{:?}`", 1362 a, 1363 b, 1364 ); 1365 } 1366 } 1367 } 1368 1369 #[test] test_set()1370 fn test_set() { 1371 let mut e1 = Flags::A | Flags::C; 1372 e1.set(Flags::B, true); 1373 e1.set(Flags::C, false); 1374 1375 assert_eq!(e1, Flags::A | Flags::B); 1376 } 1377 1378 #[test] test_assignment_operators()1379 fn test_assignment_operators() { 1380 let mut m1 = Flags::empty(); 1381 let e1 = Flags::A | Flags::C; 1382 // union 1383 m1 |= Flags::A; 1384 assert_eq!(m1, Flags::A); 1385 // intersection 1386 m1 &= e1; 1387 assert_eq!(m1, Flags::A); 1388 // set difference 1389 m1 -= m1; 1390 assert_eq!(m1, Flags::empty()); 1391 // toggle 1392 m1 ^= e1; 1393 assert_eq!(m1, e1); 1394 } 1395 1396 #[test] test_const_fn()1397 fn test_const_fn() { 1398 const _M1: Flags = Flags::empty(); 1399 1400 const M2: Flags = Flags::A; 1401 assert_eq!(M2, Flags::A); 1402 1403 const M3: Flags = Flags::C; 1404 assert_eq!(M3, Flags::C); 1405 } 1406 1407 #[test] test_extend()1408 fn test_extend() { 1409 let mut flags; 1410 1411 flags = Flags::empty(); 1412 flags.extend([].iter().cloned()); 1413 assert_eq!(flags, Flags::empty()); 1414 1415 flags = Flags::empty(); 1416 flags.extend([Flags::A, Flags::B].iter().cloned()); 1417 assert_eq!(flags, Flags::A | Flags::B); 1418 1419 flags = Flags::A; 1420 flags.extend([Flags::A, Flags::B].iter().cloned()); 1421 assert_eq!(flags, Flags::A | Flags::B); 1422 1423 flags = Flags::B; 1424 flags.extend([Flags::A, Flags::ABC].iter().cloned()); 1425 assert_eq!(flags, Flags::ABC); 1426 } 1427 1428 #[test] test_from_iterator()1429 fn test_from_iterator() { 1430 assert_eq!([].iter().cloned().collect::<Flags>(), Flags::empty()); 1431 assert_eq!( 1432 [Flags::A, Flags::B].iter().cloned().collect::<Flags>(), 1433 Flags::A | Flags::B 1434 ); 1435 assert_eq!( 1436 [Flags::A, Flags::ABC].iter().cloned().collect::<Flags>(), 1437 Flags::ABC 1438 ); 1439 } 1440 1441 #[test] test_lt()1442 fn test_lt() { 1443 let mut a = Flags::empty(); 1444 let mut b = Flags::empty(); 1445 1446 assert!(!(a < b) && !(b < a)); 1447 b = Flags::B; 1448 assert!(a < b); 1449 a = Flags::C; 1450 assert!(!(a < b) && b < a); 1451 b = Flags::C | Flags::B; 1452 assert!(a < b); 1453 } 1454 1455 #[test] test_ord()1456 fn test_ord() { 1457 let mut a = Flags::empty(); 1458 let mut b = Flags::empty(); 1459 1460 assert!(a <= b && a >= b); 1461 a = Flags::A; 1462 assert!(a > b && a >= b); 1463 assert!(b < a && b <= a); 1464 b = Flags::B; 1465 assert!(b > a && b >= a); 1466 assert!(a < b && a <= b); 1467 } 1468 hash<T: Hash>(t: &T) -> u641469 fn hash<T: Hash>(t: &T) -> u64 { 1470 let mut s = DefaultHasher::new(); 1471 t.hash(&mut s); 1472 s.finish() 1473 } 1474 1475 #[test] test_hash()1476 fn test_hash() { 1477 let mut x = Flags::empty(); 1478 let mut y = Flags::empty(); 1479 assert_eq!(hash(&x), hash(&y)); 1480 x = Flags::all(); 1481 y = Flags::ABC; 1482 assert_eq!(hash(&x), hash(&y)); 1483 } 1484 1485 #[test] test_default()1486 fn test_default() { 1487 assert_eq!(Flags::empty(), Flags::default()); 1488 } 1489 1490 #[test] test_debug()1491 fn test_debug() { 1492 assert_eq!(format!("{:?}", Flags::A | Flags::B), "A | B"); 1493 assert_eq!(format!("{:?}", Flags::empty()), "(empty)"); 1494 assert_eq!(format!("{:?}", Flags::ABC), "A | B | C | ABC"); 1495 let extra = unsafe { Flags::from_bits_unchecked(0xb8) }; 1496 assert_eq!(format!("{:?}", extra), "0xb8"); 1497 assert_eq!(format!("{:?}", Flags::A | extra), "A | 0xb8"); 1498 1499 assert_eq!( 1500 format!("{:?}", Flags::ABC | extra), 1501 "A | B | C | ABC | 0xb8" 1502 ); 1503 1504 assert_eq!(format!("{:?}", EmptyFlags::empty()), "(empty)"); 1505 } 1506 1507 #[test] test_binary()1508 fn test_binary() { 1509 assert_eq!(format!("{:b}", Flags::ABC), "111"); 1510 assert_eq!(format!("{:#b}", Flags::ABC), "0b111"); 1511 let extra = unsafe { Flags::from_bits_unchecked(0b1010000) }; 1512 assert_eq!(format!("{:b}", Flags::ABC | extra), "1010111"); 1513 assert_eq!(format!("{:#b}", Flags::ABC | extra), "0b1010111"); 1514 } 1515 1516 #[test] test_octal()1517 fn test_octal() { 1518 assert_eq!(format!("{:o}", LongFlags::LONG_A), "177777"); 1519 assert_eq!(format!("{:#o}", LongFlags::LONG_A), "0o177777"); 1520 let extra = unsafe { LongFlags::from_bits_unchecked(0o5000000) }; 1521 assert_eq!(format!("{:o}", LongFlags::LONG_A | extra), "5177777"); 1522 assert_eq!(format!("{:#o}", LongFlags::LONG_A | extra), "0o5177777"); 1523 } 1524 1525 #[test] test_lowerhex()1526 fn test_lowerhex() { 1527 assert_eq!(format!("{:x}", LongFlags::LONG_A), "ffff"); 1528 assert_eq!(format!("{:#x}", LongFlags::LONG_A), "0xffff"); 1529 let extra = unsafe { LongFlags::from_bits_unchecked(0xe00000) }; 1530 assert_eq!(format!("{:x}", LongFlags::LONG_A | extra), "e0ffff"); 1531 assert_eq!(format!("{:#x}", LongFlags::LONG_A | extra), "0xe0ffff"); 1532 } 1533 1534 #[test] test_upperhex()1535 fn test_upperhex() { 1536 assert_eq!(format!("{:X}", LongFlags::LONG_A), "FFFF"); 1537 assert_eq!(format!("{:#X}", LongFlags::LONG_A), "0xFFFF"); 1538 let extra = unsafe { LongFlags::from_bits_unchecked(0xe00000) }; 1539 assert_eq!(format!("{:X}", LongFlags::LONG_A | extra), "E0FFFF"); 1540 assert_eq!(format!("{:#X}", LongFlags::LONG_A | extra), "0xE0FFFF"); 1541 } 1542 1543 mod submodule { 1544 bitflags! { 1545 pub struct PublicFlags: i8 { 1546 const X = 0; 1547 } 1548 1549 struct PrivateFlags: i8 { 1550 const Y = 0; 1551 } 1552 } 1553 1554 #[test] test_private()1555 fn test_private() { 1556 let _ = PrivateFlags::Y; 1557 } 1558 } 1559 1560 #[test] test_public()1561 fn test_public() { 1562 let _ = submodule::PublicFlags::X; 1563 } 1564 1565 mod t1 { 1566 mod foo { 1567 pub type Bar = i32; 1568 } 1569 1570 bitflags! { 1571 /// baz 1572 struct Flags: foo::Bar { 1573 const A = 0b00000001; 1574 #[cfg(foo)] 1575 const B = 0b00000010; 1576 #[cfg(foo)] 1577 const C = 0b00000010; 1578 } 1579 } 1580 } 1581 1582 #[test] test_in_function()1583 fn test_in_function() { 1584 bitflags! { 1585 struct Flags: u8 { 1586 const A = 1; 1587 #[cfg(any())] // false 1588 const B = 2; 1589 } 1590 } 1591 assert_eq!(Flags::all(), Flags::A); 1592 assert_eq!(format!("{:?}", Flags::A), "A"); 1593 } 1594 1595 #[test] test_deprecated()1596 fn test_deprecated() { 1597 bitflags! { 1598 pub struct TestFlags: u32 { 1599 #[deprecated(note = "Use something else.")] 1600 const ONE = 1; 1601 } 1602 } 1603 } 1604 1605 #[test] test_pub_crate()1606 fn test_pub_crate() { 1607 mod module { 1608 bitflags! { 1609 pub (crate) struct Test: u8 { 1610 const FOO = 1; 1611 } 1612 } 1613 } 1614 1615 assert_eq!(module::Test::FOO.bits(), 1); 1616 } 1617 1618 #[test] test_pub_in_module()1619 fn test_pub_in_module() { 1620 mod module { 1621 mod submodule { 1622 bitflags! { 1623 // `pub (in super)` means only the module `module` will 1624 // be able to access this. 1625 pub (in super) struct Test: u8 { 1626 const FOO = 1; 1627 } 1628 } 1629 } 1630 1631 mod test { 1632 // Note: due to `pub (in super)`, 1633 // this cannot be accessed directly by the testing code. 1634 pub(super) fn value() -> u8 { 1635 super::submodule::Test::FOO.bits() 1636 } 1637 } 1638 1639 pub fn value() -> u8 { 1640 test::value() 1641 } 1642 } 1643 1644 assert_eq!(module::value(), 1) 1645 } 1646 1647 #[test] test_zero_value_flags()1648 fn test_zero_value_flags() { 1649 bitflags! { 1650 struct Flags: u32 { 1651 const NONE = 0b0; 1652 const SOME = 0b1; 1653 } 1654 } 1655 1656 assert!(Flags::empty().contains(Flags::NONE)); 1657 assert!(Flags::SOME.contains(Flags::NONE)); 1658 assert!(Flags::NONE.is_empty()); 1659 1660 assert_eq!(format!("{:?}", Flags::empty()), "NONE"); 1661 assert_eq!(format!("{:?}", Flags::SOME), "SOME"); 1662 } 1663 1664 #[test] test_empty_bitflags()1665 fn test_empty_bitflags() { 1666 bitflags! {} 1667 } 1668 1669 #[test] test_u128_bitflags()1670 fn test_u128_bitflags() { 1671 bitflags! { 1672 struct Flags128: u128 { 1673 const A = 0x0000_0000_0000_0000_0000_0000_0000_0001; 1674 const B = 0x0000_0000_0000_1000_0000_0000_0000_0000; 1675 const C = 0x8000_0000_0000_0000_0000_0000_0000_0000; 1676 const ABC = Self::A.bits | Self::B.bits | Self::C.bits; 1677 } 1678 } 1679 1680 assert_eq!(Flags128::ABC, Flags128::A | Flags128::B | Flags128::C); 1681 assert_eq!(Flags128::A.bits, 0x0000_0000_0000_0000_0000_0000_0000_0001); 1682 assert_eq!(Flags128::B.bits, 0x0000_0000_0000_1000_0000_0000_0000_0000); 1683 assert_eq!(Flags128::C.bits, 0x8000_0000_0000_0000_0000_0000_0000_0000); 1684 assert_eq!( 1685 Flags128::ABC.bits, 1686 0x8000_0000_0000_1000_0000_0000_0000_0001 1687 ); 1688 assert_eq!(format!("{:?}", Flags128::A), "A"); 1689 assert_eq!(format!("{:?}", Flags128::B), "B"); 1690 assert_eq!(format!("{:?}", Flags128::C), "C"); 1691 assert_eq!(format!("{:?}", Flags128::ABC), "A | B | C | ABC"); 1692 } 1693 1694 #[test] test_serde_bitflags_serialize()1695 fn test_serde_bitflags_serialize() { 1696 let flags = SerdeFlags::A | SerdeFlags::B; 1697 1698 let serialized = serde_json::to_string(&flags).unwrap(); 1699 1700 assert_eq!(serialized, r#"{"bits":3}"#); 1701 } 1702 1703 #[test] test_serde_bitflags_deserialize()1704 fn test_serde_bitflags_deserialize() { 1705 let deserialized: SerdeFlags = serde_json::from_str(r#"{"bits":12}"#).unwrap(); 1706 1707 let expected = SerdeFlags::C | SerdeFlags::D; 1708 1709 assert_eq!(deserialized.bits, expected.bits); 1710 } 1711 1712 #[test] test_serde_bitflags_roundtrip()1713 fn test_serde_bitflags_roundtrip() { 1714 let flags = SerdeFlags::A | SerdeFlags::B; 1715 1716 let deserialized: SerdeFlags = serde_json::from_str(&serde_json::to_string(&flags).unwrap()).unwrap(); 1717 1718 assert_eq!(deserialized.bits, flags.bits); 1719 } 1720 1721 bitflags! { 1722 #[derive(serde::Serialize, serde::Deserialize)] 1723 struct SerdeFlags: u32 { 1724 const A = 1; 1725 const B = 2; 1726 const C = 4; 1727 const D = 8; 1728 } 1729 } 1730 } 1731