#
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 the known bits from a flags value.
    156    fn known_bits(&self) -> Self::Bits {
    157        self.bits() & Self::all().bits()
    158    }
    159
    160    /// Get the unknown bits from a flags value.
    161    fn unknown_bits(&self) -> Self::Bits {
    162        self.bits() & !Self::all().bits()
    163    }
    164
    165    /// This method will return `true` if any unknown bits are set.
    166    fn contains_unknown_bits(&self) -> bool {
    167        self.unknown_bits() != Self::Bits::EMPTY
    168    }
    169
    170    /// Get the underlying bits value.
    171    ///
    172    /// The returned value is exactly the bits set in this flags value.
    173    fn bits(&self) -> Self::Bits;
    174
    175    /// Convert from a bits value.
    176    ///
    177    /// This method will return `None` if any unknown bits are set.
    178    fn from_bits(bits: Self::Bits) -> Option<Self> {
    179        let truncated = Self::from_bits_truncate(bits);
    180
    181        if truncated.bits() == bits {
    182            Some(truncated)
    183        } else {
    184            None
    185        }
    186    }
    187
    188    /// Convert from a bits value, unsetting any unknown bits.
    189    fn from_bits_truncate(bits: Self::Bits) -> Self {
    190        Self::from_bits_retain(bits & Self::all().bits())
    191    }
    192
    193    /// Convert from a bits value exactly.
    194    fn from_bits_retain(bits: Self::Bits) -> Self;
    195
    196    /// Get a flags value with the bits of a flag with the given name set.
    197    ///
    198    /// This method will return `None` if `name` is empty or doesn't
    199    /// correspond to any named flag.
    200    fn from_name(name: &str) -> Option<Self> {
    201        // Don't parse empty names as empty flags
    202        if name.is_empty() {
    203            return None;
    204        }
    205
    206        for flag in Self::FLAGS {
    207            if flag.name() == name {
    208                return Some(Self::from_bits_retain(flag.value().bits()));
    209            }
    210        }
    211
    212        None
    213    }
    214
    215    /// Yield a set of contained flags values.
    216    ///
    217    /// Each yielded flags value will correspond to a defined named flag. Any unknown bits
    218    /// will be yielded together as a final flags value.
    219    fn iter(&self) -> iter::Iter<Self> {
    220        iter::Iter::new(self)
    221    }
    222
    223    /// Yield a set of contained named flags values.
    224    ///
    225    /// This method is like [`Flags::iter`], except only yields bits in contained named flags.
    226    /// Any unknown bits, or bits not corresponding to a contained flag will not be yielded.
    227    fn iter_names(&self) -> iter::IterNames<Self> {
    228        iter::IterNames::new(self)
    229    }
    230
    231    /// Yield a set of all named flags defined by [`Self::FLAGS`].
    232    fn iter_defined_names() -> iter::IterDefinedNames<Self> {
    233        iter::IterDefinedNames::new()
    234    }
    235
    236    /// Whether all bits in this flags value are unset.
    237    fn is_empty(&self) -> bool {
    238        self.bits() == Self::Bits::EMPTY
    239    }
    240
    241    /// Whether all known bits in this flags value are set.
    242    fn is_all(&self) -> bool {
    243        // NOTE: We check against `Self::all` here, not `Self::Bits::ALL`
    244        // because the set of all flags may not use all bits
    245        Self::all().bits() | self.bits() == self.bits()
    246    }
    247
    248    /// Whether any set bits in a source flags value are also set in a target flags value.
    249    fn intersects(&self, other: Self) -> bool
    250    where
    251        Self: Sized,
    252    {
    253        self.bits() & other.bits() != Self::Bits::EMPTY
    254    }
    255
    256    /// Whether all set bits in a source flags value are also set in a target flags value.
    257    fn contains(&self, other: Self) -> bool
    258    where
    259        Self: Sized,
    260    {
    261        self.bits() & other.bits() == other.bits()
    262    }
    263
    264    /// Remove any unknown bits from the flags.
    265    fn truncate(&mut self)
    266    where
    267        Self: Sized,
    268    {
    269        *self = Self::from_bits_truncate(self.bits());
    270    }
    271
    272    /// The bitwise or (`|`) of the bits in two flags values.
    273    fn insert(&mut self, other: Self)
    274    where
    275        Self: Sized,
    276    {
    277        *self = Self::from_bits_retain(self.bits()).union(other);
    278    }
    279
    280    /// The intersection of a source flags value with the complement of a target flags value (`&!`).
    281    ///
    282    /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
    283    /// `remove` won't truncate `other`, but the `!` operator will.
    284    fn remove(&mut self, other: Self)
    285    where
    286        Self: Sized,
    287    {
    288        *self = Self::from_bits_retain(self.bits()).difference(other);
    289    }
    290
    291    /// The bitwise exclusive-or (`^`) of the bits in two flags values.
    292    fn toggle(&mut self, other: Self)
    293    where
    294        Self: Sized,
    295    {
    296        *self = Self::from_bits_retain(self.bits()).symmetric_difference(other);
    297    }
    298
    299    /// Call [`Flags::insert`] when `value` is `true` or [`Flags::remove`] when `value` is `false`.
    300    fn set(&mut self, other: Self, value: bool)
    301    where
    302        Self: Sized,
    303    {
    304        if value {
    305            self.insert(other);
    306        } else {
    307            self.remove(other);
    308        }
    309    }
    310
    311    /// Unsets all bits in the flags.
    312    fn clear(&mut self)
    313    where
    314        Self: Sized,
    315    {
    316        *self = Self::empty();
    317    }
    318
    319    /// The bitwise and (`&`) of the bits in two flags values.
    320    #[must_use]
    321    fn intersection(self, other: Self) -> Self {
    322        Self::from_bits_retain(self.bits() & other.bits())
    323    }
    324
    325    /// The bitwise or (`|`) of the bits in two flags values.
    326    #[must_use]
    327    fn union(self, other: Self) -> Self {
    328        Self::from_bits_retain(self.bits() | other.bits())
    329    }
    330
    331    /// The intersection of a source flags value with the complement of a target flags value (`&!`).
    332    ///
    333    /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
    334    /// `difference` won't truncate `other`, but the `!` operator will.
    335    #[must_use]
    336    fn difference(self, other: Self) -> Self {
    337        Self::from_bits_retain(self.bits() & !other.bits())
    338    }
    339
    340    /// The bitwise exclusive-or (`^`) of the bits in two flags values.
    341    #[must_use]
    342    fn symmetric_difference(self, other: Self) -> Self {
    343        Self::from_bits_retain(self.bits() ^ other.bits())
    344    }
    345
    346    /// The bitwise negation (`!`) of the bits in a flags value, truncating the result.
    347    #[must_use]
    348    fn complement(self) -> Self {
    349        Self::from_bits_truncate(!self.bits())
    350    }
    351}
    352
    353/**
    354A bits type that can be used as storage for a flags type.
    355*/
    356pub trait Bits:
    357    Clone
    358    + Copy
    359    + PartialEq
    360    + BitAnd<Output = Self>
    361    + BitOr<Output = Self>
    362    + BitXor<Output = Self>
    363    + Not<Output = Self>
    364    + Sized
    365    + 'static
    366{
    367    /// A value with all bits unset.
    368    const EMPTY: Self;
    369
    370    /// A value with all bits set.
    371    const ALL: Self;
    372}
    373
    374// Not re-exported: prevent custom `Bits` impls being used in the `bitflags!` macro,
    375// or they may fail to compile based on crate features
    376pub trait Primitive {}
    377
    378macro_rules! impl_bits {
    379    ($($u:ty, $i:ty,)*) => {
    380        $(
    381            impl Bits for $u {
    382                const EMPTY: $u = 0;
    383                const ALL: $u = <$u>::MAX;
    384            }
    385
    386            impl Bits for $i {
    387                const EMPTY: $i = 0;
    388                const ALL: $i = <$u>::MAX as $i;
    389            }
    390
    391            impl ParseHex for $u {
    392                fn parse_hex(input: &str) -> Result<Self, ParseError> {
    393                    <$u>::from_str_radix(input, 16).map_err(|_| ParseError::invalid_hex_flag(input))
    394                }
    395            }
    396
    397            impl ParseHex for $i {
    398                fn parse_hex(input: &str) -> Result<Self, ParseError> {
    399                    <$i>::from_str_radix(input, 16).map_err(|_| ParseError::invalid_hex_flag(input))
    400                }
    401            }
    402
    403            impl WriteHex for $u {
    404                fn write_hex<W: fmt::Write>(&self, mut writer: W) -> fmt::Result {
    405                    write!(writer, "{:x}", self)
    406                }
    407            }
    408
    409            impl WriteHex for $i {
    410                fn write_hex<W: fmt::Write>(&self, mut writer: W) -> fmt::Result {
    411                    write!(writer, "{:x}", self)
    412                }
    413            }
    414
    415            impl Primitive for $i {}
    416            impl Primitive for $u {}
    417        )*
    418    }
    419}
    420
    421impl_bits! {
    422    u8, i8,
    423    u16, i16,
    424    u32, i32,
    425    u64, i64,
    426    u128, i128,
    427    usize, isize,
    428}
    429
    430/// A trait for referencing the `bitflags`-owned internal type
    431/// without exposing it publicly.
    432pub trait PublicFlags {
    433    /// The type of the underlying storage.
    434    type Primitive: Primitive;
    435
    436    /// The type of the internal field on the generated flags type.
    437    type Internal;
    438}
    439
    440#[doc(hidden)]
    441#[deprecated(note = "use the `Flags` trait instead")]
    442pub trait BitFlags: ImplementedByBitFlagsMacro + Flags {
    443    /// An iterator over enabled flags in an instance of the type.
    444    type Iter: Iterator<Item = Self>;
    445
    446    /// An iterator over the raw names and bits for enabled flags in an instance of the type.
    447    type IterNames: Iterator<Item = (&'static str, Self)>;
    448}
    449
    450#[allow(deprecated)]
    451impl<B: Flags> BitFlags for B {
    452    type Iter = iter::Iter<Self>;
    453    type IterNames = iter::IterNames<Self>;
    454}
    455
    456impl<B: Flags> ImplementedByBitFlagsMacro for B {}
    457
    458/// A marker trait that signals that an implementation of `BitFlags` came from the `bitflags!` macro.
    459///
    460/// There's nothing stopping an end-user from implementing this trait, but we don't guarantee their
    461/// manual implementations won't break between non-breaking releases.
    462#[doc(hidden)]
    463pub trait ImplementedByBitFlagsMacro {}
    464
    465pub(crate) mod __private {
    466    pub use super::{ImplementedByBitFlagsMacro, PublicFlags};
    467}