Skip to main content

bitflags/
traits.rs

1use core::{
2    fmt,
3    ops::{BitAnd, BitOr, BitXor, Not},
4};
5
6use crate::{
7    iter,
8    parser::{ParseError, ParseHex, WriteHex},
9};
10
11/**
12A defined flags value that may be named or unnamed.
13*/
14#[derive(Debug)]
15pub struct Flag<B> {
16    name: &'static str,
17    value: B,
18}
19
20impl<B> Flag<B> {
21    /**
22    Define a flag.
23
24    If `name` is non-empty then the flag is named, otherwise it's unnamed.
25    */
26    pub const fn new(name: &'static str, value: B) -> Self {
27        Flag { name, value }
28    }
29
30    /**
31    Get the name of this flag.
32
33    If the flag is unnamed then the returned string will be empty.
34    */
35    pub const fn name(&self) -> &'static str {
36        self.name
37    }
38
39    /**
40    Get the flags value of this flag.
41    */
42    pub const fn value(&self) -> &B {
43        &self.value
44    }
45
46    /**
47    Whether the flag is named.
48
49    If [`Flag::name`] returns a non-empty string then this method will return `true`.
50    */
51    pub const fn is_named(&self) -> bool {
52        !self.name.is_empty()
53    }
54
55    /**
56    Whether the flag is unnamed.
57
58    If [`Flag::name`] returns a non-empty string then this method will return `false`.
59    */
60    pub const fn is_unnamed(&self) -> bool {
61        self.name.is_empty()
62    }
63}
64
65/**
66A set of defined flags using a bits type as storage.
67
68## Implementing `Flags`
69
70This trait is implemented by the [`bitflags`](macro.bitflags.html) macro:
71
72```
73use bitflags::bitflags;
74
75bitflags! {
76    struct MyFlags: u8 {
77        const A = 1;
78        const B = 1 << 1;
79    }
80}
81```
82
83It can also be implemented manually:
84
85```
86use bitflags::{Flag, Flags};
87
88struct MyFlags(u8);
89
90impl Flags for MyFlags {
91    const FLAGS: &'static [Flag<Self>] = &[
92        Flag::new("A", MyFlags(1)),
93        Flag::new("B", MyFlags(1 << 1)),
94    ];
95
96    type Bits = u8;
97
98    fn from_bits_retain(bits: Self::Bits) -> Self {
99        MyFlags(bits)
100    }
101
102    fn bits(&self) -> Self::Bits {
103        self.0
104    }
105}
106```
107
108## Using `Flags`
109
110The `Flags` trait can be used generically to work with any flags types. In this example,
111we can count the number of defined named flags:
112
113```
114# use bitflags::{bitflags, Flags};
115fn defined_flags<F: Flags>() -> usize {
116    F::FLAGS.iter().filter(|f| f.is_named()).count()
117}
118
119bitflags! {
120    struct MyFlags: u8 {
121        const A = 1;
122        const B = 1 << 1;
123        const C = 1 << 2;
124
125        const _ = !0;
126    }
127}
128
129assert_eq!(3, defined_flags::<MyFlags>());
130```
131*/
132pub trait Flags: Sized + 'static {
133    /// The set of defined flags.
134    const FLAGS: &'static [Flag<Self>];
135
136    /// The underlying bits type.
137    type Bits: Bits;
138
139    /// Get a flags value with all bits unset.
140    fn empty() -> Self {
141        Self::from_bits_retain(Self::Bits::EMPTY)
142    }
143
144    /// Get a flags value with all known bits set.
145    fn all() -> Self {
146        let mut truncated = Self::Bits::EMPTY;
147
148        for flag in Self::FLAGS.iter() {
149            truncated = truncated | flag.value().bits();
150        }
151
152        Self::from_bits_retain(truncated)
153    }
154
155    /// Get a flags value with all bits from named flags set.
156    ///
157    /// This method is equivalent to [`Flags::all`] unless [`Flags::FLAGS`] contains unnamed flags.
158    fn all_named() -> Self {
159        Self::from_bits_retain(
160            Self::FLAGS
161                .iter()
162                .filter(|f| !f.name().is_empty())
163                .fold(Self::empty().bits(), |acc, f| acc | f.value().bits()),
164        )
165    }
166
167    /// Get the known bits from a flags value.
168    fn known_bits(&self) -> Self::Bits {
169        self.bits() & Self::all().bits()
170    }
171
172    /// Get the unknown bits from a flags value.
173    fn unknown_bits(&self) -> Self::Bits {
174        self.bits() & !Self::all().bits()
175    }
176
177    /// This method will return `true` if any unknown bits are set.
178    fn contains_unknown_bits(&self) -> bool {
179        self.unknown_bits() != Self::Bits::EMPTY
180    }
181
182    /// Get the underlying bits value.
183    ///
184    /// The returned value is exactly the bits set in this flags value.
185    fn bits(&self) -> Self::Bits;
186
187    /// Convert from a bits value.
188    ///
189    /// This method will return `None` if any unknown bits are set.
190    fn from_bits(bits: Self::Bits) -> Option<Self> {
191        let truncated = Self::from_bits_truncate(bits);
192
193        if truncated.bits() == bits {
194            Some(truncated)
195        } else {
196            None
197        }
198    }
199
200    /// Convert from a bits value, unsetting any unknown bits.
201    fn from_bits_truncate(bits: Self::Bits) -> Self {
202        Self::from_bits_retain(bits & Self::all().bits())
203    }
204
205    /// Convert from a bits value exactly.
206    fn from_bits_retain(bits: Self::Bits) -> Self;
207
208    /// Get a flags value with the bits of a flag with the given name set.
209    ///
210    /// This method will return `None` if `name` is empty or doesn't
211    /// correspond to any named flag.
212    fn from_name(name: &str) -> Option<Self> {
213        // Don't parse empty names as empty flags
214        if name.is_empty() {
215            return None;
216        }
217
218        for flag in Self::FLAGS {
219            if flag.name() == name {
220                return Some(Self::from_bits_retain(flag.value().bits()));
221            }
222        }
223
224        None
225    }
226
227    /// Yield a set of contained flags values.
228    ///
229    /// Each yielded flags value will correspond to a defined named flag. Any unknown bits
230    /// will be yielded together as a final flags value.
231    fn iter(&self) -> iter::Iter<Self> {
232        iter::Iter::new(self)
233    }
234
235    /// Yield a set of contained named flags values.
236    ///
237    /// This method is like [`Flags::iter`], except only yields bits in contained named flags.
238    /// Any unknown bits, or bits not corresponding to a contained flag will not be yielded.
239    fn iter_names(&self) -> iter::IterNames<Self> {
240        iter::IterNames::new(self)
241    }
242
243    /// Yield a set of all named flags defined by [`Self::FLAGS`].
244    fn iter_defined_names() -> iter::IterDefinedNames<Self> {
245        iter::IterDefinedNames::new()
246    }
247
248    /// Get an iterator over all defined names for this flags value.
249    ///
250    /// This iterator will yield all defined names for the flags value, including
251    /// any convenience flags.
252    fn iter_equal_names(&self) -> iter::IterEqualNames<Self> {
253        iter::IterEqualNames::new(self)
254    }
255
256    /// Whether all bits in this flags value are unset.
257    fn is_empty(&self) -> bool {
258        self.bits() == Self::Bits::EMPTY
259    }
260
261    /// Whether all known bits in this flags value are set.
262    fn is_all(&self) -> bool {
263        // NOTE: We check against `Self::all` here, not `Self::Bits::ALL`
264        // because the set of all flags may not use all bits
265        Self::all().bits() | self.bits() == self.bits()
266    }
267
268    /// Whether any set bits in `other` are also set in `self`.
269    fn intersects(&self, other: Self) -> bool
270    where
271        Self: Sized,
272    {
273        self.bits() & other.bits() != Self::Bits::EMPTY
274    }
275
276    /// Whether all set bits in `other` are also set in `self`.
277    fn contains(&self, other: Self) -> bool
278    where
279        Self: Sized,
280    {
281        self.bits() & other.bits() == other.bits()
282    }
283
284    /// Remove any unknown bits from the flags.
285    fn truncate(&mut self)
286    where
287        Self: Sized,
288    {
289        *self = Self::from_bits_truncate(self.bits());
290    }
291
292    /// The bitwise or (`|`) of the bits in `self` and `other`.
293    fn insert(&mut self, other: Self)
294    where
295        Self: Sized,
296    {
297        *self = Self::from_bits_retain(self.bits()).union(other);
298    }
299
300    /// The intersection of `self` with the complement of `other` (`&!`).
301    ///
302    /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
303    /// `remove` won't truncate `other`, but the `!` operator will.
304    fn remove(&mut self, other: Self)
305    where
306        Self: Sized,
307    {
308        *self = Self::from_bits_retain(self.bits()).difference(other);
309    }
310
311    /// The bitwise exclusive-or (`^`) of the bits in `self` and `other`.
312    fn toggle(&mut self, other: Self)
313    where
314        Self: Sized,
315    {
316        *self = Self::from_bits_retain(self.bits()).symmetric_difference(other);
317    }
318
319    /// Call [`Flags::insert`] when `value` is `true` or [`Flags::remove`] when `value` is `false`.
320    fn set(&mut self, other: Self, value: bool)
321    where
322        Self: Sized,
323    {
324        if value {
325            self.insert(other);
326        } else {
327            self.remove(other);
328        }
329    }
330
331    /// Unsets all bits in the flags.
332    fn clear(&mut self)
333    where
334        Self: Sized,
335    {
336        *self = Self::empty();
337    }
338
339    /// The bitwise and (`&`) of the bits in `self` and `other`.
340    #[must_use]
341    fn intersection(self, other: Self) -> Self {
342        Self::from_bits_retain(self.bits() & other.bits())
343    }
344
345    /// The bitwise or (`|`) of the bits in `self` and `other`.
346    #[must_use]
347    fn union(self, other: Self) -> Self {
348        Self::from_bits_retain(self.bits() | other.bits())
349    }
350
351    /// The intersection of `self` with the complement of `other` (`&!`).
352    ///
353    /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
354    /// `difference` won't truncate `other`, but the `!` operator will.
355    #[must_use]
356    fn difference(self, other: Self) -> Self {
357        Self::from_bits_retain(self.bits() & !other.bits())
358    }
359
360    /// The bitwise exclusive-or (`^`) of the bits in `self` and `other`.
361    #[must_use]
362    fn symmetric_difference(self, other: Self) -> Self {
363        Self::from_bits_retain(self.bits() ^ other.bits())
364    }
365
366    /// The bitwise negation (`!`) of the bits in `self`, truncating the result.
367    #[must_use]
368    fn complement(self) -> Self {
369        Self::from_bits_truncate(!self.bits())
370    }
371}
372
373/**
374A bits type that can be used as storage for a flags type.
375*/
376pub trait Bits:
377    Clone
378    + Copy
379    + PartialEq
380    + BitAnd<Output = Self>
381    + BitOr<Output = Self>
382    + BitXor<Output = Self>
383    + Not<Output = Self>
384    + Sized
385    + 'static
386{
387    /// A value with all bits unset.
388    const EMPTY: Self;
389
390    /// A value with all bits set.
391    const ALL: Self;
392}
393
394// Not re-exported: prevent custom `Bits` impls being used in the `bitflags!` macro,
395// or they may fail to compile based on crate features
396pub trait Primitive {}
397
398macro_rules! impl_bits {
399    ($($u:ty, $i:ty,)*) => {
400        $(
401            impl Bits for $u {
402                const EMPTY: $u = 0;
403                const ALL: $u = <$u>::MAX;
404            }
405
406            impl Bits for $i {
407                const EMPTY: $i = 0;
408                const ALL: $i = <$u>::MAX as $i;
409            }
410
411            impl ParseHex for $u {
412                fn parse_hex(input: &str) -> Result<Self, ParseError> {
413                    <$u>::from_str_radix(input, 16).map_err(|_| ParseError::invalid_hex_flag(input))
414                }
415            }
416
417            impl ParseHex for $i {
418                fn parse_hex(input: &str) -> Result<Self, ParseError> {
419                    <$i>::from_str_radix(input, 16).map_err(|_| ParseError::invalid_hex_flag(input))
420                }
421            }
422
423            impl WriteHex for $u {
424                fn write_hex<W: fmt::Write>(&self, mut writer: W) -> fmt::Result {
425                    write!(writer, "{:x}", self)
426                }
427            }
428
429            impl WriteHex for $i {
430                fn write_hex<W: fmt::Write>(&self, mut writer: W) -> fmt::Result {
431                    write!(writer, "{:x}", self)
432                }
433            }
434
435            impl Primitive for $i {}
436            impl Primitive for $u {}
437        )*
438    }
439}
440
441impl_bits! {
442    u8, i8,
443    u16, i16,
444    u32, i32,
445    u64, i64,
446    u128, i128,
447    usize, isize,
448}
449
450/// A trait for referencing the `bitflags`-owned internal type
451/// without exposing it publicly.
452pub trait PublicFlags {
453    /// The type of the underlying storage.
454    type Primitive: Primitive;
455
456    /// The type of the internal field on the generated flags type.
457    type Internal;
458}
459
460#[doc(hidden)]
461#[deprecated(note = "use the `Flags` trait instead")]
462pub trait BitFlags: ImplementedByBitFlagsMacro + Flags {
463    /// An iterator over enabled flags in an instance of the type.
464    type Iter: Iterator<Item = Self>;
465
466    /// An iterator over the raw names and bits for enabled flags in an instance of the type.
467    type IterNames: Iterator<Item = (&'static str, Self)>;
468}
469
470#[allow(deprecated)]
471impl<B: Flags> BitFlags for B {
472    type Iter = iter::Iter<Self>;
473    type IterNames = iter::IterNames<Self>;
474}
475
476impl<B: Flags> ImplementedByBitFlagsMacro for B {}
477
478/// A marker trait that signals that an implementation of `BitFlags` came from the `bitflags!` macro.
479///
480/// There's nothing stopping an end-user from implementing this trait, but we don't guarantee their
481/// manual implementations won't break between non-breaking releases.
482#[doc(hidden)]
483pub trait ImplementedByBitFlagsMacro {}
484
485pub(crate) mod __private {
486    pub use super::{ImplementedByBitFlagsMacro, PublicFlags};
487}