Skip to main content

mago_codex/metadata/
flags.rs

1use mago_database::file::FileType;
2
3#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
4#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
5pub struct MetadataFlags(u64);
6
7impl MetadataFlags {
8    pub const ABSTRACT: MetadataFlags = MetadataFlags(1 << 0);
9    pub const FINAL: MetadataFlags = MetadataFlags(1 << 1);
10    pub const READONLY: MetadataFlags = MetadataFlags(1 << 3);
11    pub const DEPRECATED: MetadataFlags = MetadataFlags(1 << 4);
12    pub const ENUM_INTERFACE: MetadataFlags = MetadataFlags(1 << 5);
13    pub const POPULATED: MetadataFlags = MetadataFlags(1 << 6);
14    pub const INTERNAL: MetadataFlags = MetadataFlags(1 << 7);
15    pub const CONSISTENT_CONSTRUCTOR: MetadataFlags = MetadataFlags(1 << 11);
16    pub const CONSISTENT_TEMPLATES: MetadataFlags = MetadataFlags(1 << 12);
17    pub const UNCHECKED: MetadataFlags = MetadataFlags(1 << 13);
18    pub const USER_DEFINED: MetadataFlags = MetadataFlags(1 << 14);
19    pub const BUILTIN: MetadataFlags = MetadataFlags(1 << 15);
20    pub const HAS_YIELD: MetadataFlags = MetadataFlags(1 << 16);
21    pub const MUST_USE: MetadataFlags = MetadataFlags(1 << 17);
22    pub const HAS_THROW: MetadataFlags = MetadataFlags(1 << 18);
23    pub const PURE: MetadataFlags = MetadataFlags(1 << 19);
24    pub const IGNORE_NULLABLE_RETURN: MetadataFlags = MetadataFlags(1 << 20);
25    pub const IGNORE_FALSABLE_RETURN: MetadataFlags = MetadataFlags(1 << 21);
26    pub const INHERITS_DOCS: MetadataFlags = MetadataFlags(1 << 22);
27    pub const NO_NAMED_ARGUMENTS: MetadataFlags = MetadataFlags(1 << 23);
28    pub const BACKED_ENUM_CASE: MetadataFlags = MetadataFlags(1 << 24);
29    pub const UNIT_ENUM_CASE: MetadataFlags = MetadataFlags(1 << 25);
30    pub const BY_REFERENCE: MetadataFlags = MetadataFlags(1 << 26);
31    pub const VARIADIC: MetadataFlags = MetadataFlags(1 << 27);
32    pub const PROMOTED_PROPERTY: MetadataFlags = MetadataFlags(1 << 28);
33    pub const HAS_DEFAULT: MetadataFlags = MetadataFlags(1 << 29);
34    pub const VIRTUAL_PROPERTY: MetadataFlags = MetadataFlags(1 << 30);
35    pub const ASYMMETRIC_PROPERTY: MetadataFlags = MetadataFlags(1 << 31);
36    pub const STATIC: MetadataFlags = MetadataFlags(1 << 32);
37    pub const WRITEONLY: MetadataFlags = MetadataFlags(1 << 33);
38    pub const MAGIC_PROPERTY: MetadataFlags = MetadataFlags(1 << 34);
39    pub const MAGIC_METHOD: MetadataFlags = MetadataFlags(1 << 35);
40    pub const API: MetadataFlags = MetadataFlags(1 << 36);
41    pub const MUTATION_FREE: MetadataFlags = MetadataFlags(1 << 37);
42    pub const EXTERNAL_MUTATION_FREE: MetadataFlags = MetadataFlags(1 << 38);
43    pub const SUSPENDS_FIBER: MetadataFlags = MetadataFlags(1 << 39);
44    pub const EXPERIMENTAL: MetadataFlags = MetadataFlags(1 << 40);
45    pub const POLYFILL: MetadataFlags = MetadataFlags(1 << 41);
46    pub const PATCH: MetadataFlags = MetadataFlags(1 << 42);
47}
48
49impl MetadataFlags {
50    #[inline]
51    #[must_use]
52    pub const fn empty() -> Self {
53        MetadataFlags(0)
54    }
55
56    #[inline]
57    pub const fn insert(&mut self, other: MetadataFlags) {
58        self.0 |= other.0;
59    }
60
61    #[inline]
62    pub const fn set(&mut self, other: MetadataFlags, value: bool) {
63        if value {
64            self.insert(other);
65        } else {
66            self.0 &= !other.0;
67        }
68    }
69
70    #[inline]
71    #[must_use]
72    pub const fn contains(self, other: MetadataFlags) -> bool {
73        (self.0 & other.0) == other.0
74    }
75
76    #[inline]
77    pub const fn remove(&mut self, other: MetadataFlags) {
78        self.0 &= !other.0;
79    }
80
81    #[inline]
82    #[must_use]
83    pub const fn intersects(self, other: MetadataFlags) -> bool {
84        (self.0 & other.0) != 0
85    }
86
87    #[inline]
88    #[must_use]
89    pub const fn union(&self, other: MetadataFlags) -> MetadataFlags {
90        MetadataFlags(self.0 | other.0)
91    }
92
93    #[inline]
94    #[must_use]
95    pub const fn intersection(&self, other: MetadataFlags) -> MetadataFlags {
96        MetadataFlags(self.0 & other.0)
97    }
98}
99
100impl MetadataFlags {
101    #[inline]
102    #[must_use]
103    pub const fn is_deprecated(self) -> bool {
104        self.contains(Self::DEPRECATED)
105    }
106
107    #[inline]
108    #[must_use]
109    pub const fn is_abstract(self) -> bool {
110        self.contains(Self::ABSTRACT)
111    }
112
113    #[inline]
114    #[must_use]
115    pub const fn is_final(self) -> bool {
116        self.contains(Self::FINAL)
117    }
118
119    #[inline]
120    #[must_use]
121    pub const fn has_yield(self) -> bool {
122        self.contains(Self::HAS_YIELD)
123    }
124
125    #[inline]
126    #[must_use]
127    pub const fn must_use(self) -> bool {
128        self.contains(Self::MUST_USE)
129    }
130
131    #[inline]
132    #[must_use]
133    pub const fn is_pure(self) -> bool {
134        self.contains(Self::PURE)
135    }
136
137    #[inline]
138    #[must_use]
139    pub const fn has_consistent_constructor(self) -> bool {
140        self.contains(Self::CONSISTENT_CONSTRUCTOR)
141    }
142
143    #[inline]
144    #[must_use]
145    pub const fn has_consistent_templates(self) -> bool {
146        self.contains(Self::CONSISTENT_TEMPLATES)
147    }
148
149    #[inline]
150    #[must_use]
151    pub const fn is_user_defined(self) -> bool {
152        self.contains(Self::USER_DEFINED)
153    }
154
155    #[inline]
156    #[must_use]
157    pub const fn is_built_in(self) -> bool {
158        self.contains(Self::BUILTIN)
159    }
160
161    #[inline]
162    #[must_use]
163    pub const fn is_internal(self) -> bool {
164        self.contains(Self::INTERNAL)
165    }
166
167    #[inline]
168    #[must_use]
169    pub const fn is_populated(self) -> bool {
170        self.contains(Self::POPULATED)
171    }
172
173    #[inline]
174    #[must_use]
175    pub const fn is_readonly(self) -> bool {
176        self.contains(Self::READONLY)
177    }
178
179    #[inline]
180    #[must_use]
181    pub const fn is_writeonly(self) -> bool {
182        self.contains(Self::WRITEONLY)
183    }
184
185    #[inline]
186    #[must_use]
187    pub const fn is_enum_interface(self) -> bool {
188        self.contains(Self::ENUM_INTERFACE)
189    }
190
191    #[inline]
192    #[must_use]
193    pub const fn is_unchecked(self) -> bool {
194        self.contains(Self::UNCHECKED)
195    }
196
197    #[inline]
198    #[must_use]
199    pub const fn ignore_nullable_return(self) -> bool {
200        self.contains(Self::IGNORE_NULLABLE_RETURN)
201    }
202
203    #[inline]
204    #[must_use]
205    pub const fn ignore_falsable_return(self) -> bool {
206        self.contains(Self::IGNORE_FALSABLE_RETURN)
207    }
208
209    #[inline]
210    #[must_use]
211    pub const fn inherits_docs(self) -> bool {
212        self.contains(Self::INHERITS_DOCS)
213    }
214
215    #[inline]
216    #[must_use]
217    pub const fn forbids_named_arguments(self) -> bool {
218        self.contains(Self::NO_NAMED_ARGUMENTS)
219    }
220
221    #[inline]
222    #[must_use]
223    pub const fn has_throw(self) -> bool {
224        self.contains(Self::HAS_THROW)
225    }
226
227    #[inline]
228    #[must_use]
229    pub const fn is_backed_enum_case(self) -> bool {
230        self.contains(Self::BACKED_ENUM_CASE)
231    }
232
233    #[inline]
234    #[must_use]
235    pub const fn is_unit_enum_case(self) -> bool {
236        self.contains(Self::UNIT_ENUM_CASE)
237    }
238
239    #[inline]
240    #[must_use]
241    pub const fn is_by_reference(self) -> bool {
242        self.contains(Self::BY_REFERENCE)
243    }
244
245    #[inline]
246    #[must_use]
247    pub const fn is_variadic(self) -> bool {
248        self.contains(Self::VARIADIC)
249    }
250
251    #[inline]
252    #[must_use]
253    pub const fn is_promoted_property(self) -> bool {
254        self.contains(Self::PROMOTED_PROPERTY)
255    }
256
257    #[inline]
258    #[must_use]
259    pub const fn has_default(self) -> bool {
260        self.contains(Self::HAS_DEFAULT)
261    }
262
263    #[inline]
264    #[must_use]
265    pub const fn is_virtual_property(self) -> bool {
266        self.contains(Self::VIRTUAL_PROPERTY)
267    }
268
269    #[inline]
270    #[must_use]
271    pub const fn is_magic_property(self) -> bool {
272        self.contains(Self::MAGIC_PROPERTY)
273    }
274
275    #[inline]
276    #[must_use]
277    pub const fn is_magic_method(self) -> bool {
278        self.contains(Self::MAGIC_METHOD)
279    }
280
281    #[inline]
282    #[must_use]
283    pub const fn is_asymmetric_property(self) -> bool {
284        self.contains(Self::ASYMMETRIC_PROPERTY)
285    }
286
287    #[inline]
288    #[must_use]
289    pub const fn is_static(self) -> bool {
290        self.contains(Self::STATIC)
291    }
292
293    #[inline]
294    #[must_use]
295    pub const fn is_public_api(self) -> bool {
296        self.contains(Self::API)
297    }
298
299    #[inline]
300    #[must_use]
301    pub const fn is_experimental(self) -> bool {
302        self.contains(Self::EXPERIMENTAL)
303    }
304
305    #[inline]
306    #[must_use]
307    pub const fn is_mutation_free(self) -> bool {
308        self.contains(Self::MUTATION_FREE)
309    }
310
311    #[inline]
312    #[must_use]
313    pub const fn is_external_mutation_free(self) -> bool {
314        self.contains(Self::EXTERNAL_MUTATION_FREE)
315    }
316
317    #[inline]
318    #[must_use]
319    pub const fn suspends_fiber(self) -> bool {
320        self.contains(Self::SUSPENDS_FIBER)
321    }
322
323    #[inline]
324    #[must_use]
325    pub const fn is_polyfill(self) -> bool {
326        self.contains(Self::POLYFILL)
327    }
328
329    #[inline]
330    #[must_use]
331    pub const fn is_patch(self) -> bool {
332        self.contains(Self::PATCH)
333    }
334
335    #[inline]
336    #[must_use]
337    pub const fn origin_flags(file_type: FileType) -> Self {
338        match file_type {
339            FileType::Host => Self::USER_DEFINED,
340            FileType::Builtin => Self::BUILTIN,
341            FileType::Patch => Self::PATCH,
342            FileType::Vendored => Self::empty(),
343        }
344    }
345}
346
347impl std::ops::BitOr for MetadataFlags {
348    type Output = Self;
349
350    #[inline]
351    fn bitor(self, rhs: Self) -> Self::Output {
352        MetadataFlags(self.0 | rhs.0)
353    }
354}
355
356impl std::ops::BitAnd for MetadataFlags {
357    type Output = Self;
358
359    #[inline]
360    fn bitand(self, rhs: Self) -> Self::Output {
361        MetadataFlags(self.0 & rhs.0)
362    }
363}
364
365impl std::ops::BitXor for MetadataFlags {
366    type Output = Self;
367
368    #[inline]
369    fn bitxor(self, rhs: Self) -> Self::Output {
370        MetadataFlags(self.0 ^ rhs.0)
371    }
372}
373
374impl std::ops::Not for MetadataFlags {
375    type Output = Self;
376
377    #[inline]
378    fn not(self) -> Self::Output {
379        MetadataFlags(!self.0)
380    }
381}
382
383impl std::ops::BitOrAssign for MetadataFlags {
384    #[inline]
385    fn bitor_assign(&mut self, rhs: Self) {
386        self.0 |= rhs.0;
387    }
388}
389
390impl std::ops::BitAndAssign for MetadataFlags {
391    #[inline]
392    fn bitand_assign(&mut self, rhs: Self) {
393        self.0 &= rhs.0;
394    }
395}
396
397impl std::ops::BitXorAssign for MetadataFlags {
398    #[inline]
399    fn bitxor_assign(&mut self, rhs: Self) {
400        self.0 ^= rhs.0;
401    }
402}