1 use core::{
2     fmt,
3     ops::{BitAnd, BitOr, BitXor, Not},
4 };
5 
6 use crate::{
7     iter,
8     parser::{ParseError, ParseHex, WriteHex},
9 };
10 
11 /**
12 A defined flags value that may be named or unnamed.
13 */
14 #[derive(Debug)]
15 pub struct Flag<B> {
16     name: &'static str,
17     value: B,
18 }
19 
20 impl<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     */
new(name: &'static str, value: B) -> Self26     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     */
name(&self) -> &'static str35     pub const fn name(&self) -> &'static str {
36         self.name
37     }
38 
39     /**
40     Get the flags value of this flag.
41     */
value(&self) -> &B42     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     */
is_named(&self) -> bool51     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     */
is_unnamed(&self) -> bool60     pub const fn is_unnamed(&self) -> bool {
61         self.name.is_empty()
62     }
63 }
64 
65 /**
66 A set of defined flags using a bits type as storage.
67 
68 ## Implementing `Flags`
69 
70 This trait is implemented by the [`bitflags`](macro.bitflags.html) macro:
71 
72 ```
73 use bitflags::bitflags;
74 
75 bitflags! {
76     struct MyFlags: u8 {
77         const A = 1;
78         const B = 1 << 1;
79     }
80 }
81 ```
82 
83 It can also be implemented manually:
84 
85 ```
86 use bitflags::{Flag, Flags};
87 
88 struct MyFlags(u8);
89 
90 impl 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 
110 The `Flags` trait can be used generically to work with any flags types. In this example,
111 we can count the number of defined named flags:
112 
113 ```
114 # use bitflags::{bitflags, Flags};
115 fn defined_flags<F: Flags>() -> usize {
116     F::FLAGS.iter().filter(|f| f.is_named()).count()
117 }
118 
119 bitflags! {
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 
129 assert_eq!(3, defined_flags::<MyFlags>());
130 ```
131 */
132 pub 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.
empty() -> Self140     fn empty() -> Self {
141         Self::from_bits_retain(Self::Bits::EMPTY)
142     }
143 
144     /// Get a flags value with all known bits set.
all() -> Self145     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 underlying bits value.
156     ///
157     /// The returned value is exactly the bits set in this flags value.
bits(&self) -> Self::Bits158     fn bits(&self) -> Self::Bits;
159 
160     /// Convert from a bits value.
161     ///
162     /// This method will return `None` if any unknown bits are set.
from_bits(bits: Self::Bits) -> Option<Self>163     fn from_bits(bits: Self::Bits) -> Option<Self> {
164         let truncated = Self::from_bits_truncate(bits);
165 
166         if truncated.bits() == bits {
167             Some(truncated)
168         } else {
169             None
170         }
171     }
172 
173     /// Convert from a bits value, unsetting any unknown bits.
from_bits_truncate(bits: Self::Bits) -> Self174     fn from_bits_truncate(bits: Self::Bits) -> Self {
175         Self::from_bits_retain(bits & Self::all().bits())
176     }
177 
178     /// Convert from a bits value exactly.
from_bits_retain(bits: Self::Bits) -> Self179     fn from_bits_retain(bits: Self::Bits) -> Self;
180 
181     /// Get a flags value with the bits of a flag with the given name set.
182     ///
183     /// This method will return `None` if `name` is empty or doesn't
184     /// correspond to any named flag.
from_name(name: &str) -> Option<Self>185     fn from_name(name: &str) -> Option<Self> {
186         // Don't parse empty names as empty flags
187         if name.is_empty() {
188             return None;
189         }
190 
191         for flag in Self::FLAGS {
192             if flag.name() == name {
193                 return Some(Self::from_bits_retain(flag.value().bits()));
194             }
195         }
196 
197         None
198     }
199 
200     /// Yield a set of contained flags values.
201     ///
202     /// Each yielded flags value will correspond to a defined named flag. Any unknown bits
203     /// will be yielded together as a final flags value.
iter(&self) -> iter::Iter<Self>204     fn iter(&self) -> iter::Iter<Self> {
205         iter::Iter::new(self)
206     }
207 
208     /// Yield a set of contained named flags values.
209     ///
210     /// This method is like [`Flags::iter`], except only yields bits in contained named flags.
211     /// Any unknown bits, or bits not corresponding to a contained flag will not be yielded.
iter_names(&self) -> iter::IterNames<Self>212     fn iter_names(&self) -> iter::IterNames<Self> {
213         iter::IterNames::new(self)
214     }
215 
216     /// Whether all bits in this flags value are unset.
is_empty(&self) -> bool217     fn is_empty(&self) -> bool {
218         self.bits() == Self::Bits::EMPTY
219     }
220 
221     /// Whether all known bits in this flags value are set.
is_all(&self) -> bool222     fn is_all(&self) -> bool {
223         // NOTE: We check against `Self::all` here, not `Self::Bits::ALL`
224         // because the set of all flags may not use all bits
225         Self::all().bits() | self.bits() == self.bits()
226     }
227 
228     /// Whether any set bits in a source flags value are also set in a target flags value.
intersects(&self, other: Self) -> bool where Self: Sized,229     fn intersects(&self, other: Self) -> bool
230     where
231         Self: Sized,
232     {
233         self.bits() & other.bits() != Self::Bits::EMPTY
234     }
235 
236     /// Whether all set bits in a source flags value are also set in a target flags value.
contains(&self, other: Self) -> bool where Self: Sized,237     fn contains(&self, other: Self) -> bool
238     where
239         Self: Sized,
240     {
241         self.bits() & other.bits() == other.bits()
242     }
243 
244     /// The bitwise or (`|`) of the bits in two flags values.
insert(&mut self, other: Self) where Self: Sized,245     fn insert(&mut self, other: Self)
246     where
247         Self: Sized,
248     {
249         *self = Self::from_bits_retain(self.bits()).union(other);
250     }
251 
252     /// The intersection of a source flags value with the complement of a target flags value (`&!`).
253     ///
254     /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
255     /// `remove` won't truncate `other`, but the `!` operator will.
remove(&mut self, other: Self) where Self: Sized,256     fn remove(&mut self, other: Self)
257     where
258         Self: Sized,
259     {
260         *self = Self::from_bits_retain(self.bits()).difference(other);
261     }
262 
263     /// The bitwise exclusive-or (`^`) of the bits in two flags values.
toggle(&mut self, other: Self) where Self: Sized,264     fn toggle(&mut self, other: Self)
265     where
266         Self: Sized,
267     {
268         *self = Self::from_bits_retain(self.bits()).symmetric_difference(other);
269     }
270 
271     /// Call [`Flags::insert`] when `value` is `true` or [`Flags::remove`] when `value` is `false`.
set(&mut self, other: Self, value: bool) where Self: Sized,272     fn set(&mut self, other: Self, value: bool)
273     where
274         Self: Sized,
275     {
276         if value {
277             self.insert(other);
278         } else {
279             self.remove(other);
280         }
281     }
282 
283     /// The bitwise and (`&`) of the bits in two flags values.
284     #[must_use]
intersection(self, other: Self) -> Self285     fn intersection(self, other: Self) -> Self {
286         Self::from_bits_retain(self.bits() & other.bits())
287     }
288 
289     /// The bitwise or (`|`) of the bits in two flags values.
290     #[must_use]
union(self, other: Self) -> Self291     fn union(self, other: Self) -> Self {
292         Self::from_bits_retain(self.bits() | other.bits())
293     }
294 
295     /// The intersection of a source flags value with the complement of a target flags value (`&!`).
296     ///
297     /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
298     /// `difference` won't truncate `other`, but the `!` operator will.
299     #[must_use]
difference(self, other: Self) -> Self300     fn difference(self, other: Self) -> Self {
301         Self::from_bits_retain(self.bits() & !other.bits())
302     }
303 
304     /// The bitwise exclusive-or (`^`) of the bits in two flags values.
305     #[must_use]
symmetric_difference(self, other: Self) -> Self306     fn symmetric_difference(self, other: Self) -> Self {
307         Self::from_bits_retain(self.bits() ^ other.bits())
308     }
309 
310     /// The bitwise negation (`!`) of the bits in a flags value, truncating the result.
311     #[must_use]
complement(self) -> Self312     fn complement(self) -> Self {
313         Self::from_bits_truncate(!self.bits())
314     }
315 }
316 
317 /**
318 A bits type that can be used as storage for a flags type.
319 */
320 pub trait Bits:
321     Clone
322     + Copy
323     + PartialEq
324     + BitAnd<Output = Self>
325     + BitOr<Output = Self>
326     + BitXor<Output = Self>
327     + Not<Output = Self>
328     + Sized
329     + 'static
330 {
331     /// A value with all bits unset.
332     const EMPTY: Self;
333 
334     /// A value with all bits set.
335     const ALL: Self;
336 }
337 
338 // Not re-exported: prevent custom `Bits` impls being used in the `bitflags!` macro,
339 // or they may fail to compile based on crate features
340 pub trait Primitive {}
341 
342 macro_rules! impl_bits {
343     ($($u:ty, $i:ty,)*) => {
344         $(
345             impl Bits for $u {
346                 const EMPTY: $u = 0;
347                 const ALL: $u = <$u>::MAX;
348             }
349 
350             impl Bits for $i {
351                 const EMPTY: $i = 0;
352                 const ALL: $i = <$u>::MAX as $i;
353             }
354 
355             impl ParseHex for $u {
356                 fn parse_hex(input: &str) -> Result<Self, ParseError> {
357                     <$u>::from_str_radix(input, 16).map_err(|_| ParseError::invalid_hex_flag(input))
358                 }
359             }
360 
361             impl ParseHex for $i {
362                 fn parse_hex(input: &str) -> Result<Self, ParseError> {
363                     <$i>::from_str_radix(input, 16).map_err(|_| ParseError::invalid_hex_flag(input))
364                 }
365             }
366 
367             impl WriteHex for $u {
368                 fn write_hex<W: fmt::Write>(&self, mut writer: W) -> fmt::Result {
369                     write!(writer, "{:x}", self)
370                 }
371             }
372 
373             impl WriteHex for $i {
374                 fn write_hex<W: fmt::Write>(&self, mut writer: W) -> fmt::Result {
375                     write!(writer, "{:x}", self)
376                 }
377             }
378 
379             impl Primitive for $i {}
380             impl Primitive for $u {}
381         )*
382     }
383 }
384 
385 impl_bits! {
386     u8, i8,
387     u16, i16,
388     u32, i32,
389     u64, i64,
390     u128, i128,
391     usize, isize,
392 }
393 
394 /// A trait for referencing the `bitflags`-owned internal type
395 /// without exposing it publicly.
396 pub trait PublicFlags {
397     /// The type of the underlying storage.
398     type Primitive: Primitive;
399 
400     /// The type of the internal field on the generated flags type.
401     type Internal;
402 }
403 
404 #[doc(hidden)]
405 #[deprecated(note = "use the `Flags` trait instead")]
406 pub trait BitFlags: ImplementedByBitFlagsMacro + Flags {
407     /// An iterator over enabled flags in an instance of the type.
408     type Iter: Iterator<Item = Self>;
409 
410     /// An iterator over the raw names and bits for enabled flags in an instance of the type.
411     type IterNames: Iterator<Item = (&'static str, Self)>;
412 }
413 
414 #[allow(deprecated)]
415 impl<B: Flags> BitFlags for B {
416     type Iter = iter::Iter<Self>;
417     type IterNames = iter::IterNames<Self>;
418 }
419 
420 impl<B: Flags> ImplementedByBitFlagsMacro for B {}
421 
422 /// A marker trait that signals that an implementation of `BitFlags` came from the `bitflags!` macro.
423 ///
424 /// There's nothing stopping an end-user from implementing this trait, but we don't guarantee their
425 /// manual implementations won't break between non-breaking releases.
426 #[doc(hidden)]
427 pub trait ImplementedByBitFlagsMacro {}
428 
429 pub(crate) mod __private {
430     pub use super::{ImplementedByBitFlagsMacro, PublicFlags};
431 }
432