1 | //! Generate the user-facing flags type. |
2 | //! |
3 | //! The code here belongs to the end-user, so new trait implementations and methods can't be |
4 | //! added without potentially breaking users. |
5 | |
6 | /// Declare the user-facing bitflags struct. |
7 | /// |
8 | /// This type is guaranteed to be a newtype with a `bitflags`-facing type as its single field. |
9 | #[macro_export ] |
10 | #[doc (hidden)] |
11 | macro_rules! __declare_public_bitflags { |
12 | ( |
13 | $(#[$outer:meta])* |
14 | $vis:vis struct $PublicBitFlags:ident |
15 | ) => { |
16 | $(#[$outer])* |
17 | $vis struct $PublicBitFlags(<$PublicBitFlags as $crate::__private::PublicFlags>::Internal); |
18 | }; |
19 | } |
20 | |
21 | /// Implement functions on the public (user-facing) bitflags type. |
22 | /// |
23 | /// We need to be careful about adding new methods and trait implementations here because they |
24 | /// could conflict with items added by the end-user. |
25 | #[macro_export ] |
26 | #[doc (hidden)] |
27 | macro_rules! __impl_public_bitflags_forward { |
28 | ( |
29 | $PublicBitFlags:ident: $T:ty, $InternalBitFlags:ident |
30 | ) => { |
31 | $crate::__impl_bitflags! { |
32 | $PublicBitFlags: $T { |
33 | fn empty() { |
34 | Self($InternalBitFlags::empty()) |
35 | } |
36 | |
37 | fn all() { |
38 | Self($InternalBitFlags::all()) |
39 | } |
40 | |
41 | fn bits(f) { |
42 | f.0.bits() |
43 | } |
44 | |
45 | fn from_bits(bits) { |
46 | match $InternalBitFlags::from_bits(bits) { |
47 | $crate::__private::core::option::Option::Some(bits) => $crate::__private::core::option::Option::Some(Self(bits)), |
48 | $crate::__private::core::option::Option::None => $crate::__private::core::option::Option::None, |
49 | } |
50 | } |
51 | |
52 | fn from_bits_truncate(bits) { |
53 | Self($InternalBitFlags::from_bits_truncate(bits)) |
54 | } |
55 | |
56 | fn from_bits_retain(bits) { |
57 | Self($InternalBitFlags::from_bits_retain(bits)) |
58 | } |
59 | |
60 | fn from_name(name) { |
61 | match $InternalBitFlags::from_name(name) { |
62 | $crate::__private::core::option::Option::Some(bits) => $crate::__private::core::option::Option::Some(Self(bits)), |
63 | $crate::__private::core::option::Option::None => $crate::__private::core::option::Option::None, |
64 | } |
65 | } |
66 | |
67 | fn is_empty(f) { |
68 | f.0.is_empty() |
69 | } |
70 | |
71 | fn is_all(f) { |
72 | f.0.is_all() |
73 | } |
74 | |
75 | fn intersects(f, other) { |
76 | f.0.intersects(other.0) |
77 | } |
78 | |
79 | fn contains(f, other) { |
80 | f.0.contains(other.0) |
81 | } |
82 | |
83 | fn insert(f, other) { |
84 | f.0.insert(other.0) |
85 | } |
86 | |
87 | fn remove(f, other) { |
88 | f.0.remove(other.0) |
89 | } |
90 | |
91 | fn toggle(f, other) { |
92 | f.0.toggle(other.0) |
93 | } |
94 | |
95 | fn set(f, other, value) { |
96 | f.0.set(other.0, value) |
97 | } |
98 | |
99 | fn intersection(f, other) { |
100 | Self(f.0.intersection(other.0)) |
101 | } |
102 | |
103 | fn union(f, other) { |
104 | Self(f.0.union(other.0)) |
105 | } |
106 | |
107 | fn difference(f, other) { |
108 | Self(f.0.difference(other.0)) |
109 | } |
110 | |
111 | fn symmetric_difference(f, other) { |
112 | Self(f.0.symmetric_difference(other.0)) |
113 | } |
114 | |
115 | fn complement(f) { |
116 | Self(f.0.complement()) |
117 | } |
118 | } |
119 | } |
120 | }; |
121 | } |
122 | |
123 | /// Implement functions on the public (user-facing) bitflags type. |
124 | /// |
125 | /// We need to be careful about adding new methods and trait implementations here because they |
126 | /// could conflict with items added by the end-user. |
127 | #[macro_export ] |
128 | #[doc (hidden)] |
129 | macro_rules! __impl_public_bitflags { |
130 | ( |
131 | $BitFlags:ident: $T:ty, $PublicBitFlags:ident { |
132 | $( |
133 | $(#[$inner:ident $($args:tt)*])* |
134 | const $Flag:tt = $value:expr; |
135 | )* |
136 | } |
137 | ) => { |
138 | $crate::__impl_bitflags! { |
139 | $BitFlags: $T { |
140 | fn empty() { |
141 | Self(<$T as $crate::Bits>::EMPTY) |
142 | } |
143 | |
144 | fn all() { |
145 | let mut truncated = <$T as $crate::Bits>::EMPTY; |
146 | let mut i = 0; |
147 | |
148 | $( |
149 | $crate::__bitflags_expr_safe_attrs!( |
150 | $(#[$inner $($args)*])* |
151 | {{ |
152 | let flag = <$PublicBitFlags as $crate::Flags>::FLAGS[i].value().bits(); |
153 | |
154 | truncated = truncated | flag; |
155 | i += 1; |
156 | }} |
157 | ); |
158 | )* |
159 | |
160 | let _ = i; |
161 | Self::from_bits_retain(truncated) |
162 | } |
163 | |
164 | fn bits(f) { |
165 | f.0 |
166 | } |
167 | |
168 | fn from_bits(bits) { |
169 | let truncated = Self::from_bits_truncate(bits).0; |
170 | |
171 | if truncated == bits { |
172 | $crate::__private::core::option::Option::Some(Self(bits)) |
173 | } else { |
174 | $crate::__private::core::option::Option::None |
175 | } |
176 | } |
177 | |
178 | fn from_bits_truncate(bits) { |
179 | Self(bits & Self::all().bits()) |
180 | } |
181 | |
182 | fn from_bits_retain(bits) { |
183 | Self(bits) |
184 | } |
185 | |
186 | fn from_name(name) { |
187 | $( |
188 | $crate::__bitflags_flag!({ |
189 | name: $Flag, |
190 | named: { |
191 | $crate::__bitflags_expr_safe_attrs!( |
192 | $(#[$inner $($args)*])* |
193 | { |
194 | if name == $crate::__private::core::stringify!($Flag) { |
195 | return $crate::__private::core::option::Option::Some(Self($PublicBitFlags::$Flag.bits())); |
196 | } |
197 | } |
198 | ); |
199 | }, |
200 | unnamed: {}, |
201 | }); |
202 | )* |
203 | |
204 | let _ = name; |
205 | $crate::__private::core::option::Option::None |
206 | } |
207 | |
208 | fn is_empty(f) { |
209 | f.bits() == <$T as $crate::Bits>::EMPTY |
210 | } |
211 | |
212 | fn is_all(f) { |
213 | // NOTE: We check against `Self::all` here, not `Self::Bits::ALL` |
214 | // because the set of all flags may not use all bits |
215 | Self::all().bits() | f.bits() == f.bits() |
216 | } |
217 | |
218 | fn intersects(f, other) { |
219 | f.bits() & other.bits() != <$T as $crate::Bits>::EMPTY |
220 | } |
221 | |
222 | fn contains(f, other) { |
223 | f.bits() & other.bits() == other.bits() |
224 | } |
225 | |
226 | fn insert(f, other) { |
227 | *f = Self::from_bits_retain(f.bits()).union(other); |
228 | } |
229 | |
230 | fn remove(f, other) { |
231 | *f = Self::from_bits_retain(f.bits()).difference(other); |
232 | } |
233 | |
234 | fn toggle(f, other) { |
235 | *f = Self::from_bits_retain(f.bits()).symmetric_difference(other); |
236 | } |
237 | |
238 | fn set(f, other, value) { |
239 | if value { |
240 | f.insert(other); |
241 | } else { |
242 | f.remove(other); |
243 | } |
244 | } |
245 | |
246 | fn intersection(f, other) { |
247 | Self::from_bits_retain(f.bits() & other.bits()) |
248 | } |
249 | |
250 | fn union(f, other) { |
251 | Self::from_bits_retain(f.bits() | other.bits()) |
252 | } |
253 | |
254 | fn difference(f, other) { |
255 | Self::from_bits_retain(f.bits() & !other.bits()) |
256 | } |
257 | |
258 | fn symmetric_difference(f, other) { |
259 | Self::from_bits_retain(f.bits() ^ other.bits()) |
260 | } |
261 | |
262 | fn complement(f) { |
263 | Self::from_bits_truncate(!f.bits()) |
264 | } |
265 | } |
266 | } |
267 | }; |
268 | } |
269 | |
270 | /// Implement iterators on the public (user-facing) bitflags type. |
271 | #[macro_export ] |
272 | #[doc (hidden)] |
273 | macro_rules! __impl_public_bitflags_iter { |
274 | ($BitFlags:ident: $T:ty, $PublicBitFlags:ident) => { |
275 | impl $BitFlags { |
276 | /// Yield a set of contained flags values. |
277 | /// |
278 | /// Each yielded flags value will correspond to a defined named flag. Any unknown bits |
279 | /// will be yielded together as a final flags value. |
280 | #[inline] |
281 | pub const fn iter(&self) -> $crate::iter::Iter<$PublicBitFlags> { |
282 | $crate::iter::Iter::__private_const_new( |
283 | <$PublicBitFlags as $crate::Flags>::FLAGS, |
284 | $PublicBitFlags::from_bits_retain(self.bits()), |
285 | $PublicBitFlags::from_bits_retain(self.bits()), |
286 | ) |
287 | } |
288 | |
289 | /// Yield a set of contained named flags values. |
290 | /// |
291 | /// This method is like [`iter`](#method.iter), except only yields bits in contained named flags. |
292 | /// Any unknown bits, or bits not corresponding to a contained flag will not be yielded. |
293 | #[inline] |
294 | pub const fn iter_names(&self) -> $crate::iter::IterNames<$PublicBitFlags> { |
295 | $crate::iter::IterNames::__private_const_new( |
296 | <$PublicBitFlags as $crate::Flags>::FLAGS, |
297 | $PublicBitFlags::from_bits_retain(self.bits()), |
298 | $PublicBitFlags::from_bits_retain(self.bits()), |
299 | ) |
300 | } |
301 | } |
302 | |
303 | impl $crate::__private::core::iter::IntoIterator for $BitFlags { |
304 | type Item = $PublicBitFlags; |
305 | type IntoIter = $crate::iter::Iter<$PublicBitFlags>; |
306 | |
307 | fn into_iter(self) -> Self::IntoIter { |
308 | self.iter() |
309 | } |
310 | } |
311 | }; |
312 | } |
313 | |
314 | /// Implement traits on the public (user-facing) bitflags type. |
315 | #[macro_export ] |
316 | #[doc (hidden)] |
317 | macro_rules! __impl_public_bitflags_ops { |
318 | ($PublicBitFlags:ident) => { |
319 | impl $crate::__private::core::fmt::Binary for $PublicBitFlags { |
320 | fn fmt( |
321 | &self, |
322 | f: &mut $crate::__private::core::fmt::Formatter, |
323 | ) -> $crate::__private::core::fmt::Result { |
324 | let inner = self.0; |
325 | $crate::__private::core::fmt::Binary::fmt(&inner, f) |
326 | } |
327 | } |
328 | |
329 | impl $crate::__private::core::fmt::Octal for $PublicBitFlags { |
330 | fn fmt( |
331 | &self, |
332 | f: &mut $crate::__private::core::fmt::Formatter, |
333 | ) -> $crate::__private::core::fmt::Result { |
334 | let inner = self.0; |
335 | $crate::__private::core::fmt::Octal::fmt(&inner, f) |
336 | } |
337 | } |
338 | |
339 | impl $crate::__private::core::fmt::LowerHex for $PublicBitFlags { |
340 | fn fmt( |
341 | &self, |
342 | f: &mut $crate::__private::core::fmt::Formatter, |
343 | ) -> $crate::__private::core::fmt::Result { |
344 | let inner = self.0; |
345 | $crate::__private::core::fmt::LowerHex::fmt(&inner, f) |
346 | } |
347 | } |
348 | |
349 | impl $crate::__private::core::fmt::UpperHex for $PublicBitFlags { |
350 | fn fmt( |
351 | &self, |
352 | f: &mut $crate::__private::core::fmt::Formatter, |
353 | ) -> $crate::__private::core::fmt::Result { |
354 | let inner = self.0; |
355 | $crate::__private::core::fmt::UpperHex::fmt(&inner, f) |
356 | } |
357 | } |
358 | |
359 | impl $crate::__private::core::ops::BitOr for $PublicBitFlags { |
360 | type Output = Self; |
361 | |
362 | /// The bitwise or (`|`) of the bits in two flags values. |
363 | #[inline] |
364 | fn bitor(self, other: $PublicBitFlags) -> Self { |
365 | self.union(other) |
366 | } |
367 | } |
368 | |
369 | impl $crate::__private::core::ops::BitOrAssign for $PublicBitFlags { |
370 | /// The bitwise or (`|`) of the bits in two flags values. |
371 | #[inline] |
372 | fn bitor_assign(&mut self, other: Self) { |
373 | self.insert(other); |
374 | } |
375 | } |
376 | |
377 | impl $crate::__private::core::ops::BitXor for $PublicBitFlags { |
378 | type Output = Self; |
379 | |
380 | /// The bitwise exclusive-or (`^`) of the bits in two flags values. |
381 | #[inline] |
382 | fn bitxor(self, other: Self) -> Self { |
383 | self.symmetric_difference(other) |
384 | } |
385 | } |
386 | |
387 | impl $crate::__private::core::ops::BitXorAssign for $PublicBitFlags { |
388 | /// The bitwise exclusive-or (`^`) of the bits in two flags values. |
389 | #[inline] |
390 | fn bitxor_assign(&mut self, other: Self) { |
391 | self.toggle(other); |
392 | } |
393 | } |
394 | |
395 | impl $crate::__private::core::ops::BitAnd for $PublicBitFlags { |
396 | type Output = Self; |
397 | |
398 | /// The bitwise and (`&`) of the bits in two flags values. |
399 | #[inline] |
400 | fn bitand(self, other: Self) -> Self { |
401 | self.intersection(other) |
402 | } |
403 | } |
404 | |
405 | impl $crate::__private::core::ops::BitAndAssign for $PublicBitFlags { |
406 | /// The bitwise and (`&`) of the bits in two flags values. |
407 | #[inline] |
408 | fn bitand_assign(&mut self, other: Self) { |
409 | *self = Self::from_bits_retain(self.bits()).intersection(other); |
410 | } |
411 | } |
412 | |
413 | impl $crate::__private::core::ops::Sub for $PublicBitFlags { |
414 | type Output = Self; |
415 | |
416 | /// The intersection of a source flags value with the complement of a target flags value (`&!`). |
417 | /// |
418 | /// This method is not equivalent to `self & !other` when `other` has unknown bits set. |
419 | /// `difference` won't truncate `other`, but the `!` operator will. |
420 | #[inline] |
421 | fn sub(self, other: Self) -> Self { |
422 | self.difference(other) |
423 | } |
424 | } |
425 | |
426 | impl $crate::__private::core::ops::SubAssign for $PublicBitFlags { |
427 | /// The intersection of a source flags value with the complement of a target flags value (`&!`). |
428 | /// |
429 | /// This method is not equivalent to `self & !other` when `other` has unknown bits set. |
430 | /// `difference` won't truncate `other`, but the `!` operator will. |
431 | #[inline] |
432 | fn sub_assign(&mut self, other: Self) { |
433 | self.remove(other); |
434 | } |
435 | } |
436 | |
437 | impl $crate::__private::core::ops::Not for $PublicBitFlags { |
438 | type Output = Self; |
439 | |
440 | /// The bitwise negation (`!`) of the bits in a flags value, truncating the result. |
441 | #[inline] |
442 | fn not(self) -> Self { |
443 | self.complement() |
444 | } |
445 | } |
446 | |
447 | impl $crate::__private::core::iter::Extend<$PublicBitFlags> for $PublicBitFlags { |
448 | /// The bitwise or (`|`) of the bits in each flags value. |
449 | fn extend<T: $crate::__private::core::iter::IntoIterator<Item = Self>>( |
450 | &mut self, |
451 | iterator: T, |
452 | ) { |
453 | for item in iterator { |
454 | self.insert(item) |
455 | } |
456 | } |
457 | } |
458 | |
459 | impl $crate::__private::core::iter::FromIterator<$PublicBitFlags> for $PublicBitFlags { |
460 | /// The bitwise or (`|`) of the bits in each flags value. |
461 | fn from_iter<T: $crate::__private::core::iter::IntoIterator<Item = Self>>( |
462 | iterator: T, |
463 | ) -> Self { |
464 | use $crate::__private::core::iter::Extend; |
465 | |
466 | let mut result = Self::empty(); |
467 | result.extend(iterator); |
468 | result |
469 | } |
470 | } |
471 | }; |
472 | } |
473 | |
474 | /// Implement constants on the public (user-facing) bitflags type. |
475 | #[macro_export ] |
476 | #[doc (hidden)] |
477 | macro_rules! __impl_public_bitflags_consts { |
478 | ( |
479 | $PublicBitFlags:ident: $T:ty { |
480 | $( |
481 | $(#[$inner:ident $($args:tt)*])* |
482 | const $Flag:tt = $value:expr; |
483 | )* |
484 | } |
485 | ) => { |
486 | impl $PublicBitFlags { |
487 | $( |
488 | $crate::__bitflags_flag!({ |
489 | name: $Flag, |
490 | named: { |
491 | $(#[$inner $($args)*])* |
492 | #[allow( |
493 | deprecated, |
494 | non_upper_case_globals, |
495 | )] |
496 | pub const $Flag: Self = Self::from_bits_retain($value); |
497 | }, |
498 | unnamed: {}, |
499 | }); |
500 | )* |
501 | } |
502 | |
503 | impl $crate::Flags for $PublicBitFlags { |
504 | const FLAGS: &'static [$crate::Flag<$PublicBitFlags>] = &[ |
505 | $( |
506 | $crate::__bitflags_flag!({ |
507 | name: $Flag, |
508 | named: { |
509 | $crate::__bitflags_expr_safe_attrs!( |
510 | $(#[$inner $($args)*])* |
511 | { |
512 | #[allow( |
513 | deprecated, |
514 | non_upper_case_globals, |
515 | )] |
516 | $crate::Flag::new($crate::__private::core::stringify!($Flag), $PublicBitFlags::$Flag) |
517 | } |
518 | ) |
519 | }, |
520 | unnamed: { |
521 | $crate::__bitflags_expr_safe_attrs!( |
522 | $(#[$inner $($args)*])* |
523 | { |
524 | #[allow( |
525 | deprecated, |
526 | non_upper_case_globals, |
527 | )] |
528 | $crate::Flag::new("" , $PublicBitFlags::from_bits_retain($value)) |
529 | } |
530 | ) |
531 | }, |
532 | }), |
533 | )* |
534 | ]; |
535 | |
536 | type Bits = $T; |
537 | |
538 | fn bits(&self) -> $T { |
539 | $PublicBitFlags::bits(self) |
540 | } |
541 | |
542 | fn from_bits_retain(bits: $T) -> $PublicBitFlags { |
543 | $PublicBitFlags::from_bits_retain(bits) |
544 | } |
545 | } |
546 | }; |
547 | } |
548 | |