aboutsummaryrefslogtreecommitdiff
path: root/src/public.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/public.rs')
-rw-r--r--src/public.rs467
1 files changed, 467 insertions, 0 deletions
diff --git a/src/public.rs b/src/public.rs
new file mode 100644
index 0000000..643f843
--- /dev/null
+++ b/src/public.rs
@@ -0,0 +1,467 @@
+//! Generate the user-facing flags type.
+//!
+//! The code here belongs to the end-user, so new trait implementations and methods can't be
+//! added without potentially breaking users.
+
+/// Declare the user-facing bitflags struct.
+///
+/// This type is guaranteed to be a newtype with a `bitflags`-facing type as its single field.
+#[macro_export(local_inner_macros)]
+#[doc(hidden)]
+macro_rules! __declare_public_bitflags {
+ (
+ $(#[$outer:meta])*
+ $vis:vis struct $BitFlags:ident;
+ ) => {
+ $(#[$outer])*
+ $vis struct $BitFlags(<$BitFlags as $crate::__private::PublicFlags>::Internal);
+ };
+}
+
+/// 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 {
+ (
+ $PublicBitFlags:ident: $T:ty, $InternalBitFlags:ident, $Iter:ident, $IterNames: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 $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)
+ }
+ }
+
+ 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)
+ }
+ }
+
+ 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)
+ }
+ }
+
+ impl $PublicBitFlags {
+ /// Returns an empty set of flags.
+ #[inline]
+ pub const fn empty() -> Self {
+ Self($InternalBitFlags::empty())
+ }
+
+ /// Returns the set containing all flags.
+ #[inline]
+ pub const fn all() -> Self {
+ Self($InternalBitFlags::all())
+ }
+
+ /// Returns the raw value of the flags currently stored.
+ #[inline]
+ pub const fn bits(&self) -> $T {
+ self.0.bits()
+ }
+
+ /// 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,
+ }
+ }
+
+ /// 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))
+ }
+
+ /// 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))
+ }
+
+ /// 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,
+ }
+ }
+
+ /// Iterate over enabled flag values.
+ #[inline]
+ pub const fn iter(&self) -> $Iter {
+ self.0.iter()
+ }
+
+ /// Iterate over enabled flag values with their stringified names.
+ #[inline]
+ pub const fn iter_names(&self) -> $IterNames {
+ self.0.iter_names()
+ }
+
+ /// Returns `true` if no flags are currently stored.
+ #[inline]
+ pub const fn is_empty(&self) -> bool {
+ self.0.is_empty()
+ }
+
+ /// Returns `true` if all flags are currently set.
+ #[inline]
+ pub const fn is_all(&self) -> bool {
+ self.0.is_all()
+ }
+
+ /// 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)
+ }
+
+ /// 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)
+ }
+
+ /// Inserts the specified flags in-place.
+ #[inline]
+ pub fn insert(&mut self, other: Self) {
+ self.0.insert(other.0)
+ }
+
+ /// Removes the specified flags in-place.
+ #[inline]
+ pub fn remove(&mut self, other: Self) {
+ self.0.remove(other.0)
+ }
+
+ /// Toggles the specified flags in-place.
+ #[inline]
+ pub fn toggle(&mut self, other: Self) {
+ self.0.toggle(other.0)
+ }
+
+ /// Inserts or removes the specified flags depending on the passed value.
+ #[inline]
+ pub fn set(&mut self, other: Self, value: bool) {
+ self.0.set(other.0, value)
+ }
+
+ /// 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))
+ }
+
+ /// 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))
+ }
+
+ /// 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))
+ }
+
+ /// 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))
+ }
+
+ /// 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::ops::BitOr for $PublicBitFlags {
+ type Output = Self;
+
+ /// Returns the union of the two sets of flags.
+ #[inline]
+ fn bitor(self, other: $PublicBitFlags) -> Self {
+ self.union(other)
+ }
+ }
+
+ impl $crate::__private::core::ops::BitOrAssign for $PublicBitFlags {
+ /// Adds the set of flags.
+ #[inline]
+ fn bitor_assign(&mut self, other: Self) {
+ self.0 = self.0.union(other.0);
+ }
+ }
+
+ impl $crate::__private::core::ops::BitXor for $PublicBitFlags {
+ type Output = Self;
+
+ /// Returns the left flags, but with all the right flags toggled.
+ #[inline]
+ fn bitxor(self, other: Self) -> Self {
+ self.symmetric_difference(other)
+ }
+ }
+
+ impl $crate::__private::core::ops::BitXorAssign for $PublicBitFlags {
+ /// Toggles the set of flags.
+ #[inline]
+ fn bitxor_assign(&mut self, other: Self) {
+ self.0 = self.0.symmetric_difference(other.0);
+ }
+ }
+
+ impl $crate::__private::core::ops::BitAnd for $PublicBitFlags {
+ type Output = Self;
+
+ /// Returns the intersection between the two sets of flags.
+ #[inline]
+ fn bitand(self, other: Self) -> Self {
+ self.intersection(other)
+ }
+ }
+
+ impl $crate::__private::core::ops::BitAndAssign for $PublicBitFlags {
+ /// Disables all flags disabled in the set.
+ #[inline]
+ fn bitand_assign(&mut self, other: Self) {
+ self.0 = self.0.intersection(other.0);
+ }
+ }
+
+ impl $crate::__private::core::ops::Sub for $PublicBitFlags {
+ type Output = Self;
+
+ /// Returns the set difference of the two sets of flags.
+ #[inline]
+ fn sub(self, other: Self) -> Self {
+ self.difference(other)
+ }
+ }
+
+ impl $crate::__private::core::ops::SubAssign for $PublicBitFlags {
+ /// Disables all flags enabled in the set.
+ #[inline]
+ fn sub_assign(&mut self, other: Self) {
+ self.0 = self.0.difference(other.0);
+ }
+ }
+
+ impl $crate::__private::core::ops::Not for $PublicBitFlags {
+ type Output = Self;
+
+ /// Returns the complement of this set of flags.
+ #[inline]
+ fn not(self) -> Self {
+ self.complement()
+ }
+ }
+
+ impl $crate::__private::core::iter::Extend<$PublicBitFlags> for $PublicBitFlags {
+ fn extend<T: $crate::__private::core::iter::IntoIterator<Item=Self>>(&mut self, iterator: T) {
+ for item in iterator {
+ self.insert(item)
+ }
+ }
+ }
+
+ impl $crate::__private::core::iter::FromIterator<$PublicBitFlags> for $PublicBitFlags {
+ 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();
+ result.extend(iterator);
+ 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 {}
+ };
+}
+
+/// Implement constants on the public (user-facing) bitflags type.
+#[macro_export(local_inner_macros)]
+#[doc(hidden)]
+macro_rules! __impl_public_bitflags_consts {
+ (
+ $PublicBitFlags:ident {
+ $(
+ $(#[$attr:ident $($args:tt)*])*
+ $Flag:ident = $value:expr;
+ )*
+ }
+ ) => {
+ impl $PublicBitFlags {
+ $(
+ $(#[$attr $($args)*])*
+ pub const $Flag: Self = Self::from_bits_retain($value);
+ )*
+ }
+ };
+}