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;