#
bitflags/
internal.rs

    1//! Generate the internal `bitflags`-facing flags type.
    2//!
    3//! The code generated here is owned by `bitflags`, but still part of its public API.
    4//! Changes to the types generated here need to be considered like any other public API change.
    5
    6/// Declare the `bitflags`-facing bitflags struct.
    7///
    8/// This type is part of the `bitflags` crate's public API, but not part of the user's.
    9#[macro_export]
    10#[doc(hidden)]
    11macro_rules! __declare_internal_bitflags {
    12    (
    13        $vis:vis struct $InternalBitFlags:ident: $T:ty
    14    ) => {
    15        // NOTE: The ABI of this type is _guaranteed_ to be the same as `T`
    16        // This is relied on by some external libraries like `bytemuck` to make
    17        // its `unsafe` trait impls sound.
    18        #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
    19        #[repr(transparent)]
    20        $vis struct $InternalBitFlags($T);
    21    };
    22}
    23
    24/// Implement functions on the private (bitflags-facing) bitflags type.
    25///
    26/// Methods and trait implementations can be freely added here without breaking end-users.
    27/// If we want to expose new functionality to `#[derive]`, this is the place to do it.
    28#[macro_export]
    29#[doc(hidden)]
    30macro_rules! __impl_internal_bitflags {
    31    (
    32        $InternalBitFlags:ident: $T:ty, $PublicBitFlags:ident {
    33            $(
    34                $(#[$inner:ident $($args:tt)*])*
    35                const $Flag:tt = $value:expr;
    36            )*
    37        }
    38    ) => {
    39        // NOTE: This impl is also used to prevent using bits types from non-primitive types
    40        // in the `bitflags` macro. If this approach is changed, this guard will need to be
    41        // retained somehow
    42        impl $crate::__private::PublicFlags for $PublicBitFlags {
    43            type Primitive = $T;
    44            type Internal = $InternalBitFlags;
    45        }
    46
    47        impl $crate::__private::core::default::Default for $InternalBitFlags {
    48            #[inline]
    49            fn default() -> Self {
    50                $InternalBitFlags::empty()
    51            }
    52        }
    53
    54        impl $crate::__private::core::fmt::Debug for $InternalBitFlags {
    55            fn fmt(&self, f: &mut $crate::__private::core::fmt::Formatter<'_>) -> $crate::__private::core::fmt::Result {
    56                if self.is_empty() {
    57                    // If no flags are set then write an empty hex flag to avoid
    58                    // writing an empty string. In some contexts, like serialization,
    59                    // an empty string is preferable, but it may be unexpected in
    60                    // others for a format not to produce any output.
    61                    //
    62                    // We can remove this `0x0` and remain compatible with `FromStr`,
    63                    // because an empty string will still parse to an empty set of flags,
    64                    // just like `0x0` does.
    65                    $crate::__private::core::write!(f, "{:#x}", <$T as $crate::Bits>::EMPTY)
    66                } else {
    67                    $crate::__private::core::fmt::Display::fmt(self, f)
    68                }
    69            }
    70        }
    71
    72        impl $crate::__private::core::fmt::Display for $InternalBitFlags {
    73            fn fmt(&self, f: &mut $crate::__private::core::fmt::Formatter<'_>) -> $crate::__private::core::fmt::Result {
    74                $crate::parser::to_writer(&$PublicBitFlags(*self), f)
    75            }
    76        }
    77
    78        impl $crate::__private::core::str::FromStr for $InternalBitFlags {
    79            type Err = $crate::parser::ParseError;
    80
    81            fn from_str(s: &str) -> $crate::__private::core::result::Result<Self, Self::Err> {
    82                $crate::parser::from_str::<$PublicBitFlags>(s).map(|flags| flags.0)
    83            }
    84        }
    85
    86        impl $crate::__private::core::convert::AsRef<$T> for $InternalBitFlags {
    87            fn as_ref(&self) -> &$T {
    88                &self.0
    89            }
    90        }
    91
    92        impl $crate::__private::core::convert::From<$T> for $InternalBitFlags {
    93            fn from(bits: $T) -> Self {
    94                Self::from_bits_retain(bits)
    95            }
    96        }
    97
    98        // The internal flags type offers a similar API to the public one
    99
    100        $crate::__impl_public_bitflags! {
    101            $InternalBitFlags: $T, $PublicBitFlags {
    102                $(
    103                    $(#[$inner $($args)*])*
    104                    const $Flag = $value;
    105                )*
    106            }
    107        }
    108
    109        $crate::__impl_public_bitflags_ops! {
    110            $InternalBitFlags
    111        }
    112
    113        $crate::__impl_public_bitflags_iter! {
    114            $InternalBitFlags: $T, $PublicBitFlags
    115        }
    116
    117        impl $InternalBitFlags {
    118            /// Returns a mutable reference to the raw value of the flags currently stored.
    119            #[inline]
    120            pub fn bits_mut(&mut self) -> &mut $T {
    121                &mut self.0
    122            }
    123        }
    124    };
    125}