mago_codex/flags/
attribute.rs1#[derive(Clone, Copy, Debug, PartialEq, Eq)]
4#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
5#[repr(transparent)]
6pub struct AttributeFlags(u8);
7
8impl AttributeFlags {
9 pub const TARGET_CLASS: AttributeFlags = AttributeFlags(1 << 0);
12
13 pub const TARGET_FUNCTION: AttributeFlags = AttributeFlags(1 << 1);
16
17 pub const TARGET_METHOD: AttributeFlags = AttributeFlags(1 << 2);
20
21 pub const TARGET_PROPERTY: AttributeFlags = AttributeFlags(1 << 3);
24
25 pub const TARGET_CLASS_CONSTANT: AttributeFlags = AttributeFlags(1 << 4);
28
29 pub const TARGET_PARAMETER: AttributeFlags = AttributeFlags(1 << 5);
32
33 pub const TARGET_CONSTANT: AttributeFlags = AttributeFlags(1 << 6);
36
37 pub const TARGET_ALL: AttributeFlags =
40 AttributeFlags((1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4) | (1 << 5) | (1 << 6));
41
42 pub const IS_REPEATABLE: AttributeFlags = AttributeFlags(1 << 7);
45}
46
47impl AttributeFlags {
48 #[inline]
49 #[must_use]
50 pub const fn empty() -> Self {
51 AttributeFlags(0)
52 }
53
54 #[inline]
55 #[must_use]
56 pub const fn from_bits(bits: u8) -> Self {
57 AttributeFlags(bits)
58 }
59
60 #[inline]
61 pub const fn insert(&mut self, other: AttributeFlags) {
62 self.0 |= other.0;
63 }
64
65 #[inline]
66 pub const fn set(&mut self, other: AttributeFlags, value: bool) {
67 if value {
68 self.insert(other);
69 } else {
70 self.0 &= !other.0;
71 }
72 }
73
74 #[inline]
75 #[must_use]
76 pub const fn contains(self, other: AttributeFlags) -> bool {
77 (self.0 & other.0) == other.0
78 }
79
80 #[inline]
81 pub const fn remove(&mut self, other: AttributeFlags) {
82 self.0 &= !other.0;
83 }
84
85 #[inline]
86 #[must_use]
87 pub const fn intersects(self, other: AttributeFlags) -> bool {
88 (self.0 & other.0) != 0
89 }
90
91 #[inline]
92 #[must_use]
93 pub const fn union(&self, other: AttributeFlags) -> AttributeFlags {
94 AttributeFlags(self.0 | other.0)
95 }
96
97 #[inline]
98 #[must_use]
99 pub const fn intersection(&self, other: AttributeFlags) -> AttributeFlags {
100 AttributeFlags(self.0 & other.0)
101 }
102
103 #[inline]
104 #[must_use]
105 pub const fn bits(self) -> u8 {
106 self.0
107 }
108
109 #[inline]
110 #[must_use]
111 pub const fn all() -> Self {
112 Self(Self::TARGET_ALL.0 | Self::IS_REPEATABLE.0)
113 }
114}
115
116impl AttributeFlags {
117 #[must_use]
120 pub const fn is_repeatable(&self) -> bool {
121 self.contains(Self::IS_REPEATABLE)
122 }
123
124 #[must_use]
127 pub const fn targets_class(&self) -> bool {
128 self.contains(Self::TARGET_CLASS)
129 }
130
131 #[must_use]
134 pub const fn targets_function(&self) -> bool {
135 self.contains(Self::TARGET_FUNCTION)
136 }
137
138 #[must_use]
141 pub const fn targets_method(&self) -> bool {
142 self.contains(Self::TARGET_METHOD)
143 }
144
145 #[must_use]
148 pub const fn targets_property(&self) -> bool {
149 self.contains(Self::TARGET_PROPERTY)
150 }
151
152 #[must_use]
155 pub const fn targets_class_constant(&self) -> bool {
156 self.contains(Self::TARGET_CLASS_CONSTANT)
157 }
158
159 #[must_use]
162 pub const fn targets_parameter(&self) -> bool {
163 self.contains(Self::TARGET_PARAMETER)
164 }
165
166 #[must_use]
169 pub const fn targets_constant(&self) -> bool {
170 self.contains(Self::TARGET_CONSTANT)
171 }
172
173 #[must_use]
175 pub fn get_target_names(&self) -> Vec<&'static str> {
176 let mut targets = Vec::with_capacity(7);
177
178 if self.targets_class() {
179 targets.push("classes");
180 }
181
182 if self.targets_function() {
183 targets.push("functions");
184 }
185
186 if self.targets_method() {
187 targets.push("methods");
188 }
189
190 if self.targets_property() {
191 targets.push("properties");
192 }
193
194 if self.targets_class_constant() {
195 targets.push("class constants");
196 }
197
198 if self.targets_parameter() {
199 targets.push("parameters");
200 }
201
202 if self.targets_constant() {
203 targets.push("global constants");
204 }
205
206 targets
207 }
208}
209
210impl std::ops::BitOr for AttributeFlags {
211 type Output = Self;
212
213 #[inline]
214 fn bitor(self, rhs: Self) -> Self::Output {
215 AttributeFlags(self.0 | rhs.0)
216 }
217}
218
219impl std::ops::BitAnd for AttributeFlags {
220 type Output = Self;
221
222 #[inline]
223 fn bitand(self, rhs: Self) -> Self::Output {
224 AttributeFlags(self.0 & rhs.0)
225 }
226}
227
228impl std::ops::BitXor for AttributeFlags {
229 type Output = Self;
230
231 #[inline]
232 fn bitxor(self, rhs: Self) -> Self::Output {
233 AttributeFlags(self.0 ^ rhs.0)
234 }
235}
236
237impl std::ops::Not for AttributeFlags {
238 type Output = Self;
239
240 #[inline]
241 fn not(self) -> Self::Output {
242 AttributeFlags(!self.0)
243 }
244}
245
246impl std::ops::BitOrAssign for AttributeFlags {
247 #[inline]
248 fn bitor_assign(&mut self, rhs: Self) {
249 self.0 |= rhs.0;
250 }
251}
252
253impl std::ops::BitAndAssign for AttributeFlags {
254 #[inline]
255 fn bitand_assign(&mut self, rhs: Self) {
256 self.0 &= rhs.0;
257 }
258}
259
260impl std::ops::BitXorAssign for AttributeFlags {
261 #[inline]
262 fn bitxor_assign(&mut self, rhs: Self) {
263 self.0 ^= rhs.0;
264 }
265}