blob: 87d01cc0cb5f55edb1b3b451cebde8095fbf85a5 [file] [log] [blame]
Jakob Vukalovicfa6723a2023-04-26 10:38:55 +01001//! 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.
Stephen Hines5fc2b792024-02-21 12:13:08 -08009#[macro_export]
Jakob Vukalovicfa6723a2023-04-26 10:38:55 +010010#[doc(hidden)]
11macro_rules! __declare_internal_bitflags {
12 (
Andrew Walbranff6563b2023-06-13 10:21:55 +000013 $vis:vis struct $InternalBitFlags:ident: $T:ty
Jakob Vukalovicfa6723a2023-04-26 10:38:55 +010014 ) => {
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)]
Andrew Walbranff6563b2023-06-13 10:21:55 +000020 $vis struct $InternalBitFlags($T);
Jakob Vukalovicfa6723a2023-04-26 10:38:55 +010021 };
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.
Stephen Hines5fc2b792024-02-21 12:13:08 -080028#[macro_export]
Jakob Vukalovicfa6723a2023-04-26 10:38:55 +010029#[doc(hidden)]
30macro_rules! __impl_internal_bitflags {
31 (
Andrew Walbranff6563b2023-06-13 10:21:55 +000032 $InternalBitFlags:ident: $T:ty, $PublicBitFlags:ident {
Jakob Vukalovicfa6723a2023-04-26 10:38:55 +010033 $(
Stephen Hines5fc2b792024-02-21 12:13:08 -080034 $(#[$inner:ident $($args:tt)*])*
35 const $Flag:tt = $value:expr;
Jakob Vukalovicfa6723a2023-04-26 10:38:55 +010036 )*
37 }
38 ) => {
Andrew Walbranff6563b2023-06-13 10:21:55 +000039 // 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;
Jakob Vukalovicfa6723a2023-04-26 10:38:55 +010044 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,
Stephen Hines5fc2b792024-02-21 12:13:08 -080059 // an empty string is preferable, but it may be unexpected in
Jakob Vukalovicfa6723a2023-04-26 10:38:55 +010060 // 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.
Andrew Walbranff6563b2023-06-13 10:21:55 +000065 $crate::__private::core::write!(f, "{:#x}", <$T as $crate::Bits>::EMPTY)
Jakob Vukalovicfa6723a2023-04-26 10:38:55 +010066 } 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 {
Andrew Walbranff6563b2023-06-13 10:21:55 +000074 $crate::parser::to_writer(&$PublicBitFlags(*self), f)
Jakob Vukalovicfa6723a2023-04-26 10:38:55 +010075 }
76 }
77
Jakob Vukalovicfa6723a2023-04-26 10:38:55 +010078 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> {
Andrew Walbranff6563b2023-06-13 10:21:55 +000082 $crate::parser::from_str::<$PublicBitFlags>(s).map(|flags| flags.0)
Jakob Vukalovicfa6723a2023-04-26 10:38:55 +010083 }
84 }
85
86 impl $crate::__private::core::convert::AsRef<$T> for $InternalBitFlags {
87 fn as_ref(&self) -> &$T {
Andrew Walbranff6563b2023-06-13 10:21:55 +000088 &self.0
Jakob Vukalovicfa6723a2023-04-26 10:38:55 +010089 }
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
Andrew Walbranff6563b2023-06-13 10:21:55 +000098 // The internal flags type offers a similar API to the public one
Jakob Vukalovicfa6723a2023-04-26 10:38:55 +010099
Stephen Hines5fc2b792024-02-21 12:13:08 -0800100 $crate::__impl_public_bitflags! {
Andrew Walbranff6563b2023-06-13 10:21:55 +0000101 $InternalBitFlags: $T, $PublicBitFlags {
102 $(
Stephen Hines5fc2b792024-02-21 12:13:08 -0800103 $(#[$inner $($args)*])*
104 const $Flag = $value;
Andrew Walbranff6563b2023-06-13 10:21:55 +0000105 )*
Jakob Vukalovicfa6723a2023-04-26 10:38:55 +0100106 }
107 }
108
Stephen Hines5fc2b792024-02-21 12:13:08 -0800109 $crate::__impl_public_bitflags_ops! {
110 $InternalBitFlags
111 }
112
113 $crate::__impl_public_bitflags_iter! {
Andrew Walbranff6563b2023-06-13 10:21:55 +0000114 $InternalBitFlags: $T, $PublicBitFlags
115 }
Jakob Vukalovicfa6723a2023-04-26 10:38:55 +0100116
Andrew Walbranff6563b2023-06-13 10:21:55 +0000117 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
Jakob Vukalovicfa6723a2023-04-26 10:38:55 +0100122 }
123 }
124 };
125}