bitflags/lib.rs
1// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2// file at the top-level directory of this distribution and at
3// http://rust-lang.org/COPYRIGHT.
4//
5// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8// option. This file may not be copied, modified, or distributed
9// except according to those terms.
10
11//! 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 a `struct` that manages 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//! extern crate bitflags;
22//!
23//! bitflags::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//! extern crate bitflags;
50//!
51//! use std::fmt;
52//!
53//! bitflags::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 struct and its 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 `flags`:
88//!
89//! ```
90//! extern crate bitflags;
91//!
92//! mod example {
93//! bitflags::bitflags! {
94//! pub struct Flags1: u32 {
95//! const A = 0b00000001;
96//! }
97//! }
98//! bitflags::bitflags! {
99//! # pub
100//! struct Flags2: u32 {
101//! const B = 0b00000010;
102//! }
103//! }
104//! }
105//!
106//! fn main() {
107//! let flag1 = example::Flags1::A;
108//! let flag2 = example::Flags2::B; // error: const `B` is private
109//! }
110//! ```
111//!
112//! # Attributes
113//!
114//! Attributes can be attached to the generated `struct` by placing them
115//! before the `flags` keyword.
116//!
117//! # Trait implementations
118//!
119//! The `Copy`, `Clone`, `PartialEq`, `Eq`, and `Hash`
120//! traits automatically derived for the `struct` using the `derive` attribute.
121//! Additional traits can be derived by providing an explicit `derive`
122//! attribute on `flags`.
123//!
124//! The `Extend` and `FromIterator` traits are implemented for the `struct`,
125//! too: `Extend` adds the union of the instances of the `struct` iterated over,
126//! while `FromIterator` calculates the union.
127//!
128//! The `Binary`, `Debug`, `LowerExp`, `Octal` and `UpperExp` trait is also
129//! implemented by displaying the bits value of the internal struct.
130//!
131//! ## Operators
132//!
133//! The following operator traits are implemented for the generated `struct`:
134//!
135//! - `BitOr` and `BitOrAssign`: union
136//! - `BitAnd` and `BitAndAssign`: intersection
137//! - `BitXor` and `BitXorAssign`: toggle
138//! - `Sub` and `SubAssign`: set difference
139//! - `Not`: set complement
140//!
141//! # Methods
142//!
143//! The following methods are defined for the generated `struct`:
144//!
145//! - `empty`: an empty set of flags
146//! - `all`: the set of all flags
147//! - `bits`: the raw value of the flags currently stored
148//! - `from_bits`: convert from underlying bit representation, unless that
149//! representation contains bits that do not correspond to a flag
150//! - `from_bits_truncate`: convert from underlying bit representation, dropping
151//! any bits that do not correspond to flags
152//! - `is_empty`: `true` if no flags are currently stored
153//! - `is_all`: `true` if all flags are currently set
154//! - `intersects`: `true` if there are flags common to both `self` and `other`
155//! - `contains`: `true` all of the flags in `other` are contained within `self`
156//! - `insert`: inserts the specified flags in-place
157//! - `remove`: removes the specified flags in-place
158//! - `toggle`: the specified flags will be inserted if not present, and removed
159//! if they are.
160//! - `set`: inserts or removes the specified flags depending on the passed value
161//!
162//! ## Default
163//!
164//! The `Default` trait is not automatically implemented for the generated struct.
165//!
166//! If your default value is equal to `0` (which is the same value as calling `empty()`
167//! on the generated struct), you can simply derive `Default`:
168//!
169//! ```
170//! extern crate bitflags;
171//!
172//! bitflags::bitflags! {
173//! // Results in default value with bits: 0
174//! #[derive(Default)]
175//! struct Flags: u32 {
176//! const A = 0b00000001;
177//! const B = 0b00000010;
178//! const C = 0b00000100;
179//! }
180//! }
181//!
182//! fn main() {
183//! let derived_default: Flags = Default::default();
184//! assert_eq!(derived_default.bits(), 0);
185//! }
186//! ```
187//!
188//! If your default value is not equal to `0` you need to implement `Default` yourself:
189//!
190//! ```
191//! extern crate bitflags;
192//!
193//! bitflags::bitflags! {
194//! struct Flags: u32 {
195//! const A = 0b00000001;
196//! const B = 0b00000010;
197//! const C = 0b00000100;
198//! }
199//! }
200//!
201//! // explicit `Default` implementation
202//! impl Default for Flags {
203//! fn default() -> Flags {
204//! Flags::A | Flags::C
205//! }
206//! }
207//!
208//! fn main() {
209//! let implemented_default: Flags = Default::default();
210//! assert_eq!(implemented_default, (Flags::A | Flags::C));
211//! }
212//! ```
213
214#![no_std]
215
216#[cfg(test)]
217#[macro_use]
218extern crate std;
219
220// Re-export libcore using an alias so that the macros can work without
221// requiring `extern crate core` downstream.
222#[doc(hidden)]
223pub extern crate core as _core;
224
225/// The macro used to generate the flag structure.
226///
227/// See the [crate level docs](../bitflags/index.html) for complete documentation.
228///
229/// # Example
230///
231/// ```
232/// extern crate bitflags;
233///
234/// bitflags::bitflags! {
235/// struct Flags: u32 {
236/// const A = 0b00000001;
237/// const B = 0b00000010;
238/// const C = 0b00000100;
239/// const ABC = Self::A.bits | Self::B.bits | Self::C.bits;
240/// }
241/// }
242///
243/// fn main() {
244/// let e1 = Flags::A | Flags::C;
245/// let e2 = Flags::B | Flags::C;
246/// assert_eq!((e1 | e2), Flags::ABC); // union
247/// assert_eq!((e1 & e2), Flags::C); // intersection
248/// assert_eq!((e1 - e2), Flags::A); // set difference
249/// assert_eq!(!e2, Flags::A); // set complement
250/// }
251/// ```
252///
253/// The generated `struct`s can also be extended with type and trait
254/// implementations:
255///
256/// ```
257/// extern crate bitflags;
258///
259/// use std::fmt;
260///
261/// bitflags::bitflags! {
262/// struct Flags: u32 {
263/// const A = 0b00000001;
264/// const B = 0b00000010;
265/// }
266/// }
267///
268/// impl Flags {
269/// pub fn clear(&mut self) {
270/// self.bits = 0; // The `bits` field can be accessed from within the
271/// // same module where the `bitflags!` macro was invoked.
272/// }
273/// }
274///
275/// impl fmt::Display for Flags {
276/// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
277/// write!(f, "hi!")
278/// }
279/// }
280///
281/// fn main() {
282/// let mut flags = Flags::A | Flags::B;
283/// flags.clear();
284/// assert!(flags.is_empty());
285/// assert_eq!(format!("{}", flags), "hi!");
286/// assert_eq!(format!("{:?}", Flags::A | Flags::B), "A | B");
287/// assert_eq!(format!("{:?}", Flags::B), "B");
288/// }
289/// ```
290#[macro_export]
291macro_rules! bitflags {
292 (
293 $(#[$outer:meta])*
294 pub struct $BitFlags:ident: $T:ty {
295 $(
296 $(#[$inner:ident $($args:tt)*])*
297 const $Flag:ident = $value:expr;
298 )*
299 }
300 ) => {
301 $crate::__bitflags! {
302 $(#[$outer])*
303 (pub) $BitFlags: $T {
304 $(
305 $(#[$inner $($args)*])*
306 $Flag = $value;
307 )*
308 }
309 }
310 };
311 (
312 $(#[$outer:meta])*
313 struct $BitFlags:ident: $T:ty {
314 $(
315 $(#[$inner:ident $($args:tt)*])*
316 const $Flag:ident = $value:expr;
317 )*
318 }
319 ) => {
320 $crate::__bitflags! {
321 $(#[$outer])*
322 () $BitFlags: $T {
323 $(
324 $(#[$inner $($args)*])*
325 $Flag = $value;
326 )*
327 }
328 }
329 };
330 (
331 $(#[$outer:meta])*
332 pub ($($vis:tt)+) struct $BitFlags:ident: $T:ty {
333 $(
334 $(#[$inner:ident $($args:tt)*])*
335 const $Flag:ident = $value:expr;
336 )*
337 }
338 ) => {
339 $crate::__bitflags! {
340 $(#[$outer])*
341 (pub ($($vis)+)) $BitFlags: $T {
342 $(
343 $(#[$inner $($args)*])*
344 $Flag = $value;
345 )*
346 }
347 }
348 };
349}
350
351#[macro_export]
352#[doc(hidden)]
353macro_rules! __bitflags {
354 (
355 $(#[$outer:meta])*
356 ($($vis:tt)*) $BitFlags:ident: $T:ty {
357 $(
358 $(#[$inner:ident $($args:tt)*])*
359 $Flag:ident = $value:expr;
360 )*
361 }
362 ) => {
363 #[derive(Copy, PartialEq, Eq, Clone, Hash)]
364 $(#[$outer])*
365 $($vis)* struct $BitFlags {
366 bits: $T,
367 }
368
369 $crate::__impl_bitflags! {
370 $BitFlags: $T {
371 $(
372 $(#[$inner $($args)*])*
373 $Flag = $value;
374 )*
375 }
376 }
377 };
378}
379
380#[macro_export]
381#[doc(hidden)]
382macro_rules! __impl_bitflags {
383 (
384 $BitFlags:ident: $T:ty {
385 $(
386 $(#[$attr:ident $($args:tt)*])*
387 $Flag:ident = $value:expr;
388 )*
389 }
390 ) => {
391 impl $crate::_core::cmp::PartialOrd for $BitFlags {
392 fn partial_cmp(&self, other: &Self) -> $crate::_core::option::Option<$crate::_core::cmp::Ordering> {
393 use $crate::_core::cmp::Ordering::*;
394 use $crate::_core::option::Option::*;
395 match (self.contains(*other), other.contains(*self)) {
396 (false, false) => None,
397 (false, true) => Some(Less),
398 (true, false) => Some(Greater),
399 (true, true) => Some(Equal),
400 }
401 }
402 }
403 impl $crate::_core::fmt::Debug for $BitFlags {
404 fn fmt(&self, f: &mut $crate::_core::fmt::Formatter) -> $crate::_core::fmt::Result {
405 // This convoluted approach is to handle #[cfg]-based flag
406 // omission correctly. For example it needs to support:
407 //
408 // #[cfg(unix)] const A: Flag = /* ... */;
409 // #[cfg(windows)] const B: Flag = /* ... */;
410
411 // Unconditionally define a check for every flag, even disabled
412 // ones.
413 #[allow(non_snake_case)]
414 trait __BitFlags {
415 $(
416 #[inline]
417 fn $Flag(&self) -> bool { false }
418 )*
419 }
420
421 // Conditionally override the check for just those flags that
422 // are not #[cfg]ed away.
423 impl __BitFlags for $BitFlags {
424 $(
425 $crate::__impl_bitflags! {
426 #[allow(deprecated)]
427 #[inline]
428 $(? #[$attr $($args)*])*
429 fn $Flag(&self) -> bool {
430 self.bits & Self::$Flag.bits == Self::$Flag.bits
431 }
432 }
433 )*
434 }
435
436 let mut first = true;
437 $(
438 if <$BitFlags as __BitFlags>::$Flag(self) {
439 if !first {
440 f.write_str(" | ")?;
441 }
442 first = false;
443 f.write_str(stringify!($Flag))?;
444 }
445 )*
446 if first {
447 f.write_str("(empty)")?;
448 }
449 Ok(())
450 }
451 }
452 impl $crate::_core::fmt::Binary for $BitFlags {
453 fn fmt(&self, f: &mut $crate::_core::fmt::Formatter) -> $crate::_core::fmt::Result {
454 $crate::_core::fmt::Binary::fmt(&self.bits, f)
455 }
456 }
457 impl $crate::_core::fmt::Octal for $BitFlags {
458 fn fmt(&self, f: &mut $crate::_core::fmt::Formatter) -> $crate::_core::fmt::Result {
459 $crate::_core::fmt::Octal::fmt(&self.bits, f)
460 }
461 }
462 impl $crate::_core::fmt::LowerHex for $BitFlags {
463 fn fmt(&self, f: &mut $crate::_core::fmt::Formatter) -> $crate::_core::fmt::Result {
464 $crate::_core::fmt::LowerHex::fmt(&self.bits, f)
465 }
466 }
467 impl $crate::_core::fmt::UpperHex for $BitFlags {
468 fn fmt(&self, f: &mut $crate::_core::fmt::Formatter) -> $crate::_core::fmt::Result {
469 $crate::_core::fmt::UpperHex::fmt(&self.bits, f)
470 }
471 }
472
473 #[allow(dead_code)]
474 impl $BitFlags {
475 $(
476 $(#[$attr $($args)*])*
477 pub const $Flag: $BitFlags = $BitFlags { bits: $value };
478 )*
479
480 /// Returns an empty set of flags.
481 #[inline]
482 pub const fn empty() -> $BitFlags {
483 $BitFlags { bits: 0 }
484 }
485
486 /// Returns the set containing all flags.
487 #[inline]
488 pub const fn all() -> $BitFlags {
489 // See `Debug::fmt` for why this approach is taken.
490 #[allow(non_snake_case)]
491 trait __BitFlags {
492 $(
493 #[inline]
494 const $Flag: $T = 0;
495 )*
496 }
497 impl __BitFlags for $BitFlags {
498 $(
499 $crate::__impl_bitflags! {
500 #[allow(deprecated)]
501 #[inline]
502 $(? #[$attr $($args)*])*
503 const $Flag: $T = Self::$Flag.bits;
504 }
505 )*
506 }
507 $BitFlags { bits: $(<$BitFlags as __BitFlags>::$Flag|)* 0 }
508 }
509
510 /// Returns the raw value of the flags currently stored.
511 #[inline]
512 pub const fn bits(&self) -> $T {
513 self.bits
514 }
515
516 /// Convert from underlying bit representation, unless that
517 /// representation contains bits that do not correspond to a flag.
518 #[inline]
519 pub fn from_bits(bits: $T) -> $crate::_core::option::Option<$BitFlags> {
520 if (bits & !$BitFlags::all().bits()) == 0 {
521 $crate::_core::option::Option::Some($BitFlags { bits })
522 } else {
523 $crate::_core::option::Option::None
524 }
525 }
526
527 /// Convert from underlying bit representation, dropping any bits
528 /// that do not correspond to flags.
529 #[inline]
530 pub const fn from_bits_truncate(bits: $T) -> $BitFlags {
531 $BitFlags { bits: bits & Self::all().bits }
532 }
533
534 /// Returns `true` if no flags are currently stored.
535 #[inline]
536 pub const fn is_empty(&self) -> bool {
537 0 == self.bits
538 }
539
540 /// Returns `true` if all flags are currently set.
541 #[inline]
542 pub const fn is_all(&self) -> bool {
543 self.bits == Self::all().bits
544 }
545
546 /// Returns `true` if there are flags common to both `self` and `other`.
547 #[inline]
548 pub const fn intersects(&self, other: $BitFlags) -> bool {
549 0 != self.bits & other.bits
550 }
551
552 /// Returns `true` all of the flags in `other` are contained within `self`.
553 #[inline]
554 pub const fn contains(&self, other: $BitFlags) -> bool {
555 self.bits & other.bits == other.bits
556 }
557
558 /// Inserts the specified flags in-place.
559 #[inline]
560 pub fn insert(&mut self, other: $BitFlags) {
561 self.bits |= other.bits;
562 }
563
564 /// Removes the specified flags in-place.
565 #[inline]
566 pub fn remove(&mut self, other: $BitFlags) {
567 self.bits &= !other.bits;
568 }
569
570 /// Toggles the specified flags in-place.
571 #[inline]
572 pub fn toggle(&mut self, other: $BitFlags) {
573 self.bits ^= other.bits;
574 }
575
576 /// Inserts or removes the specified flags depending on the passed value.
577 #[inline]
578 pub fn set(&mut self, other: $BitFlags, value: bool) {
579 if value {
580 self.insert(other);
581 } else {
582 self.remove(other);
583 }
584 }
585 }
586
587 impl $crate::_core::ops::BitOr for $BitFlags {
588 type Output = $BitFlags;
589
590 /// Returns the union of the two sets of flags.
591 #[inline]
592 fn bitor(self, other: $BitFlags) -> $BitFlags {
593 $BitFlags { bits: self.bits | other.bits }
594 }
595 }
596
597 impl $crate::_core::ops::BitOrAssign for $BitFlags {
598
599 /// Adds the set of flags.
600 #[inline]
601 fn bitor_assign(&mut self, other: $BitFlags) {
602 self.bits |= other.bits;
603 }
604 }
605
606 impl $crate::_core::ops::BitXor for $BitFlags {
607 type Output = $BitFlags;
608
609 /// Returns the left flags, but with all the right flags toggled.
610 #[inline]
611 fn bitxor(self, other: $BitFlags) -> $BitFlags {
612 $BitFlags { bits: self.bits ^ other.bits }
613 }
614 }
615
616 impl $crate::_core::ops::BitXorAssign for $BitFlags {
617
618 /// Toggles the set of flags.
619 #[inline]
620 fn bitxor_assign(&mut self, other: $BitFlags) {
621 self.bits ^= other.bits;
622 }
623 }
624
625 impl $crate::_core::ops::BitAnd for $BitFlags {
626 type Output = $BitFlags;
627
628 /// Returns the intersection between the two sets of flags.
629 #[inline]
630 fn bitand(self, other: $BitFlags) -> $BitFlags {
631 $BitFlags { bits: self.bits & other.bits }
632 }
633 }
634
635 impl $crate::_core::ops::BitAndAssign for $BitFlags {
636
637 /// Disables all flags disabled in the set.
638 #[inline]
639 fn bitand_assign(&mut self, other: $BitFlags) {
640 self.bits &= other.bits;
641 }
642 }
643
644 impl $crate::_core::ops::Sub for $BitFlags {
645 type Output = $BitFlags;
646
647 /// Returns the set difference of the two sets of flags.
648 #[inline]
649 fn sub(self, other: $BitFlags) -> $BitFlags {
650 $BitFlags { bits: self.bits & !other.bits }
651 }
652 }
653
654 impl $crate::_core::ops::SubAssign for $BitFlags {
655
656 /// Disables all flags enabled in the set.
657 #[inline]
658 fn sub_assign(&mut self, other: $BitFlags) {
659 self.bits &= !other.bits;
660 }
661 }
662
663 impl $crate::_core::ops::Not for $BitFlags {
664 type Output = $BitFlags;
665
666 /// Returns the complement of this set of flags.
667 #[inline]
668 fn not(self) -> $BitFlags {
669 $BitFlags { bits: !self.bits } & $BitFlags::all()
670 }
671 }
672
673 impl $crate::_core::iter::Extend<$BitFlags> for $BitFlags {
674 fn extend<T: $crate::_core::iter::IntoIterator<Item=$BitFlags>>(&mut self, iterator: T) {
675 for item in iterator {
676 self.insert(item)
677 }
678 }
679 }
680
681 impl $crate::_core::iter::FromIterator<$BitFlags> for $BitFlags {
682 fn from_iter<T: $crate::_core::iter::IntoIterator<Item=$BitFlags>>(iterator: T) -> $BitFlags {
683 let mut result = Self::empty();
684 result.extend(iterator);
685 result
686 }
687 }
688 };
689
690 // Every attribute that the user writes on a const is applied to the
691 // corresponding const that we generate, but within the implementation of
692 // Debug and all() we want to ignore everything but #[cfg] attributes. In
693 // particular, including a #[deprecated] attribute on those items would fail
694 // to compile.
695 // https://github.com/rust-lang-nursery/bitflags/issues/109
696 //
697 // Input:
698 //
699 // ? #[cfg(feature = "advanced")]
700 // ? #[deprecated(note = "Use somthing else.")]
701 // ? #[doc = r"High quality documentation."]
702 // fn f() -> i32 { /* ... */ }
703 //
704 // Output:
705 //
706 // #[cfg(feature = "advanced")]
707 // fn f() -> i32 { /* ... */ }
708 (
709 $(#[$filtered:meta])*
710 ? #[cfg $($cfgargs:tt)*]
711 $(? #[$rest:ident $($restargs:tt)*])*
712 fn $($item:tt)*
713 ) => {
714 $crate::__impl_bitflags! {
715 $(#[$filtered])*
716 #[cfg $($cfgargs)*]
717 $(? #[$rest $($restargs)*])*
718 fn $($item)*
719 }
720 };
721 (
722 $(#[$filtered:meta])*
723 // $next != `cfg`
724 ? #[$next:ident $($nextargs:tt)*]
725 $(? #[$rest:ident $($restargs:tt)*])*
726 fn $($item:tt)*
727 ) => {
728 $crate::__impl_bitflags! {
729 $(#[$filtered])*
730 // $next filtered out
731 $(? #[$rest $($restargs)*])*
732 fn $($item)*
733 }
734 };
735 (
736 $(#[$filtered:meta])*
737 fn $($item:tt)*
738 ) => {
739 $(#[$filtered])*
740 fn $($item)*
741 };
742
743 (
744 $(#[$filtered:meta])*
745 ? #[cfg $($cfgargs:tt)*]
746 $(? #[$rest:ident $($restargs:tt)*])*
747 const $($item:tt)*
748 ) => {
749 $crate::__impl_bitflags! {
750 $(#[$filtered])*
751 #[cfg $($cfgargs)*]
752 $(? #[$rest $($restargs)*])*
753 const $($item)*
754 }
755 };
756 (
757 $(#[$filtered:meta])*
758 // $next != `cfg`
759 ? #[$next:ident $($nextargs:tt)*]
760 $(? #[$rest:ident $($restargs:tt)*])*
761 const $($item:tt)*
762 ) => {
763 $crate::__impl_bitflags! {
764 $(#[$filtered])*
765 // $next filtered out
766 $(? #[$rest $($restargs)*])*
767 const $($item)*
768 }
769 };
770 (
771 $(#[$filtered:meta])*
772 const $($item:tt)*
773 ) => {
774 $(#[$filtered])*
775 const $($item)*
776 };
777}
778
779#[cfg(feature = "example_generated")]
780pub mod example_generated;
781
782#[cfg(test)]
783mod tests {
784 use std::collections::hash_map::DefaultHasher;
785 use std::hash::{Hash, Hasher};
786
787 bitflags! {
788 #[doc = "> The first principle is that you must not fool yourself — and"]
789 #[doc = "> you are the easiest person to fool."]
790 #[doc = "> "]
791 #[doc = "> - Richard Feynman"]
792 struct Flags: u32 {
793 const A = 0b00000001;
794 #[doc = "<pcwalton> macros are way better at generating code than trans is"]
795 const B = 0b00000010;
796 const C = 0b00000100;
797 #[doc = "* cmr bed"]
798 #[doc = "* strcat table"]
799 #[doc = "<strcat> wait what?"]
800 const ABC = Self::A.bits | Self::B.bits | Self::C.bits;
801 }
802 }
803
804 bitflags! {
805 struct _CfgFlags: u32 {
806 #[cfg(windows)]
807 const _CFG_A = 0b01;
808 #[cfg(unix)]
809 const _CFG_B = 0b01;
810 #[cfg(windows)]
811 const _CFG_C = _CFG_A.bits | 0b10;
812 }
813 }
814
815 bitflags! {
816 struct AnotherSetOfFlags: i8 {
817 const ANOTHER_FLAG = -1_i8;
818 }
819 }
820
821 bitflags! {
822 struct LongFlags: u32 {
823 const LONG_A = 0b1111111111111111;
824 }
825 }
826
827 #[test]
828 fn test_bits() {
829 assert_eq!(Flags::empty().bits(), 0b00000000);
830 assert_eq!(Flags::A.bits(), 0b00000001);
831 assert_eq!(Flags::ABC.bits(), 0b00000111);
832
833 assert_eq!(AnotherSetOfFlags::empty().bits(), 0b00);
834 assert_eq!(AnotherSetOfFlags::ANOTHER_FLAG.bits(), !0_i8);
835 }
836
837 #[test]
838 fn test_from_bits() {
839 assert_eq!(Flags::from_bits(0), Some(Flags::empty()));
840 assert_eq!(Flags::from_bits(0b1), Some(Flags::A));
841 assert_eq!(Flags::from_bits(0b10), Some(Flags::B));
842 assert_eq!(Flags::from_bits(0b11), Some(Flags::A | Flags::B));
843 assert_eq!(Flags::from_bits(0b1000), None);
844
845 assert_eq!(AnotherSetOfFlags::from_bits(!0_i8), Some(AnotherSetOfFlags::ANOTHER_FLAG));
846 }
847
848 #[test]
849 fn test_from_bits_truncate() {
850 assert_eq!(Flags::from_bits_truncate(0), Flags::empty());
851 assert_eq!(Flags::from_bits_truncate(0b1), Flags::A);
852 assert_eq!(Flags::from_bits_truncate(0b10), Flags::B);
853 assert_eq!(Flags::from_bits_truncate(0b11), (Flags::A | Flags::B));
854 assert_eq!(Flags::from_bits_truncate(0b1000), Flags::empty());
855 assert_eq!(Flags::from_bits_truncate(0b1001), Flags::A);
856
857 assert_eq!(AnotherSetOfFlags::from_bits_truncate(0_i8), AnotherSetOfFlags::empty());
858 }
859
860 #[test]
861 fn test_is_empty() {
862 assert!(Flags::empty().is_empty());
863 assert!(!Flags::A.is_empty());
864 assert!(!Flags::ABC.is_empty());
865
866 assert!(!AnotherSetOfFlags::ANOTHER_FLAG.is_empty());
867 }
868
869 #[test]
870 fn test_is_all() {
871 assert!(Flags::all().is_all());
872 assert!(!Flags::A.is_all());
873 assert!(Flags::ABC.is_all());
874
875 assert!(AnotherSetOfFlags::ANOTHER_FLAG.is_all());
876 }
877
878 #[test]
879 fn test_two_empties_do_not_intersect() {
880 let e1 = Flags::empty();
881 let e2 = Flags::empty();
882 assert!(!e1.intersects(e2));
883
884 assert!(AnotherSetOfFlags::ANOTHER_FLAG.intersects(AnotherSetOfFlags::ANOTHER_FLAG));
885 }
886
887 #[test]
888 fn test_empty_does_not_intersect_with_full() {
889 let e1 = Flags::empty();
890 let e2 = Flags::ABC;
891 assert!(!e1.intersects(e2));
892 }
893
894 #[test]
895 fn test_disjoint_intersects() {
896 let e1 = Flags::A;
897 let e2 = Flags::B;
898 assert!(!e1.intersects(e2));
899 }
900
901 #[test]
902 fn test_overlapping_intersects() {
903 let e1 = Flags::A;
904 let e2 = Flags::A | Flags::B;
905 assert!(e1.intersects(e2));
906 }
907
908 #[test]
909 fn test_contains() {
910 let e1 = Flags::A;
911 let e2 = Flags::A | Flags::B;
912 assert!(!e1.contains(e2));
913 assert!(e2.contains(e1));
914 assert!(Flags::ABC.contains(e2));
915
916 assert!(AnotherSetOfFlags::ANOTHER_FLAG.contains(AnotherSetOfFlags::ANOTHER_FLAG));
917 }
918
919 #[test]
920 fn test_insert() {
921 let mut e1 = Flags::A;
922 let e2 = Flags::A | Flags::B;
923 e1.insert(e2);
924 assert_eq!(e1, e2);
925
926 let mut e3 = AnotherSetOfFlags::empty();
927 e3.insert(AnotherSetOfFlags::ANOTHER_FLAG);
928 assert_eq!(e3, AnotherSetOfFlags::ANOTHER_FLAG);
929 }
930
931 #[test]
932 fn test_remove() {
933 let mut e1 = Flags::A | Flags::B;
934 let e2 = Flags::A | Flags::C;
935 e1.remove(e2);
936 assert_eq!(e1, Flags::B);
937
938 let mut e3 = AnotherSetOfFlags::ANOTHER_FLAG;
939 e3.remove(AnotherSetOfFlags::ANOTHER_FLAG);
940 assert_eq!(e3, AnotherSetOfFlags::empty());
941 }
942
943 #[test]
944 fn test_operators() {
945 let e1 = Flags::A | Flags::C;
946 let e2 = Flags::B | Flags::C;
947 assert_eq!((e1 | e2), Flags::ABC); // union
948 assert_eq!((e1 & e2), Flags::C); // intersection
949 assert_eq!((e1 - e2), Flags::A); // set difference
950 assert_eq!(!e2, Flags::A); // set complement
951 assert_eq!(e1 ^ e2, Flags::A | Flags::B); // toggle
952 let mut e3 = e1;
953 e3.toggle(e2);
954 assert_eq!(e3, Flags::A | Flags::B);
955
956 let mut m4 = AnotherSetOfFlags::empty();
957 m4.toggle(AnotherSetOfFlags::empty());
958 assert_eq!(m4, AnotherSetOfFlags::empty());
959 }
960
961 #[test]
962 fn test_set() {
963 let mut e1 = Flags::A | Flags::C;
964 e1.set(Flags::B, true);
965 e1.set(Flags::C, false);
966
967 assert_eq!(e1, Flags::A | Flags::B);
968 }
969
970 #[test]
971 fn test_assignment_operators() {
972 let mut m1 = Flags::empty();
973 let e1 = Flags::A | Flags::C;
974 // union
975 m1 |= Flags::A;
976 assert_eq!(m1, Flags::A);
977 // intersection
978 m1 &= e1;
979 assert_eq!(m1, Flags::A);
980 // set difference
981 m1 -= m1;
982 assert_eq!(m1, Flags::empty());
983 // toggle
984 m1 ^= e1;
985 assert_eq!(m1, e1);
986 }
987
988 #[test]
989 fn test_extend() {
990 let mut flags;
991
992 flags = Flags::empty();
993 flags.extend([].iter().cloned());
994 assert_eq!(flags, Flags::empty());
995
996 flags = Flags::empty();
997 flags.extend([Flags::A, Flags::B].iter().cloned());
998 assert_eq!(flags, Flags::A | Flags::B);
999
1000 flags = Flags::A;
1001 flags.extend([Flags::A, Flags::B].iter().cloned());
1002 assert_eq!(flags, Flags::A | Flags::B);
1003
1004 flags = Flags::B;
1005 flags.extend([Flags::A, Flags::ABC].iter().cloned());
1006 assert_eq!(flags, Flags::ABC);
1007 }
1008
1009 #[test]
1010 fn test_from_iterator() {
1011 assert_eq!([].iter().cloned().collect::<Flags>(), Flags::empty());
1012 assert_eq!([Flags::A, Flags::B].iter().cloned().collect::<Flags>(),
1013 Flags::A | Flags::B);
1014 assert_eq!([Flags::A, Flags::ABC].iter().cloned().collect::<Flags>(), Flags::ABC);
1015 }
1016
1017 #[test]
1018 fn test_lt() {
1019 let mut a = Flags::empty();
1020 let mut b = Flags::empty();
1021
1022 assert!(!(a < b) && !(b < a));
1023 b = Flags::B;
1024 assert!(a < b);
1025 a = Flags::C;
1026 assert!(!(a < b) && !(b < a));
1027 b = Flags::C | Flags::B;
1028 assert!(a < b);
1029 }
1030
1031 #[test]
1032 fn test_ord() {
1033 let a = Flags::A;
1034 let b = Flags::B;
1035 let e = Flags::empty();
1036
1037 assert!(e <= e && e >= e);
1038 assert!(a > e && a >= e);
1039 assert!(e < a && e <= a);
1040 assert!(b > e && b >= e);
1041 assert!(e < b && e <= b);
1042
1043 let ab = a | b;
1044 assert!(ab > e && ab >= e);
1045 assert!(e < ab && e <= ab);
1046 assert!(ab > a && ab >= a);
1047 assert!(a < ab && a <= ab);
1048 assert!(ab > b && ab >= b);
1049 assert!(b < ab && b <= ab);
1050 }
1051
1052 fn hash<T: Hash>(t: &T) -> u64 {
1053 let mut s = DefaultHasher::new();
1054 t.hash(&mut s);
1055 s.finish()
1056 }
1057
1058 #[test]
1059 fn test_hash() {
1060 let mut x = Flags::empty();
1061 let mut y = Flags::empty();
1062 assert_eq!(hash(&x), hash(&y));
1063 x = Flags::all();
1064 y = Flags::ABC;
1065 assert_eq!(hash(&x), hash(&y));
1066 }
1067
1068 #[test]
1069 fn test_debug() {
1070 assert_eq!(format!("{:?}", Flags::A | Flags::B), "A | B");
1071 assert_eq!(format!("{:?}", Flags::empty()), "(empty)");
1072 assert_eq!(format!("{:?}", Flags::ABC), "A | B | C | ABC");
1073 }
1074
1075 #[test]
1076 fn test_binary() {
1077 assert_eq!(format!("{:b}", Flags::ABC), "111");
1078 assert_eq!(format!("{:#b}", Flags::ABC), "0b111");
1079 }
1080
1081 #[test]
1082 fn test_octal() {
1083 assert_eq!(format!("{:o}", LongFlags::LONG_A), "177777");
1084 assert_eq!(format!("{:#o}", LongFlags::LONG_A), "0o177777");
1085 }
1086
1087 #[test]
1088 fn test_lowerhex() {
1089 assert_eq!(format!("{:x}", LongFlags::LONG_A), "ffff");
1090 assert_eq!(format!("{:#x}", LongFlags::LONG_A), "0xffff");
1091 }
1092
1093 #[test]
1094 fn test_upperhex() {
1095 assert_eq!(format!("{:X}", LongFlags::LONG_A), "FFFF");
1096 assert_eq!(format!("{:#X}", LongFlags::LONG_A), "0xFFFF");
1097 }
1098
1099 mod submodule {
1100 bitflags! {
1101 pub struct PublicFlags: i8 {
1102 const X = 0;
1103 }
1104 }
1105 bitflags! {
1106 struct PrivateFlags: i8 {
1107 const Y = 0;
1108 }
1109 }
1110
1111 #[test]
1112 fn test_private() { let _ = PrivateFlags::Y; }
1113 }
1114
1115 #[test]
1116 fn test_public() { let _ = submodule::PublicFlags::X; }
1117
1118 mod t1 {
1119 mod foo {
1120 pub type Bar = i32;
1121 }
1122
1123 bitflags! {
1124 /// baz
1125 struct Flags: foo::Bar {
1126 const A = 0b00000001;
1127 #[cfg(foo)]
1128 const B = 0b00000010;
1129 #[cfg(foo)]
1130 const C = 0b00000010;
1131 }
1132 }
1133 }
1134
1135 #[test]
1136 fn test_in_function() {
1137 bitflags! {
1138 struct Flags: u8 {
1139 const A = 1;
1140 #[cfg(any())] // false
1141 const B = 2;
1142 }
1143 }
1144 assert_eq!(Flags::all(), Flags::A);
1145 assert_eq!(format!("{:?}", Flags::A), "A");
1146 }
1147
1148 #[test]
1149 fn test_deprecated() {
1150 bitflags! {
1151 pub struct TestFlags: u32 {
1152 #[deprecated(note = "Use something else.")]
1153 const ONE = 1;
1154 }
1155 }
1156 }
1157
1158 #[test]
1159 fn test_pub_crate() {
1160 mod module {
1161 bitflags! {
1162 pub (crate) struct Test: u8 {
1163 const FOO = 1;
1164 }
1165 }
1166 }
1167
1168 assert_eq!(module::Test::FOO.bits(), 1);
1169 }
1170
1171 #[test]
1172 fn test_pub_in_module() {
1173 mod module {
1174 mod submodule {
1175 bitflags! {
1176 // `pub (in super)` means only the module `module` will
1177 // be able to access this.
1178 pub (in super) struct Test: u8 {
1179 const FOO = 1;
1180 }
1181 }
1182 }
1183
1184 mod test {
1185 // Note: due to `pub (in super)`,
1186 // this cannot be accessed directly by the testing code.
1187 pub(super) fn value() -> u8 { super::submodule::Test::FOO.bits() }
1188 }
1189
1190 pub fn value() -> u8 { test::value() }
1191 }
1192
1193 assert_eq!(module::value(), 1)
1194 }
1195}