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 bits(self) -> u8 {
88 self.0
89 }
90
91 #[inline]
92 #[must_use]
93 pub const fn all() -> Self {
94 Self(Self::TARGET_ALL.0 | Self::IS_REPEATABLE.0)
95 }
96}
97
98impl AttributeFlags {
99 #[must_use]
102 pub const fn is_repeatable(&self) -> bool {
103 self.contains(Self::IS_REPEATABLE)
104 }
105
106 #[must_use]
109 pub const fn targets_class(&self) -> bool {
110 self.contains(Self::TARGET_CLASS)
111 }
112
113 #[must_use]
116 pub const fn targets_function(&self) -> bool {
117 self.contains(Self::TARGET_FUNCTION)
118 }
119
120 #[must_use]
123 pub const fn targets_method(&self) -> bool {
124 self.contains(Self::TARGET_METHOD)
125 }
126
127 #[must_use]
130 pub const fn targets_property(&self) -> bool {
131 self.contains(Self::TARGET_PROPERTY)
132 }
133
134 #[must_use]
137 pub const fn targets_class_constant(&self) -> bool {
138 self.contains(Self::TARGET_CLASS_CONSTANT)
139 }
140
141 #[must_use]
144 pub const fn targets_parameter(&self) -> bool {
145 self.contains(Self::TARGET_PARAMETER)
146 }
147
148 #[must_use]
151 pub const fn targets_constant(&self) -> bool {
152 self.contains(Self::TARGET_CONSTANT)
153 }
154
155 #[must_use]
157 pub fn get_target_names(&self) -> Vec<&'static str> {
158 let mut targets = Vec::with_capacity(7);
159
160 if self.targets_class() {
161 targets.push("classes");
162 }
163
164 if self.targets_function() {
165 targets.push("functions");
166 }
167
168 if self.targets_method() {
169 targets.push("methods");
170 }
171
172 if self.targets_property() {
173 targets.push("properties");
174 }
175
176 if self.targets_class_constant() {
177 targets.push("class constants");
178 }
179
180 if self.targets_parameter() {
181 targets.push("parameters");
182 }
183
184 if self.targets_constant() {
185 targets.push("global constants");
186 }
187
188 targets
189 }
190}
191
192impl std::ops::BitOr for AttributeFlags {
193 type Output = Self;
194
195 #[inline]
196 fn bitor(self, rhs: Self) -> Self::Output {
197 AttributeFlags(self.0 | rhs.0)
198 }
199}
200
201impl std::ops::BitAnd for AttributeFlags {
202 type Output = Self;
203
204 #[inline]
205 fn bitand(self, rhs: Self) -> Self::Output {
206 AttributeFlags(self.0 & rhs.0)
207 }
208}
209
210impl std::ops::BitXor for AttributeFlags {
211 type Output = Self;
212
213 #[inline]
214 fn bitxor(self, rhs: Self) -> Self::Output {
215 AttributeFlags(self.0 ^ rhs.0)
216 }
217}
218
219impl std::ops::Not for AttributeFlags {
220 type Output = Self;
221
222 #[inline]
223 fn not(self) -> Self::Output {
224 AttributeFlags(!self.0)
225 }
226}
227
228impl std::ops::BitOrAssign for AttributeFlags {
229 #[inline]
230 fn bitor_assign(&mut self, rhs: Self) {
231 self.0 |= rhs.0;
232 }
233}
234
235impl std::ops::BitAndAssign for AttributeFlags {
236 #[inline]
237 fn bitand_assign(&mut self, rhs: Self) {
238 self.0 &= rhs.0;
239 }
240}
241
242impl std::ops::BitXorAssign for AttributeFlags {
243 #[inline]
244 fn bitxor_assign(&mut self, rhs: Self) {
245 self.0 ^= rhs.0;
246 }
247}