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.
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.
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.
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.
21 //! use 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;
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
42 //! See [`example_generated::Flags`](./example_generated/struct.Flags.html) for documentation of code
43 //! generated by the above `bitflags!` expansion.
45 //! The generated `struct`s can also be extended with type and trait
51 //! use bitflags::bitflags;
54 //! struct Flags: u32 {
55 //! const A = 0b00000001;
56 //! const B = 0b00000010;
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.
67 //! impl fmt::Display for Flags {
68 //! fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
74 //! let mut flags = Flags::A | Flags::B;
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");
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`:
91 //! use bitflags::bitflags;
94 //! pub struct Flags1: u32 {
95 //! const A = 0b00000001;
99 //! struct Flags2: u32 {
100 //! const B = 0b00000010;
106 //! let flag1 = example::Flags1::A;
107 //! let flag2 = example::Flags2::B; // error: const `B` is private
113 //! Attributes can be attached to the generated `struct`s by placing them
114 //! before the `struct` keyword.
116 //! ## Representations
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.
122 //! use bitflags::bitflags;
125 //! #[repr(transparent)]
126 //! struct Flags: u32 {
127 //! const A = 0b00000001;
128 //! const B = 0b00000010;
129 //! const C = 0b00000100;
134 //! # Trait implementations
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`.
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.
145 //! The `Binary`, `Debug`, `LowerHex`, `Octal` and `UpperHex` traits are also
146 //! implemented by displaying the bits value of the internal struct.
150 //! The following operator traits are implemented for the generated `struct`s:
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
160 //! The following methods are defined for the generated `struct`s:
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
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
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
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.
197 //! The `Default` trait is not automatically implemented for the generated structs.
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`:
203 //! use bitflags::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;
216 //! let derived_default: Flags = Default::default();
217 //! assert_eq!(derived_default.bits(), 0);
221 //! If your default value is not equal to `0` you need to implement `Default` yourself:
224 //! use bitflags::bitflags;
227 //! struct Flags: u32 {
228 //! const A = 0b00000001;
229 //! const B = 0b00000010;
230 //! const C = 0b00000100;
234 //! // explicit `Default` implementation
235 //! impl Default for Flags {
236 //! fn default() -> Flags {
237 //! Flags::A | Flags::C
242 //! let implemented_default: Flags = Default::default();
243 //! assert_eq!(implemented_default, (Flags::A | Flags::C));
249 //! Flags with a value equal to zero will have some strange behavior that one should be aware of.
252 //! use bitflags::bitflags;
255 //! struct Flags: u32 {
256 //! const NONE = 0b00000000;
257 //! const SOME = 0b00000001;
262 //! let empty = Flags::empty();
263 //! let none = Flags::NONE;
264 //! let some = Flags::SOME;
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));
271 //! // Zero flags will be ignored when testing for emptiness
272 //! assert!(none.is_empty());
276 //! Users should generally avoid defining a flag with a value of zero.
278 #![cfg_attr(not(test), no_std)]
279 #![doc(html_root_url = "https://docs.rs/bitflags/1.3.1")]
282 pub extern crate core
as _core
;
284 /// The macro used to generate the flag structures.
286 /// See the [crate level docs](../bitflags/index.html) for complete documentation.
291 /// use bitflags::bitflags;
294 /// struct Flags: u32 {
295 /// const A = 0b00000001;
296 /// const B = 0b00000010;
297 /// const C = 0b00000100;
298 /// const ABC = Self::A.bits | Self::B.bits | Self::C.bits;
303 /// let e1 = Flags::A | Flags::C;
304 /// let e2 = Flags::B | Flags::C;
305 /// assert_eq!((e1 | e2), Flags::ABC); // union
306 /// assert_eq!((e1 & e2), Flags::C); // intersection
307 /// assert_eq!((e1 - e2), Flags::A); // set difference
308 /// assert_eq!(!e2, Flags::A); // set complement
312 /// The generated `struct`s can also be extended with type and trait
318 /// use bitflags::bitflags;
321 /// struct Flags: u32 {
322 /// const A = 0b00000001;
323 /// const B = 0b00000010;
328 /// pub fn clear(&mut self) {
329 /// self.bits = 0; // The `bits` field can be accessed from within the
330 /// // same module where the `bitflags!` macro was invoked.
334 /// impl fmt::Display for Flags {
335 /// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
341 /// let mut flags = Flags::A | Flags::B;
343 /// assert!(flags.is_empty());
344 /// assert_eq!(format!("{}", flags), "hi!");
345 /// assert_eq!(format!("{:?}", Flags::A | Flags::B), "A | B");
346 /// assert_eq!(format!("{:?}", Flags::B), "B");
349 #[macro_export(local_inner_macros)]
350 macro_rules
! bitflags
{
353 $vis
:vis
struct $BitFlags
:ident
: $T
:ty
{
355 $
(#[$inner:ident $($args:tt)*])*
356 const $Flag
:ident
= $value
:expr
;
363 #[derive(Copy, PartialEq, Eq, Clone, PartialOrd, Ord, Hash)]
364 $vis
struct $BitFlags
{
371 $
(#[$inner $($args)*])*
384 // A helper macro to implement the `all` function.
385 #[macro_export(local_inner_macros)]
387 macro_rules
! __impl_all_bitflags
{
389 $BitFlags
:ident
: $T
:ty
{
391 $
(#[$attr:ident $($args:tt)*])*
392 $Flag
:ident
= $value
:expr
;
396 // See `Debug::fmt` for why this approach is taken.
397 #[allow(non_snake_case)]
403 impl __BitFlags
for $BitFlags
{
407 $
(?
#[$attr $($args)*])*
408 const $Flag
: $T
= Self::$Flag
.bits
;
412 Self { bits: $(<Self as __BitFlags>::$Flag)|+ }
415 $BitFlags
:ident
: $T
:ty { }
421 #[macro_export(local_inner_macros)]
423 macro_rules
! __impl_bitflags
{
425 $BitFlags
:ident
: $T
:ty
{
427 $
(#[$attr:ident $($args:tt)*])*
428 $Flag
:ident
= $value
:expr
;
432 impl $
crate::_core
::fmt
::Debug
for $BitFlags
{
433 fn fmt(&self, f
: &mut $
crate::_core
::fmt
::Formatter
) -> $
crate::_core
::fmt
::Result
{
434 // This convoluted approach is to handle #[cfg]-based flag
435 // omission correctly. For example it needs to support:
437 // #[cfg(unix)] const A: Flag = /* ... */;
438 // #[cfg(windows)] const B: Flag = /* ... */;
440 // Unconditionally define a check for every flag, even disabled
442 #[allow(non_snake_case)]
446 fn $
Flag(&self) -> bool { false }
450 // Conditionally override the check for just those flags that
451 // are not #[cfg]ed away.
452 impl __BitFlags
for $BitFlags
{
457 $
(?
#[$attr $($args)*])*
458 fn $
Flag(&self) -> bool
{
459 if Self::$Flag
.bits
== 0 && self.bits
!= 0 {
462 self.bits
& Self::$Flag
.bits
== Self::$Flag
.bits
469 let mut first
= true;
471 if <Self as __BitFlags
>::$
Flag(self) {
476 f
.write_str($
crate::_core
::stringify
!($Flag
))?
;
479 let extra_bits
= self.bits
& !Self::all().bits();
486 $
crate::_core
::fmt
::LowerHex
::fmt(&extra_bits
, f
)?
;
489 f
.write_str("(empty)")?
;
494 impl $
crate::_core
::fmt
::Binary
for $BitFlags
{
495 fn fmt(&self, f
: &mut $
crate::_core
::fmt
::Formatter
) -> $
crate::_core
::fmt
::Result
{
496 $
crate::_core
::fmt
::Binary
::fmt(&self.bits
, f
)
499 impl $
crate::_core
::fmt
::Octal
for $BitFlags
{
500 fn fmt(&self, f
: &mut $
crate::_core
::fmt
::Formatter
) -> $
crate::_core
::fmt
::Result
{
501 $
crate::_core
::fmt
::Octal
::fmt(&self.bits
, f
)
504 impl $
crate::_core
::fmt
::LowerHex
for $BitFlags
{
505 fn fmt(&self, f
: &mut $
crate::_core
::fmt
::Formatter
) -> $
crate::_core
::fmt
::Result
{
506 $
crate::_core
::fmt
::LowerHex
::fmt(&self.bits
, f
)
509 impl $
crate::_core
::fmt
::UpperHex
for $BitFlags
{
510 fn fmt(&self, f
: &mut $
crate::_core
::fmt
::Formatter
) -> $
crate::_core
::fmt
::Result
{
511 $
crate::_core
::fmt
::UpperHex
::fmt(&self.bits
, f
)
518 $
(#[$attr $($args)*])*
519 pub const $Flag
: Self = Self { bits: $value }
;
522 /// Returns an empty set of flags.
524 pub const fn empty() -> Self {
528 /// Returns the set containing all flags.
530 pub const fn all() -> Self {
531 __impl_all_bitflags
! {
534 $
(#[$attr $($args)*])*
541 /// Returns the raw value of the flags currently stored.
543 pub const fn bits(&self) -> $T
{
547 /// Convert from underlying bit representation, unless that
548 /// representation contains bits that do not correspond to a flag.
550 pub const fn from_bits(bits
: $T
) -> $
crate::_core
::option
::Option
<Self> {
551 if (bits
& !Self::all().bits()) == 0 {
552 $
crate::_core
::option
::Option
::Some(Self { bits }
)
554 $
crate::_core
::option
::Option
::None
558 /// Convert from underlying bit representation, dropping any bits
559 /// that do not correspond to flags.
561 pub const fn from_bits_truncate(bits
: $T
) -> Self {
562 Self { bits: bits & Self::all().bits }
565 /// Convert from underlying bit representation, preserving all
566 /// bits (even those not corresponding to a defined flag).
570 /// The caller of the `bitflags!` macro can chose to allow or
571 /// disallow extra bits for their bitflags type.
573 /// The caller of `from_bits_unchecked()` has to ensure that
574 /// all bits correspond to a defined flag or that extra bits
575 /// are valid for this bitflags type.
577 pub const unsafe fn from_bits_unchecked(bits
: $T
) -> Self {
581 /// Returns `true` if no flags are currently stored.
583 pub const fn is_empty(&self) -> bool
{
584 self.bits() == Self::empty().bits()
587 /// Returns `true` if all flags are currently set.
589 pub const fn is_all(&self) -> bool
{
590 Self::all().bits
| self.bits
== self.bits
593 /// Returns `true` if there are flags common to both `self` and `other`.
595 pub const fn intersects(&self, other
: Self) -> bool
{
596 !(Self { bits: self.bits & other.bits}
).is_empty()
599 /// Returns `true` if all of the flags in `other` are contained within `self`.
601 pub const fn contains(&self, other
: Self) -> bool
{
602 (self.bits
& other
.bits
) == other
.bits
605 /// Inserts the specified flags in-place.
607 pub fn insert(&mut self, other
: Self) {
608 self.bits
|= other
.bits
;
611 /// Removes the specified flags in-place.
613 pub fn remove(&mut self, other
: Self) {
614 self.bits
&= !other
.bits
;
617 /// Toggles the specified flags in-place.
619 pub fn toggle(&mut self, other
: Self) {
620 self.bits ^
= other
.bits
;
623 /// Inserts or removes the specified flags depending on the passed value.
625 pub fn set(&mut self, other
: Self, value
: bool
) {
633 /// Returns the intersection between the flags in `self` and
636 /// Specifically, the returned set contains only the flags which are
637 /// present in *both* `self` *and* `other`.
639 /// This is equivalent to using the `&` operator (e.g.
640 /// [`ops::BitAnd`]), as in `flags & other`.
642 /// [`ops::BitAnd`]: https://doc.rust-lang.org/std/ops/trait.BitAnd.html
645 pub const fn intersection(self, other
: Self) -> Self {
646 Self { bits: self.bits & other.bits }
649 /// Returns the union of between the flags in `self` and `other`.
651 /// Specifically, the returned set contains all flags which are
652 /// present in *either* `self` *or* `other`, including any which are
653 /// present in both (see [`Self::symmetric_difference`] if that
656 /// This is equivalent to using the `|` operator (e.g.
657 /// [`ops::BitOr`]), as in `flags | other`.
659 /// [`ops::BitOr`]: https://doc.rust-lang.org/std/ops/trait.BitOr.html
662 pub const fn union(self, other
: Self) -> Self {
663 Self { bits: self.bits | other.bits }
666 /// Returns the difference between the flags in `self` and `other`.
668 /// Specifically, the returned set contains all flags present in
669 /// `self`, except for the ones present in `other`.
671 /// It is also conceptually equivalent to the "bit-clear" operation:
672 /// `flags & !other` (and this syntax is also supported).
674 /// This is equivalent to using the `-` operator (e.g.
675 /// [`ops::Sub`]), as in `flags - other`.
677 /// [`ops::Sub`]: https://doc.rust-lang.org/std/ops/trait.Sub.html
680 pub const fn difference(self, other
: Self) -> Self {
681 Self { bits: self.bits & !other.bits }
684 /// Returns the [symmetric difference][sym-diff] between the flags
685 /// in `self` and `other`.
687 /// Specifically, the returned set contains the flags present which
688 /// are present in `self` or `other`, but that are not present in
689 /// both. Equivalently, it contains the flags present in *exactly
690 /// one* of the sets `self` and `other`.
692 /// This is equivalent to using the `^` operator (e.g.
693 /// [`ops::BitXor`]), as in `flags ^ other`.
695 /// [sym-diff]: https://en.wikipedia.org/wiki/Symmetric_difference
696 /// [`ops::BitXor`]: https://doc.rust-lang.org/std/ops/trait.BitXor.html
699 pub const fn symmetric_difference(self, other
: Self) -> Self {
700 Self { bits: self.bits ^ other.bits }
703 /// Returns the complement of this set of flags.
705 /// Specifically, the returned set contains all the flags which are
706 /// not set in `self`, but which are allowed for this type.
708 /// Alternatively, it can be thought of as the set difference
709 /// between [`Self::all()`] and `self` (e.g. `Self::all() - self`)
711 /// This is equivalent to using the `!` operator (e.g.
712 /// [`ops::Not`]), as in `!flags`.
714 /// [`Self::all()`]: Self::all
715 /// [`ops::Not`]: https://doc.rust-lang.org/std/ops/trait.Not.html
718 pub const fn complement(self) -> Self {
719 Self::from_bits_truncate(!self.bits
)
724 impl $
crate::_core
::ops
::BitOr
for $BitFlags
{
727 /// Returns the union of the two sets of flags.
729 fn bitor(self, other
: $BitFlags
) -> Self {
730 Self { bits: self.bits | other.bits }
734 impl $
crate::_core
::ops
::BitOrAssign
for $BitFlags
{
735 /// Adds the set of flags.
737 fn bitor_assign(&mut self, other
: Self) {
738 self.bits
|= other
.bits
;
742 impl $
crate::_core
::ops
::BitXor
for $BitFlags
{
745 /// Returns the left flags, but with all the right flags toggled.
747 fn bitxor(self, other
: Self) -> Self {
748 Self { bits: self.bits ^ other.bits }
752 impl $
crate::_core
::ops
::BitXorAssign
for $BitFlags
{
753 /// Toggles the set of flags.
755 fn bitxor_assign(&mut self, other
: Self) {
756 self.bits ^
= other
.bits
;
760 impl $
crate::_core
::ops
::BitAnd
for $BitFlags
{
763 /// Returns the intersection between the two sets of flags.
765 fn bitand(self, other
: Self) -> Self {
766 Self { bits: self.bits & other.bits }
770 impl $
crate::_core
::ops
::BitAndAssign
for $BitFlags
{
771 /// Disables all flags disabled in the set.
773 fn bitand_assign(&mut self, other
: Self) {
774 self.bits
&= other
.bits
;
778 impl $
crate::_core
::ops
::Sub
for $BitFlags
{
781 /// Returns the set difference of the two sets of flags.
783 fn sub(self, other
: Self) -> Self {
784 Self { bits: self.bits & !other.bits }
788 impl $
crate::_core
::ops
::SubAssign
for $BitFlags
{
789 /// Disables all flags enabled in the set.
791 fn sub_assign(&mut self, other
: Self) {
792 self.bits
&= !other
.bits
;
796 impl $
crate::_core
::ops
::Not
for $BitFlags
{
799 /// Returns the complement of this set of flags.
801 fn not(self) -> Self {
802 Self { bits: !self.bits }
& Self::all()
806 impl $
crate::_core
::iter
::Extend
<$BitFlags
> for $BitFlags
{
807 fn extend
<T
: $
crate::_core
::iter
::IntoIterator
<Item
=Self>>(&mut self, iterator
: T
) {
808 for item
in iterator
{
814 impl $
crate::_core
::iter
::FromIterator
<$BitFlags
> for $BitFlags
{
815 fn from_iter
<T
: $
crate::_core
::iter
::IntoIterator
<Item
=Self>>(iterator
: T
) -> Self {
816 let mut result
= Self::empty();
817 result
.extend(iterator
);
823 // Every attribute that the user writes on a const is applied to the
824 // corresponding const that we generate, but within the implementation of
825 // Debug and all() we want to ignore everything but #[cfg] attributes. In
826 // particular, including a #[deprecated] attribute on those items would fail
828 // https://github.com/bitflags/bitflags/issues/109
832 // ? #[cfg(feature = "advanced")]
833 // ? #[deprecated(note = "Use something else.")]
834 // ? #[doc = r"High quality documentation."]
835 // fn f() -> i32 { /* ... */ }
839 // #[cfg(feature = "advanced")]
840 // fn f() -> i32 { /* ... */ }
842 $
(#[$filtered:meta])*
843 ?
#[cfg $($cfgargs:tt)*]
844 $
(?
#[$rest:ident $($restargs:tt)*])*
850 $
(?
#[$rest $($restargs)*])*
855 $
(#[$filtered:meta])*
857 ?
#[$next:ident $($nextargs:tt)*]
858 $
(?
#[$rest:ident $($restargs:tt)*])*
863 // $next filtered out
864 $
(?
#[$rest $($restargs)*])*
869 $
(#[$filtered:meta])*
876 // Every attribute that the user writes on a const is applied to the
877 // corresponding const that we generate, but within the implementation of
878 // Debug and all() we want to ignore everything but #[cfg] attributes. In
879 // particular, including a #[deprecated] attribute on those items would fail
881 // https://github.com/bitflags/bitflags/issues/109
887 // ? #[cfg(feature = "advanced")]
888 // ? #[deprecated(note = "Use something else.")]
889 // ? #[doc = r"High quality documentation."]
890 // const f: i32 { /* ... */ }
894 // #[cfg(feature = "advanced")]
895 // const f: i32 { /* ... */ }
897 $
(#[$filtered:meta])*
898 ?
#[cfg $($cfgargs:tt)*]
899 $
(?
#[$rest:ident $($restargs:tt)*])*
905 $
(?
#[$rest $($restargs)*])*
910 $
(#[$filtered:meta])*
912 ?
#[$next:ident $($nextargs:tt)*]
913 $
(?
#[$rest:ident $($restargs:tt)*])*
918 // $next filtered out
919 $
(?
#[$rest $($restargs)*])*
924 $
(#[$filtered:meta])*
932 #[cfg(feature = "example_generated")]
933 pub mod example_generated
;
937 use std
::collections
::hash_map
::DefaultHasher
;
938 use std
::hash
::{Hash, Hasher}
;
941 #[doc = "> The first principle is that you must not fool yourself — and"]
942 #[doc = "> you are the easiest person to fool."]
944 #[doc = "> - Richard Feynman"]
947 const A
= 0b00000001;
948 #[doc = "<pcwalton> macros are way better at generating code than trans is"]
949 const B
= 0b00000010;
950 const C
= 0b00000100;
952 #[doc = "* strcat table"]
953 #[doc = "<strcat> wait what?"]
954 const ABC
= Self::A
.bits
| Self::B
.bits
| Self::C
.bits
;
957 struct _CfgFlags
: u32 {
963 const _CFG_C
= Self::_CFG_A
.bits
| 0b10;
966 struct AnotherSetOfFlags
: i8 {
967 const ANOTHER_FLAG
= -1_i8;
970 struct LongFlags
: u32 {
971 const LONG_A
= 0b1111111111111111;
976 struct EmptyFlags
: u32 {
982 assert_eq
!(Flags
::empty().bits(), 0b00000000);
983 assert_eq
!(Flags
::A
.bits(), 0b00000001);
984 assert_eq
!(Flags
::ABC
.bits(), 0b00000111);
986 assert_eq
!(AnotherSetOfFlags
::empty().bits(), 0b00);
987 assert_eq
!(AnotherSetOfFlags
::ANOTHER_FLAG
.bits(), !0_i8);
989 assert_eq
!(EmptyFlags
::empty().bits(), 0b00000000);
993 fn test_from_bits() {
994 assert_eq
!(Flags
::from_bits(0), Some(Flags
::empty()));
995 assert_eq
!(Flags
::from_bits(0b1), Some(Flags
::A
));
996 assert_eq
!(Flags
::from_bits(0b10), Some(Flags
::B
));
997 assert_eq
!(Flags
::from_bits(0b11), Some(Flags
::A
| Flags
::B
));
998 assert_eq
!(Flags
::from_bits(0b1000), None
);
1001 AnotherSetOfFlags
::from_bits(!0_i8),
1002 Some(AnotherSetOfFlags
::ANOTHER_FLAG
)
1005 assert_eq
!(EmptyFlags
::from_bits(0), Some(EmptyFlags
::empty()));
1006 assert_eq
!(EmptyFlags
::from_bits(0b1), None
);
1010 fn test_from_bits_truncate() {
1011 assert_eq
!(Flags
::from_bits_truncate(0), Flags
::empty());
1012 assert_eq
!(Flags
::from_bits_truncate(0b1), Flags
::A
);
1013 assert_eq
!(Flags
::from_bits_truncate(0b10), Flags
::B
);
1014 assert_eq
!(Flags
::from_bits_truncate(0b11), (Flags
::A
| Flags
::B
));
1015 assert_eq
!(Flags
::from_bits_truncate(0b1000), Flags
::empty());
1016 assert_eq
!(Flags
::from_bits_truncate(0b1001), Flags
::A
);
1019 AnotherSetOfFlags
::from_bits_truncate(0_i8),
1020 AnotherSetOfFlags
::empty()
1023 assert_eq
!(EmptyFlags
::from_bits_truncate(0), EmptyFlags
::empty());
1024 assert_eq
!(EmptyFlags
::from_bits_truncate(0b1), EmptyFlags
::empty());
1028 fn test_from_bits_unchecked() {
1029 let extra
= unsafe { Flags::from_bits_unchecked(0b1000) }
;
1030 assert_eq
!(unsafe { Flags::from_bits_unchecked(0) }
, Flags
::empty());
1031 assert_eq
!(unsafe { Flags::from_bits_unchecked(0b1) }
, Flags
::A
);
1032 assert_eq
!(unsafe { Flags::from_bits_unchecked(0b10) }
, Flags
::B
);
1035 unsafe { Flags::from_bits_unchecked(0b11) }
,
1036 (Flags
::A
| Flags
::B
)
1039 unsafe { Flags::from_bits_unchecked(0b1000) }
,
1040 (extra
| Flags
::empty())
1043 unsafe { Flags::from_bits_unchecked(0b1001) }
,
1047 let extra
= unsafe { EmptyFlags::from_bits_unchecked(0b1000) }
;
1049 unsafe { EmptyFlags::from_bits_unchecked(0b1000) }
,
1050 (extra
| EmptyFlags
::empty())
1055 fn test_is_empty() {
1056 assert
!(Flags
::empty().is_empty());
1057 assert
!(!Flags
::A
.is_empty());
1058 assert
!(!Flags
::ABC
.is_empty());
1060 assert
!(!AnotherSetOfFlags
::ANOTHER_FLAG
.is_empty());
1062 assert
!(EmptyFlags
::empty().is_empty());
1063 assert
!(EmptyFlags
::all().is_empty());
1068 assert
!(Flags
::all().is_all());
1069 assert
!(!Flags
::A
.is_all());
1070 assert
!(Flags
::ABC
.is_all());
1072 let extra
= unsafe { Flags::from_bits_unchecked(0b1000) }
;
1073 assert
!(!extra
.is_all());
1074 assert
!(!(Flags
::A
| extra
).is_all());
1075 assert
!((Flags
::ABC
| extra
).is_all());
1077 assert
!(AnotherSetOfFlags
::ANOTHER_FLAG
.is_all());
1079 assert
!(EmptyFlags
::all().is_all());
1080 assert
!(EmptyFlags
::empty().is_all());
1084 fn test_two_empties_do_not_intersect() {
1085 let e1
= Flags
::empty();
1086 let e2
= Flags
::empty();
1087 assert
!(!e1
.intersects(e2
));
1089 assert
!(AnotherSetOfFlags
::ANOTHER_FLAG
.intersects(AnotherSetOfFlags
::ANOTHER_FLAG
));
1093 fn test_empty_does_not_intersect_with_full() {
1094 let e1
= Flags
::empty();
1095 let e2
= Flags
::ABC
;
1096 assert
!(!e1
.intersects(e2
));
1100 fn test_disjoint_intersects() {
1103 assert
!(!e1
.intersects(e2
));
1107 fn test_overlapping_intersects() {
1109 let e2
= Flags
::A
| Flags
::B
;
1110 assert
!(e1
.intersects(e2
));
1114 fn test_contains() {
1116 let e2
= Flags
::A
| Flags
::B
;
1117 assert
!(!e1
.contains(e2
));
1118 assert
!(e2
.contains(e1
));
1119 assert
!(Flags
::ABC
.contains(e2
));
1121 assert
!(AnotherSetOfFlags
::ANOTHER_FLAG
.contains(AnotherSetOfFlags
::ANOTHER_FLAG
));
1123 assert
!(EmptyFlags
::empty().contains(EmptyFlags
::empty()));
1128 let mut e1
= Flags
::A
;
1129 let e2
= Flags
::A
| Flags
::B
;
1133 let mut e3
= AnotherSetOfFlags
::empty();
1134 e3
.insert(AnotherSetOfFlags
::ANOTHER_FLAG
);
1135 assert_eq
!(e3
, AnotherSetOfFlags
::ANOTHER_FLAG
);
1140 let mut e1
= Flags
::A
| Flags
::B
;
1141 let e2
= Flags
::A
| Flags
::C
;
1143 assert_eq
!(e1
, Flags
::B
);
1145 let mut e3
= AnotherSetOfFlags
::ANOTHER_FLAG
;
1146 e3
.remove(AnotherSetOfFlags
::ANOTHER_FLAG
);
1147 assert_eq
!(e3
, AnotherSetOfFlags
::empty());
1151 fn test_operators() {
1152 let e1
= Flags
::A
| Flags
::C
;
1153 let e2
= Flags
::B
| Flags
::C
;
1154 assert_eq
!((e1
| e2
), Flags
::ABC
); // union
1155 assert_eq
!((e1
& e2
), Flags
::C
); // intersection
1156 assert_eq
!((e1
- e2
), Flags
::A
); // set difference
1157 assert_eq
!(!e2
, Flags
::A
); // set complement
1158 assert_eq
!(e1 ^ e2
, Flags
::A
| Flags
::B
); // toggle
1161 assert_eq
!(e3
, Flags
::A
| Flags
::B
);
1163 let mut m4
= AnotherSetOfFlags
::empty();
1164 m4
.toggle(AnotherSetOfFlags
::empty());
1165 assert_eq
!(m4
, AnotherSetOfFlags
::empty());
1169 fn test_operators_unchecked() {
1170 let extra
= unsafe { Flags::from_bits_unchecked(0b1000) }
;
1171 let e1
= Flags
::A
| Flags
::C
| extra
;
1172 let e2
= Flags
::B
| Flags
::C
;
1173 assert_eq
!((e1
| e2
), (Flags
::ABC
| extra
)); // union
1174 assert_eq
!((e1
& e2
), Flags
::C
); // intersection
1175 assert_eq
!((e1
- e2
), (Flags
::A
| extra
)); // set difference
1176 assert_eq
!(!e2
, Flags
::A
); // set complement
1177 assert_eq
!(!e1
, Flags
::B
); // set complement
1178 assert_eq
!(e1 ^ e2
, Flags
::A
| Flags
::B
| extra
); // toggle
1181 assert_eq
!(e3
, Flags
::A
| Flags
::B
| extra
);
1185 fn test_set_ops_basic() {
1186 let ab
= Flags
::A
.union(Flags
::B
);
1187 let ac
= Flags
::A
.union(Flags
::C
);
1188 let bc
= Flags
::B
.union(Flags
::C
);
1189 assert_eq
!(ab
.bits
, 0b011);
1190 assert_eq
!(bc
.bits
, 0b110);
1191 assert_eq
!(ac
.bits
, 0b101);
1193 assert_eq
!(ab
, Flags
::B
.union(Flags
::A
));
1194 assert_eq
!(ac
, Flags
::C
.union(Flags
::A
));
1195 assert_eq
!(bc
, Flags
::C
.union(Flags
::B
));
1197 assert_eq
!(ac
, Flags
::A
| Flags
::C
);
1198 assert_eq
!(bc
, Flags
::B
| Flags
::C
);
1199 assert_eq
!(ab
.union(bc
), Flags
::ABC
);
1201 assert_eq
!(ac
, Flags
::A
| Flags
::C
);
1202 assert_eq
!(bc
, Flags
::B
| Flags
::C
);
1204 assert_eq
!(ac
.union(bc
), ac
| bc
);
1205 assert_eq
!(ac
.union(bc
), Flags
::ABC
);
1206 assert_eq
!(bc
.union(ac
), Flags
::ABC
);
1208 assert_eq
!(ac
.intersection(bc
), ac
& bc
);
1209 assert_eq
!(ac
.intersection(bc
), Flags
::C
);
1210 assert_eq
!(bc
.intersection(ac
), Flags
::C
);
1212 assert_eq
!(ac
.difference(bc
), ac
- bc
);
1213 assert_eq
!(bc
.difference(ac
), bc
- ac
);
1214 assert_eq
!(ac
.difference(bc
), Flags
::A
);
1215 assert_eq
!(bc
.difference(ac
), Flags
::B
);
1217 assert_eq
!(bc
.complement(), !bc
);
1218 assert_eq
!(bc
.complement(), Flags
::A
);
1219 assert_eq
!(ac
.symmetric_difference(bc
), Flags
::A
.union(Flags
::B
));
1220 assert_eq
!(bc
.symmetric_difference(ac
), Flags
::A
.union(Flags
::B
));
1224 fn test_set_ops_const() {
1225 // These just test that these compile and don't cause use-site panics
1226 // (would be possible if we had some sort of UB)
1227 const INTERSECT
: Flags
= Flags
::all().intersection(Flags
::C
);
1228 const UNION
: Flags
= Flags
::A
.union(Flags
::C
);
1229 const DIFFERENCE
: Flags
= Flags
::all().difference(Flags
::A
);
1230 const COMPLEMENT
: Flags
= Flags
::C
.complement();
1231 const SYM_DIFFERENCE
: Flags
= UNION
.symmetric_difference(DIFFERENCE
);
1232 assert_eq
!(INTERSECT
, Flags
::C
);
1233 assert_eq
!(UNION
, Flags
::A
| Flags
::C
);
1234 assert_eq
!(DIFFERENCE
, Flags
::all() - Flags
::A
);
1235 assert_eq
!(COMPLEMENT
, !Flags
::C
);
1236 assert_eq
!(SYM_DIFFERENCE
, (Flags
::A
| Flags
::C
) ^
(Flags
::all() - Flags
::A
));
1240 fn test_set_ops_unchecked() {
1241 let extra
= unsafe { Flags::from_bits_unchecked(0b1000) }
;
1242 let e1
= Flags
::A
.union(Flags
::C
).union(extra
);
1243 let e2
= Flags
::B
.union(Flags
::C
);
1244 assert_eq
!(e1
.bits
, 0b1101);
1245 assert_eq
!(e1
.union(e2
), (Flags
::ABC
| extra
));
1246 assert_eq
!(e1
.intersection(e2
), Flags
::C
);
1247 assert_eq
!(e1
.difference(e2
), Flags
::A
| extra
);
1248 assert_eq
!(e2
.difference(e1
), Flags
::B
);
1249 assert_eq
!(e2
.complement(), Flags
::A
);
1250 assert_eq
!(e1
.complement(), Flags
::B
);
1251 assert_eq
!(e1
.symmetric_difference(e2
), Flags
::A
| Flags
::B
| extra
); // toggle
1255 fn test_set_ops_exhaustive() {
1256 // Define a flag that contains gaps to help exercise edge-cases,
1257 // especially around "unknown" flags (e.g. ones outside of `all()`
1258 // `from_bits_unchecked`).
1259 // - when lhs and rhs both have different sets of unknown flags.
1260 // - unknown flags at both ends, and in the middle
1261 // - cases with "gaps".
1264 // Intentionally no `A`
1265 const B
= 0b000000010;
1266 // Intentionally no `C`
1267 const D
= 0b000001000;
1268 const E
= 0b000010000;
1269 const F
= 0b000100000;
1270 const G
= 0b001000000;
1271 // Intentionally no `H`
1272 const I
= 0b100000000;
1275 let iter_test_flags
=
1276 || (0..=0b111_1111_1111).map(|bits
| unsafe { Test::from_bits_unchecked(bits) }
);
1278 for a
in iter_test_flags() {
1281 Test
::from_bits_truncate(!a
.bits
),
1282 "wrong result: !({:?})",
1285 assert_eq
!(a
.complement(), !a
, "named != op: !({:?})", a
);
1286 for b
in iter_test_flags() {
1287 // Check that the named operations produce the expected bitwise
1292 "wrong result: `{:?}` | `{:?}`",
1297 a
.intersection(b
).bits
,
1299 "wrong result: `{:?}` & `{:?}`",
1304 a
.symmetric_difference(b
).bits
,
1306 "wrong result: `{:?}` ^ `{:?}`",
1311 a
.difference(b
).bits
,
1313 "wrong result: `{:?}` - `{:?}`",
1317 // Note: Difference is checked as both `a - b` and `b - a`
1319 b
.difference(a
).bits
,
1321 "wrong result: `{:?}` - `{:?}`",
1325 // Check that the named set operations are equivalent to the
1326 // bitwise equivalents
1327 assert_eq
!(a
.union(b
), a
| b
, "named != op: `{:?}` | `{:?}`", a
, b
,);
1331 "named != op: `{:?}` & `{:?}`",
1336 a
.symmetric_difference(b
),
1338 "named != op: `{:?}` ^ `{:?}`",
1342 assert_eq
!(a
.difference(b
), a
- b
, "named != op: `{:?}` - `{:?}`", a
, b
,);
1343 // Note: Difference is checked as both `a - b` and `b - a`
1344 assert_eq
!(b
.difference(a
), b
- a
, "named != op: `{:?}` - `{:?}`", b
, a
,);
1345 // Verify that the operations which should be symmetric are
1346 // actually symmetric.
1347 assert_eq
!(a
.union(b
), b
.union(a
), "asymmetry: `{:?}` | `{:?}`", a
, b
,);
1351 "asymmetry: `{:?}` & `{:?}`",
1356 a
.symmetric_difference(b
),
1357 b
.symmetric_difference(a
),
1358 "asymmetry: `{:?}` ^ `{:?}`",
1368 let mut e1
= Flags
::A
| Flags
::C
;
1369 e1
.set(Flags
::B
, true);
1370 e1
.set(Flags
::C
, false);
1372 assert_eq
!(e1
, Flags
::A
| Flags
::B
);
1376 fn test_assignment_operators() {
1377 let mut m1
= Flags
::empty();
1378 let e1
= Flags
::A
| Flags
::C
;
1381 assert_eq
!(m1
, Flags
::A
);
1384 assert_eq
!(m1
, Flags
::A
);
1387 assert_eq
!(m1
, Flags
::empty());
1394 fn test_const_fn() {
1395 const _M1
: Flags
= Flags
::empty();
1397 const M2
: Flags
= Flags
::A
;
1398 assert_eq
!(M2
, Flags
::A
);
1400 const M3
: Flags
= Flags
::C
;
1401 assert_eq
!(M3
, Flags
::C
);
1408 flags
= Flags
::empty();
1409 flags
.extend([].iter().cloned());
1410 assert_eq
!(flags
, Flags
::empty());
1412 flags
= Flags
::empty();
1413 flags
.extend([Flags
::A
, Flags
::B
].iter().cloned());
1414 assert_eq
!(flags
, Flags
::A
| Flags
::B
);
1417 flags
.extend([Flags
::A
, Flags
::B
].iter().cloned());
1418 assert_eq
!(flags
, Flags
::A
| Flags
::B
);
1421 flags
.extend([Flags
::A
, Flags
::ABC
].iter().cloned());
1422 assert_eq
!(flags
, Flags
::ABC
);
1426 fn test_from_iterator() {
1427 assert_eq
!([].iter().cloned().collect
::<Flags
>(), Flags
::empty());
1429 [Flags
::A
, Flags
::B
].iter().cloned().collect
::<Flags
>(),
1433 [Flags
::A
, Flags
::ABC
].iter().cloned().collect
::<Flags
>(),
1440 let mut a
= Flags
::empty();
1441 let mut b
= Flags
::empty();
1443 assert
!(!(a
< b
) && !(b
< a
));
1447 assert
!(!(a
< b
) && b
< a
);
1448 b
= Flags
::C
| Flags
::B
;
1454 let mut a
= Flags
::empty();
1455 let mut b
= Flags
::empty();
1457 assert
!(a
<= b
&& a
>= b
);
1459 assert
!(a
> b
&& a
>= b
);
1460 assert
!(b
< a
&& b
<= a
);
1462 assert
!(b
> a
&& b
>= a
);
1463 assert
!(a
< b
&& a
<= b
);
1466 fn hash
<T
: Hash
>(t
: &T
) -> u64 {
1467 let mut s
= DefaultHasher
::new();
1474 let mut x
= Flags
::empty();
1475 let mut y
= Flags
::empty();
1476 assert_eq
!(hash(&x
), hash(&y
));
1479 assert_eq
!(hash(&x
), hash(&y
));
1484 assert_eq
!(Flags
::empty(), Flags
::default());
1489 assert_eq
!(format
!("{:?}", Flags
::A
| Flags
::B
), "A | B");
1490 assert_eq
!(format
!("{:?}", Flags
::empty()), "(empty)");
1491 assert_eq
!(format
!("{:?}", Flags
::ABC
), "A | B | C | ABC");
1492 let extra
= unsafe { Flags::from_bits_unchecked(0xb8) }
;
1493 assert_eq
!(format
!("{:?}", extra
), "0xb8");
1494 assert_eq
!(format
!("{:?}", Flags
::A
| extra
), "A | 0xb8");
1497 format
!("{:?}", Flags
::ABC
| extra
),
1498 "A | B | C | ABC | 0xb8"
1501 assert_eq
!(format
!("{:?}", EmptyFlags
::empty()), "(empty)");
1506 assert_eq
!(format
!("{:b}", Flags
::ABC
), "111");
1507 assert_eq
!(format
!("{:#b}", Flags
::ABC
), "0b111");
1508 let extra
= unsafe { Flags::from_bits_unchecked(0b1010000) }
;
1509 assert_eq
!(format
!("{:b}", Flags
::ABC
| extra
), "1010111");
1510 assert_eq
!(format
!("{:#b}", Flags
::ABC
| extra
), "0b1010111");
1515 assert_eq
!(format
!("{:o}", LongFlags
::LONG_A
), "177777");
1516 assert_eq
!(format
!("{:#o}", LongFlags
::LONG_A
), "0o177777");
1517 let extra
= unsafe { LongFlags::from_bits_unchecked(0o5000000) }
;
1518 assert_eq
!(format
!("{:o}", LongFlags
::LONG_A
| extra
), "5177777");
1519 assert_eq
!(format
!("{:#o}", LongFlags
::LONG_A
| extra
), "0o5177777");
1523 fn test_lowerhex() {
1524 assert_eq
!(format
!("{:x}", LongFlags
::LONG_A
), "ffff");
1525 assert_eq
!(format
!("{:#x}", LongFlags
::LONG_A
), "0xffff");
1526 let extra
= unsafe { LongFlags::from_bits_unchecked(0xe00000) }
;
1527 assert_eq
!(format
!("{:x}", LongFlags
::LONG_A
| extra
), "e0ffff");
1528 assert_eq
!(format
!("{:#x}", LongFlags
::LONG_A
| extra
), "0xe0ffff");
1532 fn test_upperhex() {
1533 assert_eq
!(format
!("{:X}", LongFlags
::LONG_A
), "FFFF");
1534 assert_eq
!(format
!("{:#X}", LongFlags
::LONG_A
), "0xFFFF");
1535 let extra
= unsafe { LongFlags::from_bits_unchecked(0xe00000) }
;
1536 assert_eq
!(format
!("{:X}", LongFlags
::LONG_A
| extra
), "E0FFFF");
1537 assert_eq
!(format
!("{:#X}", LongFlags
::LONG_A
| extra
), "0xE0FFFF");
1542 pub struct PublicFlags
: i8 {
1546 struct PrivateFlags
: i8 {
1553 let _
= PrivateFlags
::Y
;
1559 let _
= submodule
::PublicFlags
::X
;
1569 struct Flags
: foo
::Bar
{
1570 const A
= 0b00000001;
1572 const B
= 0b00000010;
1574 const C
= 0b00000010;
1580 fn test_in_function() {
1584 #[cfg(any())] // false
1588 assert_eq
!(Flags
::all(), Flags
::A
);
1589 assert_eq
!(format
!("{:?}", Flags
::A
), "A");
1593 fn test_deprecated() {
1595 pub struct TestFlags
: u32 {
1596 #[deprecated(note = "Use something else.")]
1603 fn test_pub_crate() {
1606 pub (crate) struct Test
: u8 {
1612 assert_eq
!(module
::Test
::FOO
.bits(), 1);
1616 fn test_pub_in_module() {
1620 // `pub (in super)` means only the module `module` will
1621 // be able to access this.
1622 pub (in super) struct Test
: u8 {
1629 // Note: due to `pub (in super)`,
1630 // this cannot be accessed directly by the testing code.
1631 pub(super) fn value() -> u8 {
1632 super::submodule
::Test
::FOO
.bits()
1636 pub fn value() -> u8 {
1641 assert_eq
!(module
::value(), 1)
1645 fn test_zero_value_flags() {
1653 assert
!(Flags
::empty().contains(Flags
::NONE
));
1654 assert
!(Flags
::SOME
.contains(Flags
::NONE
));
1655 assert
!(Flags
::NONE
.is_empty());
1657 assert_eq
!(format
!("{:?}", Flags
::empty()), "NONE");
1658 assert_eq
!(format
!("{:?}", Flags
::SOME
), "SOME");
1662 fn test_empty_bitflags() {
1667 fn test_u128_bitflags() {
1669 struct Flags128
: u128
{
1670 const A
= 0x0000_0000_0000_0000_0000_0000_0000_0001;
1671 const B
= 0x0000_0000_0000_1000_0000_0000_0000_0000;
1672 const C
= 0x8000_0000_0000_0000_0000_0000_0000_0000;
1673 const ABC
= Self::A
.bits
| Self::B
.bits
| Self::C
.bits
;
1677 assert_eq
!(Flags128
::ABC
, Flags128
::A
| Flags128
::B
| Flags128
::C
);
1678 assert_eq
!(Flags128
::A
.bits
, 0x0000_0000_0000_0000_0000_0000_0000_0001);
1679 assert_eq
!(Flags128
::B
.bits
, 0x0000_0000_0000_1000_0000_0000_0000_0000);
1680 assert_eq
!(Flags128
::C
.bits
, 0x8000_0000_0000_0000_0000_0000_0000_0000);
1683 0x8000_0000_0000_1000_0000_0000_0000_0001
1685 assert_eq
!(format
!("{:?}", Flags128
::A
), "A");
1686 assert_eq
!(format
!("{:?}", Flags128
::B
), "B");
1687 assert_eq
!(format
!("{:?}", Flags128
::C
), "C");
1688 assert_eq
!(format
!("{:?}", Flags128
::ABC
), "A | B | C | ABC");
1692 fn test_serde_bitflags_serialize() {
1693 let flags
= SerdeFlags
::A
| SerdeFlags
::B
;
1695 let serialized
= serde_json
::to_string(&flags
).unwrap();
1697 assert_eq
!(serialized
, r
#"{"bits":3}"#);
1701 fn test_serde_bitflags_deserialize() {
1702 let deserialized
: SerdeFlags
= serde_json
::from_str(r
#"{"bits":12}"#).unwrap();
1704 let expected
= SerdeFlags
::C
| SerdeFlags
::D
;
1706 assert_eq
!(deserialized
.bits
, expected
.bits
);
1710 fn test_serde_bitflags_roundtrip() {
1711 let flags
= SerdeFlags
::A
| SerdeFlags
::B
;
1713 let deserialized
: SerdeFlags
= serde_json
::from_str(&serde_json
::to_string(&flags
).unwrap()).unwrap();
1715 assert_eq
!(deserialized
.bits
, flags
.bits
);
1719 #[derive(serde::Serialize, serde::Deserialize)]
1720 struct SerdeFlags
: u32 {