bitflag_attr/lib.rs
1//! Bitflag-attr is a library for Rust that allows to generate types for C-style bitflags with
2//! ergonomic APIs using attribute macros and enums.
3//!
4//! # Overview
5//!
6//! The primary item of this crate is the [`bitflag`] macro. This attribute macro allows to define a
7//! flags type from a Rust C-style enum definition, turning it into a struct with the flags as
8//! associated constants.
9//!
10//! The remainder of this documentation is organized as follows:
11//!
12//! - [Features](#features) gives a very brief summary of the features `bitflag-attr` does and does not
13//! support.
14//! - [Usage](#usage) shows how to add `bitflag-attr` to your Rust project.
15//! - [Formatting and parsing](#formatting-and-parsing) documents the human-readable format used to
16//! parse form and format into strings
17//! - [Specification and Terminology](#specification-and-terminology) documents about the
18//! specification and the terminology used by this crate.
19//! - [Crate features](#crate-features) documents the Cargo features that can be enabled or disabled
20//! for this crate.
21//!
22//! Also, these sub-modules serve to provide longer form documentation:
23//!
24//! - [Changelog](crate::changelog)
25//! - [Specification and Terminology](crate::spec)
26//! - [Example of a generated code by the `bitflag` macro](crate::example_generated)
27//!
28//! # Features
29//!
30//! Here is a non-exhaustive list of the things that `bitflag-attr` supports:
31//!
32//! - Ergonomically create a flags type from native C-like enum syntax
33//! - `no_std` support with opt-in options to use `alloc` and `std`
34//! - Generate ergonomic API for the generated flags type
35//! - Generated methods are almost entirely const-compatible
36//! - Generated flags type auto-implements several convenient traits (complete list in the
37//! [`bitflag`] documentation)
38//! - Generated [`fmt::Debug`] implementation outputs human-readable, binary, octal and hexadecimal
39//! representation of the flags value for better debugging inspection.
40//! - Support to the enum syntax for deriving [`Default`] by using `#[default]` to choose the
41//! default flags value
42//! - Support to use all integer types and type alias in `core` and `std` as well as most common
43//! integer type alias of `libc` with opt-in option to use [other type alias as well as custom
44//! type alias](#code-generation-features)
45//! - Opt-in support for generating `serde::Serialize` and `serde::Deserialize` by using the `serde`
46//! [crate feature]
47//! - Opt-in support for generating `arbitrary::Arbitrary` by using the `arbitrary` [crate feature]
48//! - Opt-in support for generating `bytemuck::Zeroable` and `bytemuck::Pod` by using the `bytemuck`
49//! [crate feature]
50//!
51//! # Usage
52//!
53//! The `bitflag-attr` project is [on crates.io](https://crates.io/crates/bitflag-attr) and can be
54//! used by adding `bitflag-attr` to your dependencies in your project's `Cargo.toml`.
55//! Or more simply, by using `cargo add`.
56//!
57//! ```sh
58//! cargo add bitflag-attr
59//! ```
60//!
61//! or
62//!
63//! ```toml
64//! [dependencies]
65//! bitflag-attr = "0.11.1"
66//! ```
67//!
68//! ## Generating flags type
69//!
70//! Use the [`bitflag`] attribute macro to generate flags types:
71//!
72//! ```rust
73//! use bitflag_attr::bitflag;
74//!
75//! #[bitflag(u32)]
76//! #[derive(Clone, Copy)]
77//! enum Flags {
78//! A = 0b00000001,
79//! B = 0b00000010,
80//! C = 0b00000100,
81//! }
82//! ```
83//!
84//! Deriving [`Clone`] and [`Copy`] for the type is mandatory.
85//!
86//! The generated type is a **struct** wrapping the chosen primitive type.
87//!
88//! See the docs for the [`bitflag`] macro for the full syntax.
89//!
90//! Also see the [`example_generated`] module for an example of what the [`bitflag`] macro generates
91//! for a flags type.
92//!
93//! ### Externally defined flags
94//!
95//! If you're generating flags types for an external source, such as a C API, you can use the
96//! `non_exhaustive` attribute to communicate to the bitflags macro that there may be more valid
97//! flags than the known flags.
98//!
99//! Without extra configuration, it defaults to `!0` (all bits set) as a mask of all bits the
100//! external source may ever set, i.e. all bits are considered as possible values.
101//!
102//! ```rust
103//! use bitflag_attr::bitflag;
104//!
105//! #[bitflag(u32)]
106//! #[non_exhaustive] // All bits are considered as possible values.
107//! #[derive(Debug, Clone, Copy)]
108//! pub enum Flags {
109//! /// The value `A`, at bit position `0`.
110//! A = 0b00000001,
111//! /// The value `B`, at bit position `1`.
112//! B = 0b00000010,
113//! /// The value `C`, at bit position `2`.
114//! C = 0b00000100,
115//!
116//! /// The combination of `A`, `B`, and `C`.
117//! ABC = A | B | C,
118//! }
119//! ```
120//!
121//! But you can also configure this value by using the helper attribute `reserved_bits` with a
122//! desired value of valid bits that the external source may ever set.
123//!
124//! ```rust
125//! use bitflag_attr::bitflag;
126//!
127//! #[bitflag(u32)]
128//! #[non_exhaustive] // Communicate there is more potential valid flags than the known flags
129//! #[reserved_bits = 0b001001111] // Specify the extra bits to take into consideration.
130//! #[derive(Debug, Clone, Copy)]
131//! pub enum Flags {
132//! /// The value `A`, at bit position `0`.
133//! A = 0b00000001,
134//! /// The value `B`, at bit position `1`.
135//! B = 0b00000010,
136//! /// The value `C`, at bit position `2`.
137//! C = 0b00000100,
138//!
139//! /// The combination of `A`, `B`, and `C`.
140//! ABC = A | B | C,
141//! }
142//! ```
143//!
144//! Why should you do this? Generated methods like `all` and truncating operators like `!` only
145//! consider bits in defined flags. Adding an unnamed flag makes those methods consider additional
146//! bits, without generating additional constants for them. It helps compatibility when the external
147//! source may start setting additional bits at any time. The
148//! [known and unknown bits](#known-and-unknown-bits) section has more details on this behavior.
149//!
150//! ### Custom derives
151//!
152//! You can derive some traits on generated flags types if you enable Cargo features. The following
153//! libraries are currently supported:
154//!
155//! - `serde`: Support `#[derive(Serialize, Deserialize)]`, using text for human-readable formats,
156//! and a raw number for binary formats.
157//! - `arbitrary`: Support `#[derive(Arbitrary)]`, only generating flags values with known bits.
158//! - `bytemuck`: Support `#[derive(Pod, Zeroable)]`, for casting between flags values and their
159//! underlying bits values.
160//!
161//! ### Adding custom methods
162//!
163//! The [`bitflag`] macro supports any attributes on generated flags types within the macro itself,
164//! while `impl` blocks can be added normally:
165//!
166//! ```rust
167//! # use bitflag_attr::bitflag;
168//! #
169//! #[bitflag(u32)]
170//! // Attributes can be applied to flags types
171//! #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
172//! enum Flags {
173//! A = 0b00000001,
174//! B = 0b00000010,
175//! C = 0b00000100,
176//! }
177//!
178//! // Impl blocks can be added to flags types normally
179//! impl Flags {
180//! pub fn as_u64(&self) -> u64 {
181//! self.bits() as u64
182//! }
183//! }
184//! ```
185//!
186//! ## Working with flags values
187//!
188//! Use generated constants and standard bitwise operators to interact with flags values:
189//!
190//! ```rust
191//! # use bitflag_attr::bitflag;
192//! # #[bitflag(u32)]
193//! # #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
194//! # enum Flags {
195//! # A = 0b00000001,
196//! # B = 0b00000010,
197//! # C = 0b00000100,
198//! # }
199//! #
200//! // union
201//! let ab = Flags::A | Flags::B;
202//!
203//! // intersection
204//! let a = ab & Flags::A;
205//!
206//! // difference
207//! let b = ab - Flags::A;
208//!
209//! // complement
210//! let c = !ab;
211//! ```
212//!
213//! See the docs for the [`example_generated`] module and the [`Flags`] trait for more details on
214//! operators and how they behave.
215//!
216//! # Formatting and parsing
217//!
218//! `bitflag-attr` defines a text format that can be used to convert any flags value to and from
219//! strings.
220//!
221//! See the [`parser`] module for more details.
222//!
223//! # Specification and Terminology
224//!
225//! The terminology and behavior of generated flags types is specified in the documentation module
226//! [`spec`]. Details are repeated in these docs where appropriate, but is exhaustively listed in
227//! the spec. Some things are worth calling out explicitly here.
228//!
229//! ## Flags types, flags values, flags
230//!
231//! Some terminology to refer to things in the bitflags domain:
232//!
233//! - **Bits type**: A type that defines a fixed number of bits at specific locations.
234//! - **Flag**: A set of bits in a bits type that may have a unique name.
235//! - **Flags type**: A set of defined flags over a specific bits type.
236//! - **Flags value**: An instance of a flags type using its specific bits value for storage.
237//!
238//! ```rust
239//! # use bitflag_attr::bitflag;
240//! #
241//! #[bitflag(u8)]
242//! // -- Bits type
243//! #[derive(Clone, Copy)]
244//! enum FlagsType {
245//! // --------- Flags type
246//! A = 1,
247//! // ----- Flag
248//! }
249//!
250//! let flag = FlagsType::A;
251//! // ---- Flags value
252//! ```
253//!
254//! ## Known and unknown bits
255//!
256//! Any bits in a flag you define are called _known bits_. Any other bits are _unknown bits_. In the
257//! following flags type:
258//!
259//! ```rust
260//! # use bitflag_attr::bitflag;
261//! #[bitflag(u8)]
262//! #[derive(Clone, Copy)]
263//! enum Flags {
264//! A = 1,
265//! B = 1 << 1,
266//! C = 1 << 2,
267//! }
268//! ```
269//!
270//! The known bits are `0b0000_0111` and the unknown bits are `0b1111_1000`.
271//!
272//! `bitflag_attr` doesn't guarantee that a flags value will only ever have known bits set, but some
273//! operators will unset any unknown bits they encounter.
274//!
275//! If you're using `bitflags` for flags types defined externally, such as from C, you probably want
276//! all bits to be considered known, in case that external source changes. You can do this using an
277//! unnamed flag, as described in [externally defined flags](#externally-defined-flags).
278//!
279//! ## Zero-bit flags
280//!
281//! Flags with no bits set, in general, should be avoided because they interact strangely with
282//! [`contains`] and [`intersects`]. A zero-bit flag is always contained, but is never intersected. The
283//! names of zero-bit flags can be parsed, but are never formatted.
284//!
285//! [`contains`]: Flags::contains
286//! [`intersects`]: Flags::intersects
287//!
288//! ## Multi-bit flags
289//!
290//! Flags that set multiple bits should be avoided unless each bit is also in a single-bit flag.
291//! Take the following flags type as an example:
292//!
293//! ```rust
294//! # use bitflag_attr::bitflag;
295//! #[bitflag(u8)]
296//! #[derive(Clone, Copy)]
297//! enum Flags {
298//! A = 1,
299//! B = 1 | (1 << 1),
300//! }
301//! ```
302//!
303//! The result of `Flags::A ^ Flags::B` is `0b0000_0010`, which doesn't correspond to either
304//! `Flags::A` or `Flags::B` even though it's still a known bit.
305//!
306//! [`example_generated`]: crate::example_generated::ExampleFlags
307//!
308//! # Crate Features
309//!
310//! ## Ecosystem features
311//!
312//! - **std** — When enabled, `bitflag-attr` will depend on the `std` crate. Currently no
313//! particular usage and, for all intents and purposes, the same as the `alloc` feature.
314//! - **alloc** — When enabled, `bitflag-attr` will depend on the `alloc` crate. In particular,
315//! this enables functionality that requires or greatly benefits from dynamic memory allocation.
316//! If you can enable this, it is strongly encouraged that you do so. Without it, [parsing errors]
317//! will contain less information for error reporting.
318//!
319//! [parsing errors]: crate::parser::ParseError
320//!
321//! ## Code generation features
322//!
323//! - **serde** — When enabled, the [`bitflag`] macro will handle specially the `Serialize` and
324//! `Deserialize` traits passed to the enum's derive list and generate a custom implementation of
325//! those traits taking into account the human-readable format for the generated flags type.
326//! Without it, if these traits are listed in the derive list, they are passed forward to the
327//! generated code, i.e. the default derive will be used. This feature does **not** add the
328//! `serde` crate to your dependency tree, so your project must have it as a direct
329//! dependency.
330//! - **arbitrary** — When enabled, the [`bitflag`] macro will handle specially the `Arbitrary` and
331//! trait passed to the enum's derive list and generate a custom implementation of this trait
332//! taking into account the known and unknown bits, erroring out on the later. Without it, if this
333//! trait are listed in the derive list, they are passed forward to the generated code, i.e. the
334//! default derive will be used. This feature does **not** add the `arbitrary` crate to your
335//! dependency tree, so your project must have it as a direct dependency.
336//! - **bytemuck** — When enabled, the [`bitflag`] macro will handle specially the `Zeroable` and
337//! `Pod` traits passed to the enum's derive list and generate a custom implementation of
338//! those traits with static checks to ensure the correct marking. Without it, if these traits are
339//! listed in the derive list, they are passed forward to the generated code, i.e. the default
340//! derive will be used. This feature does **not** add the `bytemuck` crate to your dependency
341//! tree, so your project must have it as a direct dependency.
342//! - **custom-types** — When enabled, the [`bitflag`] macro will allow the usage of types as
343//! parameters that are not in the list of [allowed types] at the cost of worse error messages if
344//! the used type does not satisfy the requirements for the usage.
345//! - **const-mut-ref** — When enabled, the [`bitflag`] macro will generate as `const-fn` all
346//! generated methods that takes the flags value as mutable pointer. This is only allowed after
347//! Rust 1.83.0, and enabling this feature with versions inferior to this number will cause
348//! compilation errors. But if you satisfy this version limitation, it is strongly encouraged that
349//! you do enable it.
350//!
351//! [allowed types]: crate::bitflag#custom-types-feature
352//! [crate feature]: #crate-features
353#![no_std]
354
355#[cfg(feature = "alloc")]
356extern crate alloc;
357
358#[cfg(any(test, feature = "std"))]
359extern crate std;
360
361use core::{
362 fmt,
363 ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not},
364};
365
366pub use bitflags_attr_macros::bitflag;
367
368pub mod iter;
369pub mod parser;
370
371#[doc(hidden)]
372pub mod external;
373
374/// Primitive types that can be used with [`bitflag`] attribute implement this trait.
375pub trait BitsPrimitive:
376 private::Sealed
377 + Copy
378 + PartialEq
379 + BitAnd<Output = Self>
380 + BitOr<Output = Self>
381 + BitXor<Output = Self>
382 + Not<Output = Self>
383 + BitAndAssign
384 + BitOrAssign
385 + BitXorAssign
386 + fmt::Binary
387 + fmt::LowerHex
388 + fmt::UpperHex
389 + fmt::Octal
390 + Sized
391 + 'static
392{
393 /// A value with all bits unset.
394 const EMPTY: Self;
395
396 /// A value with all bits set.
397 const ALL: Self;
398}
399
400mod private {
401 pub trait Sealed {}
402}
403
404macro_rules! impl_primitive {
405 ($($ty:ty),+ $(,)?) => {
406 $(
407 impl $crate::private::Sealed for $ty {}
408 impl $crate::BitsPrimitive for $ty {
409 const EMPTY: Self = 0;
410 const ALL: Self = !0;
411 }
412 impl $crate::parser::ParseHex for $ty {
413 #[inline]
414 fn parse_hex(input: &str) -> Result<Self, $crate::parser::ParseError>
415 where
416 Self: Sized
417 {
418 <$ty>::from_str_radix(input, 16).map_err(|_| $crate::parser::ParseError::invalid_hex_flag(input))
419 }
420 }
421 )+
422 };
423}
424
425impl_primitive!(i8, i16, i32, i64, i128, isize);
426impl_primitive!(u8, u16, u32, u64, u128, usize);
427
428/// A set of defined flags using a bits type as storage.
429///
430/// ## Implementing `Flags`
431///
432/// This trait is implemented by the [`bitflag`] macro:
433///
434/// ```
435/// use bitflag_attr::bitflag;
436///
437/// #[bitflag(u8)]
438/// #[derive(Clone, Copy)]
439/// enum MyFlags {
440/// A = 1,
441/// B = 1 << 1,
442/// }
443/// ```
444///
445/// It can also be implemented manually:
446///
447/// ```
448/// use bitflag_attr::{Flags};
449///
450/// #[derive(Clone, Copy)]
451/// struct MyFlags(u8);
452///
453/// impl Flags for MyFlags {
454/// const NAMED_FLAGS: &'static [(&'static str, Self)] = &[
455/// ("A", MyFlags(1)),
456/// ("B", MyFlags(1 << 1)),
457/// ];
458///
459/// const RESERVED_BITS: Self::Bits = 1 | (1 << 1);
460///
461/// type Bits = u8;
462///
463/// fn from_bits_retain(bits: Self::Bits) -> Self {
464/// MyFlags(bits)
465/// }
466///
467/// fn bits(&self) -> Self::Bits {
468/// self.0
469/// }
470/// }
471/// ```
472///
473/// ## Using `Flags`
474///
475/// The `Flags` trait can be used generically to work with any flags types. In this example,
476/// we can count the number of defined named flags:
477///
478/// ```
479/// # use bitflag_attr::{bitflag, Flags};
480/// fn defined_flags<F: Flags>() -> usize {
481/// F::NAMED_FLAGS.iter().count()
482/// }
483///
484/// #[bitflag(u8)]
485/// #[non_exhaustive]
486/// #[derive(Clone, Copy)]
487/// enum MyFlags {
488/// A = 1,
489/// B = 1 << 1,
490/// C = 1 << 2,
491/// }
492///
493/// assert_eq!(3, defined_flags::<MyFlags>());
494/// ```
495pub trait Flags: Sized + Copy + 'static {
496 /// The set of named defined flags.
497 const NAMED_FLAGS: &'static [(&'static str, Self)];
498
499 /// All reserved bits values for the flags.
500 ///
501 /// The bits defined here can be named or unnamed and the values defined here will be considered
502 /// for the [`all`] method as a known value.
503 ///
504 /// This can be used for [externally defined flags](crate#externally-defined-flags) or even
505 /// reserving bits for future usage.
506 ///
507 /// Usually, the value of this constant can be either `0` or the bitor-ed bits values of the
508 /// named flags[^1]. For externally defined flags, the most common value is `!0`, i.e. all bits.
509 ///
510 /// [^1]: By pure logic, all bits from named flags are reserved bits. But alternatively,
511 /// "reserved bits" can be thought as only the extra bits to be reserved as known. For that
512 /// reason, the default implementation of the [`all`] method consider this value **and** the
513 /// values of [`NAMED_FLAGS`] to generate the resulting value.
514 ///
515 /// [`all`]: Flags::all
516 /// [`NAMED_FLAGS`]: Flags::NAMED_FLAGS
517 const RESERVED_BITS: Self::Bits;
518
519 /// The underlying bits type.
520 type Bits: BitsPrimitive;
521
522 /// Return the underlying bits value.
523 ///
524 /// The returned value is exactly the bits set in this flags value.
525 fn bits(&self) -> Self::Bits;
526
527 /// Convert from `bits` value exactly.
528 fn from_bits_retain(bits: Self::Bits) -> Self;
529
530 /// Converts from a `bits` value. Returning [`None`] is any unknown bits are set.
531 #[inline]
532 fn from_bits(bits: Self::Bits) -> Option<Self> {
533 let truncated = Self::from_bits_truncate(bits);
534
535 if truncated.bits() == bits {
536 Some(truncated)
537 } else {
538 None
539 }
540 }
541
542 /// Convert from `bits` value, unsetting any unknown bits.
543 #[inline]
544 fn from_bits_truncate(bits: Self::Bits) -> Self {
545 Self::from_bits_retain(bits & Self::all().bits())
546 }
547
548 /// Convert from a flag `name`.
549 #[inline]
550 fn from_flag_name(name: &str) -> Option<Self> {
551 // Don't parse empty names as empty flags
552 if name.is_empty() {
553 return None;
554 }
555
556 Self::NAMED_FLAGS
557 .iter()
558 .find(|(s, _)| *s == name)
559 .map(|(_, v)| Self::from_bits_retain(v.bits()))
560 }
561
562 /// Get a flags value with the bits of a flag with the given name set.
563 ///
564 /// This method will return `None` if `name` is empty or doesn't
565 /// correspond to any named flag.
566 #[inline]
567 fn from_name(name: &str) -> Option<Self> {
568 // Don't parse empty names as empty flags
569 if name.is_empty() {
570 return None;
571 }
572
573 for (flag_name, flag) in Self::NAMED_FLAGS {
574 if *flag_name == name {
575 return Some(Self::from_bits_retain(flag.bits()));
576 }
577 }
578
579 None
580 }
581
582 /// Construct a flags value with all bits unset.
583 #[inline]
584 fn empty() -> Self {
585 Self::from_bits_retain(Self::Bits::EMPTY)
586 }
587
588 /// Returns `true` if the flags value has all bits unset.
589 #[inline]
590 fn is_empty(&self) -> bool {
591 self.bits() == Self::Bits::EMPTY
592 }
593
594 /// Returns a flags value that contains all value.
595 ///
596 /// This will include bits that do not have any flags/meaning.
597 /// Use [`all`](Flags::all) if you want only the specified flags set.
598 #[inline]
599 fn all_bits() -> Self {
600 Self::from_bits_retain(Self::Bits::ALL)
601 }
602
603 /// Returns `true` if the bitflag contains all value bits set.
604 ///
605 /// This will check for all bits.
606 /// Use [`is_all`](Flags::is_all) if you want to check for all specified flags.
607 #[inline]
608 fn is_all_bits(&self) -> bool {
609 self.bits() == Self::Bits::ALL
610 }
611
612 /// Construct a flags value with all known flags set.
613 ///
614 /// This will only set the flags specified as associated constant and the defined extra valid
615 /// bits.
616 #[inline]
617 fn all() -> Self {
618 let mut truncated = Self::Bits::EMPTY;
619
620 for (_, flag) in Self::NAMED_FLAGS.iter() {
621 truncated |= flag.bits();
622 }
623
624 truncated |= Self::RESERVED_BITS;
625
626 Self::from_bits_retain(truncated)
627 }
628
629 /// Whether all known bits in this flags value are set.
630 #[inline]
631 fn is_all(&self) -> bool {
632 // NOTE: We check against `Self::all` here, not `Self::Bits::ALL`
633 // because the set of all flags may not use all bits
634 Self::all().bits() | self.bits() == self.bits()
635 }
636
637 /// Construct a flags value with all known named flags set.
638 ///
639 /// This will only set the flags specified as associated constant **without** the defined
640 /// extra valid bits.
641 #[inline]
642 fn all_named() -> Self {
643 let mut truncated = Self::Bits::EMPTY;
644
645 for (_, flag) in Self::NAMED_FLAGS.iter() {
646 truncated |= flag.bits();
647 }
648
649 Self::from_bits_retain(truncated)
650 }
651
652 /// Returns `true` if the flags value contais all known named flags.
653 #[inline]
654 fn is_all_named(&self) -> bool {
655 Self::all_named().bits() | self.bits() == self.bits()
656 }
657
658 /// Returns `true` if there are any unknown bits set in the flags value.
659 #[inline]
660 fn contains_unknown_bits(&self) -> bool {
661 Self::all().bits() & self.bits() != self.bits()
662 }
663
664 /// Returns `true` if there are any unnamed known bits set in the flags value.
665 #[inline]
666 fn contains_unnamed_bits(&self) -> bool {
667 Self::all_named().bits() & self.bits() != self.bits()
668 }
669
670 /// Returns a flags value with unknown bits removed from the original flags value.
671 #[inline]
672 fn truncated(&self) -> Self {
673 Self::from_bits_retain(self.bits() & Self::all().bits())
674 }
675
676 /// Returns `true` if this flags value intersects with any value in `other`.
677 ///
678 /// This is equivalent to `(self & other) != Self::empty()`
679 #[inline]
680 fn intersects(&self, other: Self) -> bool
681 where
682 Self: Sized,
683 {
684 self.bits() & other.bits() != Self::Bits::EMPTY
685 }
686
687 /// Returns `true` if this flags value contains all values of `other`.
688 ///
689 /// This is equivalent to `(self & other) == other`
690 #[inline]
691 fn contains(&self, other: Self) -> bool
692 where
693 Self: Sized,
694 {
695 self.bits() & other.bits() == other.bits()
696 }
697
698 /// Remove any unknown bits from the flags.
699 #[inline]
700 fn truncate(&mut self)
701 where
702 Self: Sized,
703 {
704 *self = Self::from_bits_truncate(self.bits());
705 }
706
707 /// Returns the intersection from this flags value with `other`.
708 #[must_use]
709 #[inline]
710 #[doc(alias = "and")]
711 fn intersection(self, other: Self) -> Self {
712 Self::from_bits_retain(self.bits() & other.bits())
713 }
714
715 /// Returns the union from this flags value with `other`.
716 #[must_use]
717 #[inline]
718 #[doc(alias = "or")]
719 fn union(self, other: Self) -> Self {
720 Self::from_bits_retain(self.bits() | other.bits())
721 }
722
723 /// Returns the difference from this flags value with `other`.
724 ///
725 /// In other words, returns the intersection of this value with the negation of `other`.
726 ///
727 /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
728 /// `difference` won't truncate `other`, but the `!` operator will.
729 #[must_use]
730 #[inline]
731 fn difference(self, other: Self) -> Self {
732 Self::from_bits_retain(self.bits() & !other.bits())
733 }
734
735 /// Returns the symmetric difference from this flags value with `other`..
736 #[must_use]
737 #[inline]
738 #[doc(alias = "xor")]
739 fn symmetric_difference(self, other: Self) -> Self {
740 Self::from_bits_retain(self.bits() ^ other.bits())
741 }
742
743 /// Returns the complement of the flags value.
744 ///
745 /// This is very similar to the `not` operation, but truncates non used bits.
746 #[must_use]
747 #[inline]
748 #[doc(alias = "not")]
749 fn complement(self) -> Self {
750 Self::from_bits_truncate(!self.bits())
751 }
752
753 /// Set the flags in `other` in the value.
754 #[inline]
755 #[doc(alias = "insert")]
756 fn set(&mut self, other: Self)
757 where
758 Self: Sized,
759 {
760 *self = Self::from_bits_retain(self.bits()).union(other);
761 }
762
763 /// Unset the flags bits in `other` in the value.
764 ///
765 /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
766 /// `remove` won't truncate `other`, but the `!` operator will.
767 #[inline]
768 #[doc(alias = "remove")]
769 fn unset(&mut self, other: Self)
770 where
771 Self: Sized,
772 {
773 *self = Self::from_bits_retain(self.bits()).difference(other);
774 }
775
776 /// Toggle the flags in `other` in the value.
777 #[inline]
778 fn toggle(&mut self, other: Self)
779 where
780 Self: Sized,
781 {
782 *self = Self::from_bits_retain(self.bits()).symmetric_difference(other);
783 }
784
785 /// Resets the flags value to a empty state.
786 #[inline]
787 fn clear(&mut self) {
788 *self = Self::empty()
789 }
790
791 /// Yield a set of contained flags values.
792 ///
793 /// Each yielded flags value will correspond to a defined named flag. Any unknown bits
794 /// will be yielded together as a final flags value.
795 #[inline]
796 fn iter(&self) -> iter::Iter<Self> {
797 iter::Iter::new(self)
798 }
799
800 /// Yield a set of contained named flags values.
801 ///
802 /// This method is like [`Flags::iter`], except only yields bits in contained named flags.
803 /// Any unknown bits, or bits not corresponding to a contained flag will not be yielded.
804 #[inline]
805 fn iter_names(&self) -> iter::IterNames<Self> {
806 iter::IterNames::new(self)
807 }
808}
809
810///////////////////////////////////////////////////////////////////////////////
811// Adapted from bitflags `bitflags_match!`
812///////////////////////////////////////////////////////////////////////////////
813
814/// A macro that matches flags values, similar to Rust's `match` statement.
815///
816/// In a regular `match` statement, the syntax `Flag::A | Flag::B` is interpreted as an or-pattern,
817/// instead of the bitwise-or of `Flag::A` and `Flag::B`. This can be surprising when combined with flags types
818/// because `Flag::A | Flag::B` won't match the pattern `Flag::A | Flag::B`. This macro is an alternative to
819/// `match` for flags values that doesn't have this issue.
820///
821/// # Syntax
822///
823/// ```ignore
824/// bitflag_match!(expression, {
825/// pattern1 => result1,
826/// pattern2 => result2,
827/// ..
828/// _ => default_result,
829/// })
830/// ```
831///
832/// The final `_ => default_result` arm is required, otherwise the macro will fail to compile.
833///
834/// # Examples
835///
836/// ```rust
837/// use bitflag_attr::{bitflag, bitflag_match};
838///
839/// #[bitflag(u8)]
840/// #[derive(Clone, Copy, PartialEq)]
841/// enum Flags {
842/// A = 1 << 0,
843/// B = 1 << 1,
844/// C = 1 << 2,
845/// }
846///
847/// let flags = Flags::A | Flags::B;
848///
849/// bitflag_match!(flags, {
850/// Flags::A | Flags::B => println!("A and/or B are set"),
851/// _ => println!("neither A nor B are set"),
852/// })
853/// ```
854///
855/// # How it works
856///
857/// The macro expands to a series of `if` statements, checking equality between the input expression
858/// and each pattern. This allows for correct matching of bitflag combinations, which is not possible
859/// with a regular match expression due to the way bitflags are implemented.
860///
861/// Patterns are evaluated in order.
862#[macro_export]
863macro_rules! bitflag_match {
864 ($operation:expr, {
865 $($t:tt)*
866 }) => {
867 // Expand to a closure so we can use `return`
868 // This makes it possible to apply attributes to the "match arms"
869 (|| {
870 $crate::__bitflag_match!($operation, { $($t)* })
871 })()
872 };
873}
874
875/// Expand the `bitflags_match` macro
876#[macro_export]
877#[doc(hidden)]
878macro_rules! __bitflag_match {
879 // Eat an optional `,` following a block match arm
880 ($operation:expr, { $pattern:expr => { $($body:tt)* } , $($t:tt)+ }) => {
881 $crate::__bitflag_match!($operation, { $pattern => { $($body)* } $($t)+ })
882 };
883 // Expand a block match arm `A => { .. }`
884 ($operation:expr, { $pattern:expr => { $($body:tt)* } $($t:tt)+ }) => {
885 {
886 if $operation == $pattern {
887 return {
888 $($body)*
889 };
890 }
891
892 $crate::__bitflag_match!($operation, { $($t)+ })
893 }
894 };
895 // Expand an expression match arm `A => x,`
896 ($operation:expr, { $pattern:expr => $body:expr , $($t:tt)+ }) => {
897 {
898 if $operation == $pattern {
899 return $body;
900 }
901
902 $crate::__bitflag_match!($operation, { $($t)+ })
903 }
904 };
905 // Expand the default case
906 ($operation:expr, { _ => $default:expr $(,)? }) => {
907 $default
908 }
909}
910
911/// A documentation module for this crate changelog.
912///
913/// This module is only available in the crate documentation.
914#[cfg(doc)]
915#[doc = include_str!("../CHANGELOG.md")]
916#[allow(rustdoc::broken_intra_doc_links)]
917pub mod changelog {}
918
919/// A documentation module for in depth specification definition and terminology.
920///
921/// This module is only available in the crate documentation.
922#[cfg(doc)]
923#[cfg(not(doctest))]
924#[doc = include_str!("../spec.md")]
925pub mod spec {}
926
927#[cfg(doc)]
928pub mod example_generated;