summaryrefslogtreecommitdiff
path: root/vendor/bitflags/src/traits.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/bitflags/src/traits.rs')
-rw-r--r--vendor/bitflags/src/traits.rs430
1 files changed, 430 insertions, 0 deletions
diff --git a/vendor/bitflags/src/traits.rs b/vendor/bitflags/src/traits.rs
new file mode 100644
index 0000000..2823514
--- /dev/null
+++ b/vendor/bitflags/src/traits.rs
@@ -0,0 +1,430 @@
+use core::{
+ fmt,
+ ops::{BitAnd, BitOr, BitXor, Not},
+};
+
+use crate::{
+ iter,
+ parser::{ParseError, ParseHex, WriteHex},
+};
+
+/**
+A defined flags value that may be named or unnamed.
+*/
+pub struct Flag<B> {
+ name: &'static str,
+ value: B,
+}
+
+impl<B> Flag<B> {
+ /**
+ Define a flag.
+
+ If `name` is non-empty then the flag is named, otherwise it's unnamed.
+ */
+ pub const fn new(name: &'static str, value: B) -> Self {
+ Flag { name, value }
+ }
+
+ /**
+ Get the name of this flag.
+
+ If the flag is unnamed then the returned string will be empty.
+ */
+ pub const fn name(&self) -> &'static str {
+ self.name
+ }
+
+ /**
+ Get the flags value of this flag.
+ */
+ pub const fn value(&self) -> &B {
+ &self.value
+ }
+
+ /**
+ Whether the flag is named.
+
+ If [`Flag::name`] returns a non-empty string then this method will return `true`.
+ */
+ pub const fn is_named(&self) -> bool {
+ !self.name.is_empty()
+ }
+
+ /**
+ Whether the flag is unnamed.
+
+ If [`Flag::name`] returns a non-empty string then this method will return `false`.
+ */
+ pub const fn is_unnamed(&self) -> bool {
+ self.name.is_empty()
+ }
+}
+
+/**
+A set of defined flags using a bits type as storage.
+
+## Implementing `Flags`
+
+This trait is implemented by the [`bitflags`](macro.bitflags.html) macro:
+
+```
+use bitflags::bitflags;
+
+bitflags! {
+ struct MyFlags: u8 {
+ const A = 1;
+ const B = 1 << 1;
+ }
+}
+```
+
+It can also be implemented manually:
+
+```
+use bitflags::{Flag, Flags};
+
+struct MyFlags(u8);
+
+impl Flags for MyFlags {
+ const FLAGS: &'static [Flag<Self>] = &[
+ Flag::new("A", MyFlags(1)),
+ Flag::new("B", MyFlags(1 << 1)),
+ ];
+
+ type Bits = u8;
+
+ fn from_bits_retain(bits: Self::Bits) -> Self {
+ MyFlags(bits)
+ }
+
+ fn bits(&self) -> Self::Bits {
+ self.0
+ }
+}
+```
+
+## Using `Flags`
+
+The `Flags` trait can be used generically to work with any flags types. In this example,
+we can count the number of defined named flags:
+
+```
+# use bitflags::{bitflags, Flags};
+fn defined_flags<F: Flags>() -> usize {
+ F::FLAGS.iter().filter(|f| f.is_named()).count()
+}
+
+bitflags! {
+ struct MyFlags: u8 {
+ const A = 1;
+ const B = 1 << 1;
+ const C = 1 << 2;
+
+ const _ = !0;
+ }
+}
+
+assert_eq!(3, defined_flags::<MyFlags>());
+```
+*/
+pub trait Flags: Sized + 'static {
+ /// The set of defined flags.
+ const FLAGS: &'static [Flag<Self>];
+
+ /// The underlying bits type.
+ type Bits: Bits;
+
+ /// Get a flags value with all bits unset.
+ fn empty() -> Self {
+ Self::from_bits_retain(Self::Bits::EMPTY)
+ }
+
+ /// Get a flags value with all known bits set.
+ fn all() -> Self {
+ let mut truncated = Self::Bits::EMPTY;
+
+ for flag in Self::FLAGS.iter() {
+ truncated = truncated | flag.value().bits();
+ }
+
+ Self::from_bits_retain(truncated)
+ }
+
+ /// Get the underlying bits value.
+ ///
+ /// The returned value is exactly the bits set in this flags value.
+ fn bits(&self) -> Self::Bits;
+
+ /// Convert from a bits value.
+ ///
+ /// This method will return `None` if any unknown bits are set.
+ fn from_bits(bits: Self::Bits) -> Option<Self> {
+ let truncated = Self::from_bits_truncate(bits);
+
+ if truncated.bits() == bits {
+ Some(truncated)
+ } else {
+ None
+ }
+ }
+
+ /// Convert from a bits value, unsetting any unknown bits.
+ fn from_bits_truncate(bits: Self::Bits) -> Self {
+ Self::from_bits_retain(bits & Self::all().bits())
+ }
+
+ /// Convert from a bits value exactly.
+ fn from_bits_retain(bits: Self::Bits) -> Self;
+
+ /// Get a flags value with the bits of a flag with the given name set.
+ ///
+ /// This method will return `None` if `name` is empty or doesn't
+ /// correspond to any named flag.
+ fn from_name(name: &str) -> Option<Self> {
+ // Don't parse empty names as empty flags
+ if name.is_empty() {
+ return None;
+ }
+
+ for flag in Self::FLAGS {
+ if flag.name() == name {
+ return Some(Self::from_bits_retain(flag.value().bits()));
+ }
+ }
+
+ None
+ }
+
+ /// Yield a set of contained flags values.
+ ///
+ /// Each yielded flags value will correspond to a defined named flag. Any unknown bits
+ /// will be yielded together as a final flags value.
+ fn iter(&self) -> iter::Iter<Self> {
+ iter::Iter::new(self)
+ }
+
+ /// Yield a set of contained named flags values.
+ ///
+ /// This method is like [`Flags::iter`], except only yields bits in contained named flags.
+ /// Any unknown bits, or bits not corresponding to a contained flag will not be yielded.
+ fn iter_names(&self) -> iter::IterNames<Self> {
+ iter::IterNames::new(self)
+ }
+
+ /// Whether all bits in this flags value are unset.
+ fn is_empty(&self) -> bool {
+ self.bits() == Self::Bits::EMPTY
+ }
+
+ /// Whether all known bits in this flags value are set.
+ fn is_all(&self) -> bool {
+ // NOTE: We check against `Self::all` here, not `Self::Bits::ALL`
+ // because the set of all flags may not use all bits
+ Self::all().bits() | self.bits() == self.bits()
+ }
+
+ /// Whether any set bits in a source flags value are also set in a target flags value.
+ fn intersects(&self, other: Self) -> bool
+ where
+ Self: Sized,
+ {
+ self.bits() & other.bits() != Self::Bits::EMPTY
+ }
+
+ /// Whether all set bits in a source flags value are also set in a target flags value.
+ fn contains(&self, other: Self) -> bool
+ where
+ Self: Sized,
+ {
+ self.bits() & other.bits() == other.bits()
+ }
+
+ /// The bitwise or (`|`) of the bits in two flags values.
+ fn insert(&mut self, other: Self)
+ where
+ Self: Sized,
+ {
+ *self = Self::from_bits_retain(self.bits()).union(other);
+ }
+
+ /// The intersection of a source flags value with the complement of a target flags value (`&!`).
+ ///
+ /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
+ /// `remove` won't truncate `other`, but the `!` operator will.
+ fn remove(&mut self, other: Self)
+ where
+ Self: Sized,
+ {
+ *self = Self::from_bits_retain(self.bits()).difference(other);
+ }
+
+ /// The bitwise exclusive-or (`^`) of the bits in two flags values.
+ fn toggle(&mut self, other: Self)
+ where
+ Self: Sized,
+ {
+ *self = Self::from_bits_retain(self.bits()).symmetric_difference(other);
+ }
+
+ /// Call [`Flags::insert`] when `value` is `true` or [`Flags::remove`] when `value` is `false`.
+ fn set(&mut self, other: Self, value: bool)
+ where
+ Self: Sized,
+ {
+ if value {
+ self.insert(other);
+ } else {
+ self.remove(other);
+ }
+ }
+
+ /// The bitwise and (`&`) of the bits in two flags values.
+ #[must_use]
+ fn intersection(self, other: Self) -> Self {
+ Self::from_bits_retain(self.bits() & other.bits())
+ }
+
+ /// The bitwise or (`|`) of the bits in two flags values.
+ #[must_use]
+ fn union(self, other: Self) -> Self {
+ Self::from_bits_retain(self.bits() | other.bits())
+ }
+
+ /// The intersection of a source flags value with the complement of a target flags value (`&!`).
+ ///
+ /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
+ /// `difference` won't truncate `other`, but the `!` operator will.
+ #[must_use]
+ fn difference(self, other: Self) -> Self {
+ Self::from_bits_retain(self.bits() & !other.bits())
+ }
+
+ /// The bitwise exclusive-or (`^`) of the bits in two flags values.
+ #[must_use]
+ fn symmetric_difference(self, other: Self) -> Self {
+ Self::from_bits_retain(self.bits() ^ other.bits())
+ }
+
+ /// The bitwise negation (`!`) of the bits in a flags value, truncating the result.
+ #[must_use]
+ fn complement(self) -> Self {
+ Self::from_bits_truncate(!self.bits())
+ }
+}
+
+/**
+A bits type that can be used as storage for a flags type.
+*/
+pub trait Bits:
+ Clone
+ + Copy
+ + PartialEq
+ + BitAnd<Output = Self>
+ + BitOr<Output = Self>
+ + BitXor<Output = Self>
+ + Not<Output = Self>
+ + Sized
+ + 'static
+{
+ /// A value with all bits unset.
+ const EMPTY: Self;
+
+ /// A value with all bits set.
+ const ALL: Self;
+}
+
+// Not re-exported: prevent custom `Bits` impls being used in the `bitflags!` macro,
+// or they may fail to compile based on crate features
+pub trait Primitive {}
+
+macro_rules! impl_bits {
+ ($($u:ty, $i:ty,)*) => {
+ $(
+ impl Bits for $u {
+ const EMPTY: $u = 0;
+ const ALL: $u = <$u>::MAX;
+ }
+
+ impl Bits for $i {
+ const EMPTY: $i = 0;
+ const ALL: $i = <$u>::MAX as $i;
+ }
+
+ impl ParseHex for $u {
+ fn parse_hex(input: &str) -> Result<Self, ParseError> {
+ <$u>::from_str_radix(input, 16).map_err(|_| ParseError::invalid_hex_flag(input))
+ }
+ }
+
+ impl ParseHex for $i {
+ fn parse_hex(input: &str) -> Result<Self, ParseError> {
+ <$i>::from_str_radix(input, 16).map_err(|_| ParseError::invalid_hex_flag(input))
+ }
+ }
+
+ impl WriteHex for $u {
+ fn write_hex<W: fmt::Write>(&self, mut writer: W) -> fmt::Result {
+ write!(writer, "{:x}", self)
+ }
+ }
+
+ impl WriteHex for $i {
+ fn write_hex<W: fmt::Write>(&self, mut writer: W) -> fmt::Result {
+ write!(writer, "{:x}", self)
+ }
+ }
+
+ impl Primitive for $i {}
+ impl Primitive for $u {}
+ )*
+ }
+}
+
+impl_bits! {
+ u8, i8,
+ u16, i16,
+ u32, i32,
+ u64, i64,
+ u128, i128,
+ usize, isize,
+}
+
+/// A trait for referencing the `bitflags`-owned internal type
+/// without exposing it publicly.
+pub trait PublicFlags {
+ /// The type of the underlying storage.
+ type Primitive: Primitive;
+
+ /// The type of the internal field on the generated flags type.
+ type Internal;
+}
+
+#[doc(hidden)]
+#[deprecated(note = "use the `Flags` trait instead")]
+pub trait BitFlags: ImplementedByBitFlagsMacro + Flags {
+ /// An iterator over enabled flags in an instance of the type.
+ type Iter: Iterator<Item = Self>;
+
+ /// An iterator over the raw names and bits for enabled flags in an instance of the type.
+ type IterNames: Iterator<Item = (&'static str, Self)>;
+}
+
+#[allow(deprecated)]
+impl<B: Flags> BitFlags for B {
+ type Iter = iter::Iter<Self>;
+ type IterNames = iter::IterNames<Self>;
+}
+
+impl<B: Flags> ImplementedByBitFlagsMacro for B {}
+
+/// A marker trait that signals that an implementation of `BitFlags` came from the `bitflags!` macro.
+///
+/// There's nothing stopping an end-user from implementing this trait, but we don't guarantee their
+/// manual implementations won't break between non-breaking releases.
+#[doc(hidden)]
+pub trait ImplementedByBitFlagsMacro {}
+
+pub(crate) mod __private {
+ pub use super::{ImplementedByBitFlagsMacro, PublicFlags};
+}