summaryrefslogtreecommitdiffstats
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.rs297
1 files changed, 238 insertions, 59 deletions
diff --git a/vendor/bitflags/src/traits.rs b/vendor/bitflags/src/traits.rs
index 85503e64e..1e44645c8 100644
--- a/vendor/bitflags/src/traits.rs
+++ b/vendor/bitflags/src/traits.rs
@@ -1,23 +1,56 @@
-use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not};
+use core::{
+ fmt,
+ ops::{BitAnd, BitOr, BitXor, Not},
+};
-/// A trait that is automatically implemented for all bitflags.
-///
-/// It should not be implemented manually.
-pub trait BitFlags: ImplementedByBitFlagsMacro {
- /// The underlying integer type.
- type Bits: Bits;
+use crate::{
+ iter,
+ parser::{ParseError, ParseHex, WriteHex},
+};
- /// An iterator over enabled flags in an instance of the type.
- type Iter: Iterator<Item = Self>;
+/// Metadata for an individual flag.
+pub struct Flag<B> {
+ name: &'static str,
+ value: B,
+}
- /// An iterator over the raw names and bits for enabled flags in an instance of the type.
- type IterNames: Iterator<Item = (&'static str, Self)>;
+impl<B> Flag<B> {
+ /// Create a new flag with the given name and value.
+ pub const fn new(name: &'static str, value: B) -> Self {
+ Flag { name, value }
+ }
+
+ /// Get the name of this flag.
+ pub const fn name(&self) -> &'static str {
+ self.name
+ }
+
+ /// Get the value of this flag.
+ pub const fn value(&self) -> &B {
+ &self.value
+ }
+}
+
+/// A set of flags.
+///
+/// This trait is automatically implemented for flags types defined using the `bitflags!` macro.
+/// It can also be implemented manually for custom flags types.
+pub trait Flags: Sized + 'static {
+ /// The set of available flags and their names.
+ const FLAGS: &'static [Flag<Self>];
+
+ /// The underlying storage type.
+ type Bits: Bits;
/// Returns an empty set of flags.
- fn empty() -> Self;
+ fn empty() -> Self {
+ Self::from_bits_retain(Self::Bits::EMPTY)
+ }
/// Returns the set containing all flags.
- fn all() -> Self;
+ fn all() -> Self {
+ Self::from_bits_truncate(Self::Bits::ALL)
+ }
/// Returns the raw value of the flags currently stored.
fn bits(&self) -> Self::Bits;
@@ -28,9 +61,15 @@ pub trait BitFlags: ImplementedByBitFlagsMacro {
/// Note that each [multi-bit flag] is treated as a unit for this comparison.
///
/// [multi-bit flag]: index.html#multi-bit-flags
- fn from_bits(bits: Self::Bits) -> Option<Self>
- where
- Self: Sized;
+ 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 underlying bit representation, dropping any bits
/// that do not correspond to flags.
@@ -38,81 +77,162 @@ pub trait BitFlags: ImplementedByBitFlagsMacro {
/// Note that each [multi-bit flag] is treated as a unit for this comparison.
///
/// [multi-bit flag]: index.html#multi-bit-flags
- fn from_bits_truncate(bits: Self::Bits) -> Self;
+ fn from_bits_truncate(bits: Self::Bits) -> Self {
+ if bits == Self::Bits::EMPTY {
+ return Self::empty();
+ }
+
+ let mut truncated = Self::Bits::EMPTY;
+
+ for flag in Self::FLAGS.iter() {
+ let flag = flag.value();
+
+ if bits & flag.bits() == flag.bits() {
+ truncated = truncated | flag.bits();
+ }
+ }
+
+ Self::from_bits_retain(truncated)
+ }
/// Convert from underlying bit representation, preserving all
/// bits (even those not corresponding to a defined flag).
fn from_bits_retain(bits: Self::Bits) -> Self;
/// Get the flag for a particular name.
- fn from_name(name: &str) -> Option<Self>
- where
- Self: Sized;
+ fn from_name(name: &str) -> Option<Self> {
+ for flag in Self::FLAGS {
+ if flag.name() == name {
+ return Some(Self::from_bits_retain(flag.value().bits()));
+ }
+ }
+
+ None
+ }
/// Iterate over enabled flag values.
- fn iter(&self) -> Self::Iter;
+ fn iter(&self) -> iter::Iter<Self> {
+ iter::Iter::new(self)
+ }
/// Iterate over the raw names and bits for enabled flag values.
- fn iter_names(&self) -> Self::IterNames;
+ fn iter_names(&self) -> iter::IterNames<Self> {
+ iter::IterNames::new(self)
+ }
/// Returns `true` if no flags are currently stored.
- fn is_empty(&self) -> bool;
+ fn is_empty(&self) -> bool {
+ self.bits() == Self::Bits::EMPTY
+ }
/// Returns `true` if all flags are currently set.
- fn is_all(&self) -> bool;
+ 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()
+ }
/// Returns `true` if there are flags common to both `self` and `other`.
- fn intersects(&self, other: Self) -> bool;
+ fn intersects(&self, other: Self) -> bool
+ where
+ Self: Sized,
+ {
+ self.bits() & other.bits() != Self::Bits::EMPTY
+ }
/// Returns `true` if all of the flags in `other` are contained within `self`.
- fn contains(&self, other: Self) -> bool;
+ fn contains(&self, other: Self) -> bool
+ where
+ Self: Sized,
+ {
+ self.bits() & other.bits() == other.bits()
+ }
/// Inserts the specified flags in-place.
- fn insert(&mut self, other: Self);
+ ///
+ /// This method is equivalent to `union`.
+ fn insert(&mut self, other: Self)
+ where
+ Self: Sized,
+ {
+ *self = Self::from_bits_retain(self.bits() | other.bits());
+ }
/// Removes the specified flags in-place.
- fn remove(&mut self, other: Self);
+ ///
+ /// This method is equivalent to `difference`.
+ fn remove(&mut self, other: Self)
+ where
+ Self: Sized,
+ {
+ *self = Self::from_bits_retain(self.bits() & !other.bits());
+ }
/// Toggles the specified flags in-place.
- fn toggle(&mut self, other: Self);
+ ///
+ /// This method is equivalent to `symmetric_difference`.
+ fn toggle(&mut self, other: Self)
+ where
+ Self: Sized,
+ {
+ *self = Self::from_bits_retain(self.bits() ^ other.bits());
+ }
/// Inserts or removes the specified flags depending on the passed value.
- fn set(&mut self, other: Self, value: bool);
-}
+ fn set(&mut self, other: Self, value: bool)
+ where
+ Self: Sized,
+ {
+ if value {
+ self.insert(other);
+ } else {
+ self.remove(other);
+ }
+ }
-/// 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 {}
+ /// Returns the intersection between the flags in `self` and `other`.
+ #[must_use]
+ fn intersection(self, other: Self) -> Self {
+ Self::from_bits_retain(self.bits() & other.bits())
+ }
+
+ /// Returns the union of between the flags in `self` and `other`.
+ #[must_use]
+ fn union(self, other: Self) -> Self {
+ Self::from_bits_retain(self.bits() | other.bits())
+ }
-// Not re-exported
-pub trait Sealed {}
+ /// Returns the difference between the flags in `self` and `other`.
+ #[must_use]
+ fn difference(self, other: Self) -> Self {
+ Self::from_bits_retain(self.bits() & !other.bits())
+ }
-// Private implementation details
-//
-// The `Bits`, `PublicFlags`, and `InternalFlags` traits are implementation details of the `bitflags!`
-// macro that we're free to change here. They work with the `bitflags!` macro to separate the generated
-// code that belongs to end-users, and the generated code that belongs to this library.
+ /// Returns the symmetric difference between the flags
+ /// in `self` and `other`.
+ #[must_use]
+ fn symmetric_difference(self, other: Self) -> Self {
+ Self::from_bits_retain(self.bits() ^ other.bits())
+ }
-/// A private trait that encodes the requirements of underlying bits types that can hold flags.
-///
-/// This trait may be made public at some future point, but it presents a compatibility hazard
-/// so is left internal for now.
-#[doc(hidden)]
+ /// Returns the complement of this set of flags.
+ #[must_use]
+ fn complement(self) -> Self {
+ Self::from_bits_truncate(!self.bits())
+ }
+}
+
+/// Underlying storage for a flags type.
pub trait Bits:
Clone
+ Copy
- + BitAnd
- + BitAndAssign
- + BitOr
- + BitOrAssign
- + BitXor
- + BitXorAssign
- + Not
+ + PartialEq
+ + BitAnd<Output = Self>
+ + BitOr<Output = Self>
+ + BitXor<Output = Self>
+ + Not<Output = Self>
+ Sized
- + Sealed
+ + 'static
{
/// The value of `Self` where no bits are set.
const EMPTY: Self;
@@ -121,6 +241,10 @@ pub trait Bits:
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,)*) => {
$(
@@ -134,8 +258,32 @@ macro_rules! impl_bits {
const ALL: $i = <$u>::MAX as $i;
}
- impl Sealed for $u {}
- impl Sealed for $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 {}
)*
}
}
@@ -152,6 +300,37 @@ impl_bits! {
/// 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;
}
+
+#[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};
+}