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