diff options
Diffstat (limited to 'vendor/bitflags/src')
-rw-r--r-- | vendor/bitflags/src/example_generated.rs | 39 | ||||
-rw-r--r-- | vendor/bitflags/src/external.rs | 110 | ||||
-rw-r--r-- | vendor/bitflags/src/external/arbitrary.rs (renamed from vendor/bitflags/src/external/arbitrary_support.rs) | 12 | ||||
-rw-r--r-- | vendor/bitflags/src/external/bytemuck.rs (renamed from vendor/bitflags/src/external/bytemuck_support.rs) | 2 | ||||
-rw-r--r-- | vendor/bitflags/src/external/serde.rs (renamed from vendor/bitflags/src/external/serde_support.rs) | 45 | ||||
-rw-r--r-- | vendor/bitflags/src/internal.rs | 509 | ||||
-rw-r--r-- | vendor/bitflags/src/iter.rs | 133 | ||||
-rw-r--r-- | vendor/bitflags/src/lib.rs | 1393 | ||||
-rw-r--r-- | vendor/bitflags/src/parser.rs | 114 | ||||
-rw-r--r-- | vendor/bitflags/src/public.rs | 602 | ||||
-rw-r--r-- | vendor/bitflags/src/tests.rs | 107 | ||||
-rw-r--r-- | vendor/bitflags/src/traits.rs | 297 |
12 files changed, 1425 insertions, 1938 deletions
diff --git a/vendor/bitflags/src/example_generated.rs b/vendor/bitflags/src/example_generated.rs index b7589014a..3586e3f04 100644 --- a/vendor/bitflags/src/example_generated.rs +++ b/vendor/bitflags/src/example_generated.rs @@ -9,30 +9,45 @@ __declare_public_bitflags! { /// This is the same `Flags` struct defined in the [crate level example](../index.html#example). /// Note that this struct is just for documentation purposes only, it must not be used outside /// this crate. - pub struct Flags; + pub struct Flags } __declare_internal_bitflags! { - pub struct Field0: u32; - pub struct Iter; - pub struct IterRaw; + pub struct Field0: u32 } __impl_internal_bitflags! { - Field0: u32, Flags, Iter, IterRaw { - A; - B; - C; - ABC; + Field0: u32, Flags { + // Field `A`. + /// + /// This flag has the value `0b00000001`. + A = 0b00000001; + /// Field `B`. + /// + /// This flag has the value `0b00000010`. + B = 0b00000010; + /// Field `C`. + /// + /// This flag has the value `0b00000100`. + C = 0b00000100; + ABC = Self::A.bits() | Self::B.bits() | Self::C.bits(); } } -__impl_public_bitflags! { - Flags: u32, Field0, Iter, IterRaw; +__impl_public_bitflags_forward! { + Flags: u32, Field0 +} + +__impl_public_bitflags_ops! { + Flags +} + +__impl_public_bitflags_iter! { + Flags: u32, Flags } __impl_public_bitflags_consts! { - Flags { + Flags: u32 { /// Field `A`. /// /// This flag has the value `0b00000001`. diff --git a/vendor/bitflags/src/external.rs b/vendor/bitflags/src/external.rs index 6b07ff64d..94bd20004 100644 --- a/vendor/bitflags/src/external.rs +++ b/vendor/bitflags/src/external.rs @@ -5,7 +5,13 @@ How do I support a new external library? Let's say we want to add support for `my_library`. -First, we define a macro like so: +First, we create a module under `external`, like `serde` with any specialized code. +Ideally, any utilities in here should just work off the `Flags` trait and maybe a +few other assumed bounds. + +Next, re-export the library from the `__private` module here. + +Next, define a macro like so: ```rust #[macro_export(local_inner_macros)] @@ -13,7 +19,7 @@ First, we define a macro like so: #[cfg(feature = "serde")] macro_rules! __impl_external_bitflags_my_library { ( - $InternalBitFlags:ident: $T:ty { + $InternalBitFlags:ident: $T:ty, $PublicBitFlags:ident { $( $(#[$attr:ident $($args:tt)*])* $Flag:ident; @@ -29,7 +35,7 @@ macro_rules! __impl_external_bitflags_my_library { #[cfg(not(feature = "my_library"))] macro_rules! __impl_external_bitflags_my_library { ( - $InternalBitFlags:ident: $T:ty { + $InternalBitFlags:ident: $T:ty, $PublicBitFlags:ident { $( $(#[$attr:ident $($args:tt)*])* $Flag:ident; @@ -49,7 +55,7 @@ Now, we add our macro call to the `__impl_external_bitflags` macro body: ```rust __impl_external_bitflags_my_library! { - $InternalBitFlags: $T { + $InternalBitFlags: $T, $PublicBitFlags { $( $(#[$attr $($args)*])* $Flag; @@ -57,34 +63,25 @@ __impl_external_bitflags_my_library! { } } ``` - -What about libraries that _must_ be supported through `#[derive]`? - -In these cases, the attributes will need to be added to the `__declare_internal_bitflags` macro when -the internal type is declared. */ -#[cfg(feature = "serde")] -pub mod serde_support; -#[cfg(feature = "serde")] -pub use serde; +pub(crate) mod __private { + #[cfg(feature = "serde")] + pub use serde; -#[cfg(feature = "arbitrary")] -pub mod arbitrary_support; -#[cfg(feature = "arbitrary")] -pub use arbitrary; + #[cfg(feature = "arbitrary")] + pub use arbitrary; -#[cfg(feature = "bytemuck")] -pub mod bytemuck_support; -#[cfg(feature = "bytemuck")] -pub use bytemuck; + #[cfg(feature = "bytemuck")] + pub use bytemuck; +} /// Implements traits from external libraries for the internal bitflags type. #[macro_export(local_inner_macros)] #[doc(hidden)] macro_rules! __impl_external_bitflags { ( - $InternalBitFlags:ident: $T:ty { + $InternalBitFlags:ident: $T:ty, $PublicBitFlags:ident { $( $(#[$attr:ident $($args:tt)*])* $Flag:ident; @@ -96,7 +93,7 @@ macro_rules! __impl_external_bitflags { // and a no-op when it isn't __impl_external_bitflags_serde! { - $InternalBitFlags: $T { + $InternalBitFlags: $T, $PublicBitFlags { $( $(#[$attr $($args)*])* $Flag; @@ -105,7 +102,7 @@ macro_rules! __impl_external_bitflags { } __impl_external_bitflags_arbitrary! { - $InternalBitFlags: $T { + $InternalBitFlags: $T, $PublicBitFlags { $( $(#[$attr $($args)*])* $Flag; @@ -114,7 +111,7 @@ macro_rules! __impl_external_bitflags { } __impl_external_bitflags_bytemuck! { - $InternalBitFlags: $T { + $InternalBitFlags: $T, $PublicBitFlags { $( $(#[$attr $($args)*])* $Flag; @@ -124,13 +121,16 @@ macro_rules! __impl_external_bitflags { }; } +#[cfg(feature = "serde")] +pub mod serde; + /// Implement `Serialize` and `Deserialize` for the internal bitflags type. #[macro_export(local_inner_macros)] #[doc(hidden)] #[cfg(feature = "serde")] macro_rules! __impl_external_bitflags_serde { ( - $InternalBitFlags:ident: $T:ty { + $InternalBitFlags:ident: $T:ty, $PublicBitFlags:ident { $( $(#[$attr:ident $($args:tt)*])* $Flag:ident; @@ -142,8 +142,8 @@ macro_rules! __impl_external_bitflags_serde { &self, serializer: S, ) -> $crate::__private::core::result::Result<S::Ok, S::Error> { - $crate::__private::serde_support::serialize_bits_default::<$InternalBitFlags, $T, S>( - &self, + $crate::serde::serialize( + &$PublicBitFlags::from_bits_retain(self.bits()), serializer, ) } @@ -153,9 +153,9 @@ macro_rules! __impl_external_bitflags_serde { fn deserialize<D: $crate::__private::serde::Deserializer<'de>>( deserializer: D, ) -> $crate::__private::core::result::Result<Self, D::Error> { - $crate::__private::serde_support::deserialize_bits_default::<$InternalBitFlags, $T, D>( - deserializer, - ) + let flags: $PublicBitFlags = $crate::serde::deserialize(deserializer)?; + + Ok(flags.0) } } }; @@ -166,7 +166,7 @@ macro_rules! __impl_external_bitflags_serde { #[cfg(not(feature = "serde"))] macro_rules! __impl_external_bitflags_serde { ( - $InternalBitFlags:ident: $T:ty { + $InternalBitFlags:ident: $T:ty, $PublicBitFlags:ident { $( $(#[$attr:ident $($args:tt)*])* $Flag:ident; @@ -175,13 +175,19 @@ macro_rules! __impl_external_bitflags_serde { ) => {}; } +#[cfg(feature = "arbitrary")] +pub mod arbitrary; + +#[cfg(feature = "bytemuck")] +mod bytemuck; + /// Implement `Arbitrary` for the internal bitflags type. #[macro_export(local_inner_macros)] #[doc(hidden)] #[cfg(feature = "arbitrary")] macro_rules! __impl_external_bitflags_arbitrary { ( - $InternalBitFlags:ident: $T:ty { + $InternalBitFlags:ident: $T:ty, $PublicBitFlags:ident { $( $(#[$attr:ident $($args:tt)*])* $Flag:ident; @@ -192,7 +198,7 @@ macro_rules! __impl_external_bitflags_arbitrary { fn arbitrary( u: &mut $crate::__private::arbitrary::Unstructured<'a>, ) -> $crate::__private::arbitrary::Result<Self> { - Self::from_bits(u.arbitrary()?).ok_or_else(|| $crate::__private::arbitrary::Error::IncorrectFormat) + $crate::arbitrary::arbitrary::<$PublicBitFlags>(u).map(|flags| flags.0) } } }; @@ -203,12 +209,12 @@ macro_rules! __impl_external_bitflags_arbitrary { #[cfg(not(feature = "arbitrary"))] macro_rules! __impl_external_bitflags_arbitrary { ( - $InternalBitFlags:ident: $T:ty { - $( - $(#[$attr:ident $($args:tt)*])* - $Flag:ident; - )* - } + $InternalBitFlags:ident: $T:ty, $PublicBitFlags:ident { + $( + $(#[$attr:ident $($args:tt)*])* + $Flag:ident; + )* + } ) => {}; } @@ -218,29 +224,25 @@ macro_rules! __impl_external_bitflags_arbitrary { #[cfg(feature = "bytemuck")] macro_rules! __impl_external_bitflags_bytemuck { ( - $InternalBitFlags:ident: $T:ty { + $InternalBitFlags:ident: $T:ty, $PublicBitFlags:ident { $( $(#[$attr:ident $($args:tt)*])* - $Flag:ident; - )* + $Flag:ident; + )* } ) => { // SAFETY: $InternalBitFlags is guaranteed to have the same ABI as $T, // and $T implements Pod - unsafe impl $crate::__private::bytemuck::Pod for $InternalBitFlags - where - $T: $crate::__private::bytemuck::Pod, + unsafe impl $crate::__private::bytemuck::Pod for $InternalBitFlags where + $T: $crate::__private::bytemuck::Pod { - } // SAFETY: $InternalBitFlags is guaranteed to have the same ABI as $T, // and $T implements Zeroable - unsafe impl $crate::__private::bytemuck::Zeroable for $InternalBitFlags - where - $T: $crate::__private::bytemuck::Zeroable, + unsafe impl $crate::__private::bytemuck::Zeroable for $InternalBitFlags where + $T: $crate::__private::bytemuck::Zeroable { - } }; } @@ -250,11 +252,11 @@ macro_rules! __impl_external_bitflags_bytemuck { #[cfg(not(feature = "bytemuck"))] macro_rules! __impl_external_bitflags_bytemuck { ( - $InternalBitFlags:ident: $T:ty { + $InternalBitFlags:ident: $T:ty, $PublicBitFlags:ident { $( $(#[$attr:ident $($args:tt)*])* - $Flag:ident; - )* + $Flag:ident; + )* } ) => {}; } diff --git a/vendor/bitflags/src/external/arbitrary_support.rs b/vendor/bitflags/src/external/arbitrary.rs index 56708f017..715ba251a 100644 --- a/vendor/bitflags/src/external/arbitrary_support.rs +++ b/vendor/bitflags/src/external/arbitrary.rs @@ -1,3 +1,15 @@ +//! Specialized fuzzing for flags types using `arbitrary`. + +use crate::Flags; + +/// Get a random known flags value. +pub fn arbitrary<'a, B: Flags>(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<B> +where + B::Bits: arbitrary::Arbitrary<'a>, +{ + B::from_bits(u.arbitrary()?).ok_or_else(|| arbitrary::Error::IncorrectFormat) +} + #[cfg(test)] mod tests { use arbitrary::Arbitrary; diff --git a/vendor/bitflags/src/external/bytemuck_support.rs b/vendor/bitflags/src/external/bytemuck.rs index 5ab109e0d..a0cd68c9d 100644 --- a/vendor/bitflags/src/external/bytemuck_support.rs +++ b/vendor/bitflags/src/external/bytemuck.rs @@ -1,7 +1,7 @@ #[cfg(test)] mod tests { use bytemuck::{Pod, Zeroable}; - + bitflags! { #[derive(Pod, Zeroable, Clone, Copy)] #[repr(transparent)] diff --git a/vendor/bitflags/src/external/serde_support.rs b/vendor/bitflags/src/external/serde.rs index 7c202a296..1d501db82 100644 --- a/vendor/bitflags/src/external/serde_support.rs +++ b/vendor/bitflags/src/external/serde.rs @@ -1,59 +1,60 @@ +//! Specialized serialization for flags types using `serde`. + +use crate::{ + parser::{self, ParseHex, WriteHex}, + Flags, +}; use core::{fmt, str}; use serde::{ de::{Error, Visitor}, Deserialize, Deserializer, Serialize, Serializer, }; -pub fn serialize_bits_default<T: fmt::Display + AsRef<B>, B: Serialize, S: Serializer>( - flags: &T, - serializer: S, -) -> Result<S::Ok, S::Error> { +/// Serialize a set of flags as a human-readable string or their underlying bits. +pub fn serialize<B: Flags, S: Serializer>(flags: &B, serializer: S) -> Result<S::Ok, S::Error> +where + B::Bits: WriteHex + Serialize, +{ // Serialize human-readable flags as a string like `"A | B"` if serializer.is_human_readable() { - serializer.collect_str(flags) + serializer.collect_str(&parser::AsDisplay(flags)) } // Serialize non-human-readable flags directly as the underlying bits else { - flags.as_ref().serialize(serializer) + flags.bits().serialize(serializer) } } -pub fn deserialize_bits_default< - 'de, - T: str::FromStr + From<B>, - B: Deserialize<'de>, - D: Deserializer<'de>, ->( - deserializer: D, -) -> Result<T, D::Error> +/// Deserialize a set of flags from a human-readable string or their underlying bits. +pub fn deserialize<'de, B: Flags, D: Deserializer<'de>>(deserializer: D) -> Result<B, D::Error> where - <T as str::FromStr>::Err: fmt::Display, + B::Bits: ParseHex + Deserialize<'de>, { if deserializer.is_human_readable() { // Deserialize human-readable flags by parsing them from strings like `"A | B"` - struct FlagsVisitor<T>(core::marker::PhantomData<T>); + struct FlagsVisitor<B>(core::marker::PhantomData<B>); - impl<'de, T: str::FromStr> Visitor<'de> for FlagsVisitor<T> + impl<'de, B: Flags> Visitor<'de> for FlagsVisitor<B> where - <T as str::FromStr>::Err: fmt::Display, + B::Bits: ParseHex, { - type Value = T; + type Value = B; fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { formatter.write_str("a string value of `|` separated flags") } fn visit_str<E: Error>(self, flags: &str) -> Result<Self::Value, E> { - flags.parse().map_err(|e| E::custom(e)) + parser::from_str(flags).map_err(|e| E::custom(e)) } } deserializer.deserialize_str(FlagsVisitor(Default::default())) } else { // Deserialize non-human-readable flags directly from the underlying bits - let bits = B::deserialize(deserializer)?; + let bits = B::Bits::deserialize(deserializer)?; - Ok(bits.into()) + Ok(B::from_bits_retain(bits)) } } diff --git a/vendor/bitflags/src/internal.rs b/vendor/bitflags/src/internal.rs index eca0a304a..824cdde45 100644 --- a/vendor/bitflags/src/internal.rs +++ b/vendor/bitflags/src/internal.rs @@ -10,29 +10,14 @@ #[doc(hidden)] macro_rules! __declare_internal_bitflags { ( - $vis:vis struct $InternalBitFlags:ident: $T:ty; - $iter_vis:vis struct $Iter:ident; - $iter_names_vis:vis struct $IterNames:ident; + $vis:vis struct $InternalBitFlags:ident: $T:ty ) => { // NOTE: The ABI of this type is _guaranteed_ to be the same as `T` // This is relied on by some external libraries like `bytemuck` to make // its `unsafe` trait impls sound. #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] #[repr(transparent)] - $vis struct $InternalBitFlags { - bits: $T, - } - - $iter_vis struct $Iter { - inner: $IterNames, - done: bool, - } - - $iter_names_vis struct $IterNames { - idx: usize, - source: $InternalBitFlags, - state: $InternalBitFlags, - } + $vis struct $InternalBitFlags($T); }; } @@ -44,14 +29,18 @@ macro_rules! __declare_internal_bitflags { #[doc(hidden)] macro_rules! __impl_internal_bitflags { ( - $InternalBitFlags:ident: $T:ty, $BitFlags:ident, $Iter:ident, $IterNames:ident { + $InternalBitFlags:ident: $T:ty, $PublicBitFlags:ident { $( $(#[$attr:ident $($args:tt)*])* - $Flag:ident; + $Flag:ident = $value:expr; )* } ) => { - impl $crate::__private::PublicFlags for $BitFlags { + // NOTE: This impl is also used to prevent using bits types from non-primitive types + // in the `bitflags` macro. If this approach is changed, this guard will need to be + // retained somehow + impl $crate::__private::PublicFlags for $PublicBitFlags { + type Primitive = $T; type Internal = $InternalBitFlags; } @@ -67,13 +56,13 @@ macro_rules! __impl_internal_bitflags { if self.is_empty() { // If no flags are set then write an empty hex flag to avoid // writing an empty string. In some contexts, like serialization, - // an empty string is preferrable, but it may be unexpected in + // an empty string is preferable, but it may be unexpected in // others for a format not to produce any output. // // We can remove this `0x0` and remain compatible with `FromStr`, // because an empty string will still parse to an empty set of flags, // just like `0x0` does. - $crate::__private::core::write!(f, "{:#x}", <$T as $crate::__private::Bits>::EMPTY) + $crate::__private::core::write!(f, "{:#x}", <$T as $crate::Bits>::EMPTY) } else { $crate::__private::core::fmt::Display::fmt(self, f) } @@ -82,278 +71,21 @@ macro_rules! __impl_internal_bitflags { impl $crate::__private::core::fmt::Display for $InternalBitFlags { fn fmt(&self, f: &mut $crate::__private::core::fmt::Formatter<'_>) -> $crate::__private::core::fmt::Result { - // A formatter for bitflags that produces text output like: - // - // A | B | 0xf6 - // - // The names of set flags are written in a bar-separated-format, - // followed by a hex number of any remaining bits that are set - // but don't correspond to any flags. - - // Iterate over the valid flags - let mut first = true; - let mut iter = self.iter_names(); - for (name, _) in &mut iter { - if !first { - f.write_str(" | ")?; - } - - first = false; - f.write_str(name)?; - } - - // Append any extra bits that correspond to flags to the end of the format - let extra_bits = iter.state.bits(); - if extra_bits != <$T as $crate::__private::Bits>::EMPTY { - if !first { - f.write_str(" | ")?; - } - - $crate::__private::core::write!(f, "{:#x}", extra_bits)?; - } - - $crate::__private::core::fmt::Result::Ok(()) + $crate::parser::to_writer(&$PublicBitFlags(*self), f) } } - // The impl for `FromStr` should parse anything produced by `Display` impl $crate::__private::core::str::FromStr for $InternalBitFlags { type Err = $crate::parser::ParseError; fn from_str(s: &str) -> $crate::__private::core::result::Result<Self, Self::Err> { - let s = s.trim(); - - let mut parsed_flags = Self::empty(); - - // If the input is empty then return an empty set of flags - if s.is_empty() { - return $crate::__private::core::result::Result::Ok(parsed_flags); - } - - for flag in s.split('|') { - let flag = flag.trim(); - - // If the flag is empty then we've got missing input - if flag.is_empty() { - return $crate::__private::core::result::Result::Err($crate::parser::ParseError::empty_flag()); - } - - // If the flag starts with `0x` then it's a hex number - // Parse it directly to the underlying bits type - let parsed_flag = if let $crate::__private::core::option::Option::Some(flag) = flag.strip_prefix("0x") { - let bits = <$T>::from_str_radix(flag, 16).map_err(|_| $crate::parser::ParseError::invalid_hex_flag(flag))?; - - Self::from_bits_retain(bits) - } - // Otherwise the flag is a name - // The generated flags type will determine whether - // or not it's a valid identifier - else { - Self::from_name(flag).ok_or_else(|| $crate::parser::ParseError::invalid_named_flag(flag))? - }; - - parsed_flags.insert(parsed_flag); - } - - $crate::__private::core::result::Result::Ok(parsed_flags) - } - } - - impl $crate::__private::core::fmt::Binary for $InternalBitFlags { - fn fmt(&self, f: &mut $crate::__private::core::fmt::Formatter) -> $crate::__private::core::fmt::Result { - $crate::__private::core::fmt::Binary::fmt(&self.bits(), f) - } - } - - impl $crate::__private::core::fmt::Octal for $InternalBitFlags { - fn fmt(&self, f: &mut $crate::__private::core::fmt::Formatter) -> $crate::__private::core::fmt::Result { - $crate::__private::core::fmt::Octal::fmt(&self.bits(), f) - } - } - - impl $crate::__private::core::fmt::LowerHex for $InternalBitFlags { - fn fmt(&self, f: &mut $crate::__private::core::fmt::Formatter) -> $crate::__private::core::fmt::Result { - $crate::__private::core::fmt::LowerHex::fmt(&self.bits(), f) - } - } - - impl $crate::__private::core::fmt::UpperHex for $InternalBitFlags { - fn fmt(&self, f: &mut $crate::__private::core::fmt::Formatter) -> $crate::__private::core::fmt::Result { - $crate::__private::core::fmt::UpperHex::fmt(&self.bits(), f) - } - } - - impl $InternalBitFlags { - #[inline] - pub const fn empty() -> Self { - Self { bits: <$T as $crate::__private::Bits>::EMPTY } - } - - #[inline] - pub const fn all() -> Self { - Self::from_bits_truncate(<$T as $crate::__private::Bits>::ALL) - } - - #[inline] - pub const fn bits(&self) -> $T { - self.bits - } - - #[inline] - pub fn bits_mut(&mut self) -> &mut $T { - &mut self.bits - } - - #[inline] - pub const fn from_bits(bits: $T) -> $crate::__private::core::option::Option<Self> { - let truncated = Self::from_bits_truncate(bits).bits; - - if truncated == bits { - $crate::__private::core::option::Option::Some(Self { bits }) - } else { - $crate::__private::core::option::Option::None - } - } - - #[inline] - pub const fn from_bits_truncate(bits: $T) -> Self { - if bits == <$T as $crate::__private::Bits>::EMPTY { - return Self { bits } - } - - let mut truncated = <$T as $crate::__private::Bits>::EMPTY; - - $( - __expr_safe_flags!( - $(#[$attr $($args)*])* - { - if bits & $BitFlags::$Flag.bits() == $BitFlags::$Flag.bits() { - truncated |= $BitFlags::$Flag.bits() - } - } - ); - )* - - Self { bits: truncated } - } - - #[inline] - pub const fn from_bits_retain(bits: $T) -> Self { - Self { bits } - } - - #[inline] - pub fn from_name(name: &str) -> $crate::__private::core::option::Option<Self> { - $( - __expr_safe_flags!( - $(#[$attr $($args)*])* - { - if name == $crate::__private::core::stringify!($Flag) { - return $crate::__private::core::option::Option::Some(Self { bits: $BitFlags::$Flag.bits() }); - } - } - ); - )* - - let _ = name; - $crate::__private::core::option::Option::None - } - - #[inline] - pub const fn iter(&self) -> $Iter { - $Iter { - inner: self.iter_names(), - done: false, - } - } - - #[inline] - pub const fn iter_names(&self) -> $IterNames { - $IterNames { - idx: 0, - source: *self, - state: *self, - } - } - - #[inline] - pub const fn is_empty(&self) -> bool { - self.bits == Self::empty().bits - } - - #[inline] - pub const fn is_all(&self) -> bool { - Self::all().bits | self.bits == self.bits - } - - #[inline] - pub const fn intersects(&self, other: Self) -> bool { - !(Self { bits: self.bits & other.bits}).is_empty() - } - - #[inline] - pub const fn contains(&self, other: Self) -> bool { - (self.bits & other.bits) == other.bits - } - - #[inline] - pub fn insert(&mut self, other: Self) { - self.bits |= other.bits; - } - - #[inline] - pub fn remove(&mut self, other: Self) { - self.bits &= !other.bits; - } - - #[inline] - pub fn toggle(&mut self, other: Self) { - self.bits ^= other.bits; - } - - #[inline] - pub fn set(&mut self, other: Self, value: bool) { - if value { - self.insert(other); - } else { - self.remove(other); - } - } - - #[inline] - #[must_use] - pub const fn intersection(self, other: Self) -> Self { - Self { bits: self.bits & other.bits } - } - - #[inline] - #[must_use] - pub const fn union(self, other: Self) -> Self { - Self { bits: self.bits | other.bits } - } - - #[inline] - #[must_use] - pub const fn difference(self, other: Self) -> Self { - Self { bits: self.bits & !other.bits } - } - - #[inline] - #[must_use] - pub const fn symmetric_difference(self, other: Self) -> Self { - Self { bits: self.bits ^ other.bits } - } - - #[inline] - #[must_use] - pub const fn complement(self) -> Self { - Self::from_bits_truncate(!self.bits) + $crate::parser::from_str::<$PublicBitFlags>(s).map(|flags| flags.0) } } impl $crate::__private::core::convert::AsRef<$T> for $InternalBitFlags { fn as_ref(&self) -> &$T { - &self.bits + &self.0 } } @@ -363,208 +95,31 @@ macro_rules! __impl_internal_bitflags { } } - impl $crate::__private::core::iter::Iterator for $Iter { - type Item = $BitFlags; - - fn next(&mut self) -> $crate::__private::core::option::Option<Self::Item> { - match self.inner.next().map(|(_, value)| value) { - $crate::__private::core::option::Option::Some(value) => $crate::__private::core::option::Option::Some(value), - $crate::__private::core::option::Option::None if !self.done => { - self.done = true; + // The internal flags type offers a similar API to the public one - // After iterating through valid names, if there are any bits left over - // then return one final value that includes them. This makes `into_iter` - // and `from_iter` roundtrip - if self.inner.state != $InternalBitFlags::empty() { - $crate::__private::core::option::Option::Some($BitFlags::from_bits_retain(self.inner.state.bits())) - } else { - $crate::__private::core::option::Option::None - } - }, - _ => $crate::__private::core::option::Option::None, - } + __impl_public_bitflags! { + $InternalBitFlags: $T, $PublicBitFlags { + $( + $(#[$attr $($args)*])* + $Flag; + )* } } - impl $crate::__private::core::iter::Iterator for $IterNames { - type Item = (&'static str, $BitFlags); - - fn next(&mut self) -> $crate::__private::core::option::Option<Self::Item> { - const NUM_FLAGS: usize = { - let mut num_flags = 0; - - $( - __expr_safe_flags!( - $(#[$attr $($args)*])* - { - { num_flags += 1; } - } - ); - )* - - num_flags - }; - - const OPTIONS: [$T; NUM_FLAGS] = [ - $( - __expr_safe_flags!( - $(#[$attr $($args)*])* - { - $BitFlags::$Flag.bits() - } - ), - )* - ]; - - const OPTIONS_NAMES: [&'static str; NUM_FLAGS] = [ - $( - __expr_safe_flags!( - $(#[$attr $($args)*])* - { - $crate::__private::core::stringify!($Flag) - } - ), - )* - ]; - - if self.state.is_empty() || NUM_FLAGS == 0 { - $crate::__private::core::option::Option::None - } else { - #[allow(clippy::indexing_slicing)] - for (flag, flag_name) in OPTIONS[self.idx..NUM_FLAGS].iter().copied() - .zip(OPTIONS_NAMES[self.idx..NUM_FLAGS].iter().copied()) - { - self.idx += 1; - - // NOTE: We check whether the flag exists in self, but remove it from - // a different value. This ensure that overlapping flags are handled - // properly. Take the following example: - // - // const A: 0b00000001; - // const B: 0b00000101; - // - // Given the bits 0b00000101, both A and B are set. But if we removed A - // as we encountered it we'd be left with 0b00000100, which doesn't - // correspond to a valid flag on its own. - if self.source.contains($InternalBitFlags { bits: flag }) { - self.state.remove($InternalBitFlags { bits: flag }); - - return $crate::__private::core::option::Option::Some((flag_name, $BitFlags::from_bits_retain(flag))) - } - } - - $crate::__private::core::option::Option::None - } - } + __impl_public_bitflags_ops! { + $InternalBitFlags } - }; -} -/// A macro that processed the input to `bitflags!` and shuffles attributes around -/// based on whether or not they're "expression-safe". -/// -/// This macro is a token-tree muncher that works on 2 levels: -/// -/// For each attribute, we explicitly match on its identifier, like `cfg` to determine -/// whether or not it should be considered expression-safe. -/// -/// If you find yourself with an attribute that should be considered expression-safe -/// and isn't, it can be added here. -#[macro_export(local_inner_macros)] -#[doc(hidden)] -macro_rules! __expr_safe_flags { - // Entrypoint: Move all flags and all attributes into `unprocessed` lists - // where they'll be munched one-at-a-time - ( - $(#[$inner:ident $($args:tt)*])* - { $e:expr } - ) => { - __expr_safe_flags! { - expr: { $e }, - attrs: { - // All attributes start here - unprocessed: [$(#[$inner $($args)*])*], - processed: { - // Attributes that are safe on expressions go here - expr: [], - }, - }, - } - }; - // Process the next attribute on the current flag - // `cfg`: The next flag should be propagated to expressions - // NOTE: You can copy this rules block and replace `cfg` with - // your attribute name that should be considered expression-safe - ( - expr: { $e:expr }, - attrs: { - unprocessed: [ - // cfg matched here - #[cfg $($args:tt)*] - $($attrs_rest:tt)* - ], - processed: { - expr: [$($expr:tt)*], - }, - }, - ) => { - __expr_safe_flags! { - expr: { $e }, - attrs: { - unprocessed: [ - $($attrs_rest)* - ], - processed: { - expr: [ - $($expr)* - // cfg added here - #[cfg $($args)*] - ], - }, - }, + __impl_public_bitflags_iter! { + $InternalBitFlags: $T, $PublicBitFlags } - }; - // Process the next attribute on the current flag - // `$other`: The next flag should not be propagated to expressions - ( - expr: { $e:expr }, - attrs: { - unprocessed: [ - // $other matched here - #[$other:ident $($args:tt)*] - $($attrs_rest:tt)* - ], - processed: { - expr: [$($expr:tt)*], - }, - }, - ) => { - __expr_safe_flags! { - expr: { $e }, - attrs: { - unprocessed: [ - $($attrs_rest)* - ], - processed: { - expr: [ - // $other not added here - $($expr)* - ], - }, - }, + + impl $InternalBitFlags { + /// Returns a mutable reference to the raw value of the flags currently stored. + #[inline] + pub fn bits_mut(&mut self) -> &mut $T { + &mut self.0 + } } }; - // Once all attributes on all flags are processed, generate the actual code - ( - expr: { $e:expr }, - attrs: { - unprocessed: [], - processed: { - expr: [$(#[$expr:ident $($exprargs:tt)*])*], - }, - }, - ) => { - $(#[$expr $($exprargs)*])* - { $e } - } } diff --git a/vendor/bitflags/src/iter.rs b/vendor/bitflags/src/iter.rs new file mode 100644 index 000000000..761124f10 --- /dev/null +++ b/vendor/bitflags/src/iter.rs @@ -0,0 +1,133 @@ +//! Iterating over set flag values. + +use crate::{Flag, Flags}; + +/// An iterator over a set of flags. +/// +/// Any bits that don't correspond to a valid flag will be yielded +/// as a final item from the iterator. +pub struct Iter<B: 'static> { + inner: IterNames<B>, + done: bool, +} + +impl<B: Flags> Iter<B> { + /// Create a new iterator over the given set of flags. + pub(crate) fn new(flags: &B) -> Self { + Iter { + inner: IterNames::new(flags), + done: false, + } + } +} + +impl<B: 'static> Iter<B> { + #[doc(hidden)] + pub const fn __private_const_new(flags: &'static [Flag<B>], source: B, remaining: B) -> Self { + Iter { + inner: IterNames::__private_const_new(flags, source, remaining), + done: false, + } + } +} + +impl<B: Flags> Iterator for Iter<B> { + type Item = B; + + fn next(&mut self) -> Option<Self::Item> { + match self.inner.next() { + Some((_, flag)) => Some(flag), + None if !self.done => { + self.done = true; + + // After iterating through valid names, if there are any bits left over + // then return one final value that includes them. This makes `into_iter` + // and `from_iter` roundtrip + if !self.inner.remaining().is_empty() { + Some(B::from_bits_retain(self.inner.remaining.bits())) + } else { + None + } + } + None => None, + } + } +} + +/// An iterator over a set of flags and their names. +/// +/// Any bits that don't correspond to a valid flag will be ignored. +pub struct IterNames<B: 'static> { + flags: &'static [Flag<B>], + idx: usize, + source: B, + remaining: B, +} + +impl<B: Flags> IterNames<B> { + /// Create a new iterator over the given set of flags. + pub(crate) fn new(flags: &B) -> Self { + IterNames { + flags: B::FLAGS, + idx: 0, + remaining: B::from_bits_retain(flags.bits()), + source: B::from_bits_retain(flags.bits()), + } + } +} + +impl<B: 'static> IterNames<B> { + #[doc(hidden)] + pub const fn __private_const_new(flags: &'static [Flag<B>], source: B, remaining: B) -> Self { + IterNames { + flags, + idx: 0, + remaining, + source, + } + } + + /// Get the remaining (unyielded) flags. + /// + /// Once the iterator has finished, this method can be used to + /// check whether or not there are any bits that didn't correspond + /// to a valid flag remaining. + pub fn remaining(&self) -> &B { + &self.remaining + } +} + +impl<B: Flags> Iterator for IterNames<B> { + type Item = (&'static str, B); + + fn next(&mut self) -> Option<Self::Item> { + while let Some(flag) = self.flags.get(self.idx) { + // Short-circuit if our state is empty + if self.remaining.is_empty() { + return None; + } + + self.idx += 1; + + let bits = flag.value().bits(); + + // If the flag is set in the original source _and_ it has bits that haven't + // been covered by a previous flag yet then yield it. These conditions cover + // two cases for multi-bit flags: + // + // 1. When flags partially overlap, such as `0b00000001` and `0b00000101`, we'll + // yield both flags. + // 2. When flags fully overlap, such as in convenience flags that are a shorthand for others, + // we won't yield both flags. + if self.source.contains(B::from_bits_retain(bits)) + && self.remaining.intersects(B::from_bits_retain(bits)) + { + self.remaining.remove(B::from_bits_retain(bits)); + + return Some((flag.name(), B::from_bits_retain(bits))); + } + } + + None + } +} diff --git a/vendor/bitflags/src/lib.rs b/vendor/bitflags/src/lib.rs index d28fd87f7..bac1d1968 100644 --- a/vendor/bitflags/src/lib.rs +++ b/vendor/bitflags/src/lib.rs @@ -281,7 +281,7 @@ //! use bitflags::bitflags; //! use std::{fmt, str}; //! -//! bitflags::bitflags! { +//! bitflags! { //! pub struct Flags: u32 { //! const A = 1; //! const B = 2; @@ -374,16 +374,16 @@ //! } //! ``` //! -//! [`from_bits`]: BitFlags::from_bits -//! [`from_bits_truncate`]: BitFlags::from_bits_truncate +//! [`from_bits`]: Flags::from_bits +//! [`from_bits_truncate`]: Flags::from_bits_truncate //! -//! # The `BitFlags` trait +//! # The `Flags` trait //! -//! This library defines a `BitFlags` trait that's implemented by all generated flags types. +//! This library defines a `Flags` trait that's implemented by all generated flags types. //! The trait makes it possible to work with flags types generically: //! //! ``` -//! fn count_unset_flags<F: bitflags::BitFlags>(flags: &F) -> usize { +//! fn count_unset_flags<F: bitflags::Flags>(flags: &F) -> usize { //! // Find out how many flags there are in total //! let total = F::all().iter().count(); //! @@ -422,22 +422,30 @@ #![cfg_attr(not(any(feature = "std", test)), no_std)] #![cfg_attr(not(test), forbid(unsafe_code))] - -#![doc(html_root_url = "https://docs.rs/bitflags/2.2.1")] +#![cfg_attr(test, allow(mixed_script_confusables))] +#![doc(html_root_url = "https://docs.rs/bitflags/2.3.3")] #[doc(inline)] -pub use traits::BitFlags; +pub use traits::{Bits, Flag, Flags}; +pub mod iter; pub mod parser; + mod traits; #[doc(hidden)] pub mod __private { - pub use crate::{external::*, traits::*}; + pub use crate::{external::__private::*, traits::__private::*}; pub use core; } +#[allow(unused_imports)] +pub use external::*; + +#[allow(deprecated)] +pub use traits::BitFlags; + /* How does the bitflags crate work? @@ -563,20 +571,14 @@ macro_rules! bitflags { // This type appears in the end-user's API __declare_public_bitflags! { $(#[$outer])* - $vis struct $BitFlags; + $vis struct $BitFlags } // Workaround for: https://github.com/bitflags/bitflags/issues/320 __impl_public_bitflags_consts! { - $BitFlags { + $BitFlags: $T { $( $(#[$inner $($args)*])* - #[allow( - dead_code, - deprecated, - unused_attributes, - non_upper_case_globals - )] $Flag = $value; )* } @@ -589,29 +591,28 @@ macro_rules! bitflags { unused_attributes, unused_mut, unused_imports, - non_upper_case_globals + non_upper_case_globals, + clippy::assign_op_pattern )] const _: () = { // Declared in a "hidden" scope that can't be reached directly // These types don't appear in the end-user's API __declare_internal_bitflags! { - $vis struct InternalBitFlags: $T; - $vis struct Iter; - $vis struct IterRaw; + $vis struct InternalBitFlags: $T } __impl_internal_bitflags! { - InternalBitFlags: $T, $BitFlags, Iter, IterRaw { + InternalBitFlags: $T, $BitFlags { $( $(#[$inner $($args)*])* - $Flag; + $Flag = $value; )* } } // This is where new library trait implementations can be added __impl_external_bitflags! { - InternalBitFlags: $T { + InternalBitFlags: $T, $BitFlags { $( $(#[$inner $($args)*])* $Flag; @@ -619,1072 +620,408 @@ macro_rules! bitflags { } } - __impl_public_bitflags! { - $BitFlags: $T, InternalBitFlags, Iter, IterRaw; + __impl_public_bitflags_forward! { + $BitFlags: $T, InternalBitFlags } - }; - - bitflags! { - $($t)* - } - }; - () => {}; -} - -#[macro_use] -mod public; -#[macro_use] -mod internal; -#[macro_use] -mod external; - -#[cfg(feature = "example_generated")] -pub mod example_generated; - -#[cfg(test)] -mod tests { - use std::{ - collections::hash_map::DefaultHasher, - fmt, - hash::{Hash, Hasher}, - str, - }; - - bitflags! { - #[doc = "> The first principle is that you must not fool yourself — and"] - #[doc = "> you are the easiest person to fool."] - #[doc = "> "] - #[doc = "> - Richard Feynman"] - #[derive(Clone, Copy, Default, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] - struct Flags: u32 { - const A = 0b00000001; - #[doc = "<pcwalton> macros are way better at generating code than trans is"] - const B = 0b00000010; - const C = 0b00000100; - #[doc = "* cmr bed"] - #[doc = "* strcat table"] - #[doc = "<strcat> wait what?"] - const ABC = Self::A.bits() | Self::B.bits() | Self::C.bits(); - } - - #[derive(Clone, Copy, Default, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] - struct _CfgFlags: u32 { - #[cfg(unix)] - const _CFG_A = 0b01; - #[cfg(windows)] - const _CFG_B = 0b01; - #[cfg(unix)] - const _CFG_C = Self::_CFG_A.bits() | 0b10; - } - - #[derive(Clone, Copy, Default, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] - struct AnotherSetOfFlags: i8 { - const ANOTHER_FLAG = -1_i8; - } - - #[derive(Clone, Copy, Default, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] - struct LongFlags: u32 { - const LONG_A = 0b1111111111111111; - } - } - - bitflags! { - #[derive(Debug, PartialEq, Eq)] - struct FmtFlags: u16 { - const 고양이 = 0b0000_0001; - const 개 = 0b0000_0010; - const 물고기 = 0b0000_0100; - const 물고기_고양이 = Self::고양이.bits() | Self::물고기.bits(); - } - } - - impl str::FromStr for FmtFlags { - type Err = crate::parser::ParseError; - - fn from_str(flags: &str) -> Result<Self, Self::Err> { - Ok(Self(flags.parse()?)) - } - } - - impl fmt::Display for FmtFlags { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Display::fmt(&self.0, f) - } - } - - bitflags! { - #[derive(Clone, Copy, Default, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] - struct EmptyFlags: u32 { - } - } - - #[test] - fn test_bits() { - assert_eq!(Flags::empty().bits(), 0b00000000); - assert_eq!(Flags::A.bits(), 0b00000001); - assert_eq!(Flags::ABC.bits(), 0b00000111); - - assert_eq!(AnotherSetOfFlags::empty().bits(), 0b00); - assert_eq!(AnotherSetOfFlags::ANOTHER_FLAG.bits(), !0_i8); - - assert_eq!(EmptyFlags::empty().bits(), 0b00000000); - } - - #[test] - fn test_from_bits() { - assert_eq!(Flags::from_bits(0), Some(Flags::empty())); - assert_eq!(Flags::from_bits(0b1), Some(Flags::A)); - assert_eq!(Flags::from_bits(0b10), Some(Flags::B)); - assert_eq!(Flags::from_bits(0b11), Some(Flags::A | Flags::B)); - assert_eq!(Flags::from_bits(0b1000), None); - - assert_eq!( - AnotherSetOfFlags::from_bits(!0_i8), - Some(AnotherSetOfFlags::ANOTHER_FLAG) - ); - - assert_eq!(EmptyFlags::from_bits(0), Some(EmptyFlags::empty())); - assert_eq!(EmptyFlags::from_bits(0b1), None); - } - - #[test] - fn test_from_bits_truncate() { - assert_eq!(Flags::from_bits_truncate(0), Flags::empty()); - assert_eq!(Flags::from_bits_truncate(0b1), Flags::A); - assert_eq!(Flags::from_bits_truncate(0b10), Flags::B); - assert_eq!(Flags::from_bits_truncate(0b11), (Flags::A | Flags::B)); - assert_eq!(Flags::from_bits_truncate(0b1000), Flags::empty()); - assert_eq!(Flags::from_bits_truncate(0b1001), Flags::A); - - assert_eq!( - AnotherSetOfFlags::from_bits_truncate(0_i8), - AnotherSetOfFlags::empty() - ); - - assert_eq!(EmptyFlags::from_bits_truncate(0), EmptyFlags::empty()); - assert_eq!(EmptyFlags::from_bits_truncate(0b1), EmptyFlags::empty()); - } - - #[test] - fn test_from_bits_retain() { - let extra = Flags::from_bits_retain(0b1000); - assert_eq!(Flags::from_bits_retain(0), Flags::empty()); - assert_eq!(Flags::from_bits_retain(0b1), Flags::A); - assert_eq!(Flags::from_bits_retain(0b10), Flags::B); - - assert_eq!(Flags::from_bits_retain(0b11), (Flags::A | Flags::B)); - assert_eq!(Flags::from_bits_retain(0b1000), (extra | Flags::empty())); - assert_eq!(Flags::from_bits_retain(0b1001), (extra | Flags::A)); - - let extra = EmptyFlags::from_bits_retain(0b1000); - assert_eq!( - EmptyFlags::from_bits_retain(0b1000), - (extra | EmptyFlags::empty()) - ); - } - - #[test] - fn test_is_empty() { - assert!(Flags::empty().is_empty()); - assert!(!Flags::A.is_empty()); - assert!(!Flags::ABC.is_empty()); - - assert!(!AnotherSetOfFlags::ANOTHER_FLAG.is_empty()); - - assert!(EmptyFlags::empty().is_empty()); - assert!(EmptyFlags::all().is_empty()); - } - - #[test] - fn test_is_all() { - assert!(Flags::all().is_all()); - assert!(!Flags::A.is_all()); - assert!(Flags::ABC.is_all()); - - let extra = Flags::from_bits_retain(0b1000); - assert!(!extra.is_all()); - assert!(!(Flags::A | extra).is_all()); - assert!((Flags::ABC | extra).is_all()); - - assert!(AnotherSetOfFlags::ANOTHER_FLAG.is_all()); - - assert!(EmptyFlags::all().is_all()); - assert!(EmptyFlags::empty().is_all()); - } - - #[test] - fn test_two_empties_do_not_intersect() { - let e1 = Flags::empty(); - let e2 = Flags::empty(); - assert!(!e1.intersects(e2)); - - assert!(AnotherSetOfFlags::ANOTHER_FLAG.intersects(AnotherSetOfFlags::ANOTHER_FLAG)); - } - - #[test] - fn test_empty_does_not_intersect_with_full() { - let e1 = Flags::empty(); - let e2 = Flags::ABC; - assert!(!e1.intersects(e2)); - } - - #[test] - fn test_disjoint_intersects() { - let e1 = Flags::A; - let e2 = Flags::B; - assert!(!e1.intersects(e2)); - } - #[test] - fn test_overlapping_intersects() { - let e1 = Flags::A; - let e2 = Flags::A | Flags::B; - assert!(e1.intersects(e2)); - } - - #[test] - fn test_contains() { - let e1 = Flags::A; - let e2 = Flags::A | Flags::B; - assert!(!e1.contains(e2)); - assert!(e2.contains(e1)); - assert!(Flags::ABC.contains(e2)); - - assert!(AnotherSetOfFlags::ANOTHER_FLAG.contains(AnotherSetOfFlags::ANOTHER_FLAG)); - - assert!(EmptyFlags::empty().contains(EmptyFlags::empty())); - } - - #[test] - fn test_insert() { - let mut e1 = Flags::A; - let e2 = Flags::A | Flags::B; - e1.insert(e2); - assert_eq!(e1, e2); - - let mut e3 = AnotherSetOfFlags::empty(); - e3.insert(AnotherSetOfFlags::ANOTHER_FLAG); - assert_eq!(e3, AnotherSetOfFlags::ANOTHER_FLAG); - } - - #[test] - fn test_remove() { - let mut e1 = Flags::A | Flags::B; - let e2 = Flags::A | Flags::C; - e1.remove(e2); - assert_eq!(e1, Flags::B); - - let mut e3 = AnotherSetOfFlags::ANOTHER_FLAG; - e3.remove(AnotherSetOfFlags::ANOTHER_FLAG); - assert_eq!(e3, AnotherSetOfFlags::empty()); - } - - #[test] - fn test_operators() { - let e1 = Flags::A | Flags::C; - let e2 = Flags::B | Flags::C; - assert_eq!((e1 | e2), Flags::ABC); // union - assert_eq!((e1 & e2), Flags::C); // intersection - assert_eq!((e1 - e2), Flags::A); // set difference - assert_eq!(!e2, Flags::A); // set complement - assert_eq!(e1 ^ e2, Flags::A | Flags::B); // toggle - let mut e3 = e1; - e3.toggle(e2); - assert_eq!(e3, Flags::A | Flags::B); - - let mut m4 = AnotherSetOfFlags::empty(); - m4.toggle(AnotherSetOfFlags::empty()); - assert_eq!(m4, AnotherSetOfFlags::empty()); - } - - #[test] - fn test_operators_unchecked() { - let extra = Flags::from_bits_retain(0b1000); - let e1 = Flags::A | Flags::C | extra; - let e2 = Flags::B | Flags::C; - assert_eq!((e1 | e2), (Flags::ABC | extra)); // union - assert_eq!((e1 & e2), Flags::C); // intersection - assert_eq!((e1 - e2), (Flags::A | extra)); // set difference - assert_eq!(!e2, Flags::A); // set complement - assert_eq!(!e1, Flags::B); // set complement - assert_eq!(e1 ^ e2, Flags::A | Flags::B | extra); // toggle - let mut e3 = e1; - e3.toggle(e2); - assert_eq!(e3, Flags::A | Flags::B | extra); - } - - #[test] - fn test_set_ops_basic() { - let ab = Flags::A.union(Flags::B); - let ac = Flags::A.union(Flags::C); - let bc = Flags::B.union(Flags::C); - assert_eq!(ab.bits(), 0b011); - assert_eq!(bc.bits(), 0b110); - assert_eq!(ac.bits(), 0b101); - - assert_eq!(ab, Flags::B.union(Flags::A)); - assert_eq!(ac, Flags::C.union(Flags::A)); - assert_eq!(bc, Flags::C.union(Flags::B)); - - assert_eq!(ac, Flags::A | Flags::C); - assert_eq!(bc, Flags::B | Flags::C); - assert_eq!(ab.union(bc), Flags::ABC); - - assert_eq!(ac, Flags::A | Flags::C); - assert_eq!(bc, Flags::B | Flags::C); - - assert_eq!(ac.union(bc), ac | bc); - assert_eq!(ac.union(bc), Flags::ABC); - assert_eq!(bc.union(ac), Flags::ABC); - - assert_eq!(ac.intersection(bc), ac & bc); - assert_eq!(ac.intersection(bc), Flags::C); - assert_eq!(bc.intersection(ac), Flags::C); - - assert_eq!(ac.difference(bc), ac - bc); - assert_eq!(bc.difference(ac), bc - ac); - assert_eq!(ac.difference(bc), Flags::A); - assert_eq!(bc.difference(ac), Flags::B); - - assert_eq!(bc.complement(), !bc); - assert_eq!(bc.complement(), Flags::A); - assert_eq!(ac.symmetric_difference(bc), Flags::A.union(Flags::B)); - assert_eq!(bc.symmetric_difference(ac), Flags::A.union(Flags::B)); - } - - #[test] - fn test_set_ops_const() { - // These just test that these compile and don't cause use-site panics - // (would be possible if we had some sort of UB) - const INTERSECT: Flags = Flags::all().intersection(Flags::C); - const UNION: Flags = Flags::A.union(Flags::C); - const DIFFERENCE: Flags = Flags::all().difference(Flags::A); - const COMPLEMENT: Flags = Flags::C.complement(); - const SYM_DIFFERENCE: Flags = UNION.symmetric_difference(DIFFERENCE); - assert_eq!(INTERSECT, Flags::C); - assert_eq!(UNION, Flags::A | Flags::C); - assert_eq!(DIFFERENCE, Flags::all() - Flags::A); - assert_eq!(COMPLEMENT, !Flags::C); - assert_eq!( - SYM_DIFFERENCE, - (Flags::A | Flags::C) ^ (Flags::all() - Flags::A) - ); - } - - #[test] - fn test_set_ops_unchecked() { - let extra = Flags::from_bits_retain(0b1000); - let e1 = Flags::A.union(Flags::C).union(extra); - let e2 = Flags::B.union(Flags::C); - assert_eq!(e1.bits(), 0b1101); - assert_eq!(e1.union(e2), (Flags::ABC | extra)); - assert_eq!(e1.intersection(e2), Flags::C); - assert_eq!(e1.difference(e2), Flags::A | extra); - assert_eq!(e2.difference(e1), Flags::B); - assert_eq!(e2.complement(), Flags::A); - assert_eq!(e1.complement(), Flags::B); - assert_eq!(e1.symmetric_difference(e2), Flags::A | Flags::B | extra); // toggle - } - - #[test] - fn test_set_ops_exhaustive() { - // Define a flag that contains gaps to help exercise edge-cases, - // especially around "unknown" flags (e.g. ones outside of `all()` - // `from_bits_retain`). - // - when lhs and rhs both have different sets of unknown flags. - // - unknown flags at both ends, and in the middle - // - cases with "gaps". - bitflags! { - #[derive(Clone, Copy, Debug, PartialEq, Eq)] - struct Test: u16 { - // Intentionally no `A` - const B = 0b000000010; - // Intentionally no `C` - const D = 0b000001000; - const E = 0b000010000; - const F = 0b000100000; - const G = 0b001000000; - // Intentionally no `H` - const I = 0b100000000; + __impl_public_bitflags_ops! { + $BitFlags } - } - let iter_test_flags = || (0..=0b111_1111_1111).map(|bits| Test::from_bits_retain(bits)); - for a in iter_test_flags() { - assert_eq!( - a.complement(), - Test::from_bits_truncate(!a.bits()), - "wrong result: !({:?})", - a, - ); - assert_eq!(a.complement(), !a, "named != op: !({:?})", a); - for b in iter_test_flags() { - // Check that the named operations produce the expected bitwise - // values. - assert_eq!( - a.union(b).bits(), - a.bits() | b.bits(), - "wrong result: `{:?}` | `{:?}`", - a, - b, - ); - assert_eq!( - a.intersection(b).bits(), - a.bits() & b.bits(), - "wrong result: `{:?}` & `{:?}`", - a, - b, - ); - assert_eq!( - a.symmetric_difference(b).bits(), - a.bits() ^ b.bits(), - "wrong result: `{:?}` ^ `{:?}`", - a, - b, - ); - assert_eq!( - a.difference(b).bits(), - a.bits() & !b.bits(), - "wrong result: `{:?}` - `{:?}`", - a, - b, - ); - // Note: Difference is checked as both `a - b` and `b - a` - assert_eq!( - b.difference(a).bits(), - b.bits() & !a.bits(), - "wrong result: `{:?}` - `{:?}`", - b, - a, - ); - // Check that the named set operations are equivalent to the - // bitwise equivalents - assert_eq!(a.union(b), a | b, "named != op: `{:?}` | `{:?}`", a, b,); - assert_eq!( - a.intersection(b), - a & b, - "named != op: `{:?}` & `{:?}`", - a, - b, - ); - assert_eq!( - a.symmetric_difference(b), - a ^ b, - "named != op: `{:?}` ^ `{:?}`", - a, - b, - ); - assert_eq!(a.difference(b), a - b, "named != op: `{:?}` - `{:?}`", a, b,); - // Note: Difference is checked as both `a - b` and `b - a` - assert_eq!(b.difference(a), b - a, "named != op: `{:?}` - `{:?}`", b, a,); - // Verify that the operations which should be symmetric are - // actually symmetric. - assert_eq!(a.union(b), b.union(a), "asymmetry: `{:?}` | `{:?}`", a, b,); - assert_eq!( - a.intersection(b), - b.intersection(a), - "asymmetry: `{:?}` & `{:?}`", - a, - b, - ); - assert_eq!( - a.symmetric_difference(b), - b.symmetric_difference(a), - "asymmetry: `{:?}` ^ `{:?}`", - a, - b, - ); + __impl_public_bitflags_iter! { + $BitFlags: $T, $BitFlags } - } - } - - #[test] - fn test_set() { - let mut e1 = Flags::A | Flags::C; - e1.set(Flags::B, true); - e1.set(Flags::C, false); - - assert_eq!(e1, Flags::A | Flags::B); - } - - #[test] - fn test_assignment_operators() { - let mut m1 = Flags::empty(); - let e1 = Flags::A | Flags::C; - // union - m1 |= Flags::A; - assert_eq!(m1, Flags::A); - // intersection - m1 &= e1; - assert_eq!(m1, Flags::A); - // set difference - m1 -= m1; - assert_eq!(m1, Flags::empty()); - // toggle - m1 ^= e1; - assert_eq!(m1, e1); - } - - #[test] - fn test_const_fn() { - const _M1: Flags = Flags::empty(); - - const M2: Flags = Flags::A; - assert_eq!(M2, Flags::A); - - const M3: Flags = Flags::C; - assert_eq!(M3, Flags::C); - } - - #[test] - fn test_extend() { - let mut flags; - - flags = Flags::empty(); - flags.extend([].iter().cloned()); - assert_eq!(flags, Flags::empty()); - - flags = Flags::empty(); - flags.extend([Flags::A, Flags::B].iter().cloned()); - assert_eq!(flags, Flags::A | Flags::B); - - flags = Flags::A; - flags.extend([Flags::A, Flags::B].iter().cloned()); - assert_eq!(flags, Flags::A | Flags::B); - - flags = Flags::B; - flags.extend([Flags::A, Flags::ABC].iter().cloned()); - assert_eq!(flags, Flags::ABC); - } - - #[test] - fn test_from_iterator() { - assert_eq!([].iter().cloned().collect::<Flags>(), Flags::empty()); - assert_eq!( - [Flags::A, Flags::B].iter().cloned().collect::<Flags>(), - Flags::A | Flags::B - ); - assert_eq!( - [Flags::A, Flags::ABC].iter().cloned().collect::<Flags>(), - Flags::ABC - ); - } - - #[test] - fn test_lt() { - let mut a = Flags::empty(); - let mut b = Flags::empty(); - - assert!(!(a < b) && !(b < a)); - b = Flags::B; - assert!(a < b); - a = Flags::C; - assert!(!(a < b) && b < a); - b = Flags::C | Flags::B; - assert!(a < b); - } - - #[test] - fn test_ord() { - let mut a = Flags::empty(); - let mut b = Flags::empty(); - - assert!(a <= b && a >= b); - a = Flags::A; - assert!(a > b && a >= b); - assert!(b < a && b <= a); - b = Flags::B; - assert!(b > a && b >= a); - assert!(a < b && a <= b); - } - - fn hash<T: Hash>(t: &T) -> u64 { - let mut s = DefaultHasher::new(); - t.hash(&mut s); - s.finish() - } - - #[test] - fn test_hash() { - let mut x = Flags::empty(); - let mut y = Flags::empty(); - assert_eq!(hash(&x), hash(&y)); - x = Flags::all(); - y = Flags::ABC; - assert_eq!(hash(&x), hash(&y)); - } - - #[test] - fn test_default() { - assert_eq!(Flags::empty(), Flags::default()); - } - - #[test] - fn test_debug() { - assert_eq!(format!("{:?}", Flags::A | Flags::B), "Flags(A | B)"); - assert_eq!(format!("{:?}", Flags::empty()), "Flags(0x0)"); - assert_eq!(format!("{:?}", Flags::ABC), "Flags(A | B | C)"); - - let extra = Flags::from_bits_retain(0xb8); - - assert_eq!(format!("{:?}", extra), "Flags(0xb8)"); - assert_eq!(format!("{:?}", Flags::A | extra), "Flags(A | 0xb8)"); - - assert_eq!( - format!("{:?}", Flags::ABC | extra), - "Flags(A | B | C | ABC | 0xb8)" - ); - - assert_eq!(format!("{:?}", EmptyFlags::empty()), "EmptyFlags(0x0)"); - } - - #[test] - fn test_display_from_str_roundtrip() { - fn format_parse_case<T: fmt::Debug + fmt::Display + str::FromStr + PartialEq>(flags: T) where <T as str::FromStr>::Err: fmt::Display { - assert_eq!(flags, { - match flags.to_string().parse::<T>() { - Ok(flags) => flags, - Err(e) => panic!("failed to parse `{}`: {}", flags, e), - } - }); - } - - fn parse_case<T: fmt::Debug + str::FromStr + PartialEq>(expected: T, flags: &str) where <T as str::FromStr>::Err: fmt::Display + fmt::Debug { - assert_eq!(expected, flags.parse::<T>().unwrap()); - } + }; bitflags! { - #[derive(Debug, Eq, PartialEq)] - pub struct MultiBitFmtFlags: u8 { - const A = 0b0000_0001u8; - const B = 0b0001_1110u8; - } + $($t)* } - - impl fmt::Display for MultiBitFmtFlags { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Display::fmt(&self.0, f) - } + }; + ( + impl $BitFlags:ident: $T:ty { + $( + $(#[$inner:ident $($args:tt)*])* + const $Flag:ident = $value:expr; + )* } - impl str::FromStr for MultiBitFmtFlags { - type Err = crate::parser::ParseError; - - fn from_str(s: &str) -> Result<Self, Self::Err> { - Ok(MultiBitFmtFlags(s.parse()?)) + $($t:tt)* + ) => { + __impl_public_bitflags_consts! { + $BitFlags: $T { + $( + $(#[$inner $($args)*])* + $Flag = $value; + )* } } - format_parse_case(FmtFlags::empty()); - format_parse_case(FmtFlags::all()); - format_parse_case(FmtFlags::고양이); - format_parse_case(FmtFlags::고양이 | FmtFlags::개); - format_parse_case(FmtFlags::물고기_고양이); - format_parse_case(FmtFlags::from_bits_retain(0xb8)); - format_parse_case(FmtFlags::from_bits_retain(0x20)); - format_parse_case(MultiBitFmtFlags::from_bits_retain(3)); - - parse_case(FmtFlags::empty(), ""); - parse_case(FmtFlags::empty(), " \r\n\t"); - parse_case(FmtFlags::empty(), "0x0"); - parse_case(FmtFlags::empty(), "0x0"); - - parse_case(FmtFlags::고양이, "고양이"); - parse_case(FmtFlags::고양이, " 고양이 "); - parse_case(FmtFlags::고양이, "고양이 | 고양이 | 고양이"); - parse_case(FmtFlags::고양이, "0x01"); - - parse_case(FmtFlags::고양이 | FmtFlags::개, "고양이 | 개"); - parse_case(FmtFlags::고양이 | FmtFlags::개, "고양이|개"); - parse_case(FmtFlags::고양이 | FmtFlags::개, "\n고양이|개 "); - - parse_case(FmtFlags::고양이 | FmtFlags::물고기, "물고기_고양이"); - } - - #[test] - fn test_from_str_err() { - fn parse_case(pat: &str, flags: &str) { - let err = flags.parse::<FmtFlags>().unwrap_err().to_string(); - assert!(err.contains(pat), "`{}` not found in error `{}`", pat, err); - } - - parse_case("empty flag", "|"); - parse_case("empty flag", "|||"); - parse_case("empty flag", "고양이 |"); - parse_case("unrecognized named flag", "NOT_A_FLAG"); - parse_case("unrecognized named flag", "고양이 개"); - parse_case("unrecognized named flag", "고양이 | NOT_A_FLAG"); - parse_case("invalid hex flag", "0xhi"); - parse_case("invalid hex flag", "고양이 | 0xhi"); - } - - #[test] - fn test_binary() { - assert_eq!(format!("{:b}", Flags::ABC), "111"); - assert_eq!(format!("{:#b}", Flags::ABC), "0b111"); - let extra = Flags::from_bits_retain(0b1010000); - assert_eq!(format!("{:b}", Flags::ABC | extra), "1010111"); - assert_eq!(format!("{:#b}", Flags::ABC | extra), "0b1010111"); - } - - #[test] - fn test_octal() { - assert_eq!(format!("{:o}", LongFlags::LONG_A), "177777"); - assert_eq!(format!("{:#o}", LongFlags::LONG_A), "0o177777"); - let extra = LongFlags::from_bits_retain(0o5000000); - assert_eq!(format!("{:o}", LongFlags::LONG_A | extra), "5177777"); - assert_eq!(format!("{:#o}", LongFlags::LONG_A | extra), "0o5177777"); - } - - #[test] - fn test_lowerhex() { - assert_eq!(format!("{:x}", LongFlags::LONG_A), "ffff"); - assert_eq!(format!("{:#x}", LongFlags::LONG_A), "0xffff"); - let extra = LongFlags::from_bits_retain(0xe00000); - assert_eq!(format!("{:x}", LongFlags::LONG_A | extra), "e0ffff"); - assert_eq!(format!("{:#x}", LongFlags::LONG_A | extra), "0xe0ffff"); - } - - #[test] - fn test_upperhex() { - assert_eq!(format!("{:X}", LongFlags::LONG_A), "FFFF"); - assert_eq!(format!("{:#X}", LongFlags::LONG_A), "0xFFFF"); - let extra = LongFlags::from_bits_retain(0xe00000); - assert_eq!(format!("{:X}", LongFlags::LONG_A | extra), "E0FFFF"); - assert_eq!(format!("{:#X}", LongFlags::LONG_A | extra), "0xE0FFFF"); - } - - mod submodule { - bitflags! { - #[derive(Clone, Copy)] - pub struct PublicFlags: i8 { - const X = 0; + #[allow( + dead_code, + deprecated, + unused_doc_comments, + unused_attributes, + unused_mut, + unused_imports, + non_upper_case_globals, + clippy::assign_op_pattern + )] + const _: () = { + __impl_public_bitflags! { + $BitFlags: $T, $BitFlags { + $( + $(#[$inner $($args)*])* + $Flag; + )* + } } - #[derive(Clone, Copy)] - struct PrivateFlags: i8 { - const Y = 0; + __impl_public_bitflags_ops! { + $BitFlags } - } - - #[test] - fn test_private() { - let _ = PrivateFlags::Y; - } - } - #[test] - fn test_public() { - let _ = submodule::PublicFlags::X; - } - - mod t1 { - mod foo { - pub type Bar = i32; - } - - bitflags! { - /// baz - #[derive(Clone, Copy)] - struct Flags: foo::Bar { - const A = 0b00000001; - #[cfg(foo)] - const B = 0b00000010; - #[cfg(foo)] - const C = 0b00000010; + __impl_public_bitflags_iter! { + $BitFlags: $T, $BitFlags } - } - } + }; - #[test] - fn test_in_function() { bitflags! { - #[derive(Clone, Copy, Debug, PartialEq, Eq)] - struct Flags: u8 { - const A = 1; - #[cfg(any())] // false - const B = 2; - } + $($t)* } - assert_eq!(Flags::all(), Flags::A); - assert_eq!(format!("{:?}", Flags::A), "Flags(A)"); - } + }; + () => {}; +} - #[test] - fn test_deprecated() { - bitflags! { - #[derive(Clone, Copy)] - pub struct TestFlags: u32 { - #[deprecated(note = "Use something else.")] - const ONE = 1; - } +/// Implement functions on bitflags types. +/// +/// We need to be careful about adding new methods and trait implementations here because they +/// could conflict with items added by the end-user. +#[macro_export(local_inner_macros)] +#[doc(hidden)] +macro_rules! __impl_bitflags { + ( + $PublicBitFlags:ident: $T:ty { + fn empty() $empty:block + fn all() $all:block + fn bits($bits0:ident) $bits:block + fn from_bits($from_bits0:ident) $from_bits:block + fn from_bits_truncate($from_bits_truncate0:ident) $from_bits_truncate:block + fn from_bits_retain($from_bits_retain0:ident) $from_bits_retain:block + fn from_name($from_name0:ident) $from_name:block + fn is_empty($is_empty0:ident) $is_empty:block + fn is_all($is_all0:ident) $is_all:block + fn intersects($intersects0:ident, $intersects1:ident) $intersects:block + fn contains($contains0:ident, $contains1:ident) $contains:block + fn insert($insert0:ident, $insert1:ident) $insert:block + fn remove($remove0:ident, $remove1:ident) $remove:block + fn toggle($toggle0:ident, $toggle1:ident) $toggle:block + fn set($set0:ident, $set1:ident, $set2:ident) $set:block + fn intersection($intersection0:ident, $intersection1:ident) $intersection:block + fn union($union0:ident, $union1:ident) $union:block + fn difference($difference0:ident, $difference1:ident) $difference:block + fn symmetric_difference($symmetric_difference0:ident, $symmetric_difference1:ident) $symmetric_difference:block + fn complement($complement0:ident) $complement:block } - } - - #[test] - fn test_pub_crate() { - mod module { - bitflags! { - #[derive(Clone, Copy)] - pub (crate) struct Test: u8 { - const FOO = 1; - } + ) => { + #[allow(dead_code, deprecated, unused_attributes)] + impl $PublicBitFlags { + /// Returns an empty set of flags. + #[inline] + pub const fn empty() -> Self { + $empty } - } - assert_eq!(module::Test::FOO.bits(), 1); - } - - #[test] - fn test_pub_in_module() { - mod module { - mod submodule { - bitflags! { - // `pub (in super)` means only the module `module` will - // be able to access this. - #[derive(Clone, Copy)] - pub (in super) struct Test: u8 { - const FOO = 1; - } - } + /// Returns the set containing all flags. + #[inline] + pub const fn all() -> Self { + $all } - mod test { - // Note: due to `pub (in super)`, - // this cannot be accessed directly by the testing code. - pub(super) fn value() -> u8 { - super::submodule::Test::FOO.bits() - } + /// Returns the raw value of the flags currently stored. + #[inline] + pub const fn bits(&self) -> $T { + let $bits0 = self; + $bits } - pub fn value() -> u8 { - test::value() + /// Convert from underlying bit representation, unless that + /// representation contains bits that do not correspond to a flag. + #[inline] + pub const fn from_bits(bits: $T) -> $crate::__private::core::option::Option<Self> { + let $from_bits0 = bits; + $from_bits } - } - - assert_eq!(module::value(), 1) - } - #[test] - fn test_zero_value_flags() { - bitflags! { - #[derive(Clone, Copy, Debug, PartialEq, Eq)] - struct Flags: u32 { - const NONE = 0b0; - const SOME = 0b1; + /// Convert from underlying bit representation, dropping any bits + /// that do not correspond to flags. + #[inline] + pub const fn from_bits_truncate(bits: $T) -> Self { + let $from_bits_truncate0 = bits; + $from_bits_truncate } - } - assert!(Flags::empty().contains(Flags::NONE)); - assert!(Flags::SOME.contains(Flags::NONE)); - assert!(Flags::NONE.is_empty()); - - assert_eq!(format!("{:?}", Flags::SOME), "Flags(NONE | SOME)"); - } - - #[test] - fn test_empty_bitflags() { - bitflags! {} - } - - #[test] - fn test_u128_bitflags() { - bitflags! { - #[derive(Clone, Copy, Debug, PartialEq, Eq)] - struct Flags: u128 { - const A = 0x0000_0000_0000_0000_0000_0000_0000_0001; - const B = 0x0000_0000_0000_1000_0000_0000_0000_0000; - const C = 0x8000_0000_0000_0000_0000_0000_0000_0000; - const ABC = Self::A.bits() | Self::B.bits() | Self::C.bits(); + /// Convert from underlying bit representation, preserving all + /// bits (even those not corresponding to a defined flag). + #[inline] + pub const fn from_bits_retain(bits: $T) -> Self { + let $from_bits_retain0 = bits; + $from_bits_retain } - } - assert_eq!(Flags::ABC, Flags::A | Flags::B | Flags::C); - assert_eq!(Flags::A.bits(), 0x0000_0000_0000_0000_0000_0000_0000_0001); - assert_eq!(Flags::B.bits(), 0x0000_0000_0000_1000_0000_0000_0000_0000); - assert_eq!(Flags::C.bits(), 0x8000_0000_0000_0000_0000_0000_0000_0000); - assert_eq!(Flags::ABC.bits(), 0x8000_0000_0000_1000_0000_0000_0000_0001); - assert_eq!(format!("{:?}", Flags::A), "Flags(A)"); - assert_eq!(format!("{:?}", Flags::B), "Flags(B)"); - assert_eq!(format!("{:?}", Flags::C), "Flags(C)"); - assert_eq!(format!("{:?}", Flags::ABC), "Flags(A | B | C)"); - } - - #[test] - fn test_from_bits_edge_cases() { - bitflags! { - #[derive(Clone, Copy, Debug, PartialEq, Eq)] - struct Flags: u8 { - const A = 0b00000001; - const BC = 0b00000110; + /// Get the value for a flag from its stringified name. + /// + /// Names are _case-sensitive_, so must correspond exactly to + /// the identifier given to the flag. + #[inline] + pub fn from_name(name: &str) -> $crate::__private::core::option::Option<Self> { + let $from_name0 = name; + $from_name } - } - - let flags = Flags::from_bits(0b00000100); - assert_eq!(flags, None); - let flags = Flags::from_bits(0b00000101); - assert_eq!(flags, None); - } - #[test] - fn test_from_bits_truncate_edge_cases() { - bitflags! { - #[derive(Clone, Copy, Debug, PartialEq, Eq)] - struct Flags: u8 { - const A = 0b00000001; - const BC = 0b00000110; + /// Returns `true` if no flags are currently stored. + #[inline] + pub const fn is_empty(&self) -> bool { + let $is_empty0 = self; + $is_empty } - } - let flags = Flags::from_bits_truncate(0b00000100); - assert_eq!(flags, Flags::empty()); - let flags = Flags::from_bits_truncate(0b00000101); - assert_eq!(flags, Flags::A); - } - - #[test] - fn test_iter() { - bitflags! { - #[derive(Clone, Copy, Debug, PartialEq, Eq)] - struct Flags: u32 { - const ONE = 0b001; - const TWO = 0b010; - const THREE = 0b100; - #[cfg(windows)] - const FOUR_WIN = 0b1000; - #[cfg(unix)] - const FOUR_UNIX = 0b10000; - const FIVE = 0b01000100; + /// Returns `true` if all flags are currently set. + #[inline] + pub const fn is_all(&self) -> bool { + let $is_all0 = self; + $is_all } - } - let count = { - #[cfg(any(unix, windows))] - { - 5 + /// Returns `true` if there are flags common to both `self` and `other`. + #[inline] + pub const fn intersects(&self, other: Self) -> bool { + let $intersects0 = self; + let $intersects1 = other; + $intersects } - #[cfg(not(any(unix, windows)))] - { - 4 + /// Returns `true` if all of the flags in `other` are contained within `self`. + #[inline] + pub const fn contains(&self, other: Self) -> bool { + let $contains0 = self; + let $contains1 = other; + $contains } - }; - - let flags = Flags::all(); - assert_eq!(flags.into_iter().count(), count); - - for flag in flags.into_iter() { - assert!(flags.contains(flag)); - } - - let mut iter = flags.iter_names(); - - assert_eq!(iter.next().unwrap(), ("ONE", Flags::ONE)); - assert_eq!(iter.next().unwrap(), ("TWO", Flags::TWO)); - assert_eq!(iter.next().unwrap(), ("THREE", Flags::THREE)); - - #[cfg(unix)] - { - assert_eq!(iter.next().unwrap(), ("FOUR_UNIX", Flags::FOUR_UNIX)); - } - #[cfg(windows)] - { - assert_eq!(iter.next().unwrap(), ("FOUR_WIN", Flags::FOUR_WIN)); - } - - assert_eq!(iter.next().unwrap(), ("FIVE", Flags::FIVE)); - - assert_eq!(iter.next(), None); - - let flags = Flags::empty(); - assert_eq!(flags.into_iter().count(), 0); - - let flags = Flags::ONE | Flags::THREE; - assert_eq!(flags.into_iter().count(), 2); - - let mut iter = flags.iter_names(); - - assert_eq!(iter.next().unwrap(), ("ONE", Flags::ONE)); - assert_eq!(iter.next().unwrap(), ("THREE", Flags::THREE)); - assert_eq!(iter.next(), None); - - let flags = Flags::from_bits_retain(0b1000_0000); - assert_eq!(flags.into_iter().count(), 1); - assert_eq!(flags.iter_names().count(), 0); - } - - #[test] - fn into_iter_from_iter_roundtrip() { - let flags = Flags::ABC | Flags::from_bits_retain(0b1000_0000); - - assert_eq!(flags, flags.into_iter().collect::<Flags>()); - } - - #[test] - fn test_from_name() { - let flags = Flags::all(); - - let mut rebuilt = Flags::empty(); - - for (name, value) in flags.iter_names() { - assert_eq!(value, Flags::from_name(name).unwrap()); - - rebuilt |= Flags::from_name(name).unwrap(); - } - assert_eq!(flags, rebuilt); - } - - #[test] - fn bits_types() { - bitflags! { - pub struct I8: i8 { - const A = 1; + /// Inserts the specified flags in-place. + /// + /// This method is equivalent to `union`. + #[inline] + pub fn insert(&mut self, other: Self) { + let $insert0 = self; + let $insert1 = other; + $insert } - pub struct I16: i16 { - const A = 1; + /// Removes the specified flags in-place. + /// + /// This method is equivalent to `difference`. + #[inline] + pub fn remove(&mut self, other: Self) { + let $remove0 = self; + let $remove1 = other; + $remove } - pub struct I32: i32 { - const A = 1; + /// Toggles the specified flags in-place. + /// + /// This method is equivalent to `symmetric_difference`. + #[inline] + pub fn toggle(&mut self, other: Self) { + let $toggle0 = self; + let $toggle1 = other; + $toggle } - pub struct I64: i64 { - const A = 1; + /// Inserts or removes the specified flags depending on the passed value. + #[inline] + pub fn set(&mut self, other: Self, value: bool) { + let $set0 = self; + let $set1 = other; + let $set2 = value; + $set } - pub struct I128: i128 { - const A = 1; + /// Returns the intersection between the flags in `self` and + /// `other`. + /// + /// Calculating `self` bitwise and (`&`) other, including + /// any bits that don't correspond to a defined flag. + #[inline] + #[must_use] + pub const fn intersection(self, other: Self) -> Self { + let $intersection0 = self; + let $intersection1 = other; + $intersection } - pub struct Isize: isize { - const A = 1; + /// Returns the union of between the flags in `self` and `other`. + /// + /// Calculates `self` bitwise or (`|`) `other`, including + /// any bits that don't correspond to a defined flag. + #[inline] + #[must_use] + pub const fn union(self, other: Self) -> Self { + let $union0 = self; + let $union1 = other; + $union } - pub struct U8: u8 { - const A = 1; + /// Returns the difference between the flags in `self` and `other`. + /// + /// Calculates `self` bitwise and (`&!`) the bitwise negation of `other`, + /// including any bits that don't correspond to a defined flag. + /// + /// This method is _not_ equivalent to `a & !b` when there are bits set that + /// don't correspond to a defined flag. The `!` operator will unset any + /// bits that don't correspond to a flag, so they'll always be unset by `a &! b`, + /// but respected by `a.difference(b)`. + #[inline] + #[must_use] + pub const fn difference(self, other: Self) -> Self { + let $difference0 = self; + let $difference1 = other; + $difference } - pub struct U16: u16 { - const A = 1; + /// Returns the symmetric difference between the flags + /// in `self` and `other`. + /// + /// Calculates `self` bitwise exclusive or (`^`) `other`, + /// including any bits that don't correspond to a defined flag. + #[inline] + #[must_use] + pub const fn symmetric_difference(self, other: Self) -> Self { + let $symmetric_difference0 = self; + let $symmetric_difference1 = other; + $symmetric_difference } - pub struct U32: u32 { - const A = 1; - } - - pub struct U64: u64 { - const A = 1; - } - - pub struct U128: u128 { - const A = 1; + /// Returns the complement of this set of flags. + /// + /// Calculates the bitwise negation (`!`) of `self`, + /// **unsetting** any bits that don't correspond to a defined flag. + #[inline] + #[must_use] + pub const fn complement(self) -> Self { + let $complement0 = self; + $complement } + } + }; +} - pub struct Usize: usize { - const A = 1; - } +/// A macro that processed the input to `bitflags!` and shuffles attributes around +/// based on whether or not they're "expression-safe". +/// +/// This macro is a token-tree muncher that works on 2 levels: +/// +/// For each attribute, we explicitly match on its identifier, like `cfg` to determine +/// whether or not it should be considered expression-safe. +/// +/// If you find yourself with an attribute that should be considered expression-safe +/// and isn't, it can be added here. +#[macro_export(local_inner_macros)] +#[doc(hidden)] +macro_rules! __bitflags_expr_safe_attrs { + // Entrypoint: Move all flags and all attributes into `unprocessed` lists + // where they'll be munched one-at-a-time + ( + $(#[$inner:ident $($args:tt)*])* + { $e:expr } + ) => { + __bitflags_expr_safe_attrs! { + expr: { $e }, + attrs: { + // All attributes start here + unprocessed: [$(#[$inner $($args)*])*], + // Attributes that are safe on expressions go here + processed: [], + }, } + }; + // Process the next attribute on the current flag + // `cfg`: The next flag should be propagated to expressions + // NOTE: You can copy this rules block and replace `cfg` with + // your attribute name that should be considered expression-safe + ( + expr: { $e:expr }, + attrs: { + unprocessed: [ + // cfg matched here + #[cfg $($args:tt)*] + $($attrs_rest:tt)* + ], + processed: [$($expr:tt)*], + }, + ) => { + __bitflags_expr_safe_attrs! { + expr: { $e }, + attrs: { + unprocessed: [ + $($attrs_rest)* + ], + processed: [ + $($expr)* + // cfg added here + #[cfg $($args)*] + ], + }, + } + }; + // Process the next attribute on the current flag + // `$other`: The next flag should not be propagated to expressions + ( + expr: { $e:expr }, + attrs: { + unprocessed: [ + // $other matched here + #[$other:ident $($args:tt)*] + $($attrs_rest:tt)* + ], + processed: [$($expr:tt)*], + }, + ) => { + __bitflags_expr_safe_attrs! { + expr: { $e }, + attrs: { + unprocessed: [ + $($attrs_rest)* + ], + processed: [ + // $other not added here + $($expr)* + ], + }, + } + }; + // Once all attributes on all flags are processed, generate the actual code + ( + expr: { $e:expr }, + attrs: { + unprocessed: [], + processed: [$(#[$expr:ident $($exprargs:tt)*])*], + }, + ) => { + $(#[$expr $($exprargs)*])* + { $e } } } + +#[macro_use] +mod public; +#[macro_use] +mod internal; +#[macro_use] +mod external; + +#[cfg(feature = "example_generated")] +pub mod example_generated; + +#[cfg(test)] +mod tests; diff --git a/vendor/bitflags/src/parser.rs b/vendor/bitflags/src/parser.rs index 48f3c6107..1f5a42fdd 100644 --- a/vendor/bitflags/src/parser.rs +++ b/vendor/bitflags/src/parser.rs @@ -28,7 +28,119 @@ #![allow(clippy::let_unit_value)] -use core::fmt; +use core::fmt::{self, Write}; + +use crate::{Bits, Flags}; + +/// Write a set of flags to a writer. +/// +/// Any bits that don't correspond to a valid flag will be formatted +/// as a hex number. +pub fn to_writer<B: Flags>(flags: &B, mut writer: impl Write) -> Result<(), fmt::Error> +where + B::Bits: WriteHex, +{ + // A formatter for bitflags that produces text output like: + // + // A | B | 0xf6 + // + // The names of set flags are written in a bar-separated-format, + // followed by a hex number of any remaining bits that are set + // but don't correspond to any flags. + + // Iterate over known flag values + let mut first = true; + let mut iter = flags.iter_names(); + for (name, _) in &mut iter { + if !first { + writer.write_str(" | ")?; + } + + first = false; + writer.write_str(name)?; + } + + // Append any extra bits that correspond to flags to the end of the format + let remaining = iter.remaining().bits(); + if remaining != B::Bits::EMPTY { + if !first { + writer.write_str(" | ")?; + } + + writer.write_str("0x")?; + remaining.write_hex(writer)?; + } + + fmt::Result::Ok(()) +} + +pub(crate) struct AsDisplay<'a, B>(pub(crate) &'a B); + +impl<'a, B: Flags> fmt::Display for AsDisplay<'a, B> +where + B::Bits: WriteHex, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + to_writer(self.0, f) + } +} + +/// Parse a set of flags from text. +/// +/// This function will fail on unknown flags rather than ignore them. +pub fn from_str<B: Flags>(input: &str) -> Result<B, ParseError> +where + B::Bits: ParseHex, +{ + let mut parsed_flags = B::empty(); + + // If the input is empty then return an empty set of flags + if input.trim().is_empty() { + return Ok(parsed_flags); + } + + for flag in input.split('|') { + let flag = flag.trim(); + + // If the flag is empty then we've got missing input + if flag.is_empty() { + return Err(ParseError::empty_flag()); + } + + // If the flag starts with `0x` then it's a hex number + // Parse it directly to the underlying bits type + let parsed_flag = if let Some(flag) = flag.strip_prefix("0x") { + let bits = + <B::Bits>::parse_hex(flag).map_err(|_| ParseError::invalid_hex_flag(flag))?; + + B::from_bits_retain(bits) + } + // Otherwise the flag is a name + // The generated flags type will determine whether + // or not it's a valid identifier + else { + B::from_name(flag).ok_or_else(|| ParseError::invalid_named_flag(flag))? + }; + + parsed_flags.insert(parsed_flag); + } + + Ok(parsed_flags) +} + +/// Encode a value as a hex number. +pub trait WriteHex { + /// Write the value as hex. + fn write_hex<W: fmt::Write>(&self, writer: W) -> fmt::Result; +} + +/// Parse a value from a number encoded as a hex string. +pub trait ParseHex { + /// Parse the value from hex. + fn parse_hex(input: &str) -> Result<Self, ParseError> + where + Self: Sized; +} /// An error encountered while parsing flags from text. #[derive(Debug)] diff --git a/vendor/bitflags/src/public.rs b/vendor/bitflags/src/public.rs index 643f8438f..eb8e4c5d5 100644 --- a/vendor/bitflags/src/public.rs +++ b/vendor/bitflags/src/public.rs @@ -11,10 +11,10 @@ macro_rules! __declare_public_bitflags { ( $(#[$outer:meta])* - $vis:vis struct $BitFlags:ident; + $vis:vis struct $PublicBitFlags:ident ) => { $(#[$outer])* - $vis struct $BitFlags(<$BitFlags as $crate::__private::PublicFlags>::Internal); + $vis struct $PublicBitFlags(<$PublicBitFlags as $crate::__private::PublicFlags>::Internal); }; } @@ -24,236 +24,320 @@ macro_rules! __declare_public_bitflags { /// could conflict with items added by the end-user. #[macro_export(local_inner_macros)] #[doc(hidden)] -macro_rules! __impl_public_bitflags { +macro_rules! __impl_public_bitflags_forward { ( - $PublicBitFlags:ident: $T:ty, $InternalBitFlags:ident, $Iter:ident, $IterNames:ident; + $PublicBitFlags:ident: $T:ty, $InternalBitFlags:ident ) => { - impl $crate::__private::core::fmt::Binary for $PublicBitFlags { - fn fmt(&self, f: &mut $crate::__private::core::fmt::Formatter) -> $crate::__private::core::fmt::Result { - $crate::__private::core::fmt::Binary::fmt(&self.0, f) - } - } + __impl_bitflags! { + $PublicBitFlags: $T { + fn empty() { + Self($InternalBitFlags::empty()) + } - impl $crate::__private::core::fmt::Octal for $PublicBitFlags { - fn fmt(&self, f: &mut $crate::__private::core::fmt::Formatter) -> $crate::__private::core::fmt::Result { - $crate::__private::core::fmt::Octal::fmt(&self.0, f) - } - } + fn all() { + Self($InternalBitFlags::all()) + } - impl $crate::__private::core::fmt::LowerHex for $PublicBitFlags { - fn fmt(&self, f: &mut $crate::__private::core::fmt::Formatter) -> $crate::__private::core::fmt::Result { - $crate::__private::core::fmt::LowerHex::fmt(&self.0, f) + fn bits(f) { + f.0.bits() + } + + fn from_bits(bits) { + match $InternalBitFlags::from_bits(bits) { + $crate::__private::core::option::Option::Some(bits) => $crate::__private::core::option::Option::Some(Self(bits)), + $crate::__private::core::option::Option::None => $crate::__private::core::option::Option::None, + } + } + + fn from_bits_truncate(bits) { + Self($InternalBitFlags::from_bits_truncate(bits)) + } + + fn from_bits_retain(bits) { + Self($InternalBitFlags::from_bits_retain(bits)) + } + + fn from_name(name) { + match $InternalBitFlags::from_name(name) { + $crate::__private::core::option::Option::Some(bits) => $crate::__private::core::option::Option::Some(Self(bits)), + $crate::__private::core::option::Option::None => $crate::__private::core::option::Option::None, + } + } + + fn is_empty(f) { + f.0.is_empty() + } + + fn is_all(f) { + f.0.is_all() + } + + fn intersects(f, other) { + f.0.intersects(other.0) + } + + fn contains(f, other) { + f.0.contains(other.0) + } + + fn insert(f, other) { + f.0.insert(other.0) + } + + fn remove(f, other) { + f.0.remove(other.0) + } + + fn toggle(f, other) { + f.0.toggle(other.0) + } + + fn set(f, other, value) { + f.0.set(other.0, value) + } + + fn intersection(f, other) { + Self(f.0.intersection(other.0)) + } + + fn union(f, other) { + Self(f.0.union(other.0)) + } + + fn difference(f, other) { + Self(f.0.difference(other.0)) + } + + fn symmetric_difference(f, other) { + Self(f.0.symmetric_difference(other.0)) + } + + fn complement(f) { + Self(f.0.complement()) + } } } + }; +} - impl $crate::__private::core::fmt::UpperHex for $PublicBitFlags { - fn fmt(&self, f: &mut $crate::__private::core::fmt::Formatter) -> $crate::__private::core::fmt::Result { - $crate::__private::core::fmt::UpperHex::fmt(&self.0, f) - } +/// Implement functions on the public (user-facing) bitflags type. +/// +/// We need to be careful about adding new methods and trait implementations here because they +/// could conflict with items added by the end-user. +#[macro_export(local_inner_macros)] +#[doc(hidden)] +macro_rules! __impl_public_bitflags { + ( + $BitFlags:ident: $T:ty, $PublicBitFlags:ident { + $( + $(#[$attr:ident $($args:tt)*])* + $Flag:ident; + )* } + ) => { + __impl_bitflags! { + $BitFlags: $T { + fn empty() { + Self(<$T as $crate::Bits>::EMPTY) + } - impl $PublicBitFlags { - /// Returns an empty set of flags. - #[inline] - pub const fn empty() -> Self { - Self($InternalBitFlags::empty()) - } + fn all() { + Self::from_bits_truncate(<$T as $crate::Bits>::ALL) + } - /// Returns the set containing all flags. - #[inline] - pub const fn all() -> Self { - Self($InternalBitFlags::all()) - } + fn bits(f) { + f.0 + } - /// Returns the raw value of the flags currently stored. - #[inline] - pub const fn bits(&self) -> $T { - self.0.bits() - } + fn from_bits(bits) { + let truncated = Self::from_bits_truncate(bits).0; - /// Convert from underlying bit representation, unless that - /// representation contains bits that do not correspond to a flag. - #[inline] - pub const fn from_bits(bits: $T) -> $crate::__private::core::option::Option<Self> { - match $InternalBitFlags::from_bits(bits) { - $crate::__private::core::option::Option::Some(bits) => $crate::__private::core::option::Option::Some(Self(bits)), - $crate::__private::core::option::Option::None => $crate::__private::core::option::Option::None, + if truncated == bits { + $crate::__private::core::option::Option::Some(Self(bits)) + } else { + $crate::__private::core::option::Option::None + } } - } - /// Convert from underlying bit representation, dropping any bits - /// that do not correspond to flags. - #[inline] - pub const fn from_bits_truncate(bits: $T) -> Self { - Self($InternalBitFlags::from_bits_truncate(bits)) - } + fn from_bits_truncate(bits) { + if bits == <$T as $crate::Bits>::EMPTY { + return Self(bits) + } + + let mut truncated = <$T as $crate::Bits>::EMPTY; + + $( + __bitflags_expr_safe_attrs!( + $(#[$attr $($args)*])* + { + if bits & $PublicBitFlags::$Flag.bits() == $PublicBitFlags::$Flag.bits() { + truncated = truncated | $PublicBitFlags::$Flag.bits() + } + } + ); + )* + + Self(truncated) + } - /// Convert from underlying bit representation, preserving all - /// bits (even those not corresponding to a defined flag). - #[inline] - pub const fn from_bits_retain(bits: $T) -> Self { - Self($InternalBitFlags::from_bits_retain(bits)) - } + fn from_bits_retain(bits) { + Self(bits) + } - /// Get the value for a flag from its stringified name. - /// - /// Names are _case-sensitive_, so must correspond exactly to - /// the identifier given to the flag. - #[inline] - pub fn from_name(name: &str) -> $crate::__private::core::option::Option<Self> { - match $InternalBitFlags::from_name(name) { - $crate::__private::core::option::Option::Some(bits) => $crate::__private::core::option::Option::Some(Self(bits)), - $crate::__private::core::option::Option::None => $crate::__private::core::option::Option::None, + fn from_name(name) { + $( + __bitflags_expr_safe_attrs!( + $(#[$attr $($args)*])* + { + if name == $crate::__private::core::stringify!($Flag) { + return $crate::__private::core::option::Option::Some(Self($PublicBitFlags::$Flag.bits())); + } + } + ); + )* + + let _ = name; + $crate::__private::core::option::Option::None } - } - /// Iterate over enabled flag values. - #[inline] - pub const fn iter(&self) -> $Iter { - self.0.iter() - } + fn is_empty(f) { + f.bits() == <$T as $crate::Bits>::EMPTY + } - /// Iterate over enabled flag values with their stringified names. - #[inline] - pub const fn iter_names(&self) -> $IterNames { - self.0.iter_names() - } + fn is_all(f) { + // 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() | f.bits() == f.bits() + } - /// Returns `true` if no flags are currently stored. - #[inline] - pub const fn is_empty(&self) -> bool { - self.0.is_empty() - } + fn intersects(f, other) { + f.bits() & other.bits() != <$T as $crate::Bits>::EMPTY + } - /// Returns `true` if all flags are currently set. - #[inline] - pub const fn is_all(&self) -> bool { - self.0.is_all() - } + fn contains(f, other) { + f.bits() & other.bits() == other.bits() + } - /// Returns `true` if there are flags common to both `self` and `other`. - #[inline] - pub const fn intersects(&self, other: Self) -> bool { - self.0.intersects(other.0) - } + fn insert(f, other) { + *f = Self::from_bits_retain(f.bits() | other.bits()); + } - /// Returns `true` if all of the flags in `other` are contained within `self`. - #[inline] - pub const fn contains(&self, other: Self) -> bool { - self.0.contains(other.0) - } + fn remove(f, other) { + *f = Self::from_bits_retain(f.bits() & !other.bits()); + } - /// Inserts the specified flags in-place. - #[inline] - pub fn insert(&mut self, other: Self) { - self.0.insert(other.0) - } + fn toggle(f, other) { + *f = Self::from_bits_retain(f.bits() ^ other.bits()); + } - /// Removes the specified flags in-place. - #[inline] - pub fn remove(&mut self, other: Self) { - self.0.remove(other.0) + fn set(f, other, value) { + if value { + f.insert(other); + } else { + f.remove(other); + } + } + + fn intersection(f, other) { + Self::from_bits_retain(f.bits() & other.bits()) + } + + fn union(f, other) { + Self::from_bits_retain(f.bits() | other.bits()) + } + + fn difference(f, other) { + Self::from_bits_retain(f.bits() & !other.bits()) + } + + fn symmetric_difference(f, other) { + Self::from_bits_retain(f.bits() ^ other.bits()) + } + + fn complement(f) { + Self::from_bits_truncate(!f.bits()) + } } + } + }; +} - /// Toggles the specified flags in-place. +/// Implement iterators on the public (user-facing) bitflags type. +#[macro_export(local_inner_macros)] +#[doc(hidden)] +macro_rules! __impl_public_bitflags_iter { + ($BitFlags:ident: $T:ty, $PublicBitFlags:ident) => { + impl $BitFlags { + /// Iterate over enabled flag values. #[inline] - pub fn toggle(&mut self, other: Self) { - self.0.toggle(other.0) + pub const fn iter(&self) -> $crate::iter::Iter<$PublicBitFlags> { + $crate::iter::Iter::__private_const_new( + <$PublicBitFlags as $crate::Flags>::FLAGS, + $PublicBitFlags::from_bits_retain(self.bits()), + $PublicBitFlags::from_bits_retain(self.bits()), + ) } - /// Inserts or removes the specified flags depending on the passed value. + /// Iterate over enabled flag values with their stringified names. #[inline] - pub fn set(&mut self, other: Self, value: bool) { - self.0.set(other.0, value) + pub const fn iter_names(&self) -> $crate::iter::IterNames<$PublicBitFlags> { + $crate::iter::IterNames::__private_const_new( + <$PublicBitFlags as $crate::Flags>::FLAGS, + $PublicBitFlags::from_bits_retain(self.bits()), + $PublicBitFlags::from_bits_retain(self.bits()), + ) } + } - /// Returns the intersection between the flags in `self` and - /// `other`. - /// - /// Specifically, the returned set contains only the flags which are - /// present in *both* `self` *and* `other`. - /// - /// This is equivalent to using the `&` operator (e.g. - /// [`ops::BitAnd`]), as in `flags & other`. - /// - /// [`ops::BitAnd`]: https://doc.rust-lang.org/std/ops/trait.BitAnd.html - #[inline] - #[must_use] - pub const fn intersection(self, other: Self) -> Self { - Self(self.0.intersection(other.0)) + impl $crate::__private::core::iter::IntoIterator for $BitFlags { + type Item = $PublicBitFlags; + type IntoIter = $crate::iter::Iter<$PublicBitFlags>; + + fn into_iter(self) -> Self::IntoIter { + self.iter() } + } + }; +} - /// Returns the union of between the flags in `self` and `other`. - /// - /// Specifically, the returned set contains all flags which are - /// present in *either* `self` *or* `other`, including any which are - /// present in both (see [`Self::symmetric_difference`] if that - /// is undesirable). - /// - /// This is equivalent to using the `|` operator (e.g. - /// [`ops::BitOr`]), as in `flags | other`. - /// - /// [`ops::BitOr`]: https://doc.rust-lang.org/std/ops/trait.BitOr.html - #[inline] - #[must_use] - pub const fn union(self, other: Self) -> Self { - Self(self.0.union(other.0)) +/// Implement traits on the public (user-facing) bitflags type. +#[macro_export(local_inner_macros)] +#[doc(hidden)] +macro_rules! __impl_public_bitflags_ops { + ($PublicBitFlags:ident) => { + impl $crate::__private::core::fmt::Binary for $PublicBitFlags { + fn fmt( + &self, + f: &mut $crate::__private::core::fmt::Formatter, + ) -> $crate::__private::core::fmt::Result { + $crate::__private::core::fmt::Binary::fmt(&self.0, f) } + } - /// Returns the difference between the flags in `self` and `other`. - /// - /// Specifically, the returned set contains all flags present in - /// `self`, except for the ones present in `other`. - /// - /// It is also conceptually equivalent to the "bit-clear" operation: - /// `flags & !other` (and this syntax is also supported). - /// - /// This is equivalent to using the `-` operator (e.g. - /// [`ops::Sub`]), as in `flags - other`. - /// - /// [`ops::Sub`]: https://doc.rust-lang.org/std/ops/trait.Sub.html - #[inline] - #[must_use] - pub const fn difference(self, other: Self) -> Self { - Self(self.0.difference(other.0)) + impl $crate::__private::core::fmt::Octal for $PublicBitFlags { + fn fmt( + &self, + f: &mut $crate::__private::core::fmt::Formatter, + ) -> $crate::__private::core::fmt::Result { + $crate::__private::core::fmt::Octal::fmt(&self.0, f) } + } - /// Returns the [symmetric difference][sym-diff] between the flags - /// in `self` and `other`. - /// - /// Specifically, the returned set contains the flags present which - /// are present in `self` or `other`, but that are not present in - /// both. Equivalently, it contains the flags present in *exactly - /// one* of the sets `self` and `other`. - /// - /// This is equivalent to using the `^` operator (e.g. - /// [`ops::BitXor`]), as in `flags ^ other`. - /// - /// [sym-diff]: https://en.wikipedia.org/wiki/Symmetric_difference - /// [`ops::BitXor`]: https://doc.rust-lang.org/std/ops/trait.BitXor.html - #[inline] - #[must_use] - pub const fn symmetric_difference(self, other: Self) -> Self { - Self(self.0.symmetric_difference(other.0)) + impl $crate::__private::core::fmt::LowerHex for $PublicBitFlags { + fn fmt( + &self, + f: &mut $crate::__private::core::fmt::Formatter, + ) -> $crate::__private::core::fmt::Result { + $crate::__private::core::fmt::LowerHex::fmt(&self.0, f) } + } - /// Returns the complement of this set of flags. - /// - /// Specifically, the returned set contains all the flags which are - /// not set in `self`, but which are allowed for this type. - /// - /// Alternatively, it can be thought of as the set difference - /// between [`Self::all()`] and `self` (e.g. `Self::all() - self`) - /// - /// This is equivalent to using the `!` operator (e.g. - /// [`ops::Not`]), as in `!flags`. - /// - /// [`Self::all()`]: Self::all - /// [`ops::Not`]: https://doc.rust-lang.org/std/ops/trait.Not.html - #[inline] - #[must_use] - pub const fn complement(self) -> Self { - Self(self.0.complement()) + impl $crate::__private::core::fmt::UpperHex for $PublicBitFlags { + fn fmt( + &self, + f: &mut $crate::__private::core::fmt::Formatter, + ) -> $crate::__private::core::fmt::Result { + $crate::__private::core::fmt::UpperHex::fmt(&self.0, f) } } @@ -271,7 +355,7 @@ macro_rules! __impl_public_bitflags { /// Adds the set of flags. #[inline] fn bitor_assign(&mut self, other: Self) { - self.0 = self.0.union(other.0); + *self = Self::from_bits_retain(self.bits()).union(other); } } @@ -289,7 +373,7 @@ macro_rules! __impl_public_bitflags { /// Toggles the set of flags. #[inline] fn bitxor_assign(&mut self, other: Self) { - self.0 = self.0.symmetric_difference(other.0); + *self = Self::from_bits_retain(self.bits()).symmetric_difference(other); } } @@ -307,7 +391,7 @@ macro_rules! __impl_public_bitflags { /// Disables all flags disabled in the set. #[inline] fn bitand_assign(&mut self, other: Self) { - self.0 = self.0.intersection(other.0); + *self = Self::from_bits_retain(self.bits()).intersection(other); } } @@ -325,7 +409,7 @@ macro_rules! __impl_public_bitflags { /// Disables all flags enabled in the set. #[inline] fn sub_assign(&mut self, other: Self) { - self.0 = self.0.difference(other.0); + *self = Self::from_bits_retain(self.bits()).difference(other); } } @@ -340,7 +424,10 @@ macro_rules! __impl_public_bitflags { } impl $crate::__private::core::iter::Extend<$PublicBitFlags> for $PublicBitFlags { - fn extend<T: $crate::__private::core::iter::IntoIterator<Item=Self>>(&mut self, iterator: T) { + fn extend<T: $crate::__private::core::iter::IntoIterator<Item = Self>>( + &mut self, + iterator: T, + ) { for item in iterator { self.insert(item) } @@ -348,7 +435,9 @@ macro_rules! __impl_public_bitflags { } impl $crate::__private::core::iter::FromIterator<$PublicBitFlags> for $PublicBitFlags { - fn from_iter<T: $crate::__private::core::iter::IntoIterator<Item=Self>>(iterator: T) -> Self { + fn from_iter<T: $crate::__private::core::iter::IntoIterator<Item = Self>>( + iterator: T, + ) -> Self { use $crate::__private::core::iter::Extend; let mut result = Self::empty(); @@ -356,92 +445,6 @@ macro_rules! __impl_public_bitflags { result } } - - impl $crate::__private::core::iter::IntoIterator for $PublicBitFlags { - type Item = Self; - type IntoIter = $Iter; - - fn into_iter(self) -> Self::IntoIter { - self.0.iter() - } - } - - impl $crate::BitFlags for $PublicBitFlags { - type Bits = $T; - - type Iter = $Iter; - type IterNames = $IterNames; - - fn empty() -> Self { - $PublicBitFlags::empty() - } - - fn all() -> Self { - $PublicBitFlags::all() - } - - fn bits(&self) -> $T { - $PublicBitFlags::bits(self) - } - - fn from_bits(bits: $T) -> $crate::__private::core::option::Option<$PublicBitFlags> { - $PublicBitFlags::from_bits(bits) - } - - fn from_bits_truncate(bits: $T) -> $PublicBitFlags { - $PublicBitFlags::from_bits_truncate(bits) - } - - fn from_bits_retain(bits: $T) -> $PublicBitFlags { - $PublicBitFlags::from_bits_retain(bits) - } - - fn from_name(name: &str) -> $crate::__private::core::option::Option<$PublicBitFlags> { - $PublicBitFlags::from_name(name) - } - - fn iter(&self) -> Self::Iter { - $PublicBitFlags::iter(self) - } - - fn iter_names(&self) -> Self::IterNames { - $PublicBitFlags::iter_names(self) - } - - fn is_empty(&self) -> bool { - $PublicBitFlags::is_empty(self) - } - - fn is_all(&self) -> bool { - $PublicBitFlags::is_all(self) - } - - fn intersects(&self, other: $PublicBitFlags) -> bool { - $PublicBitFlags::intersects(self, other) - } - - fn contains(&self, other: $PublicBitFlags) -> bool { - $PublicBitFlags::contains(self, other) - } - - fn insert(&mut self, other: $PublicBitFlags) { - $PublicBitFlags::insert(self, other) - } - - fn remove(&mut self, other: $PublicBitFlags) { - $PublicBitFlags::remove(self, other) - } - - fn toggle(&mut self, other: $PublicBitFlags) { - $PublicBitFlags::toggle(self, other) - } - - fn set(&mut self, other: $PublicBitFlags, value: bool) { - $PublicBitFlags::set(self, other, value) - } - } - - impl $crate::__private::ImplementedByBitFlagsMacro for $PublicBitFlags {} }; } @@ -450,7 +453,7 @@ macro_rules! __impl_public_bitflags { #[doc(hidden)] macro_rules! __impl_public_bitflags_consts { ( - $PublicBitFlags:ident { + $PublicBitFlags:ident: $T:ty { $( $(#[$attr:ident $($args:tt)*])* $Flag:ident = $value:expr; @@ -460,8 +463,39 @@ macro_rules! __impl_public_bitflags_consts { impl $PublicBitFlags { $( $(#[$attr $($args)*])* + #[allow( + deprecated, + non_upper_case_globals, + )] pub const $Flag: Self = Self::from_bits_retain($value); )* } + + impl $crate::Flags for $PublicBitFlags { + const FLAGS: &'static [$crate::Flag<$PublicBitFlags>] = &[ + $( + __bitflags_expr_safe_attrs!( + $(#[$attr $($args)*])* + { + #[allow( + deprecated, + non_upper_case_globals, + )] + $crate::Flag::new($crate::__private::core::stringify!($Flag), $PublicBitFlags::$Flag) + } + ), + )* + ]; + + type Bits = $T; + + fn bits(&self) -> $T { + $PublicBitFlags::bits(self) + } + + fn from_bits_retain(bits: $T) -> $PublicBitFlags { + $PublicBitFlags::from_bits_retain(bits) + } + } }; } diff --git a/vendor/bitflags/src/tests.rs b/vendor/bitflags/src/tests.rs new file mode 100644 index 000000000..cb41f75a3 --- /dev/null +++ b/vendor/bitflags/src/tests.rs @@ -0,0 +1,107 @@ +mod all; +mod bits; +mod complement; +mod contains; +mod difference; +mod empty; +mod eq; +mod extend; +mod flags; +mod fmt; +mod from_bits; +mod from_bits_retain; +mod from_bits_truncate; +mod from_name; +mod insert; +mod intersection; +mod intersects; +mod is_all; +mod is_empty; +mod iter; +mod parser; +mod remove; +mod symmetric_difference; +mod union; + +bitflags! { + #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)] + pub struct TestFlags: u8 { + /// 1 + const A = 1; + + /// 1 << 1 + const B = 1 << 1; + + /// 1 << 2 + const C = 1 << 2; + + /// 1 | (1 << 1) | (1 << 2) + const ABC = Self::A.bits() | Self::B.bits() | Self::C.bits(); + } + + #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)] + pub struct TestFlagsInvert: u8 { + /// 1 | (1 << 1) | (1 << 2) + const ABC = Self::A.bits() | Self::B.bits() | Self::C.bits(); + + /// 1 + const A = 1; + + /// 1 << 1 + const B = 1 << 1; + + /// 1 << 2 + const C = 1 << 2; + } + + #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)] + pub struct TestZero: u8 { + /// 0 + const ZERO = 0; + } + + #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)] + pub struct TestZeroOne: u8 { + /// 0 + const ZERO = 0; + + /// 1 + const ONE = 1; + } + + #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)] + pub struct TestUnicode: u8 { + /// 1 + const 一 = 1; + + /// 2 + const 二 = 1 << 1; + } + + #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)] + pub struct TestEmpty: u8 {} + + #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)] + pub struct TestOverlapping: u8 { + /// 1 | (1 << 1) + const AB = 1 | (1 << 1); + + /// (1 << 1) | (1 << 2) + const BC = (1 << 1) | (1 << 2); + } + + #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)] + pub struct TestOverlappingFull: u8 { + /// 1 + const A = 1; + + /// 1 + const B = 1; + + /// 1 + const C = 1; + + /// 2 + const D = 1 << 1; + } +} 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}; +} |