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/// Primitive types that can be used with [`bitflag`] attribute implement this trait.
372pub trait BitsPrimitive:
373    private::Sealed
374    + Copy
375    + PartialEq
376    + BitAnd<Output = Self>
377    + BitOr<Output = Self>
378    + BitXor<Output = Self>
379    + Not<Output = Self>
380    + BitAndAssign
381    + BitOrAssign
382    + BitXorAssign
383    + fmt::Binary
384    + fmt::LowerHex
385    + fmt::UpperHex
386    + fmt::Octal
387    + Sized
388    + 'static
389{
390    /// A value with all bits unset.
391    const EMPTY: Self;
392
393    /// A value with all bits set.
394    const ALL: Self;
395}
396
397mod private {
398    pub trait Sealed {}
399}
400
401macro_rules! impl_primitive {
402    ($($ty:ty),+ $(,)?) => {
403        $(
404            impl $crate::private::Sealed for $ty {}
405            impl $crate::BitsPrimitive for $ty {
406                const EMPTY: Self = 0;
407                const ALL: Self = !0;
408            }
409            impl $crate::parser::ParseHex for $ty {
410                #[inline]
411                fn parse_hex(input: &str) -> Result<Self, $crate::parser::ParseError>
412                where
413                    Self: Sized
414                {
415                    <$ty>::from_str_radix(input, 16).map_err(|_| $crate::parser::ParseError::invalid_hex_flag(input))
416                }
417            }
418        )+
419    };
420}
421
422impl_primitive!(i8, i16, i32, i64, i128, isize);
423impl_primitive!(u8, u16, u32, u64, u128, usize);
424
425/// A set of defined flags using a bits type as storage.
426///
427/// ## Implementing `Flags`
428///
429/// This trait is implemented by the [`bitflag`] macro:
430///
431/// ```
432/// use bitflag_attr::bitflag;
433///
434/// #[bitflag(u8)]
435/// #[derive(Clone, Copy)]
436/// enum MyFlags {
437///   A = 1,
438///   B = 1 << 1,
439/// }
440/// ```
441///
442/// It can also be implemented manually:
443///
444/// ```
445/// use bitflag_attr::{Flags};
446///
447/// #[derive(Clone, Copy)]
448/// struct MyFlags(u8);
449///
450/// impl Flags for MyFlags {
451///     const NAMED_FLAGS: &'static [(&'static str, Self)] = &[
452///         ("A", MyFlags(1)),
453///         ("B", MyFlags(1 << 1)),
454///     ];
455///
456///     const RESERVED_BITS: Self::Bits = 1 | (1 << 1);
457///
458///     type Bits = u8;
459///
460///     fn from_bits_retain(bits: Self::Bits) -> Self {
461///         MyFlags(bits)
462///     }
463///
464///     fn bits(&self) -> Self::Bits {
465///         self.0
466///     }
467/// }
468/// ```
469///
470/// ## Using `Flags`
471///
472/// The `Flags` trait can be used generically to work with any flags types. In this example,
473/// we can count the number of defined named flags:
474///
475/// ```
476/// # use bitflag_attr::{bitflag, Flags};
477/// fn defined_flags<F: Flags>() -> usize {
478///     F::NAMED_FLAGS.iter().count()
479/// }
480///
481/// #[bitflag(u8)]
482/// #[non_exhaustive]
483/// #[derive(Clone, Copy)]
484/// enum MyFlags {
485///     A = 1,
486///     B = 1 << 1,
487///     C = 1 << 2,
488/// }
489///
490/// assert_eq!(3, defined_flags::<MyFlags>());
491/// ```
492pub trait Flags: Sized + Copy + 'static {
493    /// The set of named defined flags.
494    const NAMED_FLAGS: &'static [(&'static str, Self)];
495
496    /// All reserved bits values for the flags.
497    ///
498    /// The bits defined here can be named or unnamed and the values defined here will be considered
499    /// for the [`all`] method as a known value.
500    ///
501    /// This can be used for [externally defined flags](crate#externally-defined-flags) or even
502    /// reserving bits for future usage.
503    ///
504    /// Usually, the value of this constant can be either `0` or the bitor-ed bits values of the
505    /// named flags[^1]. For externally defined flags, the most common value is `!0`, i.e. all bits.
506    ///
507    /// [^1]: By pure logic, all bits from named flags are reserved bits. But alternatively,
508    /// "reserved bits" can be thought as only the extra bits to be reserved as known. For that
509    /// reason, the default implementation of the [`all`] method consider this value **and** the
510    /// values of [`NAMED_FLAGS`] to generate the resulting value.
511    ///
512    /// [`all`]: Flags::all
513    /// [`NAMED_FLAGS`]: Flags::NAMED_FLAGS
514    const RESERVED_BITS: Self::Bits;
515
516    /// The underlying bits type.
517    type Bits: BitsPrimitive;
518
519    /// Return the underlying bits value.
520    ///
521    /// The returned value is exactly the bits set in this flags value.
522    fn bits(&self) -> Self::Bits;
523
524    /// Convert from `bits` value exactly.
525    fn from_bits_retain(bits: Self::Bits) -> Self;
526
527    /// Converts from a `bits` value. Returning [`None`] is any unknown bits are set.
528    #[inline]
529    fn from_bits(bits: Self::Bits) -> Option<Self> {
530        let truncated = Self::from_bits_truncate(bits);
531
532        if truncated.bits() == bits {
533            Some(truncated)
534        } else {
535            None
536        }
537    }
538
539    /// Convert from `bits` value, unsetting any unknown bits.
540    #[inline]
541    fn from_bits_truncate(bits: Self::Bits) -> Self {
542        Self::from_bits_retain(bits & Self::all().bits())
543    }
544
545    /// Convert from a flag `name`.
546    #[inline]
547    fn from_flag_name(name: &str) -> Option<Self> {
548        // Don't parse empty names as empty flags
549        if name.is_empty() {
550            return None;
551        }
552
553        Self::NAMED_FLAGS
554            .iter()
555            .find(|(s, _)| *s == name)
556            .map(|(_, v)| Self::from_bits_retain(v.bits()))
557    }
558
559    /// Get a flags value with the bits of a flag with the given name set.
560    ///
561    /// This method will return `None` if `name` is empty or doesn't
562    /// correspond to any named flag.
563    #[inline]
564    fn from_name(name: &str) -> Option<Self> {
565        // Don't parse empty names as empty flags
566        if name.is_empty() {
567            return None;
568        }
569
570        for (flag_name, flag) in Self::NAMED_FLAGS {
571            if *flag_name == name {
572                return Some(Self::from_bits_retain(flag.bits()));
573            }
574        }
575
576        None
577    }
578
579    /// Construct a flags value with all bits unset.
580    #[inline]
581    fn empty() -> Self {
582        Self::from_bits_retain(Self::Bits::EMPTY)
583    }
584
585    /// Returns `true` if the flags value has all bits unset.
586    #[inline]
587    fn is_empty(&self) -> bool {
588        self.bits() == Self::Bits::EMPTY
589    }
590
591    /// Returns a flags value that contains all value.
592    ///
593    /// This will include bits that do not have any flags/meaning.
594    /// Use [`all`](Flags::all) if you want only the specified flags set.
595    #[inline]
596    fn all_bits() -> Self {
597        Self::from_bits_retain(Self::Bits::ALL)
598    }
599
600    /// Returns `true` if the bitflag contains all value bits set.
601    ///
602    /// This will check for all bits.
603    /// Use [`is_all`](Flags::is_all) if you want to check for all specified flags.
604    #[inline]
605    fn is_all_bits(&self) -> bool {
606        self.bits() == Self::Bits::ALL
607    }
608
609    /// Construct a flags value with all known flags set.
610    ///
611    /// This will only set the flags specified as associated constant and the defined extra valid
612    /// bits.
613    #[inline]
614    fn all() -> Self {
615        let mut truncated = Self::Bits::EMPTY;
616
617        for (_, flag) in Self::NAMED_FLAGS.iter() {
618            truncated |= flag.bits();
619        }
620
621        truncated |= Self::RESERVED_BITS;
622
623        Self::from_bits_retain(truncated)
624    }
625
626    /// Whether all known bits in this flags value are set.
627    #[inline]
628    fn is_all(&self) -> bool {
629        // NOTE: We check against `Self::all` here, not `Self::Bits::ALL`
630        // because the set of all flags may not use all bits
631        Self::all().bits() | self.bits() == self.bits()
632    }
633
634    /// Construct a flags value with all known named flags set.
635    ///
636    /// This will only set the flags specified as associated constant **without** the defined
637    /// extra valid bits.
638    #[inline]
639    fn all_named() -> Self {
640        let mut truncated = Self::Bits::EMPTY;
641
642        for (_, flag) in Self::NAMED_FLAGS.iter() {
643            truncated |= flag.bits();
644        }
645
646        Self::from_bits_retain(truncated)
647    }
648
649    /// Returns `true` if the flags value contais all known named flags.
650    #[inline]
651    fn is_all_named(&self) -> bool {
652        Self::all_named().bits() | self.bits() == self.bits()
653    }
654
655    /// Returns `true` if there are any unknown bits set in the flags value.
656    #[inline]
657    fn contains_unknown_bits(&self) -> bool {
658        Self::all().bits() & self.bits() != self.bits()
659    }
660
661    /// Returns `true` if there are any unnamed known bits set in the flags value.
662    #[inline]
663    fn contains_unnamed_bits(&self) -> bool {
664        Self::all_named().bits() & self.bits() != self.bits()
665    }
666
667    /// Returns a flags value with unknown bits removed from the original flags value.
668    #[inline]
669    fn truncated(&self) -> Self {
670        Self::from_bits_retain(self.bits() & Self::all().bits())
671    }
672
673    /// Returns `true` if this flags value intersects with any value in `other`.
674    ///
675    /// This is equivalent to `(self & other) != Self::empty()`
676    #[inline]
677    fn intersects(&self, other: Self) -> bool
678    where
679        Self: Sized,
680    {
681        self.bits() & other.bits() != Self::Bits::EMPTY
682    }
683
684    /// Returns `true` if this flags value contains all values of `other`.
685    ///
686    /// This is equivalent to `(self & other) == other`
687    #[inline]
688    fn contains(&self, other: Self) -> bool
689    where
690        Self: Sized,
691    {
692        self.bits() & other.bits() == other.bits()
693    }
694
695    /// Remove any unknown bits from the flags.
696    #[inline]
697    fn truncate(&mut self)
698    where
699        Self: Sized,
700    {
701        *self = Self::from_bits_truncate(self.bits());
702    }
703
704    /// Returns the intersection from this flags value with `other`.
705    #[must_use]
706    #[inline]
707    #[doc(alias = "and")]
708    fn intersection(self, other: Self) -> Self {
709        Self::from_bits_retain(self.bits() & other.bits())
710    }
711
712    /// Returns the union from this flags value with `other`.
713    #[must_use]
714    #[inline]
715    #[doc(alias = "or")]
716    fn union(self, other: Self) -> Self {
717        Self::from_bits_retain(self.bits() | other.bits())
718    }
719
720    /// Returns the difference from this flags value with `other`.
721    ///
722    /// In other words, returns the intersection of this value with the negation of `other`.
723    ///
724    /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
725    /// `difference` won't truncate `other`, but the `!` operator will.
726    #[must_use]
727    #[inline]
728    fn difference(self, other: Self) -> Self {
729        Self::from_bits_retain(self.bits() & !other.bits())
730    }
731
732    /// Returns the symmetric difference from this flags value with `other`..
733    #[must_use]
734    #[inline]
735    #[doc(alias = "xor")]
736    fn symmetric_difference(self, other: Self) -> Self {
737        Self::from_bits_retain(self.bits() ^ other.bits())
738    }
739
740    /// Returns the complement of the flags value.
741    ///
742    /// This is very similar to the `not` operation, but truncates non used bits.
743    #[must_use]
744    #[inline]
745    #[doc(alias = "not")]
746    fn complement(self) -> Self {
747        Self::from_bits_truncate(!self.bits())
748    }
749
750    /// Set the flags in `other` in the value.
751    #[inline]
752    #[doc(alias = "insert")]
753    fn set(&mut self, other: Self)
754    where
755        Self: Sized,
756    {
757        *self = Self::from_bits_retain(self.bits()).union(other);
758    }
759
760    /// Unset the flags bits in `other` in the value.
761    ///
762    /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
763    /// `remove` won't truncate `other`, but the `!` operator will.
764    #[inline]
765    #[doc(alias = "remove")]
766    fn unset(&mut self, other: Self)
767    where
768        Self: Sized,
769    {
770        *self = Self::from_bits_retain(self.bits()).difference(other);
771    }
772
773    /// Toggle the flags in `other` in the value.
774    #[inline]
775    fn toggle(&mut self, other: Self)
776    where
777        Self: Sized,
778    {
779        *self = Self::from_bits_retain(self.bits()).symmetric_difference(other);
780    }
781
782    /// Resets the flags value to a empty state.
783    #[inline]
784    fn clear(&mut self) {
785        *self = Self::empty()
786    }
787
788    /// Yield a set of contained flags values.
789    ///
790    /// Each yielded flags value will correspond to a defined named flag. Any unknown bits
791    /// will be yielded together as a final flags value.
792    #[inline]
793    fn iter(&self) -> iter::Iter<Self> {
794        iter::Iter::new(self)
795    }
796
797    /// Yield a set of contained named flags values.
798    ///
799    /// This method is like [`Flags::iter`], except only yields bits in contained named flags.
800    /// Any unknown bits, or bits not corresponding to a contained flag will not be yielded.
801    #[inline]
802    fn iter_names(&self) -> iter::IterNames<Self> {
803        iter::IterNames::new(self)
804    }
805}
806
807///////////////////////////////////////////////////////////////////////////////
808// Adapted from bitflags `bitflags_match!`
809///////////////////////////////////////////////////////////////////////////////
810
811/// A macro that matches flags values, similar to Rust's `match` statement.
812///
813/// In a regular `match` statement, the syntax `Flag::A | Flag::B` is interpreted as an or-pattern,
814/// instead of the bitwise-or of `Flag::A` and `Flag::B`. This can be surprising when combined with flags types
815/// because `Flag::A | Flag::B` won't match the pattern `Flag::A | Flag::B`. This macro is an alternative to
816/// `match` for flags values that doesn't have this issue.
817///
818/// # Syntax
819///
820/// ```ignore
821/// bitflag_match!(expression, {
822///     pattern1 => result1,
823///     pattern2 => result2,
824///     ..
825///     _ => default_result,
826/// })
827/// ```
828///
829/// The final `_ => default_result` arm is required, otherwise the macro will fail to compile.
830///
831/// # Examples
832///
833/// ```rust
834/// use bitflag_attr::{bitflag, bitflag_match};
835///
836/// #[bitflag(u8)]
837/// #[derive(Clone, Copy, PartialEq)]
838/// enum Flags {
839///     A = 1 << 0,
840///     B = 1 << 1,
841///     C = 1 << 2,
842/// }
843///
844/// let flags = Flags::A | Flags::B;
845///
846/// bitflag_match!(flags, {
847///     Flags::A | Flags::B => println!("A and/or B are set"),
848///     _ => println!("neither A nor B are set"),
849/// })
850/// ```
851///
852/// # How it works
853///
854/// The macro expands to a series of `if` statements, checking equality between the input expression
855/// and each pattern. This allows for correct matching of bitflag combinations, which is not possible
856/// with a regular match expression due to the way bitflags are implemented.
857///
858/// Patterns are evaluated in order.
859#[macro_export]
860macro_rules! bitflag_match {
861    ($operation:expr, {
862        $($t:tt)*
863    }) => {
864        // Expand to a closure so we can use `return`
865        // This makes it possible to apply attributes to the "match arms"
866        (|| {
867            $crate::__bitflag_match!($operation, { $($t)* })
868        })()
869    };
870}
871
872/// Expand the `bitflags_match` macro
873#[macro_export]
874#[doc(hidden)]
875macro_rules! __bitflag_match {
876    // Eat an optional `,` following a block match arm
877    ($operation:expr, { $pattern:expr => { $($body:tt)* } , $($t:tt)+ }) => {
878        $crate::__bitflag_match!($operation, { $pattern => { $($body)* } $($t)+ })
879    };
880    // Expand a block match arm `A => { .. }`
881    ($operation:expr, { $pattern:expr => { $($body:tt)* } $($t:tt)+ }) => {
882        {
883            if $operation == $pattern {
884                return {
885                    $($body)*
886                };
887            }
888
889            $crate::__bitflag_match!($operation, { $($t)+ })
890        }
891    };
892    // Expand an expression match arm `A => x,`
893    ($operation:expr, { $pattern:expr => $body:expr , $($t:tt)+ }) => {
894        {
895            if $operation == $pattern {
896                return $body;
897            }
898
899            $crate::__bitflag_match!($operation, { $($t)+ })
900        }
901    };
902    // Expand the default case
903    ($operation:expr, { _ => $default:expr $(,)? }) => {
904        $default
905    }
906}
907
908/// A documentation module for this crate changelog.
909///
910/// This module is only available in the crate documentation.
911#[cfg(doc)]
912#[doc = include_str!("../CHANGELOG.md")]
913#[allow(rustdoc::broken_intra_doc_links)]
914pub mod changelog {}
915
916/// A documentation module for in depth specification definition and terminology.
917///
918/// This module is only available in the crate documentation.
919#[cfg(doc)]
920#[cfg(not(doctest))]
921#[doc = include_str!("../spec.md")]
922pub mod spec {}
923
924#[cfg(doc)]
925pub mod example_generated;