diff options
Diffstat (limited to 'vendor/bitflags/src/internal.rs')
-rw-r--r-- | vendor/bitflags/src/internal.rs | 509 |
1 files changed, 32 insertions, 477 deletions
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 } - } } |