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