1 //
2 // Copyright 2019 Red Hat, Inc.
3 //
4 // Author: Nathaniel McCallum <[email protected]>
5 //
6 // Licensed under the Apache License, Version 2.0 (the "License");
7 // you may not use this file except in compliance with the License.
8 // You may obtain a copy of the License at
9 //
10 //     http://www.apache.org/licenses/LICENSE-2.0
11 //
12 // Unless required by applicable law or agreed to in writing, software
13 // distributed under the License is distributed on an "AS IS" BASIS,
14 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 // See the License for the specific language governing permissions and
16 // limitations under the License.
17 //
18 
19 //! # Welcome to FlagSet!
20 //!
21 //! FlagSet is a new, ergonomic approach to handling flags that combines the
22 //! best of existing crates like `bitflags` and `enumflags` without their
23 //! downsides.
24 //!
25 //! ## Existing Implementations
26 //!
27 //! The `bitflags` crate has long been part of the Rust ecosystem.
28 //! Unfortunately, it doesn't feel like natural Rust. The `bitflags` crate
29 //! uses a wierd struct format to define flags. Flags themselves are just
30 //! integers constants, so there is little type-safety involved. But it doesn't
31 //! have any dependencies. It also allows you to define implied flags (otherwise
32 //! known as overlapping flags).
33 //!
34 //! The `enumflags` crate tried to improve on `bitflags` by using enumerations
35 //! to define flags. This was a big improvement to the natural feel of the code.
36 //! Unfortunately, there are some design flaws. To generate the flags,
37 //! procedural macros were used. This implied two separate crates plus
38 //! additional dependencies. Further, `enumflags` specifies the size of the
39 //! flags using a `repr($size)` attribute. Unfortunately, this attribute
40 //! cannot resolve type aliases, such as `c_int`. This makes `enumflags` a
41 //! poor fit for FFI, which is the most important place for a flags library.
42 //! The `enumflags` crate also disallows overlapping flags and is not
43 //! maintained.
44 //!
45 //! FlagSet improves on both of these by adopting the `enumflags` natural feel
46 //! and the `bitflags` mode of flag generation; as well as additional API usage
47 //! niceties. FlagSet has no dependencies and is extensively documented and
48 //! tested. It also tries very hard to prevent you from making mistakes by
49 //! avoiding external usage of the integer types. FlagSet is also a zero-cost
50 //! abstraction: all functions are inlineable and should reduce to the core
51 //! integer operations. FlagSet also does not depend on stdlib, so it can be
52 //! used in `no_std` libraries and applications.
53 //!
54 //! ## Defining Flags
55 //!
56 //! Flags are defined using the `flags!` macro:
57 //!
58 //! ```
59 //! use flagset::{FlagSet, flags};
60 //! use std::os::raw::c_int;
61 //!
62 //! flags! {
63 //!     enum FlagsA: u8 {
64 //!         Foo,
65 //!         Bar,
66 //!         Baz,
67 //!     }
68 //!
69 //!     enum FlagsB: c_int {
70 //!         Foo,
71 //!         Bar,
72 //!         Baz,
73 //!     }
74 //! }
75 //! ```
76 //!
77 //! Notice that a flag definition looks just like a regular enumeration, with
78 //! the addition of the field-size type. The field-size type is required and
79 //! can be either a type or a type alias. Both examples are given above.
80 //!
81 //! Also note that the field-size type specifies the size of the corresponding
82 //! `FlagSet` type, not size of the enumeration itself. To specify the size of
83 //! the enumeration, use the `repr($size)` attribute as specified below.
84 //!
85 //! ## Flag Values
86 //!
87 //! Flags often need values assigned to them. This can be done implicitly,
88 //! where the value depends on the order of the flags:
89 //!
90 //! ```
91 //! use flagset::{FlagSet, flags};
92 //!
93 //! flags! {
94 //!     enum Flags: u16 {
95 //!         Foo, // Implicit Value: 0b0001
96 //!         Bar, // Implicit Value: 0b0010
97 //!         Baz, // Implicit Value: 0b0100
98 //!     }
99 //! }
100 //! ```
101 //!
102 //! Alternatively, flag values can be defined explicitly, by specifying any
103 //! `const` expression:
104 //!
105 //! ```
106 //! use flagset::{FlagSet, flags};
107 //!
108 //! flags! {
109 //!     enum Flags: u16 {
110 //!         Foo = 0x01,   // Explicit Value: 0b0001
111 //!         Bar = 2,      // Explicit Value: 0b0010
112 //!         Baz = 0b0100, // Explicit Value: 0b0100
113 //!     }
114 //! }
115 //! ```
116 //!
117 //! Flags can also overlap or "imply" other flags:
118 //!
119 //! ```
120 //! use flagset::{FlagSet, flags};
121 //!
122 //! flags! {
123 //!     enum Flags: u16 {
124 //!         Foo = 0b0001,
125 //!         Bar = 0b0010,
126 //!         Baz = 0b0110, // Implies Bar
127 //!         All = (Flags::Foo | Flags::Bar | Flags::Baz).bits(),
128 //!     }
129 //! }
130 //! ```
131 //!
132 //! ## Specifying Attributes
133 //!
134 //! Attributes can be used on the enumeration itself or any of the values:
135 //!
136 //! ```
137 //! use flagset::{FlagSet, flags};
138 //!
139 //! flags! {
140 //!     #[derive(PartialOrd, Ord)]
141 //!     enum Flags: u8 {
142 //!         Foo,
143 //!         #[deprecated]
144 //!         Bar,
145 //!         Baz,
146 //!     }
147 //! }
148 //! ```
149 //!
150 //! ## Collections of Flags
151 //!
152 //! A collection of flags is a `FlagSet<T>`. If you are storing the flags in
153 //! memory, the raw `FlagSet<T>` type should be used. However, if you want to
154 //! receive flags as an input to a function, you should use
155 //! `impl Into<FlagSet<T>>`. This allows for very ergonomic APIs:
156 //!
157 //! ```
158 //! use flagset::{FlagSet, flags};
159 //!
160 //! flags! {
161 //!     enum Flags: u8 {
162 //!         Foo,
163 //!         Bar,
164 //!         Baz,
165 //!     }
166 //! }
167 //!
168 //! struct Container(FlagSet<Flags>);
169 //!
170 //! impl Container {
171 //!     fn new(flags: impl Into<FlagSet<Flags>>) -> Container {
172 //!         Container(flags.into())
173 //!     }
174 //! }
175 //!
176 //! assert_eq!(Container::new(Flags::Foo | Flags::Bar).0.bits(), 0b011);
177 //! assert_eq!(Container::new(Flags::Foo).0.bits(), 0b001);
178 //! assert_eq!(Container::new(None).0.bits(), 0b000);
179 //! ```
180 //!
181 //! ## Operations
182 //!
183 //! Operations can be performed on a `FlagSet<F>` or on individual flags:
184 //!
185 //! | Operator | Assignment Operator | Meaning                |
186 //! |----------|---------------------|------------------------|
187 //! | \|       | \|=                 | Union                  |
188 //! | &        | &=                  | Intersection           |
189 //! | ^        | ^=                  | Toggle specified flags |
190 //! | -        | -=                  | Difference             |
191 //! | %        | %=                  | Symmetric difference   |
192 //! | !        |                     | Toggle all flags       |
193 //!
194 #![cfg_attr(
195     feature = "serde",
196     doc = r#"
197 
198 ## Optional Serde support
199 
200 [Serde] support can be enabled with the 'serde' feature flag. You can then serialize and
201 deserialize `FlagSet<T>` to and from any of the [supported formats]:
202 
203  ```
204  use flagset::{FlagSet, flags};
205 
206  flags! {
207      enum Flags: u8 {
208          Foo,
209          Bar,
210      }
211  }
212 
213  let flagset = Flags::Foo | Flags::Bar;
214  let json = serde_json::to_string(&flagset).unwrap();
215  let flagset: FlagSet<Flags> = serde_json::from_str(&json).unwrap();
216  assert_eq!(flagset.bits(), 0b011);
217  ```
218 
219 For serialization and deserialization of flags enum itself, you can use the [`serde_repr`] crate
220 (or implement `serde::ser::Serialize` and `serde:de::Deserialize` manually), combined with the
221 appropriate `repr` attribute:
222 
223  ```
224  use flagset::{FlagSet, flags};
225  use serde_repr::{Serialize_repr, Deserialize_repr};
226 
227  flags! {
228     #[repr(u8)]
229     #[derive(Deserialize_repr, Serialize_repr)]
230     enum Flags: u8 {
231          Foo,
232          Bar,
233     }
234  }
235 
236  let json = serde_json::to_string(&Flags::Foo).unwrap();
237  let flag: Flags = serde_json::from_str(&json).unwrap();
238  assert_eq!(flag, Flags::Foo);
239  ```
240 
241 [Serde]: https://serde.rs/
242 [supported formats]: https://serde.rs/#data-formats
243 [`serde_repr`]: https://crates.io/crates/serde_repr
244 "#
245 )]
246 #![allow(unknown_lints)]
247 #![warn(clippy::all)]
248 #![cfg_attr(not(feature = "std"), no_std)]
249 #![cfg_attr(docsrs, feature(doc_auto_cfg))]
250 
251 /// Local Android change: Use std to allow building as a dylib.
252 #[cfg(android_dylib)]
253 extern crate std;
254 
255 use core::fmt::{Debug, Formatter, Result};
256 use core::ops::*;
257 
258 /// Error type returned when creating a new flagset from bits is invalid or undefined.
259 /// ```
260 /// use flagset::{FlagSet, flags};
261 ///
262 /// flags! {
263 ///     pub enum Flag: u16 {
264 ///         Foo = 0b0001,
265 ///         Bar = 0b0010,
266 ///         Baz = 0b0100,
267 ///         Qux = 0b1010, // Implies Bar
268 ///     }
269 /// }
270 ///
271 /// assert_eq!(FlagSet::<Flag>::new(0b01101), Err(flagset::InvalidBits)); // Invalid
272 /// assert_eq!(FlagSet::<Flag>::new(0b10101), Err(flagset::InvalidBits)); // Unknown
273 /// ```
274 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
275 pub struct InvalidBits;
276 
277 impl core::fmt::Display for InvalidBits {
278     #[inline]
fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result279     fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
280         write!(f, "invalid bits")
281     }
282 }
283 
284 #[cfg(feature = "std")]
285 impl std::error::Error for InvalidBits {}
286 
287 #[doc(hidden)]
288 pub trait Flags:
289     Copy
290     + Clone
291     + Debug
292     + PartialEq
293     + Eq
294     + BitAnd<Self, Output = FlagSet<Self>>
295     + BitOr<Self, Output = FlagSet<Self>>
296     + BitXor<Self, Output = FlagSet<Self>>
297     + Sub<Self, Output = FlagSet<Self>>
298     + Rem<Self, Output = FlagSet<Self>>
299     + Not<Output = FlagSet<Self>>
300     + Into<FlagSet<Self>>
301     + 'static
302 {
303     type Type: Copy
304         + Clone
305         + Debug
306         + PartialEq
307         + Eq
308         + Default
309         + BitAnd<Self::Type, Output = Self::Type>
310         + BitAndAssign<Self::Type>
311         + BitOr<Self::Type, Output = Self::Type>
312         + BitOrAssign<Self::Type>
313         + BitXor<Self::Type, Output = Self::Type>
314         + BitXorAssign<Self::Type>
315         + Not<Output = Self::Type>;
316 
317     /// A slice containing all the possible flag values.
318     const LIST: &'static [Self];
319 
320     /// Creates an empty `FlagSet` of this type
321     #[inline]
none() -> FlagSet<Self>322     fn none() -> FlagSet<Self> {
323         FlagSet::default()
324     }
325 }
326 
327 #[repr(C)]
328 #[derive(Copy, Clone, Eq, Hash)]
329 pub struct FlagSet<F: Flags>(F::Type);
330 
331 #[doc(hidden)]
332 #[derive(Copy, Clone)]
333 pub struct Iter<F: Flags>(FlagSet<F>, usize);
334 
335 impl<F: Flags> Iterator for Iter<F> {
336     type Item = F;
337 
338     #[inline]
next(&mut self) -> Option<Self::Item>339     fn next(&mut self) -> Option<Self::Item> {
340         while self.1 < F::LIST.len() {
341             let next = F::LIST[self.1];
342             self.1 += 1;
343 
344             if self.0.contains(next) {
345                 return Some(next);
346             }
347         }
348 
349         None
350     }
351 }
352 
353 impl<F: Flags> IntoIterator for FlagSet<F> {
354     type Item = F;
355     type IntoIter = Iter<F>;
356 
357     /// Iterate over the flags in the set.
358     ///
359     /// **NOTE**: The order in which the flags are iterated is undefined.
360     ///
361     /// ```
362     /// use flagset::{FlagSet, flags};
363     ///
364     /// flags! {
365     ///     enum Flag: u8 {
366     ///         Foo = 0b001,
367     ///         Bar = 0b010,
368     ///         Baz = 0b100
369     ///     }
370     /// }
371     ///
372     /// let set = Flag::Foo | Flag::Bar;
373     /// let mut iter = set.into_iter();
374     /// assert_eq!(iter.next(), Some(Flag::Foo));
375     /// assert_eq!(iter.next(), Some(Flag::Bar));
376     /// assert_eq!(iter.next(), None);
377     /// ```
378     #[inline]
into_iter(self) -> Self::IntoIter379     fn into_iter(self) -> Self::IntoIter {
380         Iter(self, 0)
381     }
382 }
383 
384 impl<F: Flags> Debug for FlagSet<F> {
385     #[inline]
fmt(&self, f: &mut Formatter) -> Result386     fn fmt(&self, f: &mut Formatter) -> Result {
387         write!(f, "FlagSet(")?;
388         for (i, flag) in self.into_iter().enumerate() {
389             write!(f, "{}{:?}", if i > 0 { " | " } else { "" }, flag)?;
390         }
391         write!(f, ")")
392     }
393 }
394 
395 impl<F: Flags, R: Copy + Into<FlagSet<F>>> PartialEq<R> for FlagSet<F> {
396     #[inline]
eq(&self, rhs: &R) -> bool397     fn eq(&self, rhs: &R) -> bool {
398         self.0 == (*rhs).into().0
399     }
400 }
401 
402 impl<F: Flags> AsRef<F::Type> for FlagSet<F> {
403     #[inline]
as_ref(&self) -> &F::Type404     fn as_ref(&self) -> &F::Type {
405         &self.0
406     }
407 }
408 
409 impl<F: Flags> From<Option<FlagSet<F>>> for FlagSet<F> {
410     /// Converts from `Option<FlagSet<F>>` to `FlagSet<F>`.
411     ///
412     /// Most notably, this allows for the use of `None` in many places to
413     /// substitute for manually creating an empty `FlagSet<F>`. See below.
414     ///
415     /// ```
416     /// use flagset::{FlagSet, flags};
417     ///
418     /// flags! {
419     ///     enum Flag: u8 {
420     ///         Foo = 0b001,
421     ///         Bar = 0b010,
422     ///         Baz = 0b100
423     ///     }
424     /// }
425     ///
426     /// fn convert(v: impl Into<FlagSet<Flag>>) -> u8 {
427     ///     v.into().bits()
428     /// }
429     ///
430     /// assert_eq!(convert(Flag::Foo | Flag::Bar), 0b011);
431     /// assert_eq!(convert(Flag::Foo), 0b001);
432     /// assert_eq!(convert(None), 0b000);
433     /// ```
434     #[inline]
from(value: Option<FlagSet<F>>) -> FlagSet<F>435     fn from(value: Option<FlagSet<F>>) -> FlagSet<F> {
436         value.unwrap_or_default()
437     }
438 }
439 
440 impl<F: Flags> Default for FlagSet<F> {
441     /// Creates a new, empty FlagSet.
442     ///
443     /// ```
444     /// use flagset::{FlagSet, flags};
445     ///
446     /// flags! {
447     ///     enum Flag: u8 {
448     ///         Foo = 0b001,
449     ///         Bar = 0b010,
450     ///         Baz = 0b100
451     ///     }
452     /// }
453     ///
454     /// let set = FlagSet::<Flag>::default();
455     /// assert!(set.is_empty());
456     /// assert!(!set.is_full());
457     /// assert!(!set.contains(Flag::Foo));
458     /// assert!(!set.contains(Flag::Bar));
459     /// assert!(!set.contains(Flag::Baz));
460     /// ```
461     #[inline]
default() -> Self462     fn default() -> Self {
463         FlagSet(F::Type::default())
464     }
465 }
466 
467 impl<F: Flags> Not for FlagSet<F> {
468     type Output = Self;
469 
470     /// Calculates the complement of the current set.
471     ///
472     /// In common parlance, this returns the set of all possible flags that are
473     /// not in the current set.
474     ///
475     /// ```
476     /// use flagset::{FlagSet, flags};
477     ///
478     /// flags! {
479     ///     #[derive(PartialOrd, Ord)]
480     ///     enum Flag: u8 {
481     ///         Foo = 1 << 0,
482     ///         Bar = 1 << 1,
483     ///         Baz = 1 << 2
484     ///     }
485     /// }
486     ///
487     /// let set = !FlagSet::from(Flag::Foo);
488     /// assert!(!set.is_empty());
489     /// assert!(!set.is_full());
490     /// assert!(!set.contains(Flag::Foo));
491     /// assert!(set.contains(Flag::Bar));
492     /// assert!(set.contains(Flag::Baz));
493     /// ```
494     #[inline]
not(self) -> Self495     fn not(self) -> Self {
496         FlagSet(!self.0)
497     }
498 }
499 
500 impl<F: Flags, R: Into<FlagSet<F>>> BitAnd<R> for FlagSet<F> {
501     type Output = Self;
502 
503     /// Calculates the intersection of the current set and the specified flags.
504     ///
505     /// ```
506     /// use flagset::{FlagSet, flags};
507     ///
508     /// flags! {
509     ///     #[derive(PartialOrd, Ord)]
510     ///     pub enum Flag: u8 {
511     ///         Foo = 0b001,
512     ///         Bar = 0b010,
513     ///         Baz = 0b100
514     ///     }
515     /// }
516     ///
517     /// let set0 = Flag::Foo | Flag::Bar;
518     /// let set1 = Flag::Baz | Flag::Bar;
519     /// assert_eq!(set0 & set1, Flag::Bar);
520     /// assert_eq!(set0 & Flag::Foo, Flag::Foo);
521     /// assert_eq!(set1 & Flag::Baz, Flag::Baz);
522     /// ```
523     #[inline]
bitand(self, rhs: R) -> Self524     fn bitand(self, rhs: R) -> Self {
525         FlagSet(self.0 & rhs.into().0)
526     }
527 }
528 
529 impl<F: Flags, R: Into<FlagSet<F>>> BitAndAssign<R> for FlagSet<F> {
530     /// Assigns the intersection of the current set and the specified flags.
531     ///
532     /// ```
533     /// use flagset::{FlagSet, flags};
534     ///
535     /// flags! {
536     ///     enum Flag: u64 {
537     ///         Foo = 0b001,
538     ///         Bar = 0b010,
539     ///         Baz = 0b100
540     ///     }
541     /// }
542     ///
543     /// let mut set0 = Flag::Foo | Flag::Bar;
544     /// let mut set1 = Flag::Baz | Flag::Bar;
545     ///
546     /// set0 &= set1;
547     /// assert_eq!(set0, Flag::Bar);
548     ///
549     /// set1 &= Flag::Baz;
550     /// assert_eq!(set0, Flag::Bar);
551     /// ```
552     #[inline]
bitand_assign(&mut self, rhs: R)553     fn bitand_assign(&mut self, rhs: R) {
554         self.0 &= rhs.into().0
555     }
556 }
557 
558 impl<F: Flags, R: Into<FlagSet<F>>> BitOr<R> for FlagSet<F> {
559     type Output = Self;
560 
561     /// Calculates the union of the current set with the specified flags.
562     ///
563     /// ```
564     /// use flagset::{FlagSet, flags};
565     ///
566     /// flags! {
567     ///     #[derive(PartialOrd, Ord)]
568     ///     pub enum Flag: u8 {
569     ///         Foo = 0b001,
570     ///         Bar = 0b010,
571     ///         Baz = 0b100
572     ///     }
573     /// }
574     ///
575     /// let set0 = Flag::Foo | Flag::Bar;
576     /// let set1 = Flag::Baz | Flag::Bar;
577     /// assert_eq!(set0 | set1, FlagSet::full());
578     /// ```
579     #[inline]
bitor(self, rhs: R) -> Self580     fn bitor(self, rhs: R) -> Self {
581         FlagSet(self.0 | rhs.into().0)
582     }
583 }
584 
585 impl<F: Flags, R: Into<FlagSet<F>>> BitOrAssign<R> for FlagSet<F> {
586     /// Assigns the union of the current set with the specified flags.
587     ///
588     /// ```
589     /// use flagset::{FlagSet, flags};
590     ///
591     /// flags! {
592     ///     enum Flag: u64 {
593     ///         Foo = 0b001,
594     ///         Bar = 0b010,
595     ///         Baz = 0b100
596     ///     }
597     /// }
598     ///
599     /// let mut set0 = Flag::Foo | Flag::Bar;
600     /// let mut set1 = Flag::Bar | Flag::Baz;
601     ///
602     /// set0 |= set1;
603     /// assert_eq!(set0, FlagSet::full());
604     ///
605     /// set1 |= Flag::Baz;
606     /// assert_eq!(set1, Flag::Bar | Flag::Baz);
607     /// ```
608     #[inline]
bitor_assign(&mut self, rhs: R)609     fn bitor_assign(&mut self, rhs: R) {
610         self.0 |= rhs.into().0
611     }
612 }
613 
614 impl<F: Flags, R: Into<FlagSet<F>>> BitXor<R> for FlagSet<F> {
615     type Output = Self;
616 
617     /// Calculates the current set with the specified flags toggled.
618     ///
619     /// This is commonly known as toggling the presence
620     ///
621     /// ```
622     /// use flagset::{FlagSet, flags};
623     ///
624     /// flags! {
625     ///     enum Flag: u32 {
626     ///         Foo = 0b001,
627     ///         Bar = 0b010,
628     ///         Baz = 0b100
629     ///     }
630     /// }
631     ///
632     /// let set0 = Flag::Foo | Flag::Bar;
633     /// let set1 = Flag::Baz | Flag::Bar;
634     /// assert_eq!(set0 ^ set1, Flag::Foo | Flag::Baz);
635     /// assert_eq!(set0 ^ Flag::Foo, Flag::Bar);
636     /// ```
637     #[inline]
bitxor(self, rhs: R) -> Self638     fn bitxor(self, rhs: R) -> Self {
639         FlagSet(self.0 ^ rhs.into().0)
640     }
641 }
642 
643 impl<F: Flags, R: Into<FlagSet<F>>> BitXorAssign<R> for FlagSet<F> {
644     /// Assigns the current set with the specified flags toggled.
645     ///
646     /// ```
647     /// use flagset::{FlagSet, flags};
648     ///
649     /// flags! {
650     ///     enum Flag: u16 {
651     ///         Foo = 0b001,
652     ///         Bar = 0b010,
653     ///         Baz = 0b100
654     ///     }
655     /// }
656     ///
657     /// let mut set0 = Flag::Foo | Flag::Bar;
658     /// let mut set1 = Flag::Baz | Flag::Bar;
659     ///
660     /// set0 ^= set1;
661     /// assert_eq!(set0, Flag::Foo | Flag::Baz);
662     ///
663     /// set1 ^= Flag::Baz;
664     /// assert_eq!(set1, Flag::Bar);
665     /// ```
666     #[inline]
bitxor_assign(&mut self, rhs: R)667     fn bitxor_assign(&mut self, rhs: R) {
668         self.0 ^= rhs.into().0
669     }
670 }
671 
672 impl<F: Flags, R: Into<FlagSet<F>>> Sub<R> for FlagSet<F> {
673     type Output = Self;
674 
675     /// Calculates set difference (the current set without the specified flags).
676     ///
677     /// ```
678     /// use flagset::{FlagSet, flags};
679     ///
680     /// flags! {
681     ///     pub enum Flag: u8 {
682     ///         Foo = 1,
683     ///         Bar = 2,
684     ///         Baz = 4
685     ///     }
686     /// }
687     ///
688     /// let set0 = Flag::Foo | Flag::Bar;
689     /// let set1 = Flag::Baz | Flag::Bar;
690     /// assert_eq!(set0 - set1, Flag::Foo);
691     /// ```
692     #[inline]
sub(self, rhs: R) -> Self693     fn sub(self, rhs: R) -> Self {
694         self & !rhs.into()
695     }
696 }
697 
698 impl<F: Flags, R: Into<FlagSet<F>>> SubAssign<R> for FlagSet<F> {
699     /// Assigns set difference (the current set without the specified flags).
700     ///
701     /// ```
702     /// use flagset::{FlagSet, flags};
703     ///
704     /// flags! {
705     ///     pub enum Flag: u8 {
706     ///         Foo = 1,
707     ///         Bar = 2,
708     ///         Baz = 4
709     ///     }
710     /// }
711     ///
712     /// let mut set0 = Flag::Foo | Flag::Bar;
713     /// set0 -= Flag::Baz | Flag::Bar;
714     /// assert_eq!(set0, Flag::Foo);
715     /// ```
716     #[inline]
sub_assign(&mut self, rhs: R)717     fn sub_assign(&mut self, rhs: R) {
718         *self &= !rhs.into();
719     }
720 }
721 
722 impl<F: Flags, R: Into<FlagSet<F>>> Rem<R> for FlagSet<F> {
723     type Output = Self;
724 
725     /// Calculates the symmetric difference between two sets.
726     ///
727     /// The symmetric difference between two sets is the set of all flags
728     /// that appear in one set or the other, but not both.
729     ///
730     /// ```
731     /// use flagset::{FlagSet, flags};
732     ///
733     /// flags! {
734     ///     pub enum Flag: u8 {
735     ///         Foo = 1,
736     ///         Bar = 2,
737     ///         Baz = 4
738     ///     }
739     /// }
740     ///
741     /// let set0 = Flag::Foo | Flag::Bar;
742     /// let set1 = Flag::Baz | Flag::Bar;
743     /// assert_eq!(set0 % set1, Flag::Foo | Flag::Baz);
744     /// ```
745     #[inline]
rem(self, rhs: R) -> Self746     fn rem(self, rhs: R) -> Self {
747         let rhs = rhs.into();
748         (self - rhs) | (rhs - self)
749     }
750 }
751 
752 impl<F: Flags, R: Into<FlagSet<F>>> RemAssign<R> for FlagSet<F> {
753     /// Assigns the symmetric difference between two sets.
754     ///
755     /// The symmetric difference between two sets is the set of all flags
756     /// that appear in one set or the other, but not both.
757     ///
758     /// ```
759     /// use flagset::{FlagSet, flags};
760     ///
761     /// flags! {
762     ///     pub enum Flag: u8 {
763     ///         Foo = 1,
764     ///         Bar = 2,
765     ///         Baz = 4
766     ///     }
767     /// }
768     ///
769     /// let mut set0 = Flag::Foo | Flag::Bar;
770     /// let set1 = Flag::Baz | Flag::Bar;
771     /// set0 %= set1;
772     /// assert_eq!(set0, Flag::Foo | Flag::Baz);
773     /// ```
774     #[inline]
rem_assign(&mut self, rhs: R)775     fn rem_assign(&mut self, rhs: R) {
776         *self = *self % rhs
777     }
778 }
779 
780 impl<F: Flags, R: Into<FlagSet<F>>> Extend<R> for FlagSet<F> {
781     /// Add values by iterating over some collection.
782     ///
783     /// ```
784     /// use flagset::{FlagSet, flags};
785     ///
786     /// flags! {
787     ///     pub enum Flag: u8 {
788     ///         Foo = 1,
789     ///         Bar = 2,
790     ///         Baz = 4
791     ///     }
792     /// }
793     ///
794     /// let flag_vec = vec![Flag::Bar, Flag::Baz];
795     /// let mut some_extended_flags = FlagSet::from(Flag::Foo);
796     /// some_extended_flags.extend(flag_vec);
797     /// assert_eq!(some_extended_flags, Flag::Foo | Flag::Bar | Flag::Baz);
798     /// ```
extend<T>(&mut self, iter: T) where T: IntoIterator<Item = R>,799     fn extend<T>(&mut self, iter: T)
800     where
801         T: IntoIterator<Item = R>,
802     {
803         for item in iter {
804             *self |= item;
805         }
806     }
807 }
808 
809 impl<F: Flags> FlagSet<F> {
810     /// Creates a new set from bits; returning `Err(InvalidBits)` on invalid/unknown bits.
811     ///
812     /// ```
813     /// use flagset::{FlagSet, flags};
814     ///
815     /// flags! {
816     ///     pub enum Flag: u16 {
817     ///         Foo = 0b0001,
818     ///         Bar = 0b0010,
819     ///         Baz = 0b0100,
820     ///         Qux = 0b1010, // Implies Bar
821     ///     }
822     /// }
823     ///
824     /// assert_eq!(FlagSet::<Flag>::new(0b00101), Ok(Flag::Foo | Flag::Baz));
825     /// assert_eq!(FlagSet::<Flag>::new(0b01101), Err(flagset::InvalidBits)); // Invalid
826     /// assert_eq!(FlagSet::<Flag>::new(0b10101), Err(flagset::InvalidBits)); // Unknown
827     /// ```
828     #[inline]
new(bits: F::Type) -> core::result::Result<Self, InvalidBits>829     pub fn new(bits: F::Type) -> core::result::Result<Self, InvalidBits> {
830         if Self::new_truncated(bits).0 == bits {
831             return Ok(FlagSet(bits));
832         }
833 
834         Err(InvalidBits)
835     }
836 
837     /// Creates a new set from bits; truncating invalid/unknown bits.
838     ///
839     /// ```
840     /// use flagset::{FlagSet, flags};
841     ///
842     /// flags! {
843     ///     pub enum Flag: u16 {
844     ///         Foo = 0b0001,
845     ///         Bar = 0b0010,
846     ///         Baz = 0b0100,
847     ///         Qux = 0b1010, // Implies Bar
848     ///     }
849     /// }
850     ///
851     /// let set = FlagSet::new_truncated(0b11101);  // Has invalid and unknown.
852     /// assert_eq!(set, Flag::Foo | Flag::Baz);
853     /// assert_eq!(set.bits(), 0b00101);            // Has neither.
854     /// ```
855     #[inline]
new_truncated(bits: F::Type) -> Self856     pub fn new_truncated(bits: F::Type) -> Self {
857         let mut set = Self::default();
858 
859         for flag in FlagSet::<F>(bits) {
860             set |= flag;
861         }
862 
863         set
864     }
865 
866     /// Creates a new set from bits; use of invalid/unknown bits is undefined.
867     ///
868     /// ```
869     /// use flagset::{FlagSet, flags};
870     ///
871     /// flags! {
872     ///     pub enum Flag: u16 {
873     ///         Foo = 0b0001,
874     ///         Bar = 0b0010,
875     ///         Baz = 0b0100,
876     ///         Qux = 0b1010, // Implies Bar
877     ///     }
878     /// }
879     ///
880     /// // Unknown and invalid bits are retained. Behavior is undefined.
881     /// const set: FlagSet<Flag> = unsafe { FlagSet::<Flag>::new_unchecked(0b11101) };
882     /// assert_eq!(set.bits(), 0b11101);
883     /// ```
884     ///
885     /// # Safety
886     ///
887     /// This constructor doesn't check that the bits are valid. If you pass
888     /// undefined flags, undefined behavior may result.
889     #[inline]
new_unchecked(bits: F::Type) -> Self890     pub const unsafe fn new_unchecked(bits: F::Type) -> Self {
891         FlagSet(bits)
892     }
893 
894     /// Creates a new FlagSet containing all possible flags.
895     ///
896     /// ```
897     /// use flagset::{FlagSet, flags};
898     ///
899     /// flags! {
900     ///     pub enum Flag: u8 {
901     ///         Foo = 1,
902     ///         Bar = 2,
903     ///         Baz = 4
904     ///     }
905     /// }
906     ///
907     /// let set = FlagSet::full();
908     /// assert!(!set.is_empty());
909     /// assert!(set.is_full());
910     /// assert!(set.contains(Flag::Foo));
911     /// assert!(set.contains(Flag::Bar));
912     /// assert!(set.contains(Flag::Baz));
913     /// ```
914     #[inline]
full() -> Self915     pub fn full() -> Self {
916         let mut set = Self::default();
917         for f in F::LIST {
918             set |= *f
919         }
920         set
921     }
922 
923     /// Returns the raw bits of the set.
924     ///
925     /// ```
926     /// use flagset::{FlagSet, flags};
927     ///
928     /// flags! {
929     ///     pub enum Flag: u16 {
930     ///         Foo = 0b0001,
931     ///         Bar = 0b0010,
932     ///         Baz = 0b0100,
933     ///     }
934     /// }
935     ///
936     /// let set = Flag::Foo | Flag::Baz;
937     /// assert_eq!(set.bits(), 0b0101u16);
938     /// ```
939     #[inline]
bits(self) -> F::Type940     pub fn bits(self) -> F::Type {
941         self.0
942     }
943 
944     /// Returns true if the FlagSet contains no flags.
945     ///
946     /// ```
947     /// use flagset::{FlagSet, flags};
948     ///
949     /// flags! {
950     ///     pub enum Flag: u8 {
951     ///         Foo = 1,
952     ///         Bar = 2,
953     ///         Baz = 4
954     ///     }
955     /// }
956     ///
957     /// let mut set = Flag::Foo | Flag::Bar;
958     /// assert!(!set.is_empty());
959     ///
960     /// set &= Flag::Baz;
961     /// assert!(set.is_empty());
962     /// ```
963     #[inline]
is_empty(self) -> bool964     pub fn is_empty(self) -> bool {
965         self == Self::default()
966     }
967 
968     /// Returns true if the FlagSet contains all possible flags.
969     ///
970     /// ```
971     /// use flagset::{FlagSet, flags};
972     ///
973     /// flags! {
974     ///     pub enum Flag: u8 {
975     ///         Foo = 1,
976     ///         Bar = 2,
977     ///         Baz = 4
978     ///     }
979     /// }
980     ///
981     /// let mut set = Flag::Foo | Flag::Bar;
982     /// assert!(!set.is_full());
983     ///
984     /// set |= Flag::Baz;
985     /// assert!(set.is_full());
986     /// ```
987     #[inline]
is_full(self) -> bool988     pub fn is_full(self) -> bool {
989         self == Self::full()
990     }
991 
992     /// Returns true if the two `FlagSet`s do not share any flags.
993     ///
994     /// ```
995     /// use flagset::{FlagSet, flags};
996     ///
997     /// flags! {
998     ///     pub enum Flag: u8 {
999     ///         Foo = 1,
1000     ///         Bar = 2,
1001     ///         Baz = 4
1002     ///     }
1003     /// }
1004     ///
1005     /// let set = Flag::Foo | Flag::Bar;
1006     /// assert!(!set.is_disjoint(Flag::Foo));
1007     /// assert!(!set.is_disjoint(Flag::Foo | Flag::Baz));
1008     /// assert!(set.is_disjoint(Flag::Baz));
1009     /// ```
1010     #[inline]
is_disjoint(self, rhs: impl Into<FlagSet<F>>) -> bool1011     pub fn is_disjoint(self, rhs: impl Into<FlagSet<F>>) -> bool {
1012         self & rhs == Self::default()
1013     }
1014 
1015     /// Returns true if this FlagSet is a superset of the specified flags.
1016     ///
1017     /// ```
1018     /// use flagset::{FlagSet, flags};
1019     ///
1020     /// flags! {
1021     ///     pub enum Flag: u8 {
1022     ///         Foo = 1,
1023     ///         Bar = 2,
1024     ///         Baz = 4
1025     ///     }
1026     /// }
1027     ///
1028     /// let set = Flag::Foo | Flag::Bar;
1029     /// assert!(set.contains(Flag::Foo));
1030     /// assert!(set.contains(Flag::Foo | Flag::Bar));
1031     /// assert!(!set.contains(Flag::Foo | Flag::Bar | Flag::Baz));
1032     /// ```
1033     #[inline]
contains(self, rhs: impl Into<FlagSet<F>>) -> bool1034     pub fn contains(self, rhs: impl Into<FlagSet<F>>) -> bool {
1035         let rhs = rhs.into();
1036         self & rhs == rhs
1037     }
1038 
1039     /// Removes all flags from the FlagSet.
1040     ///
1041     /// ```
1042     /// use flagset::{FlagSet, flags};
1043     ///
1044     /// flags! {
1045     ///     pub enum Flag: u8 {
1046     ///         Foo = 1,
1047     ///         Bar = 2,
1048     ///         Baz = 4
1049     ///     }
1050     /// }
1051     ///
1052     /// let mut set = Flag::Foo | Flag::Bar;
1053     /// assert!(!set.is_empty());
1054     ///
1055     /// set.clear();
1056     /// assert!(set.is_empty());
1057     /// ```
1058     #[inline]
clear(&mut self)1059     pub fn clear(&mut self) {
1060         *self = Self::default();
1061     }
1062 
1063     /// Clears the current set and returns an iterator of all removed flags.
1064     ///
1065     /// ```
1066     /// use flagset::{FlagSet, flags};
1067     ///
1068     /// flags! {
1069     ///     pub enum Flag: u8 {
1070     ///         Foo = 1,
1071     ///         Bar = 2,
1072     ///         Baz = 4
1073     ///     }
1074     /// }
1075     ///
1076     /// let mut set = Flag::Foo | Flag::Bar;
1077     /// let mut iter = set.drain();
1078     /// assert!(set.is_empty());
1079     /// assert_eq!(iter.next(), Some(Flag::Foo));
1080     /// assert_eq!(iter.next(), Some(Flag::Bar));
1081     /// assert_eq!(iter.next(), None);
1082     /// ```
1083     #[inline]
drain(&mut self) -> Iter<F>1084     pub fn drain(&mut self) -> Iter<F> {
1085         let iter = self.into_iter();
1086         *self = Self::default();
1087         iter
1088     }
1089 
1090     /// Retain only the flags flags specified by the predicate.
1091     ///
1092     /// ```
1093     /// use flagset::{FlagSet, flags};
1094     ///
1095     /// flags! {
1096     ///     pub enum Flag: u8 {
1097     ///         Foo = 1,
1098     ///         Bar = 2,
1099     ///         Baz = 4
1100     ///     }
1101     /// }
1102     ///
1103     /// let mut set0 = Flag::Foo | Flag::Bar;
1104     /// set0.retain(|f| f != Flag::Foo);
1105     /// assert_eq!(set0, Flag::Bar);
1106     /// ```
1107     #[inline]
retain(&mut self, func: impl Fn(F) -> bool)1108     pub fn retain(&mut self, func: impl Fn(F) -> bool) {
1109         for f in self.into_iter() {
1110             if !func(f) {
1111                 *self -= f
1112             }
1113         }
1114     }
1115 }
1116 
1117 #[cfg(feature = "serde")]
1118 impl<F: Flags> serde::Serialize for FlagSet<F>
1119 where
1120     F::Type: serde::ser::Serialize,
1121 {
1122     #[inline]
serialize<S>(&self, serializer: S) -> core::result::Result<S::Ok, S::Error> where S: serde::ser::Serializer,1123     fn serialize<S>(&self, serializer: S) -> core::result::Result<S::Ok, S::Error>
1124     where
1125         S: serde::ser::Serializer,
1126     {
1127         self.0.serialize(serializer)
1128     }
1129 }
1130 
1131 #[cfg(feature = "serde")]
1132 impl<'de, F: Flags> serde::Deserialize<'de> for FlagSet<F>
1133 where
1134     F::Type: serde::de::Deserialize<'de>,
1135 {
1136     #[inline]
deserialize<D>(deserializer: D) -> core::result::Result<Self, D::Error> where D: serde::de::Deserializer<'de>,1137     fn deserialize<D>(deserializer: D) -> core::result::Result<Self, D::Error>
1138     where
1139         D: serde::de::Deserializer<'de>,
1140     {
1141         Ok(FlagSet(F::Type::deserialize(deserializer)?))
1142     }
1143 }
1144 
1145 /// Define flag value using the `enum` syntax. See below for details.
1146 ///
1147 /// Each enumeration value **MUST** have a specified value.
1148 ///
1149 /// The width of the bitfield **MUST** also be specified by its integer type.
1150 ///
1151 /// It is important to note that the size of the flag enumeration itself is
1152 /// unrelated to the size of the corresponding `FlagSet` instance.
1153 ///
1154 /// It is also worth noting that this macro automatically implements a variety
1155 /// of standard traits including:
1156 ///   * Copy
1157 ///   * Clone
1158 ///   * Debug
1159 ///   * PartialEq
1160 ///   * Eq
1161 ///   * From<$enum> for $integer
1162 ///   * Not
1163 ///   * BitAnd
1164 ///   * BitOr
1165 ///   * BitXor
1166 ///   * Sub
1167 ///   * Rem
1168 ///
1169 /// ```
1170 /// use std::mem::{align_of, size_of};
1171 /// use flagset::{FlagSet, flags};
1172 ///
1173 /// flags! {
1174 ///     enum FlagEmpty: u32 {}
1175 ///
1176 ///     enum Flag8: u8 {
1177 ///         Foo = 0b001,
1178 ///         Bar = 0b010,
1179 ///         Baz = 0b100
1180 ///     }
1181 ///
1182 ///     pub enum Flag16: u16 {
1183 ///         Foo,
1184 ///         Bar,
1185 ///         #[deprecated]
1186 ///         Baz,
1187 ///     }
1188 ///
1189 ///     #[derive(PartialOrd, Ord)]
1190 ///     enum Flag32: u32 {
1191 ///         Foo = 0b001,
1192 ///         #[deprecated]
1193 ///         Bar = 0b010,
1194 ///         Baz = 0b100
1195 ///     }
1196 ///
1197 ///     #[repr(u64)]
1198 ///     enum Flag64: u64 {
1199 ///         Foo = 0b001,
1200 ///         Bar = 0b010,
1201 ///         Baz = 0b100
1202 ///     }
1203 ///
1204 ///     #[repr(u32)]
1205 ///     enum Flag128: u128 {
1206 ///         Foo = 0b001,
1207 ///         Bar = 0b010,
1208 ///         Baz = 0b100
1209 ///     }
1210 /// }
1211 ///
1212 /// assert_eq!(size_of::<Flag8>(), 1);
1213 /// assert_eq!(size_of::<Flag16>(), 1);
1214 /// assert_eq!(size_of::<Flag32>(), 1);
1215 /// assert_eq!(size_of::<Flag64>(), 8);
1216 /// assert_eq!(size_of::<Flag128>(), 4);
1217 ///
1218 /// assert_eq!(align_of::<Flag8>(), 1);
1219 /// assert_eq!(align_of::<Flag16>(), 1);
1220 /// assert_eq!(align_of::<Flag32>(), 1);
1221 /// assert_eq!(align_of::<Flag64>(), align_of::<u64>());
1222 /// assert_eq!(align_of::<Flag128>(), align_of::<u32>());
1223 ///
1224 /// assert_eq!(size_of::<FlagSet<Flag8>>(), size_of::<u8>());
1225 /// assert_eq!(size_of::<FlagSet<Flag16>>(), size_of::<u16>());
1226 /// assert_eq!(size_of::<FlagSet<Flag32>>(), size_of::<u32>());
1227 /// assert_eq!(size_of::<FlagSet<Flag64>>(), size_of::<u64>());
1228 /// assert_eq!(size_of::<FlagSet<Flag128>>(), size_of::<u128>());
1229 ///
1230 /// assert_eq!(align_of::<FlagSet<Flag8>>(), align_of::<u8>());
1231 /// assert_eq!(align_of::<FlagSet<Flag16>>(), align_of::<u16>());
1232 /// assert_eq!(align_of::<FlagSet<Flag32>>(), align_of::<u32>());
1233 /// assert_eq!(align_of::<FlagSet<Flag64>>(), align_of::<u64>());
1234 /// assert_eq!(align_of::<FlagSet<Flag128>>(), align_of::<u128>());
1235 /// ```
1236 #[macro_export]
1237 macro_rules! flags {
1238     () => {};
1239 
1240     // Entry point for enumerations without values.
1241     ($(#[$m:meta])* $p:vis enum $n:ident: $t:ty { $($(#[$a:meta])* $k:ident),+ $(,)* } $($next:tt)*) => {
1242         $crate::flags! { $(#[$m])* $p enum $n: $t { $($(#[$a])* $k = (1 << $n::$k as $t)),+ } $($next)* }
1243     };
1244 
1245     // Entrypoint for enumerations with values.
1246     ($(#[$m:meta])* $p:vis enum $n:ident: $t:ty { $($(#[$a:meta])*$k:ident = $v:expr),* $(,)* } $($next:tt)*) => {
1247         $(#[$m])*
1248         #[derive(Copy, Clone, Debug, PartialEq, Eq)]
1249         $p enum $n { $($(#[$a])* $k),* }
1250 
1251         impl $crate::Flags for $n {
1252             type Type = $t;
1253 
1254             const LIST: &'static [Self] = &[$($n::$k),*];
1255         }
1256 
1257         impl ::core::convert::From<$n> for $crate::FlagSet<$n> {
1258             #[inline]
1259             fn from(value: $n) -> Self {
1260                 unsafe {
1261                     match value {
1262                         $($n::$k => Self::new_unchecked($v)),*
1263                     }
1264                 }
1265             }
1266         }
1267 
1268         impl ::core::ops::Not for $n {
1269             type Output = $crate::FlagSet<$n>;
1270 
1271             #[inline]
1272             fn not(self) -> Self::Output {
1273                 !$crate::FlagSet::from(self)
1274             }
1275         }
1276 
1277         impl<R: ::core::convert::Into<$crate::FlagSet<$n>>> ::core::ops::BitAnd<R> for $n {
1278             type Output = $crate::FlagSet<$n>;
1279 
1280             #[inline]
1281             fn bitand(self, rhs: R) -> Self::Output {
1282                 $crate::FlagSet::from(self) & rhs
1283             }
1284         }
1285 
1286         impl<R: ::core::convert::Into<$crate::FlagSet<$n>>> ::core::ops::BitOr<R> for $n {
1287             type Output = $crate::FlagSet<$n>;
1288 
1289             #[inline]
1290             fn bitor(self, rhs: R) -> Self::Output {
1291                 $crate::FlagSet::from(self) | rhs
1292             }
1293         }
1294 
1295         impl<R: ::core::convert::Into<$crate::FlagSet<$n>>> ::core::ops::BitXor<R> for $n {
1296             type Output = $crate::FlagSet<$n>;
1297 
1298             #[inline]
1299             fn bitxor(self, rhs: R) -> Self::Output {
1300                 $crate::FlagSet::from(self) ^ rhs
1301             }
1302         }
1303 
1304         impl<R: ::core::convert::Into<$crate::FlagSet<$n>>> ::core::ops::Sub<R> for $n {
1305             type Output = $crate::FlagSet<$n>;
1306 
1307             #[inline]
1308             fn sub(self, rhs: R) -> Self::Output {
1309                 $crate::FlagSet::from(self) - rhs
1310             }
1311         }
1312 
1313         impl<R: ::core::convert::Into<$crate::FlagSet<$n>>> ::core::ops::Rem<R> for $n {
1314             type Output = $crate::FlagSet<$n>;
1315 
1316             #[inline]
1317             fn rem(self, rhs: R) -> Self::Output {
1318                 $crate::FlagSet::from(self) % rhs
1319             }
1320         }
1321 
1322         $crate::flags! { $($next)* }
1323     };
1324 }
1325