summaryrefslogtreecommitdiffstats
path: root/vendor/bitflags/src
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/bitflags/src')
-rw-r--r--vendor/bitflags/src/example_generated.rs39
-rw-r--r--vendor/bitflags/src/external.rs110
-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.rs509
-rw-r--r--vendor/bitflags/src/iter.rs133
-rw-r--r--vendor/bitflags/src/lib.rs1393
-rw-r--r--vendor/bitflags/src/parser.rs114
-rw-r--r--vendor/bitflags/src/public.rs602
-rw-r--r--vendor/bitflags/src/tests.rs107
-rw-r--r--vendor/bitflags/src/traits.rs297
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};
+}