1 | // Copyright 2014 The Rust Project Developers. See the COPYRIGHT |
2 | // file at the top-level directory of this distribution and at |
3 | // http://rust-lang.org/COPYRIGHT. |
4 | // |
5 | // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or |
6 | // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license |
7 | // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your |
8 | // option. This file may not be copied, modified, or distributed |
9 | // except according to those terms. |
10 | |
11 | /*! |
12 | Generate types for C-style flags with ergonomic APIs. |
13 | |
14 | # Getting started |
15 | |
16 | Add `bitflags` to your `Cargo.toml`: |
17 | |
18 | ```toml |
19 | [dependencies.bitflags] |
20 | version = "2.4.1" |
21 | ``` |
22 | |
23 | ## Generating flags types |
24 | |
25 | Use the [`bitflags`] macro to generate flags types: |
26 | |
27 | ```rust |
28 | use bitflags::bitflags; |
29 | |
30 | bitflags! { |
31 | pub struct Flags: u32 { |
32 | const A = 0b00000001; |
33 | const B = 0b00000010; |
34 | const C = 0b00000100; |
35 | } |
36 | } |
37 | ``` |
38 | |
39 | See the docs for the `bitflags` macro for the full syntax. |
40 | |
41 | Also see the [`example_generated`] module for an example of what the `bitflags` macro generates for a flags type. |
42 | |
43 | ### Externally defined flags |
44 | |
45 | If you're generating flags types for an external source, such as a C API, you can define |
46 | an extra unnamed flag as a mask of all bits the external source may ever set. Usually this would be all bits (`!0`): |
47 | |
48 | ```rust |
49 | # use bitflags::bitflags; |
50 | bitflags! { |
51 | pub struct Flags: u32 { |
52 | const A = 0b00000001; |
53 | const B = 0b00000010; |
54 | const C = 0b00000100; |
55 | |
56 | // The source may set any bits |
57 | const _ = !0; |
58 | } |
59 | } |
60 | ``` |
61 | |
62 | Why should you do this? Generated methods like `all` and truncating operators like `!` only consider |
63 | bits in defined flags. Adding an unnamed flag makes those methods consider additional bits, |
64 | without generating additional constants for them. It helps compatibility when the external source |
65 | may start setting additional bits at any time. The [known and unknown bits](#known-and-unknown-bits) |
66 | section has more details on this behavior. |
67 | |
68 | ### Custom derives |
69 | |
70 | You can derive some traits on generated flags types if you enable Cargo features. The following |
71 | libraries are currently supported: |
72 | |
73 | - `serde`: Support `#[derive(Serialize, Deserialize)]`, using text for human-readable formats, |
74 | and a raw number for binary formats. |
75 | - `arbitrary`: Support `#[derive(Arbitrary)]`, only generating flags values with known bits. |
76 | - `bytemuck`: Support `#[derive(Pod, Zeroable)]`, for casting between flags values and their |
77 | underlying bits values. |
78 | |
79 | You can also define your own flags type outside of the [`bitflags`] macro and then use it to generate methods. |
80 | This can be useful if you need a custom `#[derive]` attribute for a library that `bitflags` doesn't |
81 | natively support: |
82 | |
83 | ```rust |
84 | # use std::fmt::Debug as SomeTrait; |
85 | # use bitflags::bitflags; |
86 | #[derive(SomeTrait)] |
87 | pub struct Flags(u32); |
88 | |
89 | bitflags! { |
90 | impl Flags: u32 { |
91 | const A = 0b00000001; |
92 | const B = 0b00000010; |
93 | const C = 0b00000100; |
94 | } |
95 | } |
96 | ``` |
97 | |
98 | ### Adding custom methods |
99 | |
100 | The [`bitflags`] macro supports attributes on generated flags types within the macro itself, while |
101 | `impl` blocks can be added outside of it: |
102 | |
103 | ```rust |
104 | # use bitflags::bitflags; |
105 | bitflags! { |
106 | // Attributes can be applied to flags types |
107 | #[repr(transparent)] |
108 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
109 | pub struct Flags: u32 { |
110 | const A = 0b00000001; |
111 | const B = 0b00000010; |
112 | const C = 0b00000100; |
113 | } |
114 | } |
115 | |
116 | // Impl blocks can be added to flags types |
117 | impl Flags { |
118 | pub fn as_u64(&self) -> u64 { |
119 | self.bits() as u64 |
120 | } |
121 | } |
122 | ``` |
123 | |
124 | ## Working with flags values |
125 | |
126 | Use generated constants and standard bitwise operators to interact with flags values: |
127 | |
128 | ```rust |
129 | # use bitflags::bitflags; |
130 | # bitflags! { |
131 | # #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] |
132 | # pub struct Flags: u32 { |
133 | # const A = 0b00000001; |
134 | # const B = 0b00000010; |
135 | # const C = 0b00000100; |
136 | # } |
137 | # } |
138 | // union |
139 | let ab = Flags::A | Flags::B; |
140 | |
141 | // intersection |
142 | let a = ab & Flags::A; |
143 | |
144 | // difference |
145 | let b = ab - Flags::A; |
146 | |
147 | // complement |
148 | let c = !ab; |
149 | ``` |
150 | |
151 | See the docs for the [`Flags`] trait for more details on operators and how they behave. |
152 | |
153 | # Formatting and parsing |
154 | |
155 | `bitflags` defines a text format that can be used to convert any flags value to and from strings. |
156 | |
157 | See the [`parser`] module for more details. |
158 | |
159 | # Specification |
160 | |
161 | The terminology and behavior of generated flags types is |
162 | [specified in the source repository](https://github.com/bitflags/bitflags/blob/main/spec.md). |
163 | Details are repeated in these docs where appropriate, but is exhaustively listed in the spec. Some |
164 | things are worth calling out explicitly here. |
165 | |
166 | ## Flags types, flags values, flags |
167 | |
168 | The spec and these docs use consistent terminology to refer to things in the bitflags domain: |
169 | |
170 | - **Bits type**: A type that defines a fixed number of bits at specific locations. |
171 | - **Flag**: A set of bits in a bits type that may have a unique name. |
172 | - **Flags type**: A set of defined flags over a specific bits type. |
173 | - **Flags value**: An instance of a flags type using its specific bits value for storage. |
174 | |
175 | ``` |
176 | # use bitflags::bitflags; |
177 | bitflags! { |
178 | struct FlagsType: u8 { |
179 | // -- Bits type |
180 | // --------- Flags type |
181 | const A = 1; |
182 | // ----- Flag |
183 | } |
184 | } |
185 | |
186 | let flag = FlagsType::A; |
187 | // ---- Flags value |
188 | ``` |
189 | |
190 | ## Known and unknown bits |
191 | |
192 | Any bits in a flag you define are called _known bits_. Any other bits are _unknown bits_. |
193 | In the following flags type: |
194 | |
195 | ``` |
196 | # use bitflags::bitflags; |
197 | bitflags! { |
198 | struct Flags: u8 { |
199 | const A = 1; |
200 | const B = 1 << 1; |
201 | const C = 1 << 2; |
202 | } |
203 | } |
204 | ``` |
205 | |
206 | The known bits are `0b0000_0111` and the unknown bits are `0b1111_1000`. |
207 | |
208 | `bitflags` doesn't guarantee that a flags value will only ever have known bits set, but some operators |
209 | will unset any unknown bits they encounter. In a future version of `bitflags`, all operators will |
210 | unset unknown bits. |
211 | |
212 | If you're using `bitflags` for flags types defined externally, such as from C, you probably want all |
213 | bits to be considered known, in case that external source changes. You can do this using an unnamed |
214 | flag, as described in [externally defined flags](#externally-defined-flags). |
215 | |
216 | ## Zero-bit flags |
217 | |
218 | Flags with no bits set should be avoided because they interact strangely with [`Flags::contains`] |
219 | and [`Flags::intersects`]. A zero-bit flag is always contained, but is never intersected. The |
220 | names of zero-bit flags can be parsed, but are never formatted. |
221 | |
222 | ## Multi-bit flags |
223 | |
224 | Flags that set multiple bits should be avoided unless each bit is also in a single-bit flag. |
225 | Take the following flags type as an example: |
226 | |
227 | ``` |
228 | # use bitflags::bitflags; |
229 | bitflags! { |
230 | struct Flags: u8 { |
231 | const A = 1; |
232 | const B = 1 | 1 << 1; |
233 | } |
234 | } |
235 | ``` |
236 | |
237 | The result of `Flags::A ^ Flags::B` is `0b0000_0010`, which doesn't correspond to either |
238 | `Flags::A` or `Flags::B` even though it's still a known bit. |
239 | */ |
240 | |
241 | #![cfg_attr (not(any(feature = "std" , test)), no_std)] |
242 | #![cfg_attr (not(test), forbid(unsafe_code))] |
243 | #![cfg_attr (test, allow(mixed_script_confusables))] |
244 | |
245 | #[doc (inline)] |
246 | pub use traits::{Bits, Flag, Flags}; |
247 | |
248 | pub mod iter; |
249 | pub mod parser; |
250 | |
251 | mod traits; |
252 | |
253 | #[doc (hidden)] |
254 | pub mod __private { |
255 | pub use crate::{external::__private::*, traits::__private::*}; |
256 | |
257 | pub use core; |
258 | } |
259 | |
260 | #[allow (unused_imports)] |
261 | pub use external::*; |
262 | |
263 | #[allow (deprecated)] |
264 | pub use traits::BitFlags; |
265 | |
266 | /* |
267 | How does the bitflags crate work? |
268 | |
269 | This library generates a `struct` in the end-user's crate with a bunch of constants on it that represent flags. |
270 | The difference between `bitflags` and a lot of other libraries is that we don't actually control the generated `struct` in the end. |
271 | It's part of the end-user's crate, so it belongs to them. That makes it difficult to extend `bitflags` with new functionality |
272 | because we could end up breaking valid code that was already written. |
273 | |
274 | Our solution is to split the type we generate into two: the public struct owned by the end-user, and an internal struct owned by `bitflags` (us). |
275 | To give you an example, let's say we had a crate that called `bitflags!`: |
276 | |
277 | ```rust |
278 | bitflags! { |
279 | pub struct MyFlags: u32 { |
280 | const A = 1; |
281 | const B = 2; |
282 | } |
283 | } |
284 | ``` |
285 | |
286 | What they'd end up with looks something like this: |
287 | |
288 | ```rust |
289 | pub struct MyFlags(<MyFlags as PublicFlags>::InternalBitFlags); |
290 | |
291 | const _: () = { |
292 | #[repr(transparent)] |
293 | #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] |
294 | pub struct MyInternalBitFlags { |
295 | bits: u32, |
296 | } |
297 | |
298 | impl PublicFlags for MyFlags { |
299 | type Internal = InternalBitFlags; |
300 | } |
301 | }; |
302 | ``` |
303 | |
304 | If we want to expose something like a new trait impl for generated flags types, we add it to our generated `MyInternalBitFlags`, |
305 | and let `#[derive]` on `MyFlags` pick up that implementation, if an end-user chooses to add one. |
306 | |
307 | The public API is generated in the `__impl_public_flags!` macro, and the internal API is generated in |
308 | the `__impl_internal_flags!` macro. |
309 | |
310 | The macros are split into 3 modules: |
311 | |
312 | - `public`: where the user-facing flags types are generated. |
313 | - `internal`: where the `bitflags`-facing flags types are generated. |
314 | - `external`: where external library traits are implemented conditionally. |
315 | */ |
316 | |
317 | /** |
318 | Generate a flags type. |
319 | |
320 | # `struct` mode |
321 | |
322 | A declaration that begins with `$vis struct` will generate a `struct` for a flags type, along with |
323 | methods and trait implementations for it. The body of the declaration defines flags as constants, |
324 | where each constant is a flags value of the generated flags type. |
325 | |
326 | ## Examples |
327 | |
328 | Generate a flags type using `u8` as the bits type: |
329 | |
330 | ``` |
331 | # use bitflags::bitflags; |
332 | bitflags! { |
333 | struct Flags: u8 { |
334 | const A = 1; |
335 | const B = 1 << 1; |
336 | const C = 0b0000_0100; |
337 | } |
338 | } |
339 | ``` |
340 | |
341 | Flags types are private by default and accept standard visibility modifiers. Flags themselves |
342 | are always public: |
343 | |
344 | ``` |
345 | # use bitflags::bitflags; |
346 | bitflags! { |
347 | pub struct Flags: u8 { |
348 | // Constants are always `pub` |
349 | const A = 1; |
350 | } |
351 | } |
352 | ``` |
353 | |
354 | Flags may refer to other flags using their [`Flags::bits`] value: |
355 | |
356 | ``` |
357 | # use bitflags::bitflags; |
358 | bitflags! { |
359 | struct Flags: u8 { |
360 | const A = 1; |
361 | const B = 1 << 1; |
362 | const AB = Flags::A.bits() | Flags::B.bits(); |
363 | } |
364 | } |
365 | ``` |
366 | |
367 | A single `bitflags` invocation may include zero or more flags type declarations: |
368 | |
369 | ``` |
370 | # use bitflags::bitflags; |
371 | bitflags! {} |
372 | |
373 | bitflags! { |
374 | struct Flags1: u8 { |
375 | const A = 1; |
376 | } |
377 | |
378 | struct Flags2: u8 { |
379 | const A = 1; |
380 | } |
381 | } |
382 | ``` |
383 | |
384 | # `impl` mode |
385 | |
386 | A declaration that begins with `impl` will only generate methods and trait implementations for the |
387 | `struct` defined outside of the `bitflags` macro. |
388 | |
389 | The struct itself must be a newtype using the bits type as its field. |
390 | |
391 | The syntax for `impl` mode is identical to `struct` mode besides the starting token. |
392 | |
393 | ## Examples |
394 | |
395 | Implement flags methods and traits for a custom flags type using `u8` as its underlying bits type: |
396 | |
397 | ``` |
398 | # use bitflags::bitflags; |
399 | struct Flags(u8); |
400 | |
401 | bitflags! { |
402 | impl Flags: u8 { |
403 | const A = 1; |
404 | const B = 1 << 1; |
405 | const C = 0b0000_0100; |
406 | } |
407 | } |
408 | ``` |
409 | |
410 | # Named and unnamed flags |
411 | |
412 | Constants in the body of a declaration are flags. The identifier of the constant is the name of |
413 | the flag. If the identifier is `_`, then the flag is unnamed. Unnamed flags don't appear in the |
414 | generated API, but affect how bits are truncated. |
415 | |
416 | ## Examples |
417 | |
418 | Adding an unnamed flag that makes all bits known: |
419 | |
420 | ``` |
421 | # use bitflags::bitflags; |
422 | bitflags! { |
423 | struct Flags: u8 { |
424 | const A = 1; |
425 | const B = 1 << 1; |
426 | |
427 | const _ = !0; |
428 | } |
429 | } |
430 | ``` |
431 | |
432 | Flags types may define multiple unnamed flags: |
433 | |
434 | ``` |
435 | # use bitflags::bitflags; |
436 | bitflags! { |
437 | struct Flags: u8 { |
438 | const _ = 1; |
439 | const _ = 1 << 1; |
440 | } |
441 | } |
442 | ``` |
443 | */ |
444 | #[macro_export (local_inner_macros)] |
445 | macro_rules! bitflags { |
446 | ( |
447 | $(#[$outer:meta])* |
448 | $vis:vis struct $BitFlags:ident: $T:ty { |
449 | $( |
450 | $(#[$inner:ident $($args:tt)*])* |
451 | const $Flag:tt = $value:expr; |
452 | )* |
453 | } |
454 | |
455 | $($t:tt)* |
456 | ) => { |
457 | // Declared in the scope of the `bitflags!` call |
458 | // This type appears in the end-user's API |
459 | __declare_public_bitflags! { |
460 | $(#[$outer])* |
461 | $vis struct $BitFlags |
462 | } |
463 | |
464 | // Workaround for: https://github.com/bitflags/bitflags/issues/320 |
465 | __impl_public_bitflags_consts! { |
466 | $BitFlags: $T { |
467 | $( |
468 | $(#[$inner $($args)*])* |
469 | const $Flag = $value; |
470 | )* |
471 | } |
472 | } |
473 | |
474 | #[allow( |
475 | dead_code, |
476 | deprecated, |
477 | unused_doc_comments, |
478 | unused_attributes, |
479 | unused_mut, |
480 | unused_imports, |
481 | non_upper_case_globals, |
482 | clippy::assign_op_pattern, |
483 | clippy::indexing_slicing, |
484 | clippy::same_name_method, |
485 | clippy::iter_without_into_iter, |
486 | )] |
487 | const _: () = { |
488 | // Declared in a "hidden" scope that can't be reached directly |
489 | // These types don't appear in the end-user's API |
490 | __declare_internal_bitflags! { |
491 | $vis struct InternalBitFlags: $T |
492 | } |
493 | |
494 | __impl_internal_bitflags! { |
495 | InternalBitFlags: $T, $BitFlags { |
496 | $( |
497 | $(#[$inner $($args)*])* |
498 | const $Flag = $value; |
499 | )* |
500 | } |
501 | } |
502 | |
503 | // This is where new library trait implementations can be added |
504 | __impl_external_bitflags! { |
505 | InternalBitFlags: $T, $BitFlags { |
506 | $( |
507 | $(#[$inner $($args)*])* |
508 | const $Flag; |
509 | )* |
510 | } |
511 | } |
512 | |
513 | __impl_public_bitflags_forward! { |
514 | $BitFlags: $T, InternalBitFlags |
515 | } |
516 | |
517 | __impl_public_bitflags_ops! { |
518 | $BitFlags |
519 | } |
520 | |
521 | __impl_public_bitflags_iter! { |
522 | $BitFlags: $T, $BitFlags |
523 | } |
524 | }; |
525 | |
526 | bitflags! { |
527 | $($t)* |
528 | } |
529 | }; |
530 | ( |
531 | impl $BitFlags:ident: $T:ty { |
532 | $( |
533 | $(#[$inner:ident $($args:tt)*])* |
534 | const $Flag:tt = $value:expr; |
535 | )* |
536 | } |
537 | |
538 | $($t:tt)* |
539 | ) => { |
540 | __impl_public_bitflags_consts! { |
541 | $BitFlags: $T { |
542 | $( |
543 | $(#[$inner $($args)*])* |
544 | const $Flag = $value; |
545 | )* |
546 | } |
547 | } |
548 | |
549 | #[allow( |
550 | dead_code, |
551 | deprecated, |
552 | unused_doc_comments, |
553 | unused_attributes, |
554 | unused_mut, |
555 | unused_imports, |
556 | non_upper_case_globals, |
557 | clippy::assign_op_pattern, |
558 | clippy::iter_without_into_iter, |
559 | )] |
560 | const _: () = { |
561 | __impl_public_bitflags! { |
562 | $BitFlags: $T, $BitFlags { |
563 | $( |
564 | $(#[$inner $($args)*])* |
565 | const $Flag = $value; |
566 | )* |
567 | } |
568 | } |
569 | |
570 | __impl_public_bitflags_ops! { |
571 | $BitFlags |
572 | } |
573 | |
574 | __impl_public_bitflags_iter! { |
575 | $BitFlags: $T, $BitFlags |
576 | } |
577 | }; |
578 | |
579 | bitflags! { |
580 | $($t)* |
581 | } |
582 | }; |
583 | () => {}; |
584 | } |
585 | |
586 | /// Implement functions on bitflags types. |
587 | /// |
588 | /// We need to be careful about adding new methods and trait implementations here because they |
589 | /// could conflict with items added by the end-user. |
590 | #[macro_export (local_inner_macros)] |
591 | #[doc (hidden)] |
592 | macro_rules! __impl_bitflags { |
593 | ( |
594 | $PublicBitFlags:ident: $T:ty { |
595 | fn empty() $empty:block |
596 | fn all() $all:block |
597 | fn bits($bits0:ident) $bits:block |
598 | fn from_bits($from_bits0:ident) $from_bits:block |
599 | fn from_bits_truncate($from_bits_truncate0:ident) $from_bits_truncate:block |
600 | fn from_bits_retain($from_bits_retain0:ident) $from_bits_retain:block |
601 | fn from_name($from_name0:ident) $from_name:block |
602 | fn is_empty($is_empty0:ident) $is_empty:block |
603 | fn is_all($is_all0:ident) $is_all:block |
604 | fn intersects($intersects0:ident, $intersects1:ident) $intersects:block |
605 | fn contains($contains0:ident, $contains1:ident) $contains:block |
606 | fn insert($insert0:ident, $insert1:ident) $insert:block |
607 | fn remove($remove0:ident, $remove1:ident) $remove:block |
608 | fn toggle($toggle0:ident, $toggle1:ident) $toggle:block |
609 | fn set($set0:ident, $set1:ident, $set2:ident) $set:block |
610 | fn intersection($intersection0:ident, $intersection1:ident) $intersection:block |
611 | fn union($union0:ident, $union1:ident) $union:block |
612 | fn difference($difference0:ident, $difference1:ident) $difference:block |
613 | fn symmetric_difference($symmetric_difference0:ident, $symmetric_difference1:ident) $symmetric_difference:block |
614 | fn complement($complement0:ident) $complement:block |
615 | } |
616 | ) => { |
617 | #[allow(dead_code, deprecated, unused_attributes)] |
618 | impl $PublicBitFlags { |
619 | /// Get a flags value with all bits unset. |
620 | #[inline] |
621 | pub const fn empty() -> Self { |
622 | $empty |
623 | } |
624 | |
625 | /// Get a flags value with all known bits set. |
626 | #[inline] |
627 | pub const fn all() -> Self { |
628 | $all |
629 | } |
630 | |
631 | /// Get the underlying bits value. |
632 | /// |
633 | /// The returned value is exactly the bits set in this flags value. |
634 | #[inline] |
635 | pub const fn bits(&self) -> $T { |
636 | let $bits0 = self; |
637 | $bits |
638 | } |
639 | |
640 | /// Convert from a bits value. |
641 | /// |
642 | /// This method will return `None` if any unknown bits are set. |
643 | #[inline] |
644 | pub const fn from_bits(bits: $T) -> $crate::__private::core::option::Option<Self> { |
645 | let $from_bits0 = bits; |
646 | $from_bits |
647 | } |
648 | |
649 | /// Convert from a bits value, unsetting any unknown bits. |
650 | #[inline] |
651 | pub const fn from_bits_truncate(bits: $T) -> Self { |
652 | let $from_bits_truncate0 = bits; |
653 | $from_bits_truncate |
654 | } |
655 | |
656 | /// Convert from a bits value exactly. |
657 | #[inline] |
658 | pub const fn from_bits_retain(bits: $T) -> Self { |
659 | let $from_bits_retain0 = bits; |
660 | $from_bits_retain |
661 | } |
662 | |
663 | /// Get a flags value with the bits of a flag with the given name set. |
664 | /// |
665 | /// This method will return `None` if `name` is empty or doesn't |
666 | /// correspond to any named flag. |
667 | #[inline] |
668 | pub fn from_name(name: &str) -> $crate::__private::core::option::Option<Self> { |
669 | let $from_name0 = name; |
670 | $from_name |
671 | } |
672 | |
673 | /// Whether all bits in this flags value are unset. |
674 | #[inline] |
675 | pub const fn is_empty(&self) -> bool { |
676 | let $is_empty0 = self; |
677 | $is_empty |
678 | } |
679 | |
680 | /// Whether all known bits in this flags value are set. |
681 | #[inline] |
682 | pub const fn is_all(&self) -> bool { |
683 | let $is_all0 = self; |
684 | $is_all |
685 | } |
686 | |
687 | /// Whether any set bits in a source flags value are also set in a target flags value. |
688 | #[inline] |
689 | pub const fn intersects(&self, other: Self) -> bool { |
690 | let $intersects0 = self; |
691 | let $intersects1 = other; |
692 | $intersects |
693 | } |
694 | |
695 | /// Whether all set bits in a source flags value are also set in a target flags value. |
696 | #[inline] |
697 | pub const fn contains(&self, other: Self) -> bool { |
698 | let $contains0 = self; |
699 | let $contains1 = other; |
700 | $contains |
701 | } |
702 | |
703 | /// The bitwise or (`|`) of the bits in two flags values. |
704 | #[inline] |
705 | pub fn insert(&mut self, other: Self) { |
706 | let $insert0 = self; |
707 | let $insert1 = other; |
708 | $insert |
709 | } |
710 | |
711 | /// The intersection of a source flags value with the complement of a target flags value (`&!`). |
712 | /// |
713 | /// This method is not equivalent to `self & !other` when `other` has unknown bits set. |
714 | /// `remove` won't truncate `other`, but the `!` operator will. |
715 | #[inline] |
716 | pub fn remove(&mut self, other: Self) { |
717 | let $remove0 = self; |
718 | let $remove1 = other; |
719 | $remove |
720 | } |
721 | |
722 | /// The bitwise exclusive-or (`^`) of the bits in two flags values. |
723 | #[inline] |
724 | pub fn toggle(&mut self, other: Self) { |
725 | let $toggle0 = self; |
726 | let $toggle1 = other; |
727 | $toggle |
728 | } |
729 | |
730 | /// Call `insert` when `value` is `true` or `remove` when `value` is `false`. |
731 | #[inline] |
732 | pub fn set(&mut self, other: Self, value: bool) { |
733 | let $set0 = self; |
734 | let $set1 = other; |
735 | let $set2 = value; |
736 | $set |
737 | } |
738 | |
739 | /// The bitwise and (`&`) of the bits in two flags values. |
740 | #[inline] |
741 | #[must_use] |
742 | pub const fn intersection(self, other: Self) -> Self { |
743 | let $intersection0 = self; |
744 | let $intersection1 = other; |
745 | $intersection |
746 | } |
747 | |
748 | /// The bitwise or (`|`) of the bits in two flags values. |
749 | #[inline] |
750 | #[must_use] |
751 | pub const fn union(self, other: Self) -> Self { |
752 | let $union0 = self; |
753 | let $union1 = other; |
754 | $union |
755 | } |
756 | |
757 | /// The intersection of a source flags value with the complement of a target flags value (`&!`). |
758 | /// |
759 | /// This method is not equivalent to `self & !other` when `other` has unknown bits set. |
760 | /// `difference` won't truncate `other`, but the `!` operator will. |
761 | #[inline] |
762 | #[must_use] |
763 | pub const fn difference(self, other: Self) -> Self { |
764 | let $difference0 = self; |
765 | let $difference1 = other; |
766 | $difference |
767 | } |
768 | |
769 | /// The bitwise exclusive-or (`^`) of the bits in two flags values. |
770 | #[inline] |
771 | #[must_use] |
772 | pub const fn symmetric_difference(self, other: Self) -> Self { |
773 | let $symmetric_difference0 = self; |
774 | let $symmetric_difference1 = other; |
775 | $symmetric_difference |
776 | } |
777 | |
778 | /// The bitwise negation (`!`) of the bits in a flags value, truncating the result. |
779 | #[inline] |
780 | #[must_use] |
781 | pub const fn complement(self) -> Self { |
782 | let $complement0 = self; |
783 | $complement |
784 | } |
785 | } |
786 | }; |
787 | } |
788 | |
789 | /// A macro that processed the input to `bitflags!` and shuffles attributes around |
790 | /// based on whether or not they're "expression-safe". |
791 | /// |
792 | /// This macro is a token-tree muncher that works on 2 levels: |
793 | /// |
794 | /// For each attribute, we explicitly match on its identifier, like `cfg` to determine |
795 | /// whether or not it should be considered expression-safe. |
796 | /// |
797 | /// If you find yourself with an attribute that should be considered expression-safe |
798 | /// and isn't, it can be added here. |
799 | #[macro_export (local_inner_macros)] |
800 | #[doc (hidden)] |
801 | macro_rules! __bitflags_expr_safe_attrs { |
802 | // Entrypoint: Move all flags and all attributes into `unprocessed` lists |
803 | // where they'll be munched one-at-a-time |
804 | ( |
805 | $(#[$inner:ident $($args:tt)*])* |
806 | { $e:expr } |
807 | ) => { |
808 | __bitflags_expr_safe_attrs! { |
809 | expr: { $e }, |
810 | attrs: { |
811 | // All attributes start here |
812 | unprocessed: [$(#[$inner $($args)*])*], |
813 | // Attributes that are safe on expressions go here |
814 | processed: [], |
815 | }, |
816 | } |
817 | }; |
818 | // Process the next attribute on the current flag |
819 | // `cfg`: The next flag should be propagated to expressions |
820 | // NOTE: You can copy this rules block and replace `cfg` with |
821 | // your attribute name that should be considered expression-safe |
822 | ( |
823 | expr: { $e:expr }, |
824 | attrs: { |
825 | unprocessed: [ |
826 | // cfg matched here |
827 | #[cfg $($args:tt)*] |
828 | $($attrs_rest:tt)* |
829 | ], |
830 | processed: [$($expr:tt)*], |
831 | }, |
832 | ) => { |
833 | __bitflags_expr_safe_attrs! { |
834 | expr: { $e }, |
835 | attrs: { |
836 | unprocessed: [ |
837 | $($attrs_rest)* |
838 | ], |
839 | processed: [ |
840 | $($expr)* |
841 | // cfg added here |
842 | #[cfg $($args)*] |
843 | ], |
844 | }, |
845 | } |
846 | }; |
847 | // Process the next attribute on the current flag |
848 | // `$other`: The next flag should not be propagated to expressions |
849 | ( |
850 | expr: { $e:expr }, |
851 | attrs: { |
852 | unprocessed: [ |
853 | // $other matched here |
854 | #[$other:ident $($args:tt)*] |
855 | $($attrs_rest:tt)* |
856 | ], |
857 | processed: [$($expr:tt)*], |
858 | }, |
859 | ) => { |
860 | __bitflags_expr_safe_attrs! { |
861 | expr: { $e }, |
862 | attrs: { |
863 | unprocessed: [ |
864 | $($attrs_rest)* |
865 | ], |
866 | processed: [ |
867 | // $other not added here |
868 | $($expr)* |
869 | ], |
870 | }, |
871 | } |
872 | }; |
873 | // Once all attributes on all flags are processed, generate the actual code |
874 | ( |
875 | expr: { $e:expr }, |
876 | attrs: { |
877 | unprocessed: [], |
878 | processed: [$(#[$expr:ident $($exprargs:tt)*])*], |
879 | }, |
880 | ) => { |
881 | $(#[$expr $($exprargs)*])* |
882 | { $e } |
883 | } |
884 | } |
885 | |
886 | /// Implement a flag, which may be a wildcard `_`. |
887 | #[macro_export (local_inner_macros)] |
888 | #[doc (hidden)] |
889 | macro_rules! __bitflags_flag { |
890 | ( |
891 | { |
892 | name: _, |
893 | named: { $($named:tt)* }, |
894 | unnamed: { $($unnamed:tt)* }, |
895 | } |
896 | ) => { |
897 | $($unnamed)* |
898 | }; |
899 | ( |
900 | { |
901 | name: $Flag:ident, |
902 | named: { $($named:tt)* }, |
903 | unnamed: { $($unnamed:tt)* }, |
904 | } |
905 | ) => { |
906 | $($named)* |
907 | }; |
908 | } |
909 | |
910 | #[macro_use ] |
911 | mod public; |
912 | #[macro_use ] |
913 | mod internal; |
914 | #[macro_use ] |
915 | mod external; |
916 | |
917 | #[cfg (feature = "example_generated" )] |
918 | pub mod example_generated; |
919 | |
920 | #[cfg (test)] |
921 | mod tests; |
922 | |