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;