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 pub const fn contains(self, other: AttributeFlags) -> bool {
78 (self.0 & other.0) == other.0
79 }
80
81 #[inline]
82 pub const fn remove(&mut self, other: AttributeFlags) {
83 self.0 &= !other.0;
84 }
85
86 #[inline]
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 pub const fn bits(self) -> u8 {
105 self.0
106 }
107
108 #[inline]
109 #[must_use]
110 pub const fn all() -> Self {
111 Self(Self::TARGET_ALL.0 | Self::IS_REPEATABLE.0)
112 }
113}
114
115impl AttributeFlags {
116 #[must_use]
119 pub const fn is_repeatable(&self) -> bool {
120 self.contains(Self::IS_REPEATABLE)
121 }
122
123 #[must_use]
126 pub const fn targets_class(&self) -> bool {
127 self.contains(Self::TARGET_CLASS)
128 }
129
130 #[must_use]
133 pub const fn targets_function(&self) -> bool {
134 self.contains(Self::TARGET_FUNCTION)
135 }
136
137 #[must_use]
140 pub const fn targets_method(&self) -> bool {
141 self.contains(Self::TARGET_METHOD)
142 }
143
144 #[must_use]
147 pub const fn targets_property(&self) -> bool {
148 self.contains(Self::TARGET_PROPERTY)
149 }
150
151 #[must_use]
154 pub const fn targets_class_constant(&self) -> bool {
155 self.contains(Self::TARGET_CLASS_CONSTANT)
156 }
157
158 #[must_use]
161 pub const fn targets_parameter(&self) -> bool {
162 self.contains(Self::TARGET_PARAMETER)
163 }
164
165 #[must_use]
168 pub const fn targets_constant(&self) -> bool {
169 self.contains(Self::TARGET_CONSTANT)
170 }
171
172 #[must_use]
174 pub fn get_target_names(&self) -> Vec<&'static str> {
175 let mut targets = Vec::with_capacity(7);
176
177 if self.targets_class() {
178 targets.push("classes");
179 }
180
181 if self.targets_function() {
182 targets.push("functions");
183 }
184
185 if self.targets_method() {
186 targets.push("methods");
187 }
188
189 if self.targets_property() {
190 targets.push("properties");
191 }
192
193 if self.targets_class_constant() {
194 targets.push("class constants");
195 }
196
197 if self.targets_parameter() {
198 targets.push("parameters");
199 }
200
201 if self.targets_constant() {
202 targets.push("global constants");
203 }
204
205 targets
206 }
207}
208
209impl std::ops::BitOr for AttributeFlags {
210 type Output = Self;
211
212 #[inline]
213 fn bitor(self, rhs: Self) -> Self::Output {
214 AttributeFlags(self.0 | rhs.0)
215 }
216}
217
218impl std::ops::BitAnd for AttributeFlags {
219 type Output = Self;
220
221 #[inline]
222 fn bitand(self, rhs: Self) -> Self::Output {
223 AttributeFlags(self.0 & rhs.0)
224 }
225}
226
227impl std::ops::BitXor for AttributeFlags {
228 type Output = Self;
229
230 #[inline]
231 fn bitxor(self, rhs: Self) -> Self::Output {
232 AttributeFlags(self.0 ^ rhs.0)
233 }
234}
235
236impl std::ops::Not for AttributeFlags {
237 type Output = Self;
238
239 #[inline]
240 fn not(self) -> Self::Output {
241 AttributeFlags(!self.0)
242 }
243}
244
245impl std::ops::BitOrAssign for AttributeFlags {
246 #[inline]
247 fn bitor_assign(&mut self, rhs: Self) {
248 self.0 |= rhs.0;
249 }
250}
251
252impl std::ops::BitAndAssign for AttributeFlags {
253 #[inline]
254 fn bitand_assign(&mut self, rhs: Self) {
255 self.0 &= rhs.0;
256 }
257}
258
259impl std::ops::BitXorAssign for AttributeFlags {
260 #[inline]
261 fn bitxor_assign(&mut self, rhs: Self) {
262 self.0 ^= rhs.0;
263 }
264}