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 /// This method will return `true` if any unknown bits are set.
156 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.
163 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.
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.
179 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.
184 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.
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.
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.
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.
222 fn is_empty(&self) -> bool {
223 self.bits() == Self::Bits::EMPTY
224 }
225
226 /// Whether all known bits in this flags value are set.
227 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.
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.
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.
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.
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.
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.
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`.
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.
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]
306 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]
312 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]
321 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]
327 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]
333 fn complement(self) -> Self {
334 Self::from_bits_truncate(!self.bits())
335 }
336}
337
338/**
339A bits type that can be used as storage for a flags type.
340*/
341pub 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
361pub trait Primitive {}
362
363macro_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
406impl_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.
417pub 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")]
427pub 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)]
436impl<B: Flags> BitFlags for B {
437 type Iter = iter::Iter<Self>;
438 type IterNames = iter::IterNames<Self>;
439}
440
441impl<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)]
448pub trait ImplementedByBitFlagsMacro {}
449
450pub(crate) mod __private {
451 pub use super::{ImplementedByBitFlagsMacro, PublicFlags};
452}