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)] |
11 | macro_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)] |
30 | macro_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 | } |
126 | |