bitflags-2.4.2/.cargo_vcs_info.json0000644000000001360000000000100126340ustar { "git": { "sha1": "a5f9ce20e9d18444aa9b20c8fea9c00155cbafa3" }, "path_in_vcs": "" }bitflags-2.4.2/.gitignore000064400000000000000000000000371046102023000134140ustar 00000000000000wip target Cargo.lock /.idea/ bitflags-2.4.2/CHANGELOG.md000064400000000000000000000472541046102023000132510ustar 00000000000000# 2.4.2 ## What's Changed * Cargo.toml: Anchor excludes to root of the package by @jamessan in https://github.com/bitflags/bitflags/pull/387 * Update error messages by @KodrAus in https://github.com/bitflags/bitflags/pull/390 * Add support for impl mode structs to be repr(packed) by @GnomedDev in https://github.com/bitflags/bitflags/pull/388 * Remove old `unused_tuple_struct_fields` lint by @dtolnay in https://github.com/bitflags/bitflags/pull/393 * Delete use of `local_inner_macros` by @dtolnay in https://github.com/bitflags/bitflags/pull/392 ## New Contributors * @jamessan made their first contribution in https://github.com/bitflags/bitflags/pull/387 * @GnomedDev made their first contribution in https://github.com/bitflags/bitflags/pull/388 **Full Changelog**: https://github.com/bitflags/bitflags/compare/2.4.1...2.4.2 # 2.4.1 ## What's Changed * Allow some new pedantic clippy lints by @KodrAus in https://github.com/bitflags/bitflags/pull/380 **Full Changelog**: https://github.com/bitflags/bitflags/compare/2.4.0...2.4.1 # 2.4.0 ## What's Changed * Remove html_root_url by @eldruin in https://github.com/bitflags/bitflags/pull/368 * Support unnamed flags by @KodrAus in https://github.com/bitflags/bitflags/pull/371 * Update smoke test to verify all Clippy and rustc lints by @MitMaro in https://github.com/bitflags/bitflags/pull/374 * Specify the behavior of bitflags by @KodrAus in https://github.com/bitflags/bitflags/pull/369 ## New Contributors * @eldruin made their first contribution in https://github.com/bitflags/bitflags/pull/368 * @MitMaro made their first contribution in https://github.com/bitflags/bitflags/pull/374 **Full Changelog**: https://github.com/bitflags/bitflags/compare/2.3.3...2.4.0 # 2.3.3 ## Changes to `-=` The `-=` operator was incorrectly changed to truncate bits that didn't correspond to valid flags in `2.3.0`. This has been fixed up so it once again behaves the same as `-` and `difference`. ## Changes to `!` The `!` operator previously called `Self::from_bits_truncate`, which would truncate any bits that only partially overlapped with a valid flag. It will now use `bits & Self::all().bits()`, so any bits that overlap any bits specified by any flag will be respected. This is unlikely to have any practical implications, but enables defining a flag like `const ALL = !0` as a way to signal that any bit pattern is a known set of flags. ## Changes to formatting Zero-valued flags will never be printed. You'll either get `0x0` for empty flags using debug formatting, or the set of flags with zero-valued flags omitted for others. Composite flags will no longer be redundantly printed if there are extra bits to print at the end that don't correspond to a valid flag. ## What's Changed * Fix up incorrect sub assign behavior and other cleanups by @KodrAus in https://github.com/bitflags/bitflags/pull/366 **Full Changelog**: https://github.com/bitflags/bitflags/compare/2.3.2...2.3.3 # 2.3.2 ## What's Changed * [doc] [src/lib.rs] delete redundant path prefix by @OccupyMars2025 in https://github.com/bitflags/bitflags/pull/361 ## New Contributors * @OccupyMars2025 made their first contribution in https://github.com/bitflags/bitflags/pull/361 **Full Changelog**: https://github.com/bitflags/bitflags/compare/2.3.1...2.3.2 # 2.3.1 ## What's Changed * Fix Self in flags value expressions by @KodrAus in https://github.com/bitflags/bitflags/pull/355 **Full Changelog**: https://github.com/bitflags/bitflags/compare/2.3.0...2.3.1 # 2.3.0 ## What's Changed * Support ejecting flags types from the bitflags macro by @KodrAus in https://github.com/bitflags/bitflags/pull/351 **Full Changelog**: https://github.com/bitflags/bitflags/compare/2.2.1...2.3.0 # 2.2.1 ## What's Changed * Refactor attribute filtering to apply per-flag by @KodrAus in https://github.com/bitflags/bitflags/pull/345 **Full Changelog**: https://github.com/bitflags/bitflags/compare/2.2.0...2.2.1 # 2.2.0 ## What's Changed * Create SECURITY.md by @KodrAus in https://github.com/bitflags/bitflags/pull/338 * add docs to describe the behavior of multi-bit flags by @nicholasbishop in https://github.com/bitflags/bitflags/pull/340 * Add support for bytemuck by @KodrAus in https://github.com/bitflags/bitflags/pull/336 * Add a top-level macro for filtering attributes by @KodrAus in https://github.com/bitflags/bitflags/pull/341 ## New Contributors * @nicholasbishop made their first contribution in https://github.com/bitflags/bitflags/pull/340 **Full Changelog**: https://github.com/bitflags/bitflags/compare/2.1.0...2.2.0 # 2.1.0 ## What's Changed * Add docs for the internal Field0 and examples of formatting/parsing by @KodrAus in https://github.com/bitflags/bitflags/pull/328 * Add support for arbitrary by @KodrAus in https://github.com/bitflags/bitflags/pull/324 * Fix up missing docs for consts within consts by @KodrAus in https://github.com/bitflags/bitflags/pull/330 * Ignore clippy lint in generated code by @Jake-Shadle in https://github.com/bitflags/bitflags/pull/331 ## New Contributors * @Jake-Shadle made their first contribution in https://github.com/bitflags/bitflags/pull/331 **Full Changelog**: https://github.com/bitflags/bitflags/compare/2.0.2...2.1.0 # 2.0.2 ## What's Changed * Fix up missing isize and usize Bits impls by @KodrAus in https://github.com/bitflags/bitflags/pull/321 **Full Changelog**: https://github.com/bitflags/bitflags/compare/2.0.1...2.0.2 # 2.0.1 ## What's Changed * Fix up some docs issues by @KodrAus in https://github.com/bitflags/bitflags/pull/309 * Make empty_flag() const. by @tormeh in https://github.com/bitflags/bitflags/pull/313 * Fix formatting of multi-bit flags with partial overlap by @KodrAus in https://github.com/bitflags/bitflags/pull/316 ## New Contributors * @tormeh made their first contribution in https://github.com/bitflags/bitflags/pull/313 **Full Changelog**: https://github.com/bitflags/bitflags/compare/2.0.0...2.0.1 # 2.0.0 ## What's Changed * Fix a typo and call out MSRV bump by @KodrAus in https://github.com/bitflags/bitflags/pull/259 * BitFlags trait by @arturoc in https://github.com/bitflags/bitflags/pull/220 * Add a hidden trait to discourage manual impls of BitFlags by @KodrAus in https://github.com/bitflags/bitflags/pull/261 * Sanitize `Ok` by @konsumlamm in https://github.com/bitflags/bitflags/pull/266 * Fix bug in `Debug` implementation by @konsumlamm in https://github.com/bitflags/bitflags/pull/268 * Fix a typo in the generated documentation by @wackbyte in https://github.com/bitflags/bitflags/pull/271 * Use SPDX license format by @atouchet in https://github.com/bitflags/bitflags/pull/272 * serde tests fail in CI by @arturoc in https://github.com/bitflags/bitflags/pull/277 * Fix beta test output by @KodrAus in https://github.com/bitflags/bitflags/pull/279 * Add example to the README.md file by @tiaanl in https://github.com/bitflags/bitflags/pull/270 * Iterator over all the enabled options by @arturoc in https://github.com/bitflags/bitflags/pull/278 * from_bits_(truncate) fail with composite flags by @arturoc in https://github.com/bitflags/bitflags/pull/276 * Add more platform coverage to CI by @KodrAus in https://github.com/bitflags/bitflags/pull/280 * rework the way cfgs are handled by @KodrAus in https://github.com/bitflags/bitflags/pull/281 * Split generated code into two types by @KodrAus in https://github.com/bitflags/bitflags/pull/282 * expose bitflags iters using nameable types by @KodrAus in https://github.com/bitflags/bitflags/pull/286 * Support creating flags from their names by @KodrAus in https://github.com/bitflags/bitflags/pull/287 * Update README.md by @KodrAus in https://github.com/bitflags/bitflags/pull/288 * Prepare for 2.0.0-rc.1 release by @KodrAus in https://github.com/bitflags/bitflags/pull/289 * Add missing "if" to contains doc-comment in traits.rs by @rusty-snake in https://github.com/bitflags/bitflags/pull/291 * Forbid unsafe_code by @fintelia in https://github.com/bitflags/bitflags/pull/294 * serde: enable no-std support by @nim65s in https://github.com/bitflags/bitflags/pull/296 * Add a parser for flags formatted as bar-separated-values by @KodrAus in https://github.com/bitflags/bitflags/pull/297 * Prepare for 2.0.0-rc.2 release by @KodrAus in https://github.com/bitflags/bitflags/pull/299 * Use strip_prefix instead of starts_with + slice by @QuinnPainter in https://github.com/bitflags/bitflags/pull/301 * Fix up some clippy lints by @KodrAus in https://github.com/bitflags/bitflags/pull/302 * Prepare for 2.0.0-rc.3 release by @KodrAus in https://github.com/bitflags/bitflags/pull/303 * feat: Add minimum permissions to rust.yml workflow by @gabibguti in https://github.com/bitflags/bitflags/pull/305 ## New Contributors * @wackbyte made their first contribution in https://github.com/bitflags/bitflags/pull/271 * @atouchet made their first contribution in https://github.com/bitflags/bitflags/pull/272 * @tiaanl made their first contribution in https://github.com/bitflags/bitflags/pull/270 * @rusty-snake made their first contribution in https://github.com/bitflags/bitflags/pull/291 * @fintelia made their first contribution in https://github.com/bitflags/bitflags/pull/294 * @nim65s made their first contribution in https://github.com/bitflags/bitflags/pull/296 * @QuinnPainter made their first contribution in https://github.com/bitflags/bitflags/pull/301 * @gabibguti made their first contribution in https://github.com/bitflags/bitflags/pull/305 **Full Changelog**: https://github.com/bitflags/bitflags/compare/1.3.2...2.0.0 # 2.0.0-rc.3 ## What's Changed * Use strip_prefix instead of starts_with + slice by @QuinnPainter in https://github.com/bitflags/bitflags/pull/301 * Fix up some clippy lints by @KodrAus in https://github.com/bitflags/bitflags/pull/302 ## New Contributors * @QuinnPainter made their first contribution in https://github.com/bitflags/bitflags/pull/301 **Full Changelog**: https://github.com/bitflags/bitflags/compare/2.0.0-rc.2...2.0.0-rc.3 # 2.0.0-rc.2 ## Changes to `serde` serialization **⚠️ NOTE ⚠️** This release changes the default serialization you'll get if you `#[derive(Serialize, Deserialize)]` on your generated flags types. It will now use a formatted string for human-readable formats and the underlying bits type for compact formats. To keep the old behavior, see the [`bitflags-serde-legacy`](https://github.com/KodrAus/bitflags-serde-legacy) library. ## What's Changed * Add missing "if" to contains doc-comment in traits.rs by @rusty-snake in https://github.com/bitflags/bitflags/pull/291 * Forbid unsafe_code by @fintelia in https://github.com/bitflags/bitflags/pull/294 * serde: enable no-std support by @nim65s in https://github.com/bitflags/bitflags/pull/296 * Add a parser for flags formatted as bar-separated-values by @KodrAus in https://github.com/bitflags/bitflags/pull/297 ## New Contributors * @rusty-snake made their first contribution in https://github.com/bitflags/bitflags/pull/291 * @fintelia made their first contribution in https://github.com/bitflags/bitflags/pull/294 * @nim65s made their first contribution in https://github.com/bitflags/bitflags/pull/296 **Full Changelog**: https://github.com/bitflags/bitflags/compare/2.0.0-rc.1...2.0.0-rc.2 # 2.0.0-rc.1 This is a big release including a few years worth of work on a new `BitFlags` trait, iteration, and better macro organization for future extensibility. ## What's Changed * Fix a typo and call out MSRV bump by @KodrAus in https://github.com/bitflags/bitflags/pull/259 * BitFlags trait by @arturoc in https://github.com/bitflags/bitflags/pull/220 * Add a hidden trait to discourage manual impls of BitFlags by @KodrAus in https://github.com/bitflags/bitflags/pull/261 * Sanitize `Ok` by @konsumlamm in https://github.com/bitflags/bitflags/pull/266 * Fix bug in `Debug` implementation by @konsumlamm in https://github.com/bitflags/bitflags/pull/268 * Fix a typo in the generated documentation by @wackbyte in https://github.com/bitflags/bitflags/pull/271 * Use SPDX license format by @atouchet in https://github.com/bitflags/bitflags/pull/272 * serde tests fail in CI by @arturoc in https://github.com/bitflags/bitflags/pull/277 * Fix beta test output by @KodrAus in https://github.com/bitflags/bitflags/pull/279 * Add example to the README.md file by @tiaanl in https://github.com/bitflags/bitflags/pull/270 * Iterator over all the enabled options by @arturoc in https://github.com/bitflags/bitflags/pull/278 * from_bits_(truncate) fail with composite flags by @arturoc in https://github.com/bitflags/bitflags/pull/276 * Add more platform coverage to CI by @KodrAus in https://github.com/bitflags/bitflags/pull/280 * rework the way cfgs are handled by @KodrAus in https://github.com/bitflags/bitflags/pull/281 * Split generated code into two types by @KodrAus in https://github.com/bitflags/bitflags/pull/282 * expose bitflags iters using nameable types by @KodrAus in https://github.com/bitflags/bitflags/pull/286 * Support creating flags from their names by @KodrAus in https://github.com/bitflags/bitflags/pull/287 * Update README.md by @KodrAus in https://github.com/bitflags/bitflags/pull/288 ## New Contributors * @wackbyte made their first contribution in https://github.com/bitflags/bitflags/pull/271 * @atouchet made their first contribution in https://github.com/bitflags/bitflags/pull/272 * @tiaanl made their first contribution in https://github.com/bitflags/bitflags/pull/270 **Full Changelog**: https://github.com/bitflags/bitflags/compare/1.3.2...2.0.0-rc.1 # 1.3.2 - Allow `non_snake_case` in generated flags types ([#256]) [#256]: https://github.com/bitflags/bitflags/pull/256 # 1.3.1 - Revert unconditional `#[repr(transparent)]` ([#252]) [#252]: https://github.com/bitflags/bitflags/pull/252 # 1.3.0 (yanked) **This release bumps the Minimum Supported Rust Version to `1.46.0`** - Add `#[repr(transparent)]` ([#187]) - End `empty` doc comment with full stop ([#202]) - Fix typo in crate root docs ([#206]) - Document from_bits_unchecked unsafety ([#207]) - Let `is_all` ignore extra bits ([#211]) - Allows empty flag definition ([#225]) - Making crate accessible from std ([#227]) - Make `from_bits` a const fn ([#229]) - Allow multiple bitflags structs in one macro invocation ([#235]) - Add named functions to perform set operations ([#244]) - Fix typos in method docs ([#245]) - Modernization of the `bitflags` macro to take advantage of newer features and 2018 idioms ([#246]) - Fix regression (in an unreleased feature) and simplify tests ([#247]) - Use `Self` and fix bug when overriding `stringify!` ([#249]) [#187]: https://github.com/bitflags/bitflags/pull/187 [#202]: https://github.com/bitflags/bitflags/pull/202 [#206]: https://github.com/bitflags/bitflags/pull/206 [#207]: https://github.com/bitflags/bitflags/pull/207 [#211]: https://github.com/bitflags/bitflags/pull/211 [#225]: https://github.com/bitflags/bitflags/pull/225 [#227]: https://github.com/bitflags/bitflags/pull/227 [#229]: https://github.com/bitflags/bitflags/pull/229 [#235]: https://github.com/bitflags/bitflags/pull/235 [#244]: https://github.com/bitflags/bitflags/pull/244 [#245]: https://github.com/bitflags/bitflags/pull/245 [#246]: https://github.com/bitflags/bitflags/pull/246 [#247]: https://github.com/bitflags/bitflags/pull/247 [#249]: https://github.com/bitflags/bitflags/pull/249 # 1.2.1 - Remove extraneous `#[inline]` attributes ([#194]) [#194]: https://github.com/bitflags/bitflags/pull/194 # 1.2.0 - Fix typo: {Lower, Upper}Exp - {Lower, Upper}Hex ([#183]) - Add support for "unknown" bits ([#188]) [#183]: https://github.com/rust-lang-nursery/bitflags/pull/183 [#188]: https://github.com/rust-lang-nursery/bitflags/pull/188 # 1.1.0 This is a re-release of `1.0.5`, which was yanked due to a bug in the RLS. # 1.0.5 - Use compiletest_rs flags supported by stable toolchain ([#171]) - Put the user provided attributes first ([#173]) - Make bitflags methods `const` on newer compilers ([#175]) [#171]: https://github.com/rust-lang-nursery/bitflags/pull/171 [#173]: https://github.com/rust-lang-nursery/bitflags/pull/173 [#175]: https://github.com/rust-lang-nursery/bitflags/pull/175 # 1.0.4 - Support Rust 2018 style macro imports ([#165]) ```rust use bitflags::bitflags; ``` [#165]: https://github.com/rust-lang-nursery/bitflags/pull/165 # 1.0.3 - Improve zero value flag handling and documentation ([#157]) [#157]: https://github.com/rust-lang-nursery/bitflags/pull/157 # 1.0.2 - 30% improvement in compile time of bitflags crate ([#156]) - Documentation improvements ([#153]) - Implementation cleanup ([#149]) [#156]: https://github.com/rust-lang-nursery/bitflags/pull/156 [#153]: https://github.com/rust-lang-nursery/bitflags/pull/153 [#149]: https://github.com/rust-lang-nursery/bitflags/pull/149 # 1.0.1 - Add support for `pub(restricted)` specifier on the bitflags struct ([#135]) - Optimize performance of `all()` when called from a separate crate ([#136]) [#135]: https://github.com/rust-lang-nursery/bitflags/pull/135 [#136]: https://github.com/rust-lang-nursery/bitflags/pull/136 # 1.0.0 - **[breaking change]** Macro now generates [associated constants](https://doc.rust-lang.org/reference/items.html#associated-constants) ([#24]) - **[breaking change]** Minimum supported version is Rust **1.20**, due to usage of associated constants - After being broken in 0.9, the `#[deprecated]` attribute is now supported again ([#112]) - Other improvements to unit tests and documentation ([#106] and [#115]) [#24]: https://github.com/rust-lang-nursery/bitflags/pull/24 [#106]: https://github.com/rust-lang-nursery/bitflags/pull/106 [#112]: https://github.com/rust-lang-nursery/bitflags/pull/112 [#115]: https://github.com/rust-lang-nursery/bitflags/pull/115 ## How to update your code to use associated constants Assuming the following structure definition: ```rust bitflags! { struct Something: u8 { const FOO = 0b01, const BAR = 0b10 } } ``` In 0.9 and older you could do: ```rust let x = FOO.bits | BAR.bits; ``` Now you must use: ```rust let x = Something::FOO.bits | Something::BAR.bits; ``` # 0.9.1 - Fix the implementation of `Formatting` traits when other formatting traits were present in scope ([#105]) [#105]: https://github.com/rust-lang-nursery/bitflags/pull/105 # 0.9.0 - **[breaking change]** Use struct keyword instead of flags to define bitflag types ([#84]) - **[breaking change]** Terminate const items with semicolons instead of commas ([#87]) - Implement the `Hex`, `Octal`, and `Binary` formatting traits ([#86]) - Printing an empty flag value with the `Debug` trait now prints "(empty)" instead of nothing ([#85]) - The `bitflags!` macro can now be used inside of a fn body, to define a type local to that function ([#74]) [#74]: https://github.com/rust-lang-nursery/bitflags/pull/74 [#84]: https://github.com/rust-lang-nursery/bitflags/pull/84 [#85]: https://github.com/rust-lang-nursery/bitflags/pull/85 [#86]: https://github.com/rust-lang-nursery/bitflags/pull/86 [#87]: https://github.com/rust-lang-nursery/bitflags/pull/87 # 0.8.2 - Update feature flag used when building bitflags as a dependency of the Rust toolchain # 0.8.1 - Allow bitflags to be used as a dependency of the Rust toolchain # 0.8.0 - Add support for the experimental `i128` and `u128` integer types ([#57]) - Add set method: `flags.set(SOME_FLAG, true)` or `flags.set(SOME_FLAG, false)` ([#55]) This may break code that defines its own set method [#55]: https://github.com/rust-lang-nursery/bitflags/pull/55 [#57]: https://github.com/rust-lang-nursery/bitflags/pull/57 # 0.7.1 *(yanked)* # 0.7.0 - Implement the Extend trait ([#49]) - Allow definitions inside the `bitflags!` macro to refer to items imported from other modules ([#51]) [#49]: https://github.com/rust-lang-nursery/bitflags/pull/49 [#51]: https://github.com/rust-lang-nursery/bitflags/pull/51 # 0.6.0 - The `no_std` feature was removed as it is now the default - The `assignment_operators` feature was remove as it is now enabled by default - Some clippy suggestions have been applied bitflags-2.4.2/CODE_OF_CONDUCT.md000064400000000000000000000062261046102023000142310ustar 00000000000000# Contributor Covenant Code of Conduct ## Our Pledge In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation. ## Our Standards Examples of behavior that contributes to creating a positive environment include: * Using welcoming and inclusive language * Being respectful of differing viewpoints and experiences * Gracefully accepting constructive criticism * Focusing on what is best for the community * Showing empathy towards other community members Examples of unacceptable behavior by participants include: * The use of sexualized language or imagery and unwelcome sexual attention or advances * Trolling, insulting/derogatory comments, and personal or political attacks * Public or private harassment * Publishing others' private information, such as a physical or electronic address, without explicit permission * Other conduct which could reasonably be considered inappropriate in a professional setting ## Our Responsibilities Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. ## Scope This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. ## Enforcement Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at coc@senaite.org. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. ## Attribution This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html [homepage]: https://www.contributor-covenant.orgbitflags-2.4.2/CONTRIBUTING.md000064400000000000000000000006011046102023000136520ustar 00000000000000# Updating compile-fail test outputs `bitflags` uses the `trybuild` crate to integration test its macros. Since Rust error messages change frequently enough that `nightly` builds produce spurious failures, we only check the compiler output in `beta` builds. If you run: ``` TRYBUILD=overwrite cargo +beta test --all ``` it will run the tests and update the `trybuild` output files. bitflags-2.4.2/Cargo.lock0000644000000153670000000000100106230ustar # This file is automatically @generated by Cargo. # It is not intended for manual editing. version = 3 [[package]] name = "arbitrary" version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" dependencies = [ "derive_arbitrary", ] [[package]] name = "basic-toml" version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2db21524cad41c5591204d22d75e1970a2d1f71060214ca931dc7d5afe2c14e5" dependencies = [ "serde", ] [[package]] name = "bitflags" version = "2.4.2" dependencies = [ "arbitrary", "bytemuck", "compiler_builtins", "rustc-std-workspace-core", "rustversion", "serde", "serde_derive", "serde_json", "serde_test", "trybuild", "zerocopy", ] [[package]] name = "bytemuck" version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6" dependencies = [ "bytemuck_derive", ] [[package]] name = "bytemuck_derive" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "965ab7eb5f8f97d2a083c799f3a1b994fc397b2fe2da5d1da1626ce15a39f2b1" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "byteorder" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "compiler_builtins" version = "0.1.105" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3686cc48897ce1950aa70fd595bd2dc9f767a3c4cca4cd17b2cb52a2d37e6eb4" [[package]] name = "derive_arbitrary" version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "glob" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "itoa" version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" [[package]] name = "once_cell" version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "proc-macro2" version = "1.0.76" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" dependencies = [ "unicode-ident", ] [[package]] name = "quote" version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] [[package]] name = "rustc-std-workspace-core" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1956f5517128a2b6f23ab2dadf1a976f4f5b27962e7724c2bf3d45e539ec098c" [[package]] name = "rustversion" version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" [[package]] name = "ryu" version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" [[package]] name = "serde" version = "1.0.195" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" version = "1.0.195" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "serde_json" version = "1.0.111" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "176e46fa42316f18edd598015a5166857fc835ec732f5215eac6b7bdbf0a84f4" dependencies = [ "itoa", "ryu", "serde", ] [[package]] name = "serde_test" version = "1.0.176" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a2f49ace1498612d14f7e0b8245519584db8299541dfe31a06374a828d620ab" dependencies = [ "serde", ] [[package]] name = "syn" version = "2.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] [[package]] name = "termcolor" version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" dependencies = [ "winapi-util", ] [[package]] name = "trybuild" version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a9d3ba662913483d6722303f619e75ea10b7855b0f8e0d72799cf8621bb488f" dependencies = [ "basic-toml", "glob", "once_cell", "serde", "serde_derive", "serde_json", "termcolor", ] [[package]] name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "winapi" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" dependencies = [ "winapi-i686-pc-windows-gnu", "winapi-x86_64-pc-windows-gnu", ] [[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" dependencies = [ "winapi", ] [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "zerocopy" version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "854e949ac82d619ee9a14c66a1b674ac730422372ccb759ce0c39cabcf2bf8e6" dependencies = [ "byteorder", "zerocopy-derive", ] [[package]] name = "zerocopy-derive" version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "125139de3f6b9d625c39e2efdd73d41bdac468ccd556556440e322be0e1bbd91" dependencies = [ "proc-macro2", "quote", "syn", ] bitflags-2.4.2/Cargo.toml0000644000000036320000000000100106360ustar # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies. # # If you are reading this file be aware that the original Cargo.toml # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. [package] edition = "2021" rust-version = "1.56.0" name = "bitflags" version = "2.4.2" authors = ["The Rust Project Developers"] exclude = [ "/tests", "/.github", ] description = """ A macro to generate structures which behave like bitflags. """ homepage = "https://github.com/bitflags/bitflags" documentation = "https://docs.rs/bitflags" readme = "README.md" keywords = [ "bit", "bitmask", "bitflags", "flags", ] categories = ["no-std"] license = "MIT OR Apache-2.0" repository = "https://github.com/bitflags/bitflags" [package.metadata.docs.rs] features = ["example_generated"] [dependencies.arbitrary] version = "1.0" optional = true [dependencies.bytemuck] version = "1.0" optional = true [dependencies.compiler_builtins] version = "0.1.2" optional = true [dependencies.core] version = "1.0.0" optional = true package = "rustc-std-workspace-core" [dependencies.serde] version = "1.0" optional = true default-features = false [dev-dependencies.arbitrary] version = "1.0" features = ["derive"] [dev-dependencies.bytemuck] version = "1.0" features = ["derive"] [dev-dependencies.rustversion] version = "1.0" [dev-dependencies.serde_derive] version = "1.0" [dev-dependencies.serde_json] version = "1.0" [dev-dependencies.serde_test] version = "1.0" [dev-dependencies.trybuild] version = "1.0" [dev-dependencies.zerocopy] version = "0.6" [features] example_generated = [] rustc-dep-of-std = [ "core", "compiler_builtins", ] std = [] bitflags-2.4.2/Cargo.toml.orig000064400000000000000000000024431046102023000143160ustar 00000000000000[package] name = "bitflags" # NB: When modifying, also modify the number in readme (for breaking changes) version = "2.4.2" edition = "2021" rust-version = "1.56.0" authors = ["The Rust Project Developers"] license = "MIT OR Apache-2.0" keywords = ["bit", "bitmask", "bitflags", "flags"] readme = "README.md" repository = "https://github.com/bitflags/bitflags" homepage = "https://github.com/bitflags/bitflags" documentation = "https://docs.rs/bitflags" categories = ["no-std"] description = """ A macro to generate structures which behave like bitflags. """ exclude = ["/tests", "/.github"] [dependencies] serde = { version = "1.0", optional = true, default-features = false } arbitrary = { version = "1.0", optional = true } bytemuck = { version = "1.0", optional = true } core = { version = "1.0.0", optional = true, package = "rustc-std-workspace-core" } compiler_builtins = { version = "0.1.2", optional = true } [dev-dependencies] trybuild = "1.0" rustversion = "1.0" serde_derive = "1.0" serde_json = "1.0" serde_test = "1.0" zerocopy = "0.6" arbitrary = { version = "1.0", features = ["derive"] } bytemuck = { version = "1.0", features = ["derive"] } [features] std = [] example_generated = [] rustc-dep-of-std = ["core", "compiler_builtins"] [package.metadata.docs.rs] features = ["example_generated"] bitflags-2.4.2/LICENSE-APACHE000064400000000000000000000251371046102023000133600ustar 00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. bitflags-2.4.2/LICENSE-MIT000064400000000000000000000020571046102023000130640ustar 00000000000000Copyright (c) 2014 The Rust Project Developers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. bitflags-2.4.2/README.md000064400000000000000000000046071046102023000127120ustar 00000000000000bitflags ======== [![Rust](https://github.com/bitflags/bitflags/workflows/Rust/badge.svg)](https://github.com/bitflags/bitflags/actions) [![Latest version](https://img.shields.io/crates/v/bitflags.svg)](https://crates.io/crates/bitflags) [![Documentation](https://docs.rs/bitflags/badge.svg)](https://docs.rs/bitflags) ![License](https://img.shields.io/crates/l/bitflags.svg) `bitflags` generates flags enums with well-defined semantics and ergonomic end-user APIs. You can use `bitflags` to: - provide more user-friendly bindings to C APIs where flags may or may not be fully known in advance. - generate efficient options types with string parsing and formatting support. You can't use `bitflags` to: - guarantee only bits corresponding to defined flags will ever be set. `bitflags` allows access to the underlying bits type so arbitrary bits may be set. - define bitfields. `bitflags` only generates types where set bits denote the presence of some combination of flags. - [Documentation](https://docs.rs/bitflags) - [Specification](https://github.com/bitflags/bitflags/blob/main/spec.md) - [Release notes](https://github.com/bitflags/bitflags/releases) ## Usage Add this to your `Cargo.toml`: ```toml [dependencies] bitflags = "2.4.2" ``` and this to your source code: ```rust use bitflags::bitflags; ``` ## Example Generate a flags structure: ```rust use bitflags::bitflags; // The `bitflags!` macro generates `struct`s that manage a set of flags. bitflags! { /// Represents a set of flags. #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] struct Flags: u32 { /// The value `A`, at bit position `0`. const A = 0b00000001; /// The value `B`, at bit position `1`. const B = 0b00000010; /// The value `C`, at bit position `2`. const C = 0b00000100; /// The combination of `A`, `B`, and `C`. const ABC = Self::A.bits() | Self::B.bits() | Self::C.bits(); } } fn main() { let e1 = Flags::A | Flags::C; let e2 = Flags::B | Flags::C; assert_eq!((e1 | e2), Flags::ABC); // union assert_eq!((e1 & e2), Flags::C); // intersection assert_eq!((e1 - e2), Flags::A); // set difference assert_eq!(!e2, Flags::A); // set complement } ``` ## Rust Version Support The minimum supported Rust version is documented in the `Cargo.toml` file. This may be bumped in minor releases as necessary. bitflags-2.4.2/SECURITY.md000064400000000000000000000012621046102023000132160ustar 00000000000000# Security Policy ## Supported Versions Security updates are applied only to the latest release. ## Reporting a Vulnerability If you have discovered a security vulnerability in this project, please report it privately. **Do not disclose it as a public issue.** This gives us time to work with you to fix the issue before public exposure, reducing the chance that the exploit will be used before a patch is released. Please disclose it at [security advisory](https://github.com/bitflags/bitflags/security/advisories/new). This project is maintained by a team of volunteers on a reasonable-effort basis. As such, please give us at least 90 days to work on a fix before public exposure. bitflags-2.4.2/benches/parse.rs000064400000000000000000000041121046102023000145110ustar 00000000000000#![feature(test)] extern crate test; use std::{ fmt::{self, Display}, str::FromStr, }; bitflags::bitflags! { struct Flags10: u32 { const A = 0b0000_0000_0000_0001; const B = 0b0000_0000_0000_0010; const C = 0b0000_0000_0000_0100; const D = 0b0000_0000_0000_1000; const E = 0b0000_0000_0001_0000; const F = 0b0000_0000_0010_0000; const G = 0b0000_0000_0100_0000; const H = 0b0000_0000_1000_0000; const I = 0b0000_0001_0000_0000; const J = 0b0000_0010_0000_0000; } } impl FromStr for Flags10 { type Err = bitflags::parser::ParseError; fn from_str(flags: &str) -> Result { Ok(Flags10(flags.parse()?)) } } impl Display for Flags10 { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { Display::fmt(&self.0, f) } } #[bench] fn format_flags_1_present(b: &mut test::Bencher) { b.iter(|| Flags10::J.to_string()) } #[bench] fn format_flags_5_present(b: &mut test::Bencher) { b.iter(|| (Flags10::F | Flags10::G | Flags10::H | Flags10::I | Flags10::J).to_string()) } #[bench] fn format_flags_10_present(b: &mut test::Bencher) { b.iter(|| { (Flags10::A | Flags10::B | Flags10::C | Flags10::D | Flags10::E | Flags10::F | Flags10::G | Flags10::H | Flags10::I | Flags10::J) .to_string() }) } #[bench] fn parse_flags_1_10(b: &mut test::Bencher) { b.iter(|| { let flags: Flags10 = "J".parse().unwrap(); flags }) } #[bench] fn parse_flags_5_10(b: &mut test::Bencher) { b.iter(|| { let flags: Flags10 = "F | G | H | I | J".parse().unwrap(); flags }) } #[bench] fn parse_flags_10_10(b: &mut test::Bencher) { b.iter(|| { let flags: Flags10 = "A | B | C | D | E | F | G | H | I | J".parse().unwrap(); flags }) } #[bench] fn parse_flags_1_10_hex(b: &mut test::Bencher) { b.iter(|| { let flags: Flags10 = "0xFF".parse().unwrap(); flags }) } bitflags-2.4.2/examples/custom_bits_type.rs000064400000000000000000000042001046102023000172000ustar 00000000000000use std::ops::{BitAnd, BitOr, BitXor, Not}; use bitflags::{Bits, Flag, Flags}; // Define a custom container that can be used in flags types // Note custom bits types can't be used in `bitflags!` // without making the trait impls `const`. This is currently // unstable #[derive(Clone, Copy, Debug)] pub struct CustomBits([bool; 3]); impl Bits for CustomBits { const EMPTY: Self = CustomBits([false; 3]); const ALL: Self = CustomBits([true; 3]); } impl PartialEq for CustomBits { fn eq(&self, other: &Self) -> bool { self.0 == other.0 } } impl BitAnd for CustomBits { type Output = Self; fn bitand(self, other: Self) -> Self { CustomBits([ self.0[0] & other.0[0], self.0[1] & other.0[1], self.0[2] & other.0[2], ]) } } impl BitOr for CustomBits { type Output = Self; fn bitor(self, other: Self) -> Self { CustomBits([ self.0[0] | other.0[0], self.0[1] | other.0[1], self.0[2] | other.0[2], ]) } } impl BitXor for CustomBits { type Output = Self; fn bitxor(self, other: Self) -> Self { CustomBits([ self.0[0] & other.0[0], self.0[1] & other.0[1], self.0[2] & other.0[2], ]) } } impl Not for CustomBits { type Output = Self; fn not(self) -> Self { CustomBits([!self.0[0], !self.0[1], !self.0[2]]) } } #[derive(Clone, Copy, Debug)] pub struct CustomFlags(CustomBits); impl CustomFlags { pub const A: Self = CustomFlags(CustomBits([true, false, false])); pub const B: Self = CustomFlags(CustomBits([false, true, false])); pub const C: Self = CustomFlags(CustomBits([false, false, true])); } impl Flags for CustomFlags { const FLAGS: &'static [Flag] = &[ Flag::new("A", Self::A), Flag::new("B", Self::B), Flag::new("C", Self::C), ]; type Bits = CustomBits; fn bits(&self) -> Self::Bits { self.0 } fn from_bits_retain(bits: Self::Bits) -> Self { CustomFlags(bits) } } fn main() { println!("{:?}", CustomFlags::A.union(CustomFlags::C)); } bitflags-2.4.2/examples/custom_derive.rs000064400000000000000000000012041046102023000164550ustar 00000000000000//! An example of implementing the `BitFlags` trait manually for a flags type. use std::str; use bitflags::bitflags; // Define a flags type outside of the `bitflags` macro as a newtype // It can accept custom derives for libaries `bitflags` doesn't support natively #[derive(zerocopy::AsBytes, zerocopy::FromBytes)] #[repr(transparent)] pub struct ManualFlags(u32); // Next: use `impl Flags` instead of `struct Flags` bitflags! { impl ManualFlags: u32 { const A = 0b00000001; const B = 0b00000010; const C = 0b00000100; const ABC = Self::A.bits() | Self::B.bits() | Self::C.bits(); } } fn main() {} bitflags-2.4.2/examples/fmt.rs000064400000000000000000000022271046102023000144010ustar 00000000000000//! An example of implementing Rust's standard formatting and parsing traits for flags types. use core::{fmt, str}; bitflags::bitflags! { // You can `#[derive]` the `Debug` trait, but implementing it manually // can produce output like `A | B` instead of `Flags(A | B)`. // #[derive(Debug)] #[derive(PartialEq, Eq)] pub struct Flags: u32 { const A = 1; const B = 2; const C = 4; const D = 8; } } impl fmt::Debug for Flags { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { bitflags::parser::to_writer(self, f) } } impl fmt::Display for Flags { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { bitflags::parser::to_writer(self, f) } } impl str::FromStr for Flags { type Err = bitflags::parser::ParseError; fn from_str(flags: &str) -> Result { bitflags::parser::from_str(flags) } } fn main() -> Result<(), bitflags::parser::ParseError> { let flags = Flags::A | Flags::B; println!("{}", flags); let formatted = flags.to_string(); let parsed: Flags = formatted.parse()?; assert_eq!(flags, parsed); Ok(()) } bitflags-2.4.2/examples/macro_free.rs000064400000000000000000000027761046102023000157260ustar 00000000000000//! An example of implementing the `BitFlags` trait manually for a flags type. //! //! This example doesn't use any macros. use std::{fmt, str}; use bitflags::{Flag, Flags}; // First: Define your flags type. It just needs to be `Sized + 'static`. pub struct ManualFlags(u32); // Not required: Define some constants for valid flags impl ManualFlags { pub const A: ManualFlags = ManualFlags(0b00000001); pub const B: ManualFlags = ManualFlags(0b00000010); pub const C: ManualFlags = ManualFlags(0b00000100); pub const ABC: ManualFlags = ManualFlags(0b00000111); } // Next: Implement the `BitFlags` trait, specifying your set of valid flags // and iterators impl Flags for ManualFlags { const FLAGS: &'static [Flag] = &[ Flag::new("A", Self::A), Flag::new("B", Self::B), Flag::new("C", Self::C), ]; type Bits = u32; fn bits(&self) -> u32 { self.0 } fn from_bits_retain(bits: u32) -> Self { Self(bits) } } // Not required: Add parsing support impl str::FromStr for ManualFlags { type Err = bitflags::parser::ParseError; fn from_str(input: &str) -> Result { bitflags::parser::from_str(input) } } // Not required: Add formatting support impl fmt::Display for ManualFlags { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { bitflags::parser::to_writer(self, f) } } fn main() { println!( "{}", ManualFlags::A.union(ManualFlags::B).union(ManualFlags::C) ); } bitflags-2.4.2/examples/serde.rs000064400000000000000000000017011046102023000147110ustar 00000000000000//! An example of implementing `serde::Serialize` and `serde::Deserialize`. //! The `#[serde(transparent)]` attribute is recommended to serialize directly //! to the underlying bits type without wrapping it in a `serde` newtype. #[cfg(feature = "serde")] fn main() { use serde_derive::*; bitflags::bitflags! { #[derive(Serialize, Deserialize, Debug, PartialEq, Eq)] #[serde(transparent)] pub struct Flags: u32 { const A = 1; const B = 2; const C = 4; const D = 8; } } let flags = Flags::A | Flags::B; let serialized = serde_json::to_string(&flags).unwrap(); println!("{:?} -> {}", flags, serialized); assert_eq!(serialized, r#""A | B""#); let deserialized: Flags = serde_json::from_str(&serialized).unwrap(); println!("{} -> {:?}", serialized, flags); assert_eq!(deserialized, flags); } #[cfg(not(feature = "serde"))] fn main() {} bitflags-2.4.2/spec.md000064400000000000000000000245071046102023000127100ustar 00000000000000# Bitflags `bitflags` generates flags enums with well-defined semantics and ergonomic end-user APIs. You can use `bitflags` to: - provide more user-friendly bindings to C APIs where flags may or may not be fully known in advance. - generate efficient options types with string parsing and formatting support. You can't use `bitflags` to: - guarantee only bits corresponding to defined flags will ever be set. `bitflags` allows access to the underlying bits type so arbitrary bits may be set. - define bitfields. `bitflags` only generates types where set bits denote the presence of some combination of flags. ## Definitions This section formally defines the terminology and semantics of `bitflags`. It's organized so more fundamental concepts are introduced before those that build on them. It may be helpful to start from the bottom of the section and refer back up to concepts defined earlier. Examples use `bitflags` syntax with `u8` as the bits type. ### Bits type A type that defines a fixed number of bits at specific locations. ---- Bits types are typically fixed-width unsigned integers. For example, `u8` is a bits type that defines 8 bits; bit-0 through bit-7. ### Bits value An instance of a bits type where each bit may be set (`1`) or unset (`0`). ---- Some examples of bits values for the bits type `u8` are: ```rust 0b0000_0000 0b1111_1111 0b1010_0101 ``` #### Equality Two bits values are equal if their bits are in the same configuration; set bits in one are set in the other, and unset bits in one are unset in the other. #### Operations Bits values define the bitwise operators and (`&`), or (`|`), exclusive-or (`^`), and negation (`!`) that apply to each of their bits. ### Flag A set of bits in a bits type that may have a unique name. ---- Bits are not required to be exclusive to a flag. Bits are not required to be contiguous. The following is a flag for `u8` with the name `A` that includes bit-0: ```rust const A = 0b0000_0001; ``` The following is a flag for `u8` with the name `B` that includes bit-0, and bit-5: ```rust const B = 0b0010_0001; ``` #### Named flag A flag with a name. ---- The following is a named flag, where the name is `A`: ```rust const A = 0b0000_0001; ``` #### Unnamed flag A flag without a name. ---- The following is an unnamed flag: ```rust const _ = 0b0000_0001; ``` #### Zero-bit flag A flag with a set of zero bits. ---- The following is a zero-bit flag: ```rust const ZERO = 0b0000_0000; ``` #### Single-bit flag A flag with a set of one bit. ---- The following are single-bit flags: ```rust const A = 0b0000_0001; const B = 0b0000_0010; ``` #### Multi-bit flag A flag with a set of more than one bit. ---- The following are multi-bit flags: ```rust const A = 0b0000_0011; const B = 0b1111_1111; ``` ### Flags type A set of defined flags over a specific bits type. #### Known bit A bit in any defined flag. ---- In the following flags type: ```rust struct Flags { const A = 0b0000_0001; const B = 0b0000_0010; const C = 0b0000_0100; } ``` the known bits are: ```rust 0b0000_0111 ``` #### Unknown bit A bit not in any defined flag. ---- In the following flags type: ```rust struct Flags { const A = 0b0000_0001; const B = 0b0000_0010; const C = 0b0000_0100; } ``` the unknown bits are: ```rust 0b1111_1000 ``` ### Flags value An instance of a flags type using its specific bits value for storage. The flags value of a flag is one where each of its bits is set, and all others are unset. #### Contains Whether all set bits in a source flags value are also set in a target flags value. ---- Given the flags value: ```rust 0b0000_0011 ``` the following flags values are contained: ```rust 0b0000_0000 0b0000_0010 0b0000_0001 0b0000_0011 ``` but the following flags values are not contained: ```rust 0b0000_1000 0b0000_0110 ``` #### Intersects Whether any set bits in a source flags value are also set in a target flags value. ---- Given the flags value: ```rust 0b0000_0011 ``` the following flags intersect: ```rust 0b0000_0010 0b0000_0001 0b1111_1111 ``` but the following flags values do not intersect: ```rust 0b0000_0000 0b1111_0000 ``` #### Empty Whether all bits in a flags value are unset. ---- The following flags value is empty: ```rust 0b0000_0000 ``` The following flags values are not empty: ```rust 0b0000_0001 0b0110_0000 ``` #### All Whether all defined flags are contained in a flags value. ---- Given a flags type: ```rust struct Flags { const A = 0b0000_0001; const B = 0b0000_0010; } ``` the following flags values all satisfy all: ```rust 0b0000_0011 0b1000_0011 0b1111_1111 ``` ### Operations Examples in this section all use the given flags type: ```rust struct Flags { const A = 0b0000_0001; const B = 0b0000_0010; const C = 0b0000_1100; } ``` #### Truncate Unset all unknown bits in a flags value. ---- Given the flags value: ```rust 0b1111_1111 ``` the result of truncation will be: ```rust 0b0000_1111 ``` ---- Truncating doesn't guarantee that a non-empty result will contain any defined flags. Given the following flags type: ```rust struct Flags { const A = 0b0000_0101; } ``` and the following flags value: ```rust 0b0000_1110; ``` The result of truncation will be: ```rust 0b0000_0100; ``` which intersects the flag `A`, but doesn't contain it. This behavior is possible even when only operating with flags values containing defined flags. Given the following flags type: ```rust struct Flags { const A = 0b0000_0101; const B = 0b0000_0001; } ``` The result of `A ^ B` is `0b0000_0100`, which also doesn't contain any defined flag. ---- If all known bits are in the set of at least one defined single-bit flag, then all operations that produce non-empty results will always contain defined flags. #### Union The bitwise or (`|`) of the bits in two flags values. ---- The following are examples of the result of unioning flags values: ```rust 0b0000_0001 | 0b0000_0010 = 0b0000_0011 0b0000_0000 | 0b1111_1111 = 0b1111_1111 ``` #### Intersection The bitwise and (`&`) of the bits in two flags values. ---- The following are examples of the result of intersecting flags values: ```rust 0b0000_0001 & 0b0000_0010 = 0b0000_0000 0b1111_1100 & 0b1111_0111 = 0b1111_0100 0b1111_1111 & 0b1111_1111 = 0b1111_1111 ``` #### Symmetric difference The bitwise exclusive-or (`^`) of the bits in two flags values. ---- The following are examples of the symmetric difference between two flags values: ```rust 0b0000_0001 ^ 0b0000_0010 = 0b0000_0011 0b0000_1111 ^ 0b0000_0011 = 0b0000_1100 0b1100_0000 ^ 0b0011_0000 = 0b1111_0000 ``` #### Complement The bitwise negation (`!`) of the bits in a flags value, truncating the result. ---- The following are examples of the complement of a flags value: ```rust !0b0000_0000 = 0b0000_1111 !0b0000_1111 = 0b0000_0000 !0b1111_1000 = 0b0000_0111 ``` #### Difference The bitwise union (`|`) of the bits in one flags value and the bitwise negation (`!`) of the bits in another. ---- This operation is not equivalent to the intersection of one flags value with the complement of another (`&!`). The former will truncate the result, where difference will not. ---- The following are examples of the difference between two flags values: ```rust 0b0000_0001 & !0b0000_0010 = 0b0000_0001 0b0000_1101 & !0b0000_0011 = 0b0000_1100 0b1111_1111 & !0b0000_0001 = 0b1111_1110 ``` ### Iteration Yield the bits of a source flags value in a set of contained flags values. ---- To be most useful, each yielded flags value should set exactly the bits of a defined flag contained in the source. Any known bits that aren't in the set of any contained flag should be yielded together as a final flags value. ---- Given the following flags type: ```rust struct Flags { const A = 0b0000_0001; const B = 0b0000_0010; const AB = 0b0000_0011; } ``` and the following flags value: ```rust 0b0000_1111 ``` When iterated it may yield a flags value for `A` and `B`, then a final flag with the unknown bits: ```rust 0b0000_0001 0b0000_0010 0b0000_1100 ``` It may also yield a flags value for `AB`, then a final flag with the unknown bits: ```rust 0b0000_0011 0b0000_1100 ``` ---- Given the following flags type: ```rust struct Flags { const A = 0b0000_0011; } ``` and the following flags value: ```rust 0b0000_0001 ``` When iterated it will still yield a flags value for the known bit `0b0000_0001` even though it doesn't contain a flag. ### Formatting Format and parse a flags value as text using the following grammar: - _Flags:_ (_Whitespace_ _Flag_ _Whitespace_)`|`* - _Flag:_ _Name_ | _Hex Number_ - _Name:_ The name of any defined flag - _Hex Number_: `0x`([0-9a-fA-F])* - _Whitespace_: (\s)* Flags values can be formatted as _Flags_ by iterating over them, formatting each yielded flags value as a _Flag_. Any yielded flags value that sets exactly the bits of a defined flag with a name should be formatted as a _Name_. Otherwise it must be formatted as a _Hex Number_. Formatting and parsing supports three modes: - **Retain**: Formatting and parsing roundtrips exactly the bits of the source flags value. This is the default behavior. - **Truncate**: Flags values are truncated before formatting, and truncated after parsing. - **Strict**: A _Flag_ may only be formatted and parsed as a _Name_. _Hex numbers_ are not allowed. A consequence of this is that unknown bits and any bits that aren't in a contained named flag will be ignored. This is recommended for flags values serialized across API boundaries, like web services. Text that is empty or whitespace is an empty flags value. ---- Given the following flags type: ```rust struct Flags { const A = 0b0000_0001; const B = 0b0000_0010; const AB = 0b0000_0011; const C = 0b0000_1100; } ``` The following are examples of how flags values can be formatted using any mode: ```rust 0b0000_0000 = "" 0b0000_0001 = "A" 0b0000_0010 = "B" 0b0000_0011 = "A | B" 0b0000_0011 = "AB" 0b0000_1111 = "A | B | C" ``` Truncate mode will unset any unknown bits: ```rust 0b1000_0000 = "" 0b1111_1111 = "A | B | C" 0b0000_1000 = "0x8" ``` Retain mode will include any unknown bits as a final _Flag_: ```rust 0b1000_0000 = "0x80" 0b1111_1111 = "A | B | C | 0xf0" 0b0000_1000 = "0x8" ``` Strict mode will unset any unknown bits, as well as bits not contained in any defined named flags: ```rust 0b1000_0000 = "" 0b1111_1111 = "A | B | C" 0b0000_1000 = "" ``` bitflags-2.4.2/src/example_generated.rs000064400000000000000000000034631046102023000162400ustar 00000000000000//! This module shows an example of code generated by the macro. **IT MUST NOT BE USED OUTSIDE THIS //! CRATE**. //! //! Usually, when you call the `bitflags!` macro, only the `Flags` type would be visible. In this //! example, the `Field0`, `Iter`, and `IterRaw` types are also exposed so that you can explore //! their APIs. The `Field0` type can be accessed as `self.0` on an instance of `Flags`. __declare_public_bitflags! { /// This is the same `Flags` struct defined in the [crate level example](../index.html#example). /// Note that this struct is just for documentation purposes only, it must not be used outside /// this crate. pub struct Flags } __declare_internal_bitflags! { pub struct Field0: u32 } __impl_internal_bitflags! { Field0: u32, Flags { // Field `A`. /// /// This flag has the value `0b00000001`. const A = 0b00000001; /// Field `B`. /// /// This flag has the value `0b00000010`. const B = 0b00000010; /// Field `C`. /// /// This flag has the value `0b00000100`. const C = 0b00000100; const ABC = Self::A.bits() | Self::B.bits() | Self::C.bits(); } } __impl_public_bitflags_forward! { Flags: u32, Field0 } __impl_public_bitflags_ops! { Flags } __impl_public_bitflags_iter! { Flags: u32, Flags } __impl_public_bitflags_consts! { Flags: u32 { /// Field `A`. /// /// This flag has the value `0b00000001`. const A = 0b00000001; /// Field `B`. /// /// This flag has the value `0b00000010`. const B = 0b00000010; /// Field `C`. /// /// This flag has the value `0b00000100`. const C = 0b00000100; const ABC = Self::A.bits() | Self::B.bits() | Self::C.bits(); } } bitflags-2.4.2/src/external/arbitrary.rs000064400000000000000000000014231046102023000164020ustar 00000000000000//! Specialized fuzzing for flags types using `arbitrary`. use crate::Flags; /** Generate some arbitrary flags value with only known bits set. */ pub fn arbitrary<'a, B: Flags>(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result where B::Bits: arbitrary::Arbitrary<'a>, { B::from_bits(u.arbitrary()?).ok_or_else(|| arbitrary::Error::IncorrectFormat) } #[cfg(test)] mod tests { use arbitrary::Arbitrary; bitflags! { #[derive(Arbitrary)] struct Color: u32 { const RED = 0x1; const GREEN = 0x2; const BLUE = 0x4; } } #[test] fn test_arbitrary() { let mut unstructured = arbitrary::Unstructured::new(&[0_u8; 256]); let _color = Color::arbitrary(&mut unstructured); } } bitflags-2.4.2/src/external/bytemuck.rs000064400000000000000000000006171046102023000162320ustar 00000000000000#[cfg(test)] mod tests { use bytemuck::{Pod, Zeroable}; bitflags! { #[derive(Pod, Zeroable, Clone, Copy)] #[repr(transparent)] struct Color: u32 { const RED = 0x1; const GREEN = 0x2; const BLUE = 0x4; } } #[test] fn test_bytemuck() { assert_eq!(0x1, bytemuck::cast::(Color::RED)); } } bitflags-2.4.2/src/external/serde.rs000064400000000000000000000053301046102023000155060ustar 00000000000000//! Specialized serialization for flags types using `serde`. use crate::{ parser::{self, ParseHex, WriteHex}, Flags, }; use core::{fmt, str}; use serde::{ de::{Error, Visitor}, Deserialize, Deserializer, Serialize, Serializer, }; /** Serialize a set of flags as a human-readable string or their underlying bits. Any unknown bits will be retained. */ pub fn serialize(flags: &B, serializer: S) -> Result where B::Bits: WriteHex + Serialize, { // Serialize human-readable flags as a string like `"A | B"` if serializer.is_human_readable() { serializer.collect_str(&parser::AsDisplay(flags)) } // Serialize non-human-readable flags directly as the underlying bits else { flags.bits().serialize(serializer) } } /** Deserialize a set of flags from a human-readable string or their underlying bits. Any unknown bits will be retained. */ pub fn deserialize<'de, B: Flags, D: Deserializer<'de>>(deserializer: D) -> Result where B::Bits: ParseHex + Deserialize<'de>, { if deserializer.is_human_readable() { // Deserialize human-readable flags by parsing them from strings like `"A | B"` struct FlagsVisitor(core::marker::PhantomData); impl<'de, B: Flags> Visitor<'de> for FlagsVisitor where B::Bits: ParseHex, { type Value = B; fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { formatter.write_str("a string value of `|` separated flags") } fn visit_str(self, flags: &str) -> Result { parser::from_str(flags).map_err(|e| E::custom(e)) } } deserializer.deserialize_str(FlagsVisitor(Default::default())) } else { // Deserialize non-human-readable flags directly from the underlying bits let bits = B::Bits::deserialize(deserializer)?; Ok(B::from_bits_retain(bits)) } } #[cfg(test)] mod tests { use serde_test::{assert_tokens, Configure, Token::*}; bitflags! { #[derive(serde_derive::Serialize, serde_derive::Deserialize, Debug, PartialEq, Eq)] #[serde(transparent)] struct SerdeFlags: u32 { const A = 1; const B = 2; const C = 4; const D = 8; } } #[test] fn test_serde_bitflags_default() { assert_tokens(&SerdeFlags::empty().readable(), &[Str("")]); assert_tokens(&SerdeFlags::empty().compact(), &[U32(0)]); assert_tokens(&(SerdeFlags::A | SerdeFlags::B).readable(), &[Str("A | B")]); assert_tokens(&(SerdeFlags::A | SerdeFlags::B).compact(), &[U32(1 | 2)]); } } bitflags-2.4.2/src/external.rs000064400000000000000000000163021046102023000144050ustar 00000000000000//! Conditional trait implementations for external libraries. /* How do I support a new external library? Let's say we want to add support for `my_library`. First, we create a module under `external`, like `serde` with any specialized code. Ideally, any utilities in here should just work off the `Flags` trait and maybe a few other assumed bounds. Next, re-export the library from the `__private` module here. Next, define a macro like so: ```rust #[macro_export] #[doc(hidden)] #[cfg(feature = "serde")] macro_rules! __impl_external_bitflags_my_library { ( $InternalBitFlags:ident: $T:ty, $PublicBitFlags:ident { $( $(#[$inner:ident $($args:tt)*])* const $Flag:tt; )* } ) => { // Implementation goes here }; } #[macro_export] #[doc(hidden)] #[cfg(not(feature = "my_library"))] macro_rules! __impl_external_bitflags_my_library { ( $InternalBitFlags:ident: $T:ty, $PublicBitFlags:ident { $( $(#[$inner:ident $($args:tt)*])* const $Flag:tt; )* } ) => {}; } ``` Note that the macro is actually defined twice; once for when the `my_library` feature is available, and once for when it's not. This is because the `__impl_external_bitflags_my_library` macro is called in an end-user's library, not in `bitflags`. In an end-user's library we don't know whether or not a particular feature of `bitflags` is enabled, so we unconditionally call the macro, where the body of that macro depends on the feature flag. Now, we add our macro call to the `__impl_external_bitflags` macro body: ```rust __impl_external_bitflags_my_library! { $InternalBitFlags: $T, $PublicBitFlags { $( $(#[$inner $($args)*])* const $Flag; )* } } ``` */ pub(crate) mod __private { #[cfg(feature = "serde")] pub use serde; #[cfg(feature = "arbitrary")] pub use arbitrary; #[cfg(feature = "bytemuck")] pub use bytemuck; } /// Implements traits from external libraries for the internal bitflags type. #[macro_export] #[doc(hidden)] macro_rules! __impl_external_bitflags { ( $InternalBitFlags:ident: $T:ty, $PublicBitFlags:ident { $( $(#[$inner:ident $($args:tt)*])* const $Flag:tt; )* } ) => { // Any new library traits impls should be added here // Use `serde` as an example: generate code when the feature is available, // and a no-op when it isn't $crate::__impl_external_bitflags_serde! { $InternalBitFlags: $T, $PublicBitFlags { $( $(#[$inner $($args)*])* const $Flag; )* } } $crate::__impl_external_bitflags_arbitrary! { $InternalBitFlags: $T, $PublicBitFlags { $( $(#[$inner $($args)*])* const $Flag; )* } } $crate::__impl_external_bitflags_bytemuck! { $InternalBitFlags: $T, $PublicBitFlags { $( $(#[$inner $($args)*])* const $Flag; )* } } }; } #[cfg(feature = "serde")] pub mod serde; /// Implement `Serialize` and `Deserialize` for the internal bitflags type. #[macro_export] #[doc(hidden)] #[cfg(feature = "serde")] macro_rules! __impl_external_bitflags_serde { ( $InternalBitFlags:ident: $T:ty, $PublicBitFlags:ident { $( $(#[$inner:ident $($args:tt)*])* const $Flag:tt; )* } ) => { impl $crate::__private::serde::Serialize for $InternalBitFlags { fn serialize( &self, serializer: S, ) -> $crate::__private::core::result::Result { $crate::serde::serialize( &$PublicBitFlags::from_bits_retain(self.bits()), serializer, ) } } impl<'de> $crate::__private::serde::Deserialize<'de> for $InternalBitFlags { fn deserialize>( deserializer: D, ) -> $crate::__private::core::result::Result { let flags: $PublicBitFlags = $crate::serde::deserialize(deserializer)?; Ok(flags.0) } } }; } #[macro_export] #[doc(hidden)] #[cfg(not(feature = "serde"))] macro_rules! __impl_external_bitflags_serde { ( $InternalBitFlags:ident: $T:ty, $PublicBitFlags:ident { $( $(#[$inner:ident $($args:tt)*])* const $Flag:tt; )* } ) => {}; } #[cfg(feature = "arbitrary")] pub mod arbitrary; #[cfg(feature = "bytemuck")] mod bytemuck; /// Implement `Arbitrary` for the internal bitflags type. #[macro_export] #[doc(hidden)] #[cfg(feature = "arbitrary")] macro_rules! __impl_external_bitflags_arbitrary { ( $InternalBitFlags:ident: $T:ty, $PublicBitFlags:ident { $( $(#[$inner:ident $($args:tt)*])* const $Flag:tt; )* } ) => { impl<'a> $crate::__private::arbitrary::Arbitrary<'a> for $InternalBitFlags { fn arbitrary( u: &mut $crate::__private::arbitrary::Unstructured<'a>, ) -> $crate::__private::arbitrary::Result { $crate::arbitrary::arbitrary::<$PublicBitFlags>(u).map(|flags| flags.0) } } }; } #[macro_export] #[doc(hidden)] #[cfg(not(feature = "arbitrary"))] macro_rules! __impl_external_bitflags_arbitrary { ( $InternalBitFlags:ident: $T:ty, $PublicBitFlags:ident { $( $(#[$inner:ident $($args:tt)*])* const $Flag:tt; )* } ) => {}; } /// Implement `Pod` and `Zeroable` for the internal bitflags type. #[macro_export] #[doc(hidden)] #[cfg(feature = "bytemuck")] macro_rules! __impl_external_bitflags_bytemuck { ( $InternalBitFlags:ident: $T:ty, $PublicBitFlags:ident { $( $(#[$inner:ident $($args:tt)*])* const $Flag:tt; )* } ) => { // SAFETY: $InternalBitFlags is guaranteed to have the same ABI as $T, // and $T implements Pod unsafe impl $crate::__private::bytemuck::Pod for $InternalBitFlags where $T: $crate::__private::bytemuck::Pod { } // SAFETY: $InternalBitFlags is guaranteed to have the same ABI as $T, // and $T implements Zeroable unsafe impl $crate::__private::bytemuck::Zeroable for $InternalBitFlags where $T: $crate::__private::bytemuck::Zeroable { } }; } #[macro_export] #[doc(hidden)] #[cfg(not(feature = "bytemuck"))] macro_rules! __impl_external_bitflags_bytemuck { ( $InternalBitFlags:ident: $T:ty, $PublicBitFlags:ident { $( $(#[$inner:ident $($args:tt)*])* const $Flag:tt; )* } ) => {}; } bitflags-2.4.2/src/internal.rs000064400000000000000000000112531046102023000143770ustar 00000000000000//! Generate the internal `bitflags`-facing flags type. //! //! The code generated here is owned by `bitflags`, but still part of its public API. //! Changes to the types generated here need to be considered like any other public API change. /// Declare the `bitflags`-facing bitflags struct. /// /// This type is part of the `bitflags` crate's public API, but not part of the user's. #[macro_export] #[doc(hidden)] macro_rules! __declare_internal_bitflags { ( $vis:vis struct $InternalBitFlags:ident: $T:ty ) => { // NOTE: The ABI of this type is _guaranteed_ to be the same as `T` // This is relied on by some external libraries like `bytemuck` to make // its `unsafe` trait impls sound. #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] #[repr(transparent)] $vis struct $InternalBitFlags($T); }; } /// Implement functions on the private (bitflags-facing) bitflags type. /// /// Methods and trait implementations can be freely added here without breaking end-users. /// If we want to expose new functionality to `#[derive]`, this is the place to do it. #[macro_export] #[doc(hidden)] macro_rules! __impl_internal_bitflags { ( $InternalBitFlags:ident: $T:ty, $PublicBitFlags:ident { $( $(#[$inner:ident $($args:tt)*])* const $Flag:tt = $value:expr; )* } ) => { // NOTE: This impl is also used to prevent using bits types from non-primitive types // in the `bitflags` macro. If this approach is changed, this guard will need to be // retained somehow impl $crate::__private::PublicFlags for $PublicBitFlags { type Primitive = $T; type Internal = $InternalBitFlags; } impl $crate::__private::core::default::Default for $InternalBitFlags { #[inline] fn default() -> Self { $InternalBitFlags::empty() } } impl $crate::__private::core::fmt::Debug for $InternalBitFlags { fn fmt(&self, f: &mut $crate::__private::core::fmt::Formatter<'_>) -> $crate::__private::core::fmt::Result { if self.is_empty() { // If no flags are set then write an empty hex flag to avoid // writing an empty string. In some contexts, like serialization, // an empty string is preferable, but it may be unexpected in // others for a format not to produce any output. // // We can remove this `0x0` and remain compatible with `FromStr`, // because an empty string will still parse to an empty set of flags, // just like `0x0` does. $crate::__private::core::write!(f, "{:#x}", <$T as $crate::Bits>::EMPTY) } else { $crate::__private::core::fmt::Display::fmt(self, f) } } } impl $crate::__private::core::fmt::Display for $InternalBitFlags { fn fmt(&self, f: &mut $crate::__private::core::fmt::Formatter<'_>) -> $crate::__private::core::fmt::Result { $crate::parser::to_writer(&$PublicBitFlags(*self), f) } } impl $crate::__private::core::str::FromStr for $InternalBitFlags { type Err = $crate::parser::ParseError; fn from_str(s: &str) -> $crate::__private::core::result::Result { $crate::parser::from_str::<$PublicBitFlags>(s).map(|flags| flags.0) } } impl $crate::__private::core::convert::AsRef<$T> for $InternalBitFlags { fn as_ref(&self) -> &$T { &self.0 } } impl $crate::__private::core::convert::From<$T> for $InternalBitFlags { fn from(bits: $T) -> Self { Self::from_bits_retain(bits) } } // The internal flags type offers a similar API to the public one $crate::__impl_public_bitflags! { $InternalBitFlags: $T, $PublicBitFlags { $( $(#[$inner $($args)*])* const $Flag = $value; )* } } $crate::__impl_public_bitflags_ops! { $InternalBitFlags } $crate::__impl_public_bitflags_iter! { $InternalBitFlags: $T, $PublicBitFlags } impl $InternalBitFlags { /// Returns a mutable reference to the raw value of the flags currently stored. #[inline] pub fn bits_mut(&mut self) -> &mut $T { &mut self.0 } } }; } bitflags-2.4.2/src/iter.rs000064400000000000000000000101271046102023000135250ustar 00000000000000/*! Yield the bits of a source flags value in a set of contained flags values. */ use crate::{Flag, Flags}; /** An iterator over flags values. This iterator will yield flags values for contained, defined flags first, with any remaining bits yielded as a final flags value. */ pub struct Iter { inner: IterNames, done: bool, } impl Iter { pub(crate) fn new(flags: &B) -> Self { Iter { inner: IterNames::new(flags), done: false, } } } impl Iter { // Used by the `bitflags` macro #[doc(hidden)] pub const fn __private_const_new(flags: &'static [Flag], source: B, remaining: B) -> Self { Iter { inner: IterNames::__private_const_new(flags, source, remaining), done: false, } } } impl Iterator for Iter { type Item = B; fn next(&mut self) -> Option { match self.inner.next() { Some((_, flag)) => Some(flag), None if !self.done => { self.done = true; // After iterating through valid names, if there are any bits left over // then return one final value that includes them. This makes `into_iter` // and `from_iter` roundtrip if !self.inner.remaining().is_empty() { Some(B::from_bits_retain(self.inner.remaining.bits())) } else { None } } None => None, } } } /** An iterator over flags values. This iterator only yields flags values for contained, defined, named flags. Any remaining bits won't be yielded, but can be found with the [`IterNames::remaining`] method. */ pub struct IterNames { flags: &'static [Flag], idx: usize, source: B, remaining: B, } impl IterNames { pub(crate) fn new(flags: &B) -> Self { IterNames { flags: B::FLAGS, idx: 0, remaining: B::from_bits_retain(flags.bits()), source: B::from_bits_retain(flags.bits()), } } } impl IterNames { // Used by the bitflags macro #[doc(hidden)] pub const fn __private_const_new(flags: &'static [Flag], source: B, remaining: B) -> Self { IterNames { flags, idx: 0, remaining, source, } } /// Get a flags value of any remaining bits that haven't been yielded yet. /// /// Once the iterator has finished, this method can be used to /// check whether or not there are any bits that didn't correspond /// to a contained, defined, named flag remaining. pub fn remaining(&self) -> &B { &self.remaining } } impl Iterator for IterNames { type Item = (&'static str, B); fn next(&mut self) -> Option { while let Some(flag) = self.flags.get(self.idx) { // Short-circuit if our state is empty if self.remaining.is_empty() { return None; } self.idx += 1; // Skip unnamed flags if flag.name().is_empty() { continue; } let bits = flag.value().bits(); // If the flag is set in the original source _and_ it has bits that haven't // been covered by a previous flag yet then yield it. These conditions cover // two cases for multi-bit flags: // // 1. When flags partially overlap, such as `0b00000001` and `0b00000101`, we'll // yield both flags. // 2. When flags fully overlap, such as in convenience flags that are a shorthand for others, // we won't yield both flags. if self.source.contains(B::from_bits_retain(bits)) && self.remaining.intersects(B::from_bits_retain(bits)) { self.remaining.remove(B::from_bits_retain(bits)); return Some((flag.name(), B::from_bits_retain(bits))); } } None } } bitflags-2.4.2/src/lib.rs000064400000000000000000000646701046102023000133440ustar 00000000000000// Copyright 2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. /*! Generate types for C-style flags with ergonomic APIs. # Getting started Add `bitflags` to your `Cargo.toml`: ```toml [dependencies.bitflags] version = "2.4.2" ``` ## Generating flags types Use the [`bitflags`] macro to generate flags types: ```rust use bitflags::bitflags; bitflags! { pub struct Flags: u32 { const A = 0b00000001; const B = 0b00000010; const C = 0b00000100; } } ``` See the docs for the `bitflags` macro for the full syntax. Also see the [`example_generated`] module for an example of what the `bitflags` macro generates for a flags type. ### Externally defined flags If you're generating flags types for an external source, such as a C API, you can define an extra unnamed flag as a mask of all bits the external source may ever set. Usually this would be all bits (`!0`): ```rust # use bitflags::bitflags; bitflags! { pub struct Flags: u32 { const A = 0b00000001; const B = 0b00000010; const C = 0b00000100; // The source may set any bits const _ = !0; } } ``` Why should you do this? Generated methods like `all` and truncating operators like `!` only consider bits in defined flags. Adding an unnamed flag makes those methods consider additional bits, without generating additional constants for them. It helps compatibility when the external source may start setting additional bits at any time. The [known and unknown bits](#known-and-unknown-bits) section has more details on this behavior. ### Custom derives You can derive some traits on generated flags types if you enable Cargo features. The following libraries are currently supported: - `serde`: Support `#[derive(Serialize, Deserialize)]`, using text for human-readable formats, and a raw number for binary formats. - `arbitrary`: Support `#[derive(Arbitrary)]`, only generating flags values with known bits. - `bytemuck`: Support `#[derive(Pod, Zeroable)]`, for casting between flags values and their underlying bits values. You can also define your own flags type outside of the [`bitflags`] macro and then use it to generate methods. This can be useful if you need a custom `#[derive]` attribute for a library that `bitflags` doesn't natively support: ```rust # use std::fmt::Debug as SomeTrait; # use bitflags::bitflags; #[derive(SomeTrait)] pub struct Flags(u32); bitflags! { impl Flags: u32 { const A = 0b00000001; const B = 0b00000010; const C = 0b00000100; } } ``` ### Adding custom methods The [`bitflags`] macro supports attributes on generated flags types within the macro itself, while `impl` blocks can be added outside of it: ```rust # use bitflags::bitflags; bitflags! { // Attributes can be applied to flags types #[repr(transparent)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct Flags: u32 { const A = 0b00000001; const B = 0b00000010; const C = 0b00000100; } } // Impl blocks can be added to flags types impl Flags { pub fn as_u64(&self) -> u64 { self.bits() as u64 } } ``` ## Working with flags values Use generated constants and standard bitwise operators to interact with flags values: ```rust # use bitflags::bitflags; # bitflags! { # #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] # pub struct Flags: u32 { # const A = 0b00000001; # const B = 0b00000010; # const C = 0b00000100; # } # } // union let ab = Flags::A | Flags::B; // intersection let a = ab & Flags::A; // difference let b = ab - Flags::A; // complement let c = !ab; ``` See the docs for the [`Flags`] trait for more details on operators and how they behave. # Formatting and parsing `bitflags` defines a text format that can be used to convert any flags value to and from strings. See the [`parser`] module for more details. # Specification The terminology and behavior of generated flags types is [specified in the source repository](https://github.com/bitflags/bitflags/blob/main/spec.md). Details are repeated in these docs where appropriate, but is exhaustively listed in the spec. Some things are worth calling out explicitly here. ## Flags types, flags values, flags The spec and these docs use consistent terminology to refer to things in the bitflags domain: - **Bits type**: A type that defines a fixed number of bits at specific locations. - **Flag**: A set of bits in a bits type that may have a unique name. - **Flags type**: A set of defined flags over a specific bits type. - **Flags value**: An instance of a flags type using its specific bits value for storage. ``` # use bitflags::bitflags; bitflags! { struct FlagsType: u8 { // -- Bits type // --------- Flags type const A = 1; // ----- Flag } } let flag = FlagsType::A; // ---- Flags value ``` ## Known and unknown bits Any bits in a flag you define are called _known bits_. Any other bits are _unknown bits_. In the following flags type: ``` # use bitflags::bitflags; bitflags! { struct Flags: u8 { const A = 1; const B = 1 << 1; const C = 1 << 2; } } ``` The known bits are `0b0000_0111` and the unknown bits are `0b1111_1000`. `bitflags` doesn't guarantee that a flags value will only ever have known bits set, but some operators will unset any unknown bits they encounter. In a future version of `bitflags`, all operators will unset unknown bits. If you're using `bitflags` for flags types defined externally, such as from C, you probably want all bits to be considered known, in case that external source changes. You can do this using an unnamed flag, as described in [externally defined flags](#externally-defined-flags). ## Zero-bit flags Flags with no bits set should be avoided because they interact strangely with [`Flags::contains`] and [`Flags::intersects`]. A zero-bit flag is always contained, but is never intersected. The names of zero-bit flags can be parsed, but are never formatted. ## Multi-bit flags Flags that set multiple bits should be avoided unless each bit is also in a single-bit flag. Take the following flags type as an example: ``` # use bitflags::bitflags; bitflags! { struct Flags: u8 { const A = 1; const B = 1 | 1 << 1; } } ``` The result of `Flags::A ^ Flags::B` is `0b0000_0010`, which doesn't correspond to either `Flags::A` or `Flags::B` even though it's still a known bit. */ #![cfg_attr(not(any(feature = "std", test)), no_std)] #![cfg_attr(not(test), forbid(unsafe_code))] #![cfg_attr(test, allow(mixed_script_confusables))] #[doc(inline)] pub use traits::{Bits, Flag, Flags}; pub mod iter; pub mod parser; mod traits; #[doc(hidden)] pub mod __private { #[allow(unused_imports)] // Easier than conditionally checking any optional external dependencies pub use crate::{external::__private::*, traits::__private::*}; pub use core; } #[allow(unused_imports)] pub use external::*; #[allow(deprecated)] pub use traits::BitFlags; /* How does the bitflags crate work? This library generates a `struct` in the end-user's crate with a bunch of constants on it that represent flags. The difference between `bitflags` and a lot of other libraries is that we don't actually control the generated `struct` in the end. It's part of the end-user's crate, so it belongs to them. That makes it difficult to extend `bitflags` with new functionality because we could end up breaking valid code that was already written. 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). To give you an example, let's say we had a crate that called `bitflags!`: ```rust bitflags! { pub struct MyFlags: u32 { const A = 1; const B = 2; } } ``` What they'd end up with looks something like this: ```rust pub struct MyFlags(::InternalBitFlags); const _: () = { #[repr(transparent)] #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct MyInternalBitFlags { bits: u32, } impl PublicFlags for MyFlags { type Internal = InternalBitFlags; } }; ``` If we want to expose something like a new trait impl for generated flags types, we add it to our generated `MyInternalBitFlags`, and let `#[derive]` on `MyFlags` pick up that implementation, if an end-user chooses to add one. The public API is generated in the `__impl_public_flags!` macro, and the internal API is generated in the `__impl_internal_flags!` macro. The macros are split into 3 modules: - `public`: where the user-facing flags types are generated. - `internal`: where the `bitflags`-facing flags types are generated. - `external`: where external library traits are implemented conditionally. */ /** Generate a flags type. # `struct` mode A declaration that begins with `$vis struct` will generate a `struct` for a flags type, along with methods and trait implementations for it. The body of the declaration defines flags as constants, where each constant is a flags value of the generated flags type. ## Examples Generate a flags type using `u8` as the bits type: ``` # use bitflags::bitflags; bitflags! { struct Flags: u8 { const A = 1; const B = 1 << 1; const C = 0b0000_0100; } } ``` Flags types are private by default and accept standard visibility modifiers. Flags themselves are always public: ``` # use bitflags::bitflags; bitflags! { pub struct Flags: u8 { // Constants are always `pub` const A = 1; } } ``` Flags may refer to other flags using their [`Flags::bits`] value: ``` # use bitflags::bitflags; bitflags! { struct Flags: u8 { const A = 1; const B = 1 << 1; const AB = Flags::A.bits() | Flags::B.bits(); } } ``` A single `bitflags` invocation may include zero or more flags type declarations: ``` # use bitflags::bitflags; bitflags! {} bitflags! { struct Flags1: u8 { const A = 1; } struct Flags2: u8 { const A = 1; } } ``` # `impl` mode A declaration that begins with `impl` will only generate methods and trait implementations for the `struct` defined outside of the `bitflags` macro. The struct itself must be a newtype using the bits type as its field. The syntax for `impl` mode is identical to `struct` mode besides the starting token. ## Examples Implement flags methods and traits for a custom flags type using `u8` as its underlying bits type: ``` # use bitflags::bitflags; struct Flags(u8); bitflags! { impl Flags: u8 { const A = 1; const B = 1 << 1; const C = 0b0000_0100; } } ``` # Named and unnamed flags Constants in the body of a declaration are flags. The identifier of the constant is the name of the flag. If the identifier is `_`, then the flag is unnamed. Unnamed flags don't appear in the generated API, but affect how bits are truncated. ## Examples Adding an unnamed flag that makes all bits known: ``` # use bitflags::bitflags; bitflags! { struct Flags: u8 { const A = 1; const B = 1 << 1; const _ = !0; } } ``` Flags types may define multiple unnamed flags: ``` # use bitflags::bitflags; bitflags! { struct Flags: u8 { const _ = 1; const _ = 1 << 1; } } ``` */ #[macro_export] macro_rules! bitflags { ( $(#[$outer:meta])* $vis:vis struct $BitFlags:ident: $T:ty { $( $(#[$inner:ident $($args:tt)*])* const $Flag:tt = $value:expr; )* } $($t:tt)* ) => { // Declared in the scope of the `bitflags!` call // This type appears in the end-user's API $crate::__declare_public_bitflags! { $(#[$outer])* $vis struct $BitFlags } // Workaround for: https://github.com/bitflags/bitflags/issues/320 $crate::__impl_public_bitflags_consts! { $BitFlags: $T { $( $(#[$inner $($args)*])* const $Flag = $value; )* } } #[allow( dead_code, deprecated, unused_doc_comments, unused_attributes, unused_mut, unused_imports, non_upper_case_globals, clippy::assign_op_pattern, clippy::indexing_slicing, clippy::same_name_method, clippy::iter_without_into_iter, )] const _: () = { // Declared in a "hidden" scope that can't be reached directly // These types don't appear in the end-user's API $crate::__declare_internal_bitflags! { $vis struct InternalBitFlags: $T } $crate::__impl_internal_bitflags! { InternalBitFlags: $T, $BitFlags { $( $(#[$inner $($args)*])* const $Flag = $value; )* } } // This is where new library trait implementations can be added $crate::__impl_external_bitflags! { InternalBitFlags: $T, $BitFlags { $( $(#[$inner $($args)*])* const $Flag; )* } } $crate::__impl_public_bitflags_forward! { $BitFlags: $T, InternalBitFlags } $crate::__impl_public_bitflags_ops! { $BitFlags } $crate::__impl_public_bitflags_iter! { $BitFlags: $T, $BitFlags } }; $crate::bitflags! { $($t)* } }; ( impl $BitFlags:ident: $T:ty { $( $(#[$inner:ident $($args:tt)*])* const $Flag:tt = $value:expr; )* } $($t:tt)* ) => { $crate::__impl_public_bitflags_consts! { $BitFlags: $T { $( $(#[$inner $($args)*])* const $Flag = $value; )* } } #[allow( dead_code, deprecated, unused_doc_comments, unused_attributes, unused_mut, unused_imports, non_upper_case_globals, clippy::assign_op_pattern, clippy::iter_without_into_iter, )] const _: () = { $crate::__impl_public_bitflags! { $BitFlags: $T, $BitFlags { $( $(#[$inner $($args)*])* const $Flag = $value; )* } } $crate::__impl_public_bitflags_ops! { $BitFlags } $crate::__impl_public_bitflags_iter! { $BitFlags: $T, $BitFlags } }; $crate::bitflags! { $($t)* } }; () => {}; } /// Implement functions on bitflags types. /// /// We need to be careful about adding new methods and trait implementations here because they /// could conflict with items added by the end-user. #[macro_export] #[doc(hidden)] macro_rules! __impl_bitflags { ( $PublicBitFlags:ident: $T:ty { fn empty() $empty:block fn all() $all:block fn bits($bits0:ident) $bits:block fn from_bits($from_bits0:ident) $from_bits:block fn from_bits_truncate($from_bits_truncate0:ident) $from_bits_truncate:block fn from_bits_retain($from_bits_retain0:ident) $from_bits_retain:block fn from_name($from_name0:ident) $from_name:block fn is_empty($is_empty0:ident) $is_empty:block fn is_all($is_all0:ident) $is_all:block fn intersects($intersects0:ident, $intersects1:ident) $intersects:block fn contains($contains0:ident, $contains1:ident) $contains:block fn insert($insert0:ident, $insert1:ident) $insert:block fn remove($remove0:ident, $remove1:ident) $remove:block fn toggle($toggle0:ident, $toggle1:ident) $toggle:block fn set($set0:ident, $set1:ident, $set2:ident) $set:block fn intersection($intersection0:ident, $intersection1:ident) $intersection:block fn union($union0:ident, $union1:ident) $union:block fn difference($difference0:ident, $difference1:ident) $difference:block fn symmetric_difference($symmetric_difference0:ident, $symmetric_difference1:ident) $symmetric_difference:block fn complement($complement0:ident) $complement:block } ) => { #[allow(dead_code, deprecated, unused_attributes)] impl $PublicBitFlags { /// Get a flags value with all bits unset. #[inline] pub const fn empty() -> Self { $empty } /// Get a flags value with all known bits set. #[inline] pub const fn all() -> Self { $all } /// Get the underlying bits value. /// /// The returned value is exactly the bits set in this flags value. #[inline] pub const fn bits(&self) -> $T { let $bits0 = self; $bits } /// Convert from a bits value. /// /// This method will return `None` if any unknown bits are set. #[inline] pub const fn from_bits(bits: $T) -> $crate::__private::core::option::Option { let $from_bits0 = bits; $from_bits } /// Convert from a bits value, unsetting any unknown bits. #[inline] pub const fn from_bits_truncate(bits: $T) -> Self { let $from_bits_truncate0 = bits; $from_bits_truncate } /// Convert from a bits value exactly. #[inline] pub const fn from_bits_retain(bits: $T) -> Self { let $from_bits_retain0 = bits; $from_bits_retain } /// Get a flags value with the bits of a flag with the given name set. /// /// This method will return `None` if `name` is empty or doesn't /// correspond to any named flag. #[inline] pub fn from_name(name: &str) -> $crate::__private::core::option::Option { let $from_name0 = name; $from_name } /// Whether all bits in this flags value are unset. #[inline] pub const fn is_empty(&self) -> bool { let $is_empty0 = self; $is_empty } /// Whether all known bits in this flags value are set. #[inline] pub const fn is_all(&self) -> bool { let $is_all0 = self; $is_all } /// Whether any set bits in a source flags value are also set in a target flags value. #[inline] pub const fn intersects(&self, other: Self) -> bool { let $intersects0 = self; let $intersects1 = other; $intersects } /// Whether all set bits in a source flags value are also set in a target flags value. #[inline] pub const fn contains(&self, other: Self) -> bool { let $contains0 = self; let $contains1 = other; $contains } /// The bitwise or (`|`) of the bits in two flags values. #[inline] pub fn insert(&mut self, other: Self) { let $insert0 = self; let $insert1 = other; $insert } /// The intersection of a source flags value with the complement of a target flags value (`&!`). /// /// This method is not equivalent to `self & !other` when `other` has unknown bits set. /// `remove` won't truncate `other`, but the `!` operator will. #[inline] pub fn remove(&mut self, other: Self) { let $remove0 = self; let $remove1 = other; $remove } /// The bitwise exclusive-or (`^`) of the bits in two flags values. #[inline] pub fn toggle(&mut self, other: Self) { let $toggle0 = self; let $toggle1 = other; $toggle } /// Call `insert` when `value` is `true` or `remove` when `value` is `false`. #[inline] pub fn set(&mut self, other: Self, value: bool) { let $set0 = self; let $set1 = other; let $set2 = value; $set } /// The bitwise and (`&`) of the bits in two flags values. #[inline] #[must_use] pub const fn intersection(self, other: Self) -> Self { let $intersection0 = self; let $intersection1 = other; $intersection } /// The bitwise or (`|`) of the bits in two flags values. #[inline] #[must_use] pub const fn union(self, other: Self) -> Self { let $union0 = self; let $union1 = other; $union } /// The intersection of a source flags value with the complement of a target flags value (`&!`). /// /// This method is not equivalent to `self & !other` when `other` has unknown bits set. /// `difference` won't truncate `other`, but the `!` operator will. #[inline] #[must_use] pub const fn difference(self, other: Self) -> Self { let $difference0 = self; let $difference1 = other; $difference } /// The bitwise exclusive-or (`^`) of the bits in two flags values. #[inline] #[must_use] pub const fn symmetric_difference(self, other: Self) -> Self { let $symmetric_difference0 = self; let $symmetric_difference1 = other; $symmetric_difference } /// The bitwise negation (`!`) of the bits in a flags value, truncating the result. #[inline] #[must_use] pub const fn complement(self) -> Self { let $complement0 = self; $complement } } }; } /// A macro that processed the input to `bitflags!` and shuffles attributes around /// based on whether or not they're "expression-safe". /// /// This macro is a token-tree muncher that works on 2 levels: /// /// For each attribute, we explicitly match on its identifier, like `cfg` to determine /// whether or not it should be considered expression-safe. /// /// If you find yourself with an attribute that should be considered expression-safe /// and isn't, it can be added here. #[macro_export] #[doc(hidden)] macro_rules! __bitflags_expr_safe_attrs { // Entrypoint: Move all flags and all attributes into `unprocessed` lists // where they'll be munched one-at-a-time ( $(#[$inner:ident $($args:tt)*])* { $e:expr } ) => { $crate::__bitflags_expr_safe_attrs! { expr: { $e }, attrs: { // All attributes start here unprocessed: [$(#[$inner $($args)*])*], // Attributes that are safe on expressions go here processed: [], }, } }; // Process the next attribute on the current flag // `cfg`: The next flag should be propagated to expressions // NOTE: You can copy this rules block and replace `cfg` with // your attribute name that should be considered expression-safe ( expr: { $e:expr }, attrs: { unprocessed: [ // cfg matched here #[cfg $($args:tt)*] $($attrs_rest:tt)* ], processed: [$($expr:tt)*], }, ) => { $crate::__bitflags_expr_safe_attrs! { expr: { $e }, attrs: { unprocessed: [ $($attrs_rest)* ], processed: [ $($expr)* // cfg added here #[cfg $($args)*] ], }, } }; // Process the next attribute on the current flag // `$other`: The next flag should not be propagated to expressions ( expr: { $e:expr }, attrs: { unprocessed: [ // $other matched here #[$other:ident $($args:tt)*] $($attrs_rest:tt)* ], processed: [$($expr:tt)*], }, ) => { $crate::__bitflags_expr_safe_attrs! { expr: { $e }, attrs: { unprocessed: [ $($attrs_rest)* ], processed: [ // $other not added here $($expr)* ], }, } }; // Once all attributes on all flags are processed, generate the actual code ( expr: { $e:expr }, attrs: { unprocessed: [], processed: [$(#[$expr:ident $($exprargs:tt)*])*], }, ) => { $(#[$expr $($exprargs)*])* { $e } } } /// Implement a flag, which may be a wildcard `_`. #[macro_export] #[doc(hidden)] macro_rules! __bitflags_flag { ( { name: _, named: { $($named:tt)* }, unnamed: { $($unnamed:tt)* }, } ) => { $($unnamed)* }; ( { name: $Flag:ident, named: { $($named:tt)* }, unnamed: { $($unnamed:tt)* }, } ) => { $($named)* }; } #[macro_use] mod public; #[macro_use] mod internal; #[macro_use] mod external; #[cfg(feature = "example_generated")] pub mod example_generated; #[cfg(test)] mod tests; bitflags-2.4.2/src/parser.rs000064400000000000000000000135731046102023000140660ustar 00000000000000/*! Parsing flags from text. Format and parse a flags value as text using the following grammar: - _Flags:_ (_Whitespace_ _Flag_ _Whitespace_)`|`* - _Flag:_ _Name_ | _Hex Number_ - _Name:_ The name of any defined flag - _Hex Number_: `0x`([0-9a-fA-F])* - _Whitespace_: (\s)* As an example, this is how `Flags::A | Flags::B | 0x0c` can be represented as text: ```text A | B | 0x0c ``` Alternatively, it could be represented without whitespace: ```text A|B|0x0C ``` Note that identifiers are *case-sensitive*, so the following is *not equivalent*: ```text a|b|0x0C ``` */ #![allow(clippy::let_unit_value)] use core::fmt::{self, Write}; use crate::{Bits, Flags}; /** Write a flags value as text. Any bits that aren't part of a contained flag will be formatted as a hex number. */ pub fn to_writer(flags: &B, mut writer: impl Write) -> Result<(), fmt::Error> where B::Bits: WriteHex, { // A formatter for bitflags that produces text output like: // // A | B | 0xf6 // // The names of set flags are written in a bar-separated-format, // followed by a hex number of any remaining bits that are set // but don't correspond to any flags. // Iterate over known flag values let mut first = true; let mut iter = flags.iter_names(); for (name, _) in &mut iter { if !first { writer.write_str(" | ")?; } first = false; writer.write_str(name)?; } // Append any extra bits that correspond to flags to the end of the format let remaining = iter.remaining().bits(); if remaining != B::Bits::EMPTY { if !first { writer.write_str(" | ")?; } writer.write_str("0x")?; remaining.write_hex(writer)?; } fmt::Result::Ok(()) } pub(crate) struct AsDisplay<'a, B>(pub(crate) &'a B); impl<'a, B: Flags> fmt::Display for AsDisplay<'a, B> where B::Bits: WriteHex, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { to_writer(self.0, f) } } /** Parse a flags value from text. This function will fail on any names that don't correspond to defined flags. Unknown bits will be retained. */ pub fn from_str(input: &str) -> Result where B::Bits: ParseHex, { let mut parsed_flags = B::empty(); // If the input is empty then return an empty set of flags if input.trim().is_empty() { return Ok(parsed_flags); } for flag in input.split('|') { let flag = flag.trim(); // If the flag is empty then we've got missing input if flag.is_empty() { return Err(ParseError::empty_flag()); } // If the flag starts with `0x` then it's a hex number // Parse it directly to the underlying bits type let parsed_flag = if let Some(flag) = flag.strip_prefix("0x") { let bits = ::parse_hex(flag).map_err(|_| ParseError::invalid_hex_flag(flag))?; B::from_bits_retain(bits) } // Otherwise the flag is a name // The generated flags type will determine whether // or not it's a valid identifier else { B::from_name(flag).ok_or_else(|| ParseError::invalid_named_flag(flag))? }; parsed_flags.insert(parsed_flag); } Ok(parsed_flags) } /** Encode a value as a hex string. Implementors of this trait should not write the `0x` prefix. */ pub trait WriteHex { /// Write the value as hex. fn write_hex(&self, writer: W) -> fmt::Result; } /** Parse a value from a hex string. */ pub trait ParseHex { /// Parse the value from hex. fn parse_hex(input: &str) -> Result where Self: Sized; } /// An error encountered while parsing flags from text. #[derive(Debug)] pub struct ParseError(ParseErrorKind); #[derive(Debug)] #[allow(clippy::enum_variant_names)] enum ParseErrorKind { EmptyFlag, InvalidNamedFlag { #[cfg(not(feature = "std"))] got: (), #[cfg(feature = "std")] got: String, }, InvalidHexFlag { #[cfg(not(feature = "std"))] got: (), #[cfg(feature = "std")] got: String, }, } impl ParseError { /// An invalid hex flag was encountered. pub fn invalid_hex_flag(flag: impl fmt::Display) -> Self { let _flag = flag; let got = { #[cfg(feature = "std")] { _flag.to_string() } }; ParseError(ParseErrorKind::InvalidHexFlag { got }) } /// A named flag that doesn't correspond to any on the flags type was encountered. pub fn invalid_named_flag(flag: impl fmt::Display) -> Self { let _flag = flag; let got = { #[cfg(feature = "std")] { _flag.to_string() } }; ParseError(ParseErrorKind::InvalidNamedFlag { got }) } /// A hex or named flag wasn't found between separators. pub const fn empty_flag() -> Self { ParseError(ParseErrorKind::EmptyFlag) } } impl fmt::Display for ParseError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match &self.0 { ParseErrorKind::InvalidNamedFlag { got } => { let _got = got; write!(f, "unrecognized named flag")?; #[cfg(feature = "std")] { write!(f, " `{}`", _got)?; } } ParseErrorKind::InvalidHexFlag { got } => { let _got = got; write!(f, "invalid hex flag")?; #[cfg(feature = "std")] { write!(f, " `{}`", _got)?; } } ParseErrorKind::EmptyFlag => { write!(f, "encountered empty flag")?; } } Ok(()) } } #[cfg(feature = "std")] impl std::error::Error for ParseError {} bitflags-2.4.2/src/public.rs000064400000000000000000000447761046102023000140610ustar 00000000000000//! Generate the user-facing flags type. //! //! The code here belongs to the end-user, so new trait implementations and methods can't be //! added without potentially breaking users. /// Declare the user-facing bitflags struct. /// /// This type is guaranteed to be a newtype with a `bitflags`-facing type as its single field. #[macro_export] #[doc(hidden)] macro_rules! __declare_public_bitflags { ( $(#[$outer:meta])* $vis:vis struct $PublicBitFlags:ident ) => { $(#[$outer])* $vis struct $PublicBitFlags(<$PublicBitFlags as $crate::__private::PublicFlags>::Internal); }; } /// Implement functions on the public (user-facing) bitflags type. /// /// We need to be careful about adding new methods and trait implementations here because they /// could conflict with items added by the end-user. #[macro_export] #[doc(hidden)] macro_rules! __impl_public_bitflags_forward { ( $PublicBitFlags:ident: $T:ty, $InternalBitFlags:ident ) => { $crate::__impl_bitflags! { $PublicBitFlags: $T { fn empty() { Self($InternalBitFlags::empty()) } fn all() { Self($InternalBitFlags::all()) } fn bits(f) { f.0.bits() } fn from_bits(bits) { match $InternalBitFlags::from_bits(bits) { $crate::__private::core::option::Option::Some(bits) => $crate::__private::core::option::Option::Some(Self(bits)), $crate::__private::core::option::Option::None => $crate::__private::core::option::Option::None, } } fn from_bits_truncate(bits) { Self($InternalBitFlags::from_bits_truncate(bits)) } fn from_bits_retain(bits) { Self($InternalBitFlags::from_bits_retain(bits)) } fn from_name(name) { match $InternalBitFlags::from_name(name) { $crate::__private::core::option::Option::Some(bits) => $crate::__private::core::option::Option::Some(Self(bits)), $crate::__private::core::option::Option::None => $crate::__private::core::option::Option::None, } } fn is_empty(f) { f.0.is_empty() } fn is_all(f) { f.0.is_all() } fn intersects(f, other) { f.0.intersects(other.0) } fn contains(f, other) { f.0.contains(other.0) } fn insert(f, other) { f.0.insert(other.0) } fn remove(f, other) { f.0.remove(other.0) } fn toggle(f, other) { f.0.toggle(other.0) } fn set(f, other, value) { f.0.set(other.0, value) } fn intersection(f, other) { Self(f.0.intersection(other.0)) } fn union(f, other) { Self(f.0.union(other.0)) } fn difference(f, other) { Self(f.0.difference(other.0)) } fn symmetric_difference(f, other) { Self(f.0.symmetric_difference(other.0)) } fn complement(f) { Self(f.0.complement()) } } } }; } /// Implement functions on the public (user-facing) bitflags type. /// /// We need to be careful about adding new methods and trait implementations here because they /// could conflict with items added by the end-user. #[macro_export] #[doc(hidden)] macro_rules! __impl_public_bitflags { ( $BitFlags:ident: $T:ty, $PublicBitFlags:ident { $( $(#[$inner:ident $($args:tt)*])* const $Flag:tt = $value:expr; )* } ) => { $crate::__impl_bitflags! { $BitFlags: $T { fn empty() { Self(<$T as $crate::Bits>::EMPTY) } fn all() { let mut truncated = <$T as $crate::Bits>::EMPTY; let mut i = 0; $( $crate::__bitflags_expr_safe_attrs!( $(#[$inner $($args)*])* {{ let flag = <$PublicBitFlags as $crate::Flags>::FLAGS[i].value().bits(); truncated = truncated | flag; i += 1; }} ); )* let _ = i; Self::from_bits_retain(truncated) } fn bits(f) { f.0 } fn from_bits(bits) { let truncated = Self::from_bits_truncate(bits).0; if truncated == bits { $crate::__private::core::option::Option::Some(Self(bits)) } else { $crate::__private::core::option::Option::None } } fn from_bits_truncate(bits) { Self(bits & Self::all().bits()) } fn from_bits_retain(bits) { Self(bits) } fn from_name(name) { $( $crate::__bitflags_flag!({ name: $Flag, named: { $crate::__bitflags_expr_safe_attrs!( $(#[$inner $($args)*])* { if name == $crate::__private::core::stringify!($Flag) { return $crate::__private::core::option::Option::Some(Self($PublicBitFlags::$Flag.bits())); } } ); }, unnamed: {}, }); )* let _ = name; $crate::__private::core::option::Option::None } fn is_empty(f) { f.bits() == <$T as $crate::Bits>::EMPTY } fn is_all(f) { // NOTE: We check against `Self::all` here, not `Self::Bits::ALL` // because the set of all flags may not use all bits Self::all().bits() | f.bits() == f.bits() } fn intersects(f, other) { f.bits() & other.bits() != <$T as $crate::Bits>::EMPTY } fn contains(f, other) { f.bits() & other.bits() == other.bits() } fn insert(f, other) { *f = Self::from_bits_retain(f.bits()).union(other); } fn remove(f, other) { *f = Self::from_bits_retain(f.bits()).difference(other); } fn toggle(f, other) { *f = Self::from_bits_retain(f.bits()).symmetric_difference(other); } fn set(f, other, value) { if value { f.insert(other); } else { f.remove(other); } } fn intersection(f, other) { Self::from_bits_retain(f.bits() & other.bits()) } fn union(f, other) { Self::from_bits_retain(f.bits() | other.bits()) } fn difference(f, other) { Self::from_bits_retain(f.bits() & !other.bits()) } fn symmetric_difference(f, other) { Self::from_bits_retain(f.bits() ^ other.bits()) } fn complement(f) { Self::from_bits_truncate(!f.bits()) } } } }; } /// Implement iterators on the public (user-facing) bitflags type. #[macro_export] #[doc(hidden)] macro_rules! __impl_public_bitflags_iter { ($BitFlags:ident: $T:ty, $PublicBitFlags:ident) => { impl $BitFlags { /// Yield a set of contained flags values. /// /// Each yielded flags value will correspond to a defined named flag. Any unknown bits /// will be yielded together as a final flags value. #[inline] pub const fn iter(&self) -> $crate::iter::Iter<$PublicBitFlags> { $crate::iter::Iter::__private_const_new( <$PublicBitFlags as $crate::Flags>::FLAGS, $PublicBitFlags::from_bits_retain(self.bits()), $PublicBitFlags::from_bits_retain(self.bits()), ) } /// Yield a set of contained named flags values. /// /// This method is like [`iter`](#method.iter), except only yields bits in contained named flags. /// Any unknown bits, or bits not corresponding to a contained flag will not be yielded. #[inline] pub const fn iter_names(&self) -> $crate::iter::IterNames<$PublicBitFlags> { $crate::iter::IterNames::__private_const_new( <$PublicBitFlags as $crate::Flags>::FLAGS, $PublicBitFlags::from_bits_retain(self.bits()), $PublicBitFlags::from_bits_retain(self.bits()), ) } } impl $crate::__private::core::iter::IntoIterator for $BitFlags { type Item = $PublicBitFlags; type IntoIter = $crate::iter::Iter<$PublicBitFlags>; fn into_iter(self) -> Self::IntoIter { self.iter() } } }; } /// Implement traits on the public (user-facing) bitflags type. #[macro_export] #[doc(hidden)] macro_rules! __impl_public_bitflags_ops { ($PublicBitFlags:ident) => { impl $crate::__private::core::fmt::Binary for $PublicBitFlags { fn fmt( &self, f: &mut $crate::__private::core::fmt::Formatter, ) -> $crate::__private::core::fmt::Result { let inner = self.0; $crate::__private::core::fmt::Binary::fmt(&inner, f) } } impl $crate::__private::core::fmt::Octal for $PublicBitFlags { fn fmt( &self, f: &mut $crate::__private::core::fmt::Formatter, ) -> $crate::__private::core::fmt::Result { let inner = self.0; $crate::__private::core::fmt::Octal::fmt(&inner, f) } } impl $crate::__private::core::fmt::LowerHex for $PublicBitFlags { fn fmt( &self, f: &mut $crate::__private::core::fmt::Formatter, ) -> $crate::__private::core::fmt::Result { let inner = self.0; $crate::__private::core::fmt::LowerHex::fmt(&inner, f) } } impl $crate::__private::core::fmt::UpperHex for $PublicBitFlags { fn fmt( &self, f: &mut $crate::__private::core::fmt::Formatter, ) -> $crate::__private::core::fmt::Result { let inner = self.0; $crate::__private::core::fmt::UpperHex::fmt(&inner, f) } } impl $crate::__private::core::ops::BitOr for $PublicBitFlags { type Output = Self; /// The bitwise or (`|`) of the bits in two flags values. #[inline] fn bitor(self, other: $PublicBitFlags) -> Self { self.union(other) } } impl $crate::__private::core::ops::BitOrAssign for $PublicBitFlags { /// The bitwise or (`|`) of the bits in two flags values. #[inline] fn bitor_assign(&mut self, other: Self) { self.insert(other); } } impl $crate::__private::core::ops::BitXor for $PublicBitFlags { type Output = Self; /// The bitwise exclusive-or (`^`) of the bits in two flags values. #[inline] fn bitxor(self, other: Self) -> Self { self.symmetric_difference(other) } } impl $crate::__private::core::ops::BitXorAssign for $PublicBitFlags { /// The bitwise exclusive-or (`^`) of the bits in two flags values. #[inline] fn bitxor_assign(&mut self, other: Self) { self.toggle(other); } } impl $crate::__private::core::ops::BitAnd for $PublicBitFlags { type Output = Self; /// The bitwise and (`&`) of the bits in two flags values. #[inline] fn bitand(self, other: Self) -> Self { self.intersection(other) } } impl $crate::__private::core::ops::BitAndAssign for $PublicBitFlags { /// The bitwise and (`&`) of the bits in two flags values. #[inline] fn bitand_assign(&mut self, other: Self) { *self = Self::from_bits_retain(self.bits()).intersection(other); } } impl $crate::__private::core::ops::Sub for $PublicBitFlags { type Output = Self; /// The intersection of a source flags value with the complement of a target flags value (`&!`). /// /// This method is not equivalent to `self & !other` when `other` has unknown bits set. /// `difference` won't truncate `other`, but the `!` operator will. #[inline] fn sub(self, other: Self) -> Self { self.difference(other) } } impl $crate::__private::core::ops::SubAssign for $PublicBitFlags { /// The intersection of a source flags value with the complement of a target flags value (`&!`). /// /// This method is not equivalent to `self & !other` when `other` has unknown bits set. /// `difference` won't truncate `other`, but the `!` operator will. #[inline] fn sub_assign(&mut self, other: Self) { self.remove(other); } } impl $crate::__private::core::ops::Not for $PublicBitFlags { type Output = Self; /// The bitwise negation (`!`) of the bits in a flags value, truncating the result. #[inline] fn not(self) -> Self { self.complement() } } impl $crate::__private::core::iter::Extend<$PublicBitFlags> for $PublicBitFlags { /// The bitwise or (`|`) of the bits in each flags value. fn extend>( &mut self, iterator: T, ) { for item in iterator { self.insert(item) } } } impl $crate::__private::core::iter::FromIterator<$PublicBitFlags> for $PublicBitFlags { /// The bitwise or (`|`) of the bits in each flags value. fn from_iter>( iterator: T, ) -> Self { use $crate::__private::core::iter::Extend; let mut result = Self::empty(); result.extend(iterator); result } } }; } /// Implement constants on the public (user-facing) bitflags type. #[macro_export] #[doc(hidden)] macro_rules! __impl_public_bitflags_consts { ( $PublicBitFlags:ident: $T:ty { $( $(#[$inner:ident $($args:tt)*])* const $Flag:tt = $value:expr; )* } ) => { impl $PublicBitFlags { $( $crate::__bitflags_flag!({ name: $Flag, named: { $(#[$inner $($args)*])* #[allow( deprecated, non_upper_case_globals, )] pub const $Flag: Self = Self::from_bits_retain($value); }, unnamed: {}, }); )* } impl $crate::Flags for $PublicBitFlags { const FLAGS: &'static [$crate::Flag<$PublicBitFlags>] = &[ $( $crate::__bitflags_flag!({ name: $Flag, named: { $crate::__bitflags_expr_safe_attrs!( $(#[$inner $($args)*])* { #[allow( deprecated, non_upper_case_globals, )] $crate::Flag::new($crate::__private::core::stringify!($Flag), $PublicBitFlags::$Flag) } ) }, unnamed: { $crate::__bitflags_expr_safe_attrs!( $(#[$inner $($args)*])* { #[allow( deprecated, non_upper_case_globals, )] $crate::Flag::new("", $PublicBitFlags::from_bits_retain($value)) } ) }, }), )* ]; type Bits = $T; fn bits(&self) -> $T { $PublicBitFlags::bits(self) } fn from_bits_retain(bits: $T) -> $PublicBitFlags { $PublicBitFlags::from_bits_retain(bits) } } }; } bitflags-2.4.2/src/tests/all.rs000064400000000000000000000007141046102023000144750ustar 00000000000000use super::*; use crate::Flags; #[test] fn cases() { case(1 | 1 << 1 | 1 << 2, TestFlags::all); case(0, TestZero::all); case(0, TestEmpty::all); case(!0, TestExternal::all); } #[track_caller] fn case(expected: T::Bits, inherent: impl FnOnce() -> T) where ::Bits: std::fmt::Debug + PartialEq, { assert_eq!(expected, inherent().bits(), "T::all()"); assert_eq!(expected, T::all().bits(), "Flags::all()"); } bitflags-2.4.2/src/tests/bits.rs000064400000000000000000000016761046102023000146760ustar 00000000000000use super::*; use crate::Flags; #[test] fn cases() { case(0, TestFlags::empty(), TestFlags::bits); case(1, TestFlags::A, TestFlags::bits); case(1 | 1 << 1 | 1 << 2, TestFlags::ABC, TestFlags::bits); case(!0, TestFlags::from_bits_retain(u8::MAX), TestFlags::bits); case(1 << 3, TestFlags::from_bits_retain(1 << 3), TestFlags::bits); case(1 << 3, TestZero::from_bits_retain(1 << 3), TestZero::bits); case(1 << 3, TestEmpty::from_bits_retain(1 << 3), TestEmpty::bits); case( 1 << 4 | 1 << 6, TestExternal::from_bits_retain(1 << 4 | 1 << 6), TestExternal::bits, ); } #[track_caller] fn case( expected: T::Bits, value: T, inherent: impl FnOnce(&T) -> T::Bits, ) where T::Bits: std::fmt::Debug + PartialEq, { assert_eq!(expected, inherent(&value), "{:?}.bits()", value); assert_eq!(expected, Flags::bits(&value), "Flags::bits({:?})", value); } bitflags-2.4.2/src/tests/complement.rs000064400000000000000000000024541046102023000160730ustar 00000000000000use super::*; use crate::Flags; #[test] fn cases() { case(0, TestFlags::all(), TestFlags::complement); case(0, TestFlags::from_bits_retain(!0), TestFlags::complement); case(1 | 1 << 1, TestFlags::C, TestFlags::complement); case( 1 | 1 << 1, TestFlags::C | TestFlags::from_bits_retain(1 << 3), TestFlags::complement, ); case( 1 | 1 << 1 | 1 << 2, TestFlags::empty(), TestFlags::complement, ); case( 1 | 1 << 1 | 1 << 2, TestFlags::from_bits_retain(1 << 3), TestFlags::complement, ); case(0, TestZero::empty(), TestZero::complement); case(0, TestEmpty::empty(), TestEmpty::complement); case(1 << 2, TestOverlapping::AB, TestOverlapping::complement); case(!0, TestExternal::empty(), TestExternal::complement); } #[track_caller] fn case + Copy>( expected: T::Bits, value: T, inherent: impl FnOnce(T) -> T, ) where T::Bits: std::fmt::Debug + PartialEq, { assert_eq!(expected, inherent(value).bits(), "{:?}.complement()", value); assert_eq!( expected, Flags::complement(value).bits(), "Flags::complement({:?})", value ); assert_eq!(expected, (!value).bits(), "!{:?}", value); } bitflags-2.4.2/src/tests/contains.rs000064400000000000000000000050121046102023000155370ustar 00000000000000use super::*; use crate::Flags; #[test] fn cases() { case( TestFlags::empty(), &[ (TestFlags::empty(), true), (TestFlags::A, false), (TestFlags::B, false), (TestFlags::C, false), (TestFlags::from_bits_retain(1 << 3), false), ], TestFlags::contains, ); case( TestFlags::A, &[ (TestFlags::empty(), true), (TestFlags::A, true), (TestFlags::B, false), (TestFlags::C, false), (TestFlags::ABC, false), (TestFlags::from_bits_retain(1 << 3), false), (TestFlags::from_bits_retain(1 | (1 << 3)), false), ], TestFlags::contains, ); case( TestFlags::ABC, &[ (TestFlags::empty(), true), (TestFlags::A, true), (TestFlags::B, true), (TestFlags::C, true), (TestFlags::ABC, true), (TestFlags::from_bits_retain(1 << 3), false), ], TestFlags::contains, ); case( TestFlags::from_bits_retain(1 << 3), &[ (TestFlags::empty(), true), (TestFlags::A, false), (TestFlags::B, false), (TestFlags::C, false), (TestFlags::from_bits_retain(1 << 3), true), ], TestFlags::contains, ); case( TestZero::ZERO, &[(TestZero::ZERO, true)], TestZero::contains, ); case( TestOverlapping::AB, &[ (TestOverlapping::AB, true), (TestOverlapping::BC, false), (TestOverlapping::from_bits_retain(1 << 1), true), ], TestOverlapping::contains, ); case( TestExternal::all(), &[ (TestExternal::A, true), (TestExternal::B, true), (TestExternal::C, true), (TestExternal::from_bits_retain(1 << 5 | 1 << 7), true), ], TestExternal::contains, ); } #[track_caller] fn case( value: T, inputs: &[(T, bool)], mut inherent: impl FnMut(&T, T) -> bool, ) { for (input, expected) in inputs { assert_eq!( *expected, inherent(&value, *input), "{:?}.contains({:?})", value, input ); assert_eq!( *expected, Flags::contains(&value, *input), "Flags::contains({:?}, {:?})", value, input ); } } bitflags-2.4.2/src/tests/difference.rs000064400000000000000000000041401046102023000160140ustar 00000000000000use super::*; use crate::Flags; #[test] fn cases() { case( TestFlags::A | TestFlags::B, &[ (TestFlags::A, 1 << 1), (TestFlags::B, 1), (TestFlags::from_bits_retain(1 << 3), 1 | 1 << 1), ], TestFlags::difference, ); case( TestFlags::from_bits_retain(1 | 1 << 3), &[ (TestFlags::A, 1 << 3), (TestFlags::from_bits_retain(1 << 3), 1), ], TestFlags::difference, ); case( TestExternal::from_bits_retain(!0), &[(TestExternal::A, 0b1111_1110)], TestExternal::difference, ); assert_eq!( 0b1111_1110, (TestExternal::from_bits_retain(!0) & !TestExternal::A).bits() ); assert_eq!( 0b1111_1110, (TestFlags::from_bits_retain(!0).difference(TestFlags::A)).bits() ); // The `!` operator unsets bits that don't correspond to known flags assert_eq!( 1 << 1 | 1 << 2, (TestFlags::from_bits_retain(!0) & !TestFlags::A).bits() ); } #[track_caller] fn case + std::ops::SubAssign + Copy>( value: T, inputs: &[(T, T::Bits)], mut inherent: impl FnMut(T, T) -> T, ) where T::Bits: std::fmt::Debug + PartialEq + Copy, { for (input, expected) in inputs { assert_eq!( *expected, inherent(value, *input).bits(), "{:?}.difference({:?})", value, input ); assert_eq!( *expected, Flags::difference(value, *input).bits(), "Flags::difference({:?}, {:?})", value, input ); assert_eq!( *expected, (value - *input).bits(), "{:?} - {:?}", value, input ); assert_eq!( *expected, { let mut value = value; value -= *input; value } .bits(), "{:?} -= {:?}", value, input, ); } } bitflags-2.4.2/src/tests/empty.rs000064400000000000000000000007071046102023000150650ustar 00000000000000use super::*; use crate::Flags; #[test] fn cases() { case(0, TestFlags::empty); case(0, TestZero::empty); case(0, TestEmpty::empty); case(0, TestExternal::empty); } #[track_caller] fn case(expected: T::Bits, inherent: impl FnOnce() -> T) where ::Bits: std::fmt::Debug + PartialEq, { assert_eq!(expected, inherent().bits(), "T::empty()"); assert_eq!(expected, T::empty().bits(), "Flags::empty()"); } bitflags-2.4.2/src/tests/eq.rs000064400000000000000000000004571046102023000143360ustar 00000000000000use super::*; #[test] fn cases() { assert_eq!(TestFlags::empty(), TestFlags::empty()); assert_eq!(TestFlags::all(), TestFlags::all()); assert!(TestFlags::from_bits_retain(1) < TestFlags::from_bits_retain(2)); assert!(TestFlags::from_bits_retain(2) > TestFlags::from_bits_retain(1)); } bitflags-2.4.2/src/tests/extend.rs000064400000000000000000000016021046102023000152110ustar 00000000000000use super::*; #[test] fn cases() { let mut flags = TestFlags::empty(); flags.extend(TestFlags::A); assert_eq!(TestFlags::A, flags); flags.extend(TestFlags::A | TestFlags::B | TestFlags::C); assert_eq!(TestFlags::ABC, flags); flags.extend(TestFlags::from_bits_retain(1 << 5)); assert_eq!(TestFlags::ABC | TestFlags::from_bits_retain(1 << 5), flags); } mod external { use super::*; #[test] fn cases() { let mut flags = TestExternal::empty(); flags.extend(TestExternal::A); assert_eq!(TestExternal::A, flags); flags.extend(TestExternal::A | TestExternal::B | TestExternal::C); assert_eq!(TestExternal::ABC, flags); flags.extend(TestExternal::from_bits_retain(1 << 5)); assert_eq!( TestExternal::ABC | TestExternal::from_bits_retain(1 << 5), flags ); } } bitflags-2.4.2/src/tests/flags.rs000064400000000000000000000016051046102023000150210ustar 00000000000000use super::*; use crate::Flags; #[test] fn cases() { let flags = TestFlags::FLAGS .iter() .map(|flag| (flag.name(), flag.value().bits())) .collect::>(); assert_eq!( vec![ ("A", 1u8), ("B", 1 << 1), ("C", 1 << 2), ("ABC", 1 | 1 << 1 | 1 << 2), ], flags, ); assert_eq!(0, TestEmpty::FLAGS.iter().count()); } mod external { use super::*; #[test] fn cases() { let flags = TestExternal::FLAGS .iter() .map(|flag| (flag.name(), flag.value().bits())) .collect::>(); assert_eq!( vec![ ("A", 1u8), ("B", 1 << 1), ("C", 1 << 2), ("ABC", 1 | 1 << 1 | 1 << 2), ("", !0), ], flags, ); } } bitflags-2.4.2/src/tests/fmt.rs000064400000000000000000000036631046102023000145210ustar 00000000000000use super::*; #[test] fn cases() { case(TestFlags::empty(), "TestFlags(0x0)", "0", "0", "0", "0"); case(TestFlags::A, "TestFlags(A)", "1", "1", "1", "1"); case( TestFlags::all(), "TestFlags(A | B | C)", "7", "7", "7", "111", ); case( TestFlags::from_bits_retain(1 << 3), "TestFlags(0x8)", "8", "8", "10", "1000", ); case( TestFlags::A | TestFlags::from_bits_retain(1 << 3), "TestFlags(A | 0x8)", "9", "9", "11", "1001", ); case(TestZero::ZERO, "TestZero(0x0)", "0", "0", "0", "0"); case( TestZero::ZERO | TestZero::from_bits_retain(1), "TestZero(0x1)", "1", "1", "1", "1", ); case(TestZeroOne::ONE, "TestZeroOne(ONE)", "1", "1", "1", "1"); case( TestOverlapping::from_bits_retain(1 << 1), "TestOverlapping(0x2)", "2", "2", "2", "10", ); case( TestExternal::from_bits_retain(1 | 1 << 1 | 1 << 3), "TestExternal(A | B | 0x8)", "B", "b", "13", "1011", ); case( TestExternal::all(), "TestExternal(A | B | C | 0xf8)", "FF", "ff", "377", "11111111", ); case( TestExternalFull::all(), "TestExternalFull(0xff)", "FF", "ff", "377", "11111111", ); } #[track_caller] fn case< T: std::fmt::Debug + std::fmt::UpperHex + std::fmt::LowerHex + std::fmt::Octal + std::fmt::Binary, >( value: T, debug: &str, uhex: &str, lhex: &str, oct: &str, bin: &str, ) { assert_eq!(debug, format!("{:?}", value)); assert_eq!(uhex, format!("{:X}", value)); assert_eq!(lhex, format!("{:x}", value)); assert_eq!(oct, format!("{:o}", value)); assert_eq!(bin, format!("{:b}", value)); } bitflags-2.4.2/src/tests/from_bits.rs000064400000000000000000000017561046102023000157200ustar 00000000000000use super::*; use crate::Flags; #[test] fn cases() { case(Some(0), 0, TestFlags::from_bits); case(Some(1), 1, TestFlags::from_bits); case( Some(1 | 1 << 1 | 1 << 2), 1 | 1 << 1 | 1 << 2, TestFlags::from_bits, ); case(None, 1 << 3, TestFlags::from_bits); case(None, 1 | 1 << 3, TestFlags::from_bits); case(Some(1 | 1 << 1), 1 | 1 << 1, TestOverlapping::from_bits); case(Some(1 << 1), 1 << 1, TestOverlapping::from_bits); case(Some(1 << 5), 1 << 5, TestExternal::from_bits); } #[track_caller] fn case( expected: Option, input: T::Bits, inherent: impl FnOnce(T::Bits) -> Option, ) where ::Bits: std::fmt::Debug + PartialEq, { assert_eq!( expected, inherent(input).map(|f| f.bits()), "T::from_bits({:?})", input ); assert_eq!( expected, T::from_bits(input).map(|f| f.bits()), "Flags::from_bits({:?})", input ); } bitflags-2.4.2/src/tests/from_bits_retain.rs000064400000000000000000000015471046102023000172600ustar 00000000000000use super::*; use crate::Flags; #[test] fn cases() { case(0, TestFlags::from_bits_retain); case(1, TestFlags::from_bits_retain); case(1 | 1 << 1 | 1 << 2, TestFlags::from_bits_retain); case(1 << 3, TestFlags::from_bits_retain); case(1 | 1 << 3, TestFlags::from_bits_retain); case(1 | 1 << 1, TestOverlapping::from_bits_retain); case(1 << 1, TestOverlapping::from_bits_retain); case(1 << 5, TestExternal::from_bits_retain); } #[track_caller] fn case(input: T::Bits, inherent: impl FnOnce(T::Bits) -> T) where ::Bits: std::fmt::Debug + PartialEq, { assert_eq!( input, inherent(input).bits(), "T::from_bits_retain({:?})", input ); assert_eq!( input, T::from_bits_retain(input).bits(), "Flags::from_bits_retain({:?})", input ); } bitflags-2.4.2/src/tests/from_bits_truncate.rs000064400000000000000000000017621046102023000176220ustar 00000000000000use super::*; use crate::Flags; #[test] fn cases() { case(0, 0, TestFlags::from_bits_truncate); case(1, 1, TestFlags::from_bits_truncate); case( 1 | 1 << 1 | 1 << 2, 1 | 1 << 1 | 1 << 2, TestFlags::from_bits_truncate, ); case(0, 1 << 3, TestFlags::from_bits_truncate); case(1, 1 | 1 << 3, TestFlags::from_bits_truncate); case(1 | 1 << 1, 1 | 1 << 1, TestOverlapping::from_bits_truncate); case(1 << 1, 1 << 1, TestOverlapping::from_bits_truncate); case(1 << 5, 1 << 5, TestExternal::from_bits_truncate); } #[track_caller] fn case(expected: T::Bits, input: T::Bits, inherent: impl FnOnce(T::Bits) -> T) where ::Bits: std::fmt::Debug + PartialEq, { assert_eq!( expected, inherent(input).bits(), "T::from_bits_truncate({:?})", input ); assert_eq!( expected, T::from_bits_truncate(input).bits(), "Flags::from_bits_truncate({:?})", input ); } bitflags-2.4.2/src/tests/from_name.rs000064400000000000000000000020131046102023000156620ustar 00000000000000use super::*; use crate::Flags; #[test] fn cases() { case(Some(1), "A", TestFlags::from_name); case(Some(1 << 1), "B", TestFlags::from_name); case(Some(1 | 1 << 1 | 1 << 2), "ABC", TestFlags::from_name); case(None, "", TestFlags::from_name); case(None, "a", TestFlags::from_name); case(None, "0x1", TestFlags::from_name); case(None, "A | B", TestFlags::from_name); case(Some(0), "ZERO", TestZero::from_name); case(Some(2), "二", TestUnicode::from_name); case(None, "_", TestExternal::from_name); case(None, "", TestExternal::from_name); } #[track_caller] fn case(expected: Option, input: &str, inherent: impl FnOnce(&str) -> Option) where ::Bits: std::fmt::Debug + PartialEq, { assert_eq!( expected, inherent(input).map(|f| f.bits()), "T::from_name({:?})", input ); assert_eq!( expected, T::from_name(input).map(|f| f.bits()), "Flags::from_name({:?})", input ); } bitflags-2.4.2/src/tests/insert.rs000064400000000000000000000040131046102023000152250ustar 00000000000000use super::*; use crate::Flags; #[test] fn cases() { case( TestFlags::empty(), &[ (TestFlags::A, 1), (TestFlags::A | TestFlags::B, 1 | 1 << 1), (TestFlags::empty(), 0), (TestFlags::from_bits_retain(1 << 3), 1 << 3), ], TestFlags::insert, TestFlags::set, ); case( TestFlags::A, &[ (TestFlags::A, 1), (TestFlags::empty(), 1), (TestFlags::B, 1 | 1 << 1), ], TestFlags::insert, TestFlags::set, ); } #[track_caller] fn case( value: T, inputs: &[(T, T::Bits)], mut inherent_insert: impl FnMut(&mut T, T), mut inherent_set: impl FnMut(&mut T, T, bool), ) where T::Bits: std::fmt::Debug + PartialEq + Copy, { for (input, expected) in inputs { assert_eq!( *expected, { let mut value = value; inherent_insert(&mut value, *input); value } .bits(), "{:?}.insert({:?})", value, input ); assert_eq!( *expected, { let mut value = value; Flags::insert(&mut value, *input); value } .bits(), "Flags::insert({:?}, {:?})", value, input ); assert_eq!( *expected, { let mut value = value; inherent_set(&mut value, *input, true); value } .bits(), "{:?}.set({:?}, true)", value, input ); assert_eq!( *expected, { let mut value = value; Flags::set(&mut value, *input, true); value } .bits(), "Flags::set({:?}, {:?}, true)", value, input ); } } bitflags-2.4.2/src/tests/intersection.rs000064400000000000000000000034141046102023000164330ustar 00000000000000use super::*; use crate::Flags; #[test] fn cases() { case( TestFlags::empty(), &[(TestFlags::empty(), 0), (TestFlags::all(), 0)], TestFlags::intersection, ); case( TestFlags::all(), &[ (TestFlags::all(), 1 | 1 << 1 | 1 << 2), (TestFlags::A, 1), (TestFlags::from_bits_retain(1 << 3), 0), ], TestFlags::intersection, ); case( TestFlags::from_bits_retain(1 << 3), &[(TestFlags::from_bits_retain(1 << 3), 1 << 3)], TestFlags::intersection, ); case( TestOverlapping::AB, &[(TestOverlapping::BC, 1 << 1)], TestOverlapping::intersection, ); } #[track_caller] fn case + std::ops::BitAndAssign + Copy>( value: T, inputs: &[(T, T::Bits)], mut inherent: impl FnMut(T, T) -> T, ) where T::Bits: std::fmt::Debug + PartialEq + Copy, { for (input, expected) in inputs { assert_eq!( *expected, inherent(value, *input).bits(), "{:?}.intersection({:?})", value, input ); assert_eq!( *expected, Flags::intersection(value, *input).bits(), "Flags::intersection({:?}, {:?})", value, input ); assert_eq!( *expected, (value & *input).bits(), "{:?} & {:?}", value, input ); assert_eq!( *expected, { let mut value = value; value &= *input; value } .bits(), "{:?} &= {:?}", value, input, ); } } bitflags-2.4.2/src/tests/intersects.rs000064400000000000000000000042311046102023000161060ustar 00000000000000use super::*; use crate::Flags; #[test] fn cases() { case( TestFlags::empty(), &[ (TestFlags::empty(), false), (TestFlags::A, false), (TestFlags::B, false), (TestFlags::C, false), (TestFlags::from_bits_retain(1 << 3), false), ], TestFlags::intersects, ); case( TestFlags::A, &[ (TestFlags::empty(), false), (TestFlags::A, true), (TestFlags::B, false), (TestFlags::C, false), (TestFlags::ABC, true), (TestFlags::from_bits_retain(1 << 3), false), (TestFlags::from_bits_retain(1 | (1 << 3)), true), ], TestFlags::intersects, ); case( TestFlags::ABC, &[ (TestFlags::empty(), false), (TestFlags::A, true), (TestFlags::B, true), (TestFlags::C, true), (TestFlags::ABC, true), (TestFlags::from_bits_retain(1 << 3), false), ], TestFlags::intersects, ); case( TestFlags::from_bits_retain(1 << 3), &[ (TestFlags::empty(), false), (TestFlags::A, false), (TestFlags::B, false), (TestFlags::C, false), (TestFlags::from_bits_retain(1 << 3), true), ], TestFlags::intersects, ); case( TestOverlapping::AB, &[ (TestOverlapping::AB, true), (TestOverlapping::BC, true), (TestOverlapping::from_bits_retain(1 << 1), true), ], TestOverlapping::intersects, ); } #[track_caller] fn case( value: T, inputs: &[(T, bool)], mut inherent: impl FnMut(&T, T) -> bool, ) { for (input, expected) in inputs { assert_eq!( *expected, inherent(&value, *input), "{:?}.intersects({:?})", value, input ); assert_eq!( *expected, Flags::intersects(&value, *input), "Flags::intersects({:?}, {:?})", value, input ); } } bitflags-2.4.2/src/tests/is_all.rs000064400000000000000000000013551046102023000151720ustar 00000000000000use super::*; use crate::Flags; #[test] fn cases() { case(false, TestFlags::empty(), TestFlags::is_all); case(false, TestFlags::A, TestFlags::is_all); case(true, TestFlags::ABC, TestFlags::is_all); case( true, TestFlags::ABC | TestFlags::from_bits_retain(1 << 3), TestFlags::is_all, ); case(true, TestZero::empty(), TestZero::is_all); case(true, TestEmpty::empty(), TestEmpty::is_all); } #[track_caller] fn case(expected: bool, value: T, inherent: impl FnOnce(&T) -> bool) { assert_eq!(expected, inherent(&value), "{:?}.is_all()", value); assert_eq!( expected, Flags::is_all(&value), "Flags::is_all({:?})", value ); } bitflags-2.4.2/src/tests/is_empty.rs000064400000000000000000000013561046102023000155610ustar 00000000000000use super::*; use crate::Flags; #[test] fn cases() { case(true, TestFlags::empty(), TestFlags::is_empty); case(false, TestFlags::A, TestFlags::is_empty); case(false, TestFlags::ABC, TestFlags::is_empty); case( false, TestFlags::from_bits_retain(1 << 3), TestFlags::is_empty, ); case(true, TestZero::empty(), TestZero::is_empty); case(true, TestEmpty::empty(), TestEmpty::is_empty); } #[track_caller] fn case(expected: bool, value: T, inherent: impl FnOnce(&T) -> bool) { assert_eq!(expected, inherent(&value), "{:?}.is_empty()", value); assert_eq!( expected, Flags::is_empty(&value), "Flags::is_empty({:?})", value ); } bitflags-2.4.2/src/tests/iter.rs000064400000000000000000000124751046102023000146770ustar 00000000000000use super::*; use crate::Flags; #[test] #[cfg(not(miri))] // Very slow in miri fn roundtrip() { for a in 0u8..=255 { for b in 0u8..=255 { let f = TestFlags::from_bits_retain(a | b); assert_eq!(f, f.iter().collect::()); assert_eq!( TestFlags::from_bits_truncate(f.bits()), f.iter_names().map(|(_, f)| f).collect::() ); let f = TestExternal::from_bits_retain(a | b); assert_eq!(f, f.iter().collect::()); } } } mod collect { use super::*; #[test] fn cases() { assert_eq!(0, [].into_iter().collect::().bits()); assert_eq!(1, [TestFlags::A,].into_iter().collect::().bits()); assert_eq!( 1 | 1 << 1 | 1 << 2, [TestFlags::A, TestFlags::B | TestFlags::C,] .into_iter() .collect::() .bits() ); assert_eq!( 1 | 1 << 3, [ TestFlags::from_bits_retain(1 << 3), TestFlags::empty(), TestFlags::A, ] .into_iter() .collect::() .bits() ); assert_eq!( 1 << 5 | 1 << 7, [ TestExternal::empty(), TestExternal::from_bits_retain(1 << 5), TestExternal::from_bits_retain(1 << 7), ] .into_iter() .collect::() .bits() ); } } mod iter { use super::*; #[test] fn cases() { case(&[], TestFlags::empty(), TestFlags::iter); case(&[1], TestFlags::A, TestFlags::iter); case(&[1, 1 << 1], TestFlags::A | TestFlags::B, TestFlags::iter); case( &[1, 1 << 1, 1 << 3], TestFlags::A | TestFlags::B | TestFlags::from_bits_retain(1 << 3), TestFlags::iter, ); case(&[1, 1 << 1, 1 << 2], TestFlags::ABC, TestFlags::iter); case( &[1, 1 << 1, 1 << 2, 1 << 3], TestFlags::ABC | TestFlags::from_bits_retain(1 << 3), TestFlags::iter, ); case( &[1 | 1 << 1 | 1 << 2], TestFlagsInvert::ABC, TestFlagsInvert::iter, ); case(&[], TestZero::ZERO, TestZero::iter); case( &[1, 1 << 1, 1 << 2, 0b1111_1000], TestExternal::all(), TestExternal::iter, ); } #[track_caller] fn case + Copy>( expected: &[T::Bits], value: T, inherent: impl FnOnce(&T) -> crate::iter::Iter, ) where T::Bits: std::fmt::Debug + PartialEq, { assert_eq!( expected, inherent(&value).map(|f| f.bits()).collect::>(), "{:?}.iter()", value ); assert_eq!( expected, Flags::iter(&value).map(|f| f.bits()).collect::>(), "Flags::iter({:?})", value ); assert_eq!( expected, value.into_iter().map(|f| f.bits()).collect::>(), "{:?}.into_iter()", value ); } } mod iter_names { use super::*; #[test] fn cases() { case(&[], TestFlags::empty(), TestFlags::iter_names); case(&[("A", 1)], TestFlags::A, TestFlags::iter_names); case( &[("A", 1), ("B", 1 << 1)], TestFlags::A | TestFlags::B, TestFlags::iter_names, ); case( &[("A", 1), ("B", 1 << 1)], TestFlags::A | TestFlags::B | TestFlags::from_bits_retain(1 << 3), TestFlags::iter_names, ); case( &[("A", 1), ("B", 1 << 1), ("C", 1 << 2)], TestFlags::ABC, TestFlags::iter_names, ); case( &[("A", 1), ("B", 1 << 1), ("C", 1 << 2)], TestFlags::ABC | TestFlags::from_bits_retain(1 << 3), TestFlags::iter_names, ); case( &[("ABC", 1 | 1 << 1 | 1 << 2)], TestFlagsInvert::ABC, TestFlagsInvert::iter_names, ); case(&[], TestZero::ZERO, TestZero::iter_names); case( &[("A", 1)], TestOverlappingFull::A, TestOverlappingFull::iter_names, ); case( &[("A", 1), ("D", 1 << 1)], TestOverlappingFull::A | TestOverlappingFull::D, TestOverlappingFull::iter_names, ); } #[track_caller] fn case( expected: &[(&'static str, T::Bits)], value: T, inherent: impl FnOnce(&T) -> crate::iter::IterNames, ) where T::Bits: std::fmt::Debug + PartialEq, { assert_eq!( expected, inherent(&value) .map(|(n, f)| (n, f.bits())) .collect::>(), "{:?}.iter_names()", value ); assert_eq!( expected, Flags::iter_names(&value) .map(|(n, f)| (n, f.bits())) .collect::>(), "Flags::iter_names({:?})", value ); } } bitflags-2.4.2/src/tests/parser.rs000064400000000000000000000057431046102023000152300ustar 00000000000000use super::*; use crate::{ parser::{from_str, to_writer}, Flags, }; #[test] #[cfg(not(miri))] // Very slow in miri fn roundtrip() { let mut s = String::new(); for a in 0u8..=255 { for b in 0u8..=255 { let f = TestFlags::from_bits_retain(a | b); s.clear(); to_writer(&f, &mut s).unwrap(); assert_eq!(f, from_str::(&s).unwrap()); } } } mod from_str { use super::*; #[test] fn valid() { assert_eq!(0, from_str::("").unwrap().bits()); assert_eq!(1, from_str::("A").unwrap().bits()); assert_eq!(1, from_str::(" A ").unwrap().bits()); assert_eq!( 1 | 1 << 1 | 1 << 2, from_str::("A | B | C").unwrap().bits() ); assert_eq!( 1 | 1 << 1 | 1 << 2, from_str::("A\n|\tB\r\n| C ").unwrap().bits() ); assert_eq!( 1 | 1 << 1 | 1 << 2, from_str::("A|B|C").unwrap().bits() ); assert_eq!(1 << 3, from_str::("0x8").unwrap().bits()); assert_eq!(1 | 1 << 3, from_str::("A | 0x8").unwrap().bits()); assert_eq!( 1 | 1 << 1 | 1 << 3, from_str::("0x1 | 0x8 | B").unwrap().bits() ); assert_eq!( 1 | 1 << 1, from_str::("一 | 二").unwrap().bits() ); } #[test] fn invalid() { assert!(from_str::("a") .unwrap_err() .to_string() .starts_with("unrecognized named flag")); assert!(from_str::("A & B") .unwrap_err() .to_string() .starts_with("unrecognized named flag")); assert!(from_str::("0xg") .unwrap_err() .to_string() .starts_with("invalid hex flag")); assert!(from_str::("0xffffffffffff") .unwrap_err() .to_string() .starts_with("invalid hex flag")); } } mod to_writer { use super::*; #[test] fn cases() { assert_eq!("", write(TestFlags::empty())); assert_eq!("A", write(TestFlags::A)); assert_eq!("A | B | C", write(TestFlags::all())); assert_eq!("0x8", write(TestFlags::from_bits_retain(1 << 3))); assert_eq!( "A | 0x8", write(TestFlags::A | TestFlags::from_bits_retain(1 << 3)) ); assert_eq!("", write(TestZero::ZERO)); assert_eq!("ABC", write(TestFlagsInvert::all())); assert_eq!("A", write(TestOverlappingFull::C)); assert_eq!( "A | D", write(TestOverlappingFull::C | TestOverlappingFull::D) ); } fn write(value: F) -> String where F::Bits: crate::parser::WriteHex, { let mut s = String::new(); to_writer(&value, &mut s).unwrap(); s } } bitflags-2.4.2/src/tests/remove.rs000064400000000000000000000042351046102023000152240ustar 00000000000000use super::*; use crate::Flags; #[test] fn cases() { case( TestFlags::empty(), &[ (TestFlags::A, 0), (TestFlags::empty(), 0), (TestFlags::from_bits_retain(1 << 3), 0), ], TestFlags::remove, TestFlags::set, ); case( TestFlags::A, &[ (TestFlags::A, 0), (TestFlags::empty(), 1), (TestFlags::B, 1), ], TestFlags::remove, TestFlags::set, ); case( TestFlags::ABC, &[ (TestFlags::A, 1 << 1 | 1 << 2), (TestFlags::A | TestFlags::C, 1 << 1), ], TestFlags::remove, TestFlags::set, ); } #[track_caller] fn case( value: T, inputs: &[(T, T::Bits)], mut inherent_remove: impl FnMut(&mut T, T), mut inherent_set: impl FnMut(&mut T, T, bool), ) where T::Bits: std::fmt::Debug + PartialEq + Copy, { for (input, expected) in inputs { assert_eq!( *expected, { let mut value = value; inherent_remove(&mut value, *input); value } .bits(), "{:?}.remove({:?})", value, input ); assert_eq!( *expected, { let mut value = value; Flags::remove(&mut value, *input); value } .bits(), "Flags::remove({:?}, {:?})", value, input ); assert_eq!( *expected, { let mut value = value; inherent_set(&mut value, *input, false); value } .bits(), "{:?}.set({:?}, false)", value, input ); assert_eq!( *expected, { let mut value = value; Flags::set(&mut value, *input, false); value } .bits(), "Flags::set({:?}, {:?}, false)", value, input ); } } bitflags-2.4.2/src/tests/symmetric_difference.rs000064400000000000000000000051161046102023000201140ustar 00000000000000use super::*; use crate::Flags; #[test] fn cases() { case( TestFlags::empty(), &[ (TestFlags::empty(), 0), (TestFlags::all(), 1 | 1 << 1 | 1 << 2), (TestFlags::from_bits_retain(1 << 3), 1 << 3), ], TestFlags::symmetric_difference, TestFlags::toggle, ); case( TestFlags::A, &[ (TestFlags::empty(), 1), (TestFlags::A, 0), (TestFlags::all(), 1 << 1 | 1 << 2), ], TestFlags::symmetric_difference, TestFlags::toggle, ); case( TestFlags::A | TestFlags::B | TestFlags::from_bits_retain(1 << 3), &[ (TestFlags::ABC, 1 << 2 | 1 << 3), (TestFlags::from_bits_retain(1 << 3), 1 | 1 << 1), ], TestFlags::symmetric_difference, TestFlags::toggle, ); } #[track_caller] fn case + std::ops::BitXorAssign + Copy>( value: T, inputs: &[(T, T::Bits)], mut inherent_sym_diff: impl FnMut(T, T) -> T, mut inherent_toggle: impl FnMut(&mut T, T), ) where T::Bits: std::fmt::Debug + PartialEq + Copy, { for (input, expected) in inputs { assert_eq!( *expected, inherent_sym_diff(value, *input).bits(), "{:?}.symmetric_difference({:?})", value, input ); assert_eq!( *expected, Flags::symmetric_difference(value, *input).bits(), "Flags::symmetric_difference({:?}, {:?})", value, input ); assert_eq!( *expected, (value ^ *input).bits(), "{:?} ^ {:?}", value, input ); assert_eq!( *expected, { let mut value = value; value ^= *input; value } .bits(), "{:?} ^= {:?}", value, input, ); assert_eq!( *expected, { let mut value = value; inherent_toggle(&mut value, *input); value } .bits(), "{:?}.toggle({:?})", value, input, ); assert_eq!( *expected, { let mut value = value; Flags::toggle(&mut value, *input); value } .bits(), "{:?}.toggle({:?})", value, input, ); } } bitflags-2.4.2/src/tests/union.rs000064400000000000000000000031051046102023000150520ustar 00000000000000use super::*; use crate::Flags; #[test] fn cases() { case( TestFlags::empty(), &[ (TestFlags::A, 1), (TestFlags::all(), 1 | 1 << 1 | 1 << 2), (TestFlags::empty(), 0), (TestFlags::from_bits_retain(1 << 3), 1 << 3), ], TestFlags::union, ); case( TestFlags::A | TestFlags::C, &[ (TestFlags::A | TestFlags::B, 1 | 1 << 1 | 1 << 2), (TestFlags::A, 1 | 1 << 2), ], TestFlags::union, ); } #[track_caller] fn case + std::ops::BitOrAssign + Copy>( value: T, inputs: &[(T, T::Bits)], mut inherent: impl FnMut(T, T) -> T, ) where T::Bits: std::fmt::Debug + PartialEq + Copy, { for (input, expected) in inputs { assert_eq!( *expected, inherent(value, *input).bits(), "{:?}.union({:?})", value, input ); assert_eq!( *expected, Flags::union(value, *input).bits(), "Flags::union({:?}, {:?})", value, input ); assert_eq!( *expected, (value | *input).bits(), "{:?} | {:?}", value, input ); assert_eq!( *expected, { let mut value = value; value |= *input; value } .bits(), "{:?} |= {:?}", value, input, ); } } bitflags-2.4.2/src/tests.rs000064400000000000000000000051711046102023000137270ustar 00000000000000mod all; mod bits; mod complement; mod contains; mod difference; mod empty; mod eq; mod extend; mod flags; mod fmt; mod from_bits; mod from_bits_retain; mod from_bits_truncate; mod from_name; mod insert; mod intersection; mod intersects; mod is_all; mod is_empty; mod iter; mod parser; mod remove; mod symmetric_difference; mod union; bitflags! { #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)] pub struct TestFlags: u8 { /// 1 const A = 1; /// 1 << 1 const B = 1 << 1; /// 1 << 2 const C = 1 << 2; /// 1 | (1 << 1) | (1 << 2) const ABC = Self::A.bits() | Self::B.bits() | Self::C.bits(); } #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)] pub struct TestFlagsInvert: u8 { /// 1 | (1 << 1) | (1 << 2) const ABC = Self::A.bits() | Self::B.bits() | Self::C.bits(); /// 1 const A = 1; /// 1 << 1 const B = 1 << 1; /// 1 << 2 const C = 1 << 2; } #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)] pub struct TestZero: u8 { /// 0 const ZERO = 0; } #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)] pub struct TestZeroOne: u8 { /// 0 const ZERO = 0; /// 1 const ONE = 1; } #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)] pub struct TestUnicode: u8 { /// 1 const 一 = 1; /// 2 const 二 = 1 << 1; } #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)] pub struct TestEmpty: u8 {} #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)] pub struct TestOverlapping: u8 { /// 1 | (1 << 1) const AB = 1 | (1 << 1); /// (1 << 1) | (1 << 2) const BC = (1 << 1) | (1 << 2); } #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)] pub struct TestOverlappingFull: u8 { /// 1 const A = 1; /// 1 const B = 1; /// 1 const C = 1; /// 2 const D = 1 << 1; } #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)] pub struct TestExternal: u8 { /// 1 const A = 1; /// 1 << 1 const B = 1 << 1; /// 1 << 2 const C = 1 << 2; /// 1 | (1 << 1) | (1 << 2) const ABC = Self::A.bits() | Self::B.bits() | Self::C.bits(); /// External const _ = !0; } #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)] pub struct TestExternalFull: u8 { /// External const _ = !0; } } bitflags-2.4.2/src/traits.rs000064400000000000000000000261671046102023000141030ustar 00000000000000use core::{ fmt, ops::{BitAnd, BitOr, BitXor, Not}, }; use crate::{ iter, parser::{ParseError, ParseHex, WriteHex}, }; /** A defined flags value that may be named or unnamed. */ pub struct Flag { name: &'static str, value: B, } impl Flag { /** Define a flag. If `name` is non-empty then the flag is named, otherwise it's unnamed. */ pub const fn new(name: &'static str, value: B) -> Self { Flag { name, value } } /** Get the name of this flag. If the flag is unnamed then the returned string will be empty. */ pub const fn name(&self) -> &'static str { self.name } /** Get the flags value of this flag. */ pub const fn value(&self) -> &B { &self.value } /** Whether the flag is named. If [`Flag::name`] returns a non-empty string then this method will return `true`. */ pub const fn is_named(&self) -> bool { !self.name.is_empty() } /** Whether the flag is unnamed. If [`Flag::name`] returns a non-empty string then this method will return `false`. */ pub const fn is_unnamed(&self) -> bool { self.name.is_empty() } } /** A set of defined flags using a bits type as storage. ## Implementing `Flags` This trait is implemented by the [`bitflags`](macro.bitflags.html) macro: ``` use bitflags::bitflags; bitflags! { struct MyFlags: u8 { const A = 1; const B = 1 << 1; } } ``` It can also be implemented manually: ``` use bitflags::{Flag, Flags}; struct MyFlags(u8); impl Flags for MyFlags { const FLAGS: &'static [Flag] = &[ Flag::new("A", MyFlags(1)), Flag::new("B", MyFlags(1 << 1)), ]; type Bits = u8; fn from_bits_retain(bits: Self::Bits) -> Self { MyFlags(bits) } fn bits(&self) -> Self::Bits { self.0 } } ``` ## Using `Flags` The `Flags` trait can be used generically to work with any flags types. In this example, we can count the number of defined named flags: ``` # use bitflags::{bitflags, Flags}; fn defined_flags() -> usize { F::FLAGS.iter().filter(|f| f.is_named()).count() } bitflags! { struct MyFlags: u8 { const A = 1; const B = 1 << 1; const C = 1 << 2; const _ = !0; } } assert_eq!(3, defined_flags::()); ``` */ pub trait Flags: Sized + 'static { /// The set of defined flags. const FLAGS: &'static [Flag]; /// The underlying bits type. type Bits: Bits; /// Get a flags value with all bits unset. fn empty() -> Self { Self::from_bits_retain(Self::Bits::EMPTY) } /// Get a flags value with all known bits set. fn all() -> Self { let mut truncated = Self::Bits::EMPTY; for flag in Self::FLAGS.iter() { truncated = truncated | flag.value().bits(); } Self::from_bits_retain(truncated) } /// Get the underlying bits value. /// /// The returned value is exactly the bits set in this flags value. fn bits(&self) -> Self::Bits; /// Convert from a bits value. /// /// This method will return `None` if any unknown bits are set. fn from_bits(bits: Self::Bits) -> Option { let truncated = Self::from_bits_truncate(bits); if truncated.bits() == bits { Some(truncated) } else { None } } /// Convert from a bits value, unsetting any unknown bits. fn from_bits_truncate(bits: Self::Bits) -> Self { Self::from_bits_retain(bits & Self::all().bits()) } /// Convert from a bits value exactly. fn from_bits_retain(bits: Self::Bits) -> Self; /// Get a flags value with the bits of a flag with the given name set. /// /// This method will return `None` if `name` is empty or doesn't /// correspond to any named flag. fn from_name(name: &str) -> Option { // Don't parse empty names as empty flags if name.is_empty() { return None; } for flag in Self::FLAGS { if flag.name() == name { return Some(Self::from_bits_retain(flag.value().bits())); } } None } /// Yield a set of contained flags values. /// /// Each yielded flags value will correspond to a defined named flag. Any unknown bits /// will be yielded together as a final flags value. fn iter(&self) -> iter::Iter { iter::Iter::new(self) } /// Yield a set of contained named flags values. /// /// This method is like [`Flags::iter`], except only yields bits in contained named flags. /// Any unknown bits, or bits not corresponding to a contained flag will not be yielded. fn iter_names(&self) -> iter::IterNames { iter::IterNames::new(self) } /// Whether all bits in this flags value are unset. fn is_empty(&self) -> bool { self.bits() == Self::Bits::EMPTY } /// Whether all known bits in this flags value are set. fn is_all(&self) -> bool { // NOTE: We check against `Self::all` here, not `Self::Bits::ALL` // because the set of all flags may not use all bits Self::all().bits() | self.bits() == self.bits() } /// Whether any set bits in a source flags value are also set in a target flags value. fn intersects(&self, other: Self) -> bool where Self: Sized, { self.bits() & other.bits() != Self::Bits::EMPTY } /// Whether all set bits in a source flags value are also set in a target flags value. fn contains(&self, other: Self) -> bool where Self: Sized, { self.bits() & other.bits() == other.bits() } /// The bitwise or (`|`) of the bits in two flags values. fn insert(&mut self, other: Self) where Self: Sized, { *self = Self::from_bits_retain(self.bits()).union(other); } /// The intersection of a source flags value with the complement of a target flags value (`&!`). /// /// This method is not equivalent to `self & !other` when `other` has unknown bits set. /// `remove` won't truncate `other`, but the `!` operator will. fn remove(&mut self, other: Self) where Self: Sized, { *self = Self::from_bits_retain(self.bits()).difference(other); } /// The bitwise exclusive-or (`^`) of the bits in two flags values. fn toggle(&mut self, other: Self) where Self: Sized, { *self = Self::from_bits_retain(self.bits()).symmetric_difference(other); } /// Call [`Flags::insert`] when `value` is `true` or [`Flags::remove`] when `value` is `false`. fn set(&mut self, other: Self, value: bool) where Self: Sized, { if value { self.insert(other); } else { self.remove(other); } } /// The bitwise and (`&`) of the bits in two flags values. #[must_use] fn intersection(self, other: Self) -> Self { Self::from_bits_retain(self.bits() & other.bits()) } /// The bitwise or (`|`) of the bits in two flags values. #[must_use] fn union(self, other: Self) -> Self { Self::from_bits_retain(self.bits() | other.bits()) } /// The intersection of a source flags value with the complement of a target flags value (`&!`). /// /// This method is not equivalent to `self & !other` when `other` has unknown bits set. /// `difference` won't truncate `other`, but the `!` operator will. #[must_use] fn difference(self, other: Self) -> Self { Self::from_bits_retain(self.bits() & !other.bits()) } /// The bitwise exclusive-or (`^`) of the bits in two flags values. #[must_use] fn symmetric_difference(self, other: Self) -> Self { Self::from_bits_retain(self.bits() ^ other.bits()) } /// The bitwise negation (`!`) of the bits in a flags value, truncating the result. #[must_use] fn complement(self) -> Self { Self::from_bits_truncate(!self.bits()) } } /** A bits type that can be used as storage for a flags type. */ pub trait Bits: Clone + Copy + PartialEq + BitAnd + BitOr + BitXor + Not + Sized + 'static { /// A value with all bits unset. const EMPTY: Self; /// A value with all bits set. const ALL: Self; } // Not re-exported: prevent custom `Bits` impls being used in the `bitflags!` macro, // or they may fail to compile based on crate features pub trait Primitive {} macro_rules! impl_bits { ($($u:ty, $i:ty,)*) => { $( impl Bits for $u { const EMPTY: $u = 0; const ALL: $u = <$u>::MAX; } impl Bits for $i { const EMPTY: $i = 0; const ALL: $i = <$u>::MAX as $i; } impl ParseHex for $u { fn parse_hex(input: &str) -> Result { <$u>::from_str_radix(input, 16).map_err(|_| ParseError::invalid_hex_flag(input)) } } impl ParseHex for $i { fn parse_hex(input: &str) -> Result { <$i>::from_str_radix(input, 16).map_err(|_| ParseError::invalid_hex_flag(input)) } } impl WriteHex for $u { fn write_hex(&self, mut writer: W) -> fmt::Result { write!(writer, "{:x}", self) } } impl WriteHex for $i { fn write_hex(&self, mut writer: W) -> fmt::Result { write!(writer, "{:x}", self) } } impl Primitive for $i {} impl Primitive for $u {} )* } } impl_bits! { u8, i8, u16, i16, u32, i32, u64, i64, u128, i128, usize, isize, } /// A trait for referencing the `bitflags`-owned internal type /// without exposing it publicly. pub trait PublicFlags { /// The type of the underlying storage. type Primitive: Primitive; /// The type of the internal field on the generated flags type. type Internal; } #[doc(hidden)] #[deprecated(note = "use the `Flags` trait instead")] pub trait BitFlags: ImplementedByBitFlagsMacro + Flags { /// An iterator over enabled flags in an instance of the type. type Iter: Iterator; /// An iterator over the raw names and bits for enabled flags in an instance of the type. type IterNames: Iterator; } #[allow(deprecated)] impl BitFlags for B { type Iter = iter::Iter; type IterNames = iter::IterNames; } impl ImplementedByBitFlagsMacro for B {} /// A marker trait that signals that an implementation of `BitFlags` came from the `bitflags!` macro. /// /// There's nothing stopping an end-user from implementing this trait, but we don't guarantee their /// manual implementations won't break between non-breaking releases. #[doc(hidden)] pub trait ImplementedByBitFlagsMacro {} pub(crate) mod __private { pub use super::{ImplementedByBitFlagsMacro, PublicFlags}; }