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