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