diff options
| author | Robin Krahl <robin.krahl@ireas.org> | 2020-01-07 11:18:04 +0000 | 
|---|---|---|
| committer | Daniel Mueller <deso@posteo.net> | 2020-01-08 09:20:25 -0800 | 
| commit | 5e20a29b4fdc8a2d442d1093681b396dcb4b816b (patch) | |
| tree | 55ab083fa8999d2ccbb5e921c1ffe52560dca152 /bitflags | |
| parent | 203e691f46d591a2cc8acdfd850fa9f5b0fb8a98 (diff) | |
| download | nitrocli-5e20a29b4fdc8a2d442d1093681b396dcb4b816b.tar.gz nitrocli-5e20a29b4fdc8a2d442d1093681b396dcb4b816b.tar.bz2 | |
Add structopt dependency in version 0.3.7
This patch series replaces argparse with structopt in the argument
handling code. As a first step, we need structopt as a dependency.
Import subrepo structopt/:structopt at efbdda4753592e27bc430fb01f7b9650b2f3174d
Import subrepo bitflags/:bitflags at 30668016aca6bd3b02c766e8347e0b4080d4c296
Import subrepo clap/:clap at 784524f7eb193e35f81082cc69454c8c21b948f7
Import subrepo heck/:heck at 093d56fbf001e1506e56dbfa38631d99b1066df1
Import subrepo proc-macro-error/:proc-macro-error at 6c4cfe79a622c5de8ae68557993542be46eacae2
Import subrepo proc-macro2/:proc-macro2 at d5d48eddca4566e5438e8a2cbed4a74e049544de
Import subrepo quote/:quote at 727436c6c137b20f0f34dde5d8fda2679b9747ad
Import subrepo rustversion/:rustversion at 0c5663313516263059ce9059ef81fc7a1cf655ca
Import subrepo syn-mid/:syn-mid at 5d3d85414a9e6674e1857ec22a87b96e04a6851a
Import subrepo syn/:syn at e87c27e87f6f4ef8919d0372bdb056d53ef0d8f3
Import subrepo textwrap/:textwrap at abcd618beae3f74841032aa5b53c1086b0a57ca2
Import subrepo unicode-segmentation/:unicode-segmentation at 637c9874c4fe0c205ff27787faf150a40295c6c3
Import subrepo unicode-width/:unicode-width at 3033826f8bf05e82724140a981d5941e48fce393
Import subrepo unicode-xid/:unicode-xid at 4baae9fffb156ba229665b972a9cd5991787ceb7
Diffstat (limited to 'bitflags')
| -rw-r--r-- | bitflags/.gitignore | 4 | ||||
| -rw-r--r-- | bitflags/.travis.yml | 39 | ||||
| -rw-r--r-- | bitflags/CHANGELOG.md | 149 | ||||
| -rw-r--r-- | bitflags/CODE_OF_CONDUCT.md | 73 | ||||
| -rw-r--r-- | bitflags/Cargo.toml | 37 | ||||
| -rw-r--r-- | bitflags/LICENSE-APACHE | 201 | ||||
| -rw-r--r-- | bitflags/LICENSE-MIT | 25 | ||||
| -rw-r--r-- | bitflags/README.md | 34 | ||||
| -rw-r--r-- | bitflags/bors.toml | 3 | ||||
| -rw-r--r-- | bitflags/build.rs | 44 | ||||
| -rw-r--r-- | bitflags/src/example_generated.rs | 14 | ||||
| -rw-r--r-- | bitflags/src/lib.rs | 1430 | ||||
| -rw-r--r-- | bitflags/test_suite/Cargo.toml | 13 | ||||
| -rw-r--r-- | bitflags/test_suite/tests/compile-fail/private_flags.rs | 20 | ||||
| -rw-r--r-- | bitflags/test_suite/tests/compiletest.rs | 33 | ||||
| -rw-r--r-- | bitflags/test_suite/tests/conflicting_trait_impls.rs | 17 | ||||
| -rw-r--r-- | bitflags/test_suite/tests/external.rs | 19 | ||||
| -rw-r--r-- | bitflags/test_suite/tests/external_no_std.rs | 21 | ||||
| -rw-r--r-- | bitflags/test_suite/tests/i128_bitflags.rs | 30 | ||||
| -rw-r--r-- | bitflags/test_suite/tests/serde.rs | 35 | 
20 files changed, 2241 insertions, 0 deletions
| diff --git a/bitflags/.gitignore b/bitflags/.gitignore new file mode 100644 index 0000000..fbd9642 --- /dev/null +++ b/bitflags/.gitignore @@ -0,0 +1,4 @@ +target +Cargo.lock + +/.idea/ diff --git a/bitflags/.travis.yml b/bitflags/.travis.yml new file mode 100644 index 0000000..9dd45c4 --- /dev/null +++ b/bitflags/.travis.yml @@ -0,0 +1,39 @@ +branches: +  except: +  - /.*(.tmp)$/ + +language: rust +matrix: +  include: +    # This version is tested to avoid unintentional bumping of the minimum supported Rust version +    - rust: 1.20.0 +      env: +        - LABEL="msrv" +      script: +        - cargo test +    - rust: stable +      env: +        - LABEL="no-std" +      script: +        - rustup target add thumbv6m-none-eabi +        - cargo build --features example_generated --target thumbv6m-none-eabi +    - rust: nightly +      env: +        - LABEL="compiletest" +      script: +        - cargo test +        - cargo test -p test_suite --features unstable +    - rust: stable +    - rust: stable +      os: osx +    - rust: beta +  allow_failures: +    - rust: nightly + +sudo: false +script: +  - cargo test --all + +notifications: +  email: +    on_success: never diff --git a/bitflags/CHANGELOG.md b/bitflags/CHANGELOG.md new file mode 100644 index 0000000..0d49101 --- /dev/null +++ b/bitflags/CHANGELOG.md @@ -0,0 +1,149 @@ +# 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 diff --git a/bitflags/CODE_OF_CONDUCT.md b/bitflags/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..f7add90 --- /dev/null +++ b/bitflags/CODE_OF_CONDUCT.md @@ -0,0 +1,73 @@ +# 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.org
\ No newline at end of file diff --git a/bitflags/Cargo.toml b/bitflags/Cargo.toml new file mode 100644 index 0000000..afbe066 --- /dev/null +++ b/bitflags/Cargo.toml @@ -0,0 +1,37 @@ +[package] + +name = "bitflags" +# NB: When modifying, also modify: +#   1. html_root_url in lib.rs +#   2. number in readme (for breaking changes) +version = "1.2.1" +authors = ["The Rust Project Developers"] +license = "MIT/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 = [ +    ".travis.yml", +    "appveyor.yml", +    "bors.toml" +] +build = "build.rs" + +[badges] +travis-ci = { repository = "bitflags/bitflags" } + +[features] +default = [] +example_generated = [] + +[package.metadata.docs.rs] +features = [ "example_generated" ] + +[workspace] +members = ["test_suite"] diff --git a/bitflags/LICENSE-APACHE b/bitflags/LICENSE-APACHE new file mode 100644 index 0000000..16fe87b --- /dev/null +++ b/bitflags/LICENSE-APACHE @@ -0,0 +1,201 @@ +                              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. diff --git a/bitflags/LICENSE-MIT b/bitflags/LICENSE-MIT new file mode 100644 index 0000000..39d4bdb --- /dev/null +++ b/bitflags/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (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. diff --git a/bitflags/README.md b/bitflags/README.md new file mode 100644 index 0000000..df12934 --- /dev/null +++ b/bitflags/README.md @@ -0,0 +1,34 @@ +bitflags +======== + +[](https://travis-ci.com/bitflags/bitflags) +[](https://gitter.im/bitflags/Lobby?utm_source=badge&utm_medium=badge&utm_content=badge) +[](https://crates.io/crates/bitflags) +[](https://docs.rs/bitflags) + + + +A Rust macro to generate structures which behave like a set of bitflags + +- [Documentation](https://docs.rs/bitflags) +- [Release notes](https://github.com/bitflags/bitflags/releases) + +## Usage + +Add this to your `Cargo.toml`: + +```toml +[dependencies] +bitflags = "1.0" +``` + +and this to your crate root: + +```rust +#[macro_use] +extern crate bitflags; +``` + +## Rust Version Support + +The minimum supported Rust version is 1.20 due to use of associated constants. diff --git a/bitflags/bors.toml b/bitflags/bors.toml new file mode 100644 index 0000000..713ea9b --- /dev/null +++ b/bitflags/bors.toml @@ -0,0 +1,3 @@ +status = [ +	"continuous-integration/travis-ci/push", +] diff --git a/bitflags/build.rs b/bitflags/build.rs new file mode 100644 index 0000000..985757a --- /dev/null +++ b/bitflags/build.rs @@ -0,0 +1,44 @@ +use std::env; +use std::process::Command; +use std::str::{self, FromStr}; + +fn main(){ +    let minor = match rustc_minor_version() { +        Some(minor) => minor, +        None => return, +    }; + +    // const fn stabilized in Rust 1.31: +    if minor >= 31 { +        println!("cargo:rustc-cfg=bitflags_const_fn"); +    } +} + +fn rustc_minor_version() -> Option<u32> { +    let rustc = match env::var_os("RUSTC") { +        Some(rustc) => rustc, +        None => return None, +    }; + +    let output = match Command::new(rustc).arg("--version").output() { +        Ok(output) => output, +        Err(_) => return None, +    }; + +    let version = match str::from_utf8(&output.stdout) { +        Ok(version) => version, +        Err(_) => return None, +    }; + +    let mut pieces = version.split('.'); +    if pieces.next() != Some("rustc 1") { +        return None; +    } + +    let next = match pieces.next() { +        Some(next) => next, +        None => return None, +    }; + +    u32::from_str(next).ok() +}
\ No newline at end of file diff --git a/bitflags/src/example_generated.rs b/bitflags/src/example_generated.rs new file mode 100644 index 0000000..cf188d9 --- /dev/null +++ b/bitflags/src/example_generated.rs @@ -0,0 +1,14 @@ +//! This module shows an example of code generated by the macro. **IT MUST NOT BE USED OUTSIDE THIS +//! CRATE**. + +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: u32 { +        const A = 0b00000001; +        const B = 0b00000010; +        const C = 0b00000100; +        const ABC = Self::A.bits | Self::B.bits | Self::C.bits; +    } +} diff --git a/bitflags/src/lib.rs b/bitflags/src/lib.rs new file mode 100644 index 0000000..3929b02 --- /dev/null +++ b/bitflags/src/lib.rs @@ -0,0 +1,1430 @@ +// 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! A typesafe bitmask flag generator useful for sets of C-style bitmask flags. +//! It can be used for creating typesafe wrappers around C APIs. +//! +//! The `bitflags!` macro generates a `struct` that manages a set of flags. The +//! flags should only be defined for integer types, otherwise unexpected type +//! errors may occur at compile time. +//! +//! # Example +//! +//! ``` +//! #[macro_use] +//! extern crate bitflags; +//! +//! bitflags! { +//!     struct Flags: u32 { +//!         const A = 0b00000001; +//!         const B = 0b00000010; +//!         const C = 0b00000100; +//!         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 +//! } +//! ``` +//! +//! See [`example_generated::Flags`](./example_generated/struct.Flags.html) for documentation of code +//! generated by the above `bitflags!` expansion. +//! +//! The generated `struct`s can also be extended with type and trait +//! implementations: +//! +//! ``` +//! #[macro_use] +//! extern crate bitflags; +//! +//! use std::fmt; +//! +//! bitflags! { +//!     struct Flags: u32 { +//!         const A = 0b00000001; +//!         const B = 0b00000010; +//!     } +//! } +//! +//! impl Flags { +//!     pub fn clear(&mut self) { +//!         self.bits = 0;  // The `bits` field can be accessed from within the +//!                         // same module where the `bitflags!` macro was invoked. +//!     } +//! } +//! +//! impl fmt::Display for Flags { +//!     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { +//!         write!(f, "hi!") +//!     } +//! } +//! +//! fn main() { +//!     let mut flags = Flags::A | Flags::B; +//!     flags.clear(); +//!     assert!(flags.is_empty()); +//!     assert_eq!(format!("{}", flags), "hi!"); +//!     assert_eq!(format!("{:?}", Flags::A | Flags::B), "A | B"); +//!     assert_eq!(format!("{:?}", Flags::B), "B"); +//! } +//! ``` +//! +//! # Visibility +//! +//! The generated struct and its associated flag constants are not exported +//! out of the current module by default. A definition can be exported out of +//! the current module by adding `pub` before `flags`: +//! +//! ``` +//! #[macro_use] +//! extern crate bitflags; +//! +//! mod example { +//!     bitflags! { +//!         pub struct Flags1: u32 { +//!             const A = 0b00000001; +//!         } +//!     } +//!     bitflags! { +//! #       pub +//!         struct Flags2: u32 { +//!             const B = 0b00000010; +//!         } +//!     } +//! } +//! +//! fn main() { +//!     let flag1 = example::Flags1::A; +//!     let flag2 = example::Flags2::B; // error: const `B` is private +//! } +//! ``` +//! +//! # Attributes +//! +//! Attributes can be attached to the generated `struct` by placing them +//! before the `flags` keyword. +//! +//! # Trait implementations +//! +//! The `Copy`, `Clone`, `PartialEq`, `Eq`, `PartialOrd`, `Ord` and `Hash` +//! traits automatically derived for the `struct` using the `derive` attribute. +//! Additional traits can be derived by providing an explicit `derive` +//! attribute on `flags`. +//! +//! The `Extend` and `FromIterator` traits are implemented for the `struct`, +//! too: `Extend` adds the union of the instances of the `struct` iterated over, +//! while `FromIterator` calculates the union. +//! +//! The `Binary`, `Debug`, `LowerHex`, `Octal` and `UpperHex` trait is also +//! implemented by displaying the bits value of the internal struct. +//! +//! ## Operators +//! +//! The following operator traits are implemented for the generated `struct`: +//! +//! - `BitOr` and `BitOrAssign`: union +//! - `BitAnd` and `BitAndAssign`: intersection +//! - `BitXor` and `BitXorAssign`: toggle +//! - `Sub` and `SubAssign`: set difference +//! - `Not`: set complement +//! +//! # Methods +//! +//! The following methods are defined for the generated `struct`: +//! +//! - `empty`: an empty set of flags +//! - `all`: the set of all defined flags +//! - `bits`: the raw value of the flags currently stored +//! - `from_bits`: convert from underlying bit representation, unless that +//!                representation contains bits that do not correspond to a +//!                defined flag +//! - `from_bits_truncate`: convert from underlying bit representation, dropping +//!                         any bits that do not correspond to defined flags +//! - `from_bits_unchecked`: convert from underlying bit representation, keeping +//!                          all bits (even those not corresponding to defined +//!                          flags) +//! - `is_empty`: `true` if no flags are currently stored +//! - `is_all`: `true` if currently set flags exactly equal all defined flags +//! - `intersects`: `true` if there are flags common to both `self` and `other` +//! - `contains`: `true` all of the flags in `other` are contained within `self` +//! - `insert`: inserts the specified flags in-place +//! - `remove`: removes the specified flags in-place +//! - `toggle`: the specified flags will be inserted if not present, and removed +//!             if they are. +//! - `set`: inserts or removes the specified flags depending on the passed value +//! +//! ## Default +//! +//! The `Default` trait is not automatically implemented for the generated struct. +//! +//! If your default value is equal to `0` (which is the same value as calling `empty()` +//! on the generated struct), you can simply derive `Default`: +//! +//! ``` +//! #[macro_use] +//! extern crate bitflags; +//! +//! bitflags! { +//!     // Results in default value with bits: 0 +//!     #[derive(Default)] +//!     struct Flags: u32 { +//!         const A = 0b00000001; +//!         const B = 0b00000010; +//!         const C = 0b00000100; +//!     } +//! } +//! +//! fn main() { +//!     let derived_default: Flags = Default::default(); +//!     assert_eq!(derived_default.bits(), 0); +//! } +//! ``` +//! +//! If your default value is not equal to `0` you need to implement `Default` yourself: +//! +//! ``` +//! #[macro_use] +//! extern crate bitflags; +//! +//! bitflags! { +//!     struct Flags: u32 { +//!         const A = 0b00000001; +//!         const B = 0b00000010; +//!         const C = 0b00000100; +//!     } +//! } +//! +//! // explicit `Default` implementation +//! impl Default for Flags { +//!     fn default() -> Flags { +//!         Flags::A | Flags::C +//!     } +//! } +//! +//! fn main() { +//!     let implemented_default: Flags = Default::default(); +//!     assert_eq!(implemented_default, (Flags::A | Flags::C)); +//! } +//! ``` +//! +//! # Zero Flags +//! +//! Flags with a value equal to zero will have some strange behavior that one should be aware of. +//! +//! ``` +//! #[macro_use] +//! extern crate bitflags; +//! +//! bitflags! { +//!     struct Flags: u32 { +//!         const NONE = 0b00000000; +//!         const SOME = 0b00000001; +//!     } +//! } +//! +//! fn main() { +//!     let empty = Flags::empty(); +//!     let none = Flags::NONE; +//!     let some = Flags::SOME; +//! +//!     // Zero flags are treated as always present +//!     assert!(empty.contains(Flags::NONE)); +//!     assert!(none.contains(Flags::NONE)); +//!     assert!(some.contains(Flags::NONE)); +//! +//!     // Zero flags will be ignored when testing for emptiness +//!     assert!(none.is_empty()); +//! } +//! ``` + +#![no_std] +#![doc(html_root_url = "https://docs.rs/bitflags/1.2.1")] + +#[cfg(test)] +#[macro_use] +extern crate std; + +// Re-export libcore using an alias so that the macros can work without +// requiring `extern crate core` downstream. +#[doc(hidden)] +pub extern crate core as _core; + +/// The macro used to generate the flag structure. +/// +/// See the [crate level docs](../bitflags/index.html) for complete documentation. +/// +/// # Example +/// +/// ``` +/// #[macro_use] +/// extern crate bitflags; +/// +/// bitflags! { +///     struct Flags: u32 { +///         const A = 0b00000001; +///         const B = 0b00000010; +///         const C = 0b00000100; +///         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 +/// } +/// ``` +/// +/// The generated `struct`s can also be extended with type and trait +/// implementations: +/// +/// ``` +/// #[macro_use] +/// extern crate bitflags; +/// +/// use std::fmt; +/// +/// bitflags! { +///     struct Flags: u32 { +///         const A = 0b00000001; +///         const B = 0b00000010; +///     } +/// } +/// +/// impl Flags { +///     pub fn clear(&mut self) { +///         self.bits = 0;  // The `bits` field can be accessed from within the +///                         // same module where the `bitflags!` macro was invoked. +///     } +/// } +/// +/// impl fmt::Display for Flags { +///     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { +///         write!(f, "hi!") +///     } +/// } +/// +/// fn main() { +///     let mut flags = Flags::A | Flags::B; +///     flags.clear(); +///     assert!(flags.is_empty()); +///     assert_eq!(format!("{}", flags), "hi!"); +///     assert_eq!(format!("{:?}", Flags::A | Flags::B), "A | B"); +///     assert_eq!(format!("{:?}", Flags::B), "B"); +/// } +/// ``` +#[macro_export(local_inner_macros)] +macro_rules! bitflags { +    ( +        $(#[$outer:meta])* +        pub struct $BitFlags:ident: $T:ty { +            $( +                $(#[$inner:ident $($args:tt)*])* +                const $Flag:ident = $value:expr; +            )+ +        } +    ) => { +        __bitflags! { +            $(#[$outer])* +            (pub) $BitFlags: $T { +                $( +                    $(#[$inner $($args)*])* +                    $Flag = $value; +                )+ +            } +        } +    }; +    ( +        $(#[$outer:meta])* +        struct $BitFlags:ident: $T:ty { +            $( +                $(#[$inner:ident $($args:tt)*])* +                const $Flag:ident = $value:expr; +            )+ +        } +    ) => { +        __bitflags! { +            $(#[$outer])* +            () $BitFlags: $T { +                $( +                    $(#[$inner $($args)*])* +                    $Flag = $value; +                )+ +            } +        } +    }; +    ( +        $(#[$outer:meta])* +        pub ($($vis:tt)+) struct $BitFlags:ident: $T:ty { +            $( +                $(#[$inner:ident $($args:tt)*])* +                const $Flag:ident = $value:expr; +            )+ +        } +    ) => { +        __bitflags! { +            $(#[$outer])* +            (pub ($($vis)+)) $BitFlags: $T { +                $( +                    $(#[$inner $($args)*])* +                    $Flag = $value; +                )+ +            } +        } +    }; +} + +#[macro_export(local_inner_macros)] +#[doc(hidden)] +macro_rules! __bitflags { +    ( +        $(#[$outer:meta])* +        ($($vis:tt)*) $BitFlags:ident: $T:ty { +            $( +                $(#[$inner:ident $($args:tt)*])* +                $Flag:ident = $value:expr; +            )+ +        } +    ) => { +        $(#[$outer])* +        #[derive(Copy, PartialEq, Eq, Clone, PartialOrd, Ord, Hash)] +        $($vis)* struct $BitFlags { +            bits: $T, +        } + +        __impl_bitflags! { +            $BitFlags: $T { +                $( +                    $(#[$inner $($args)*])* +                    $Flag = $value; +                )+ +            } +        } +    }; +} + +#[macro_export(local_inner_macros)] +#[doc(hidden)] +#[cfg(bitflags_const_fn)] +macro_rules! __fn_bitflags { +    ( +        $(# $attr_args:tt)* +        const fn $($item:tt)* +    ) => { +        $(# $attr_args)* +        const fn $($item)* +    }; +    ( +        $(# $attr_args:tt)* +        pub const fn $($item:tt)* +    ) => { +        $(# $attr_args)* +        pub const fn $($item)* +    }; +    ( +        $(# $attr_args:tt)* +        pub const unsafe fn $($item:tt)* +    ) => { +        $(# $attr_args)* +        pub const unsafe fn $($item)* +    }; +} + +#[macro_export(local_inner_macros)] +#[doc(hidden)] +#[cfg(not(bitflags_const_fn))] +macro_rules! __fn_bitflags { +    ( +        $(# $attr_args:tt)* +        const fn $($item:tt)* +    ) => { +        $(# $attr_args)* +        fn $($item)* +    }; +    ( +        $(# $attr_args:tt)* +        pub const fn $($item:tt)* +    ) => { +        $(# $attr_args)* +        pub fn $($item)* +    }; +    ( +        $(# $attr_args:tt)* +        pub const unsafe fn $($item:tt)* +    ) => { +        $(# $attr_args)* +        pub unsafe fn $($item)* +    }; +} + +#[macro_export(local_inner_macros)] +#[doc(hidden)] +macro_rules! __impl_bitflags { +    ( +        $BitFlags:ident: $T:ty { +            $( +                $(#[$attr:ident $($args:tt)*])* +                $Flag:ident = $value:expr; +            )+ +        } +    ) => { +        impl $crate::_core::fmt::Debug for $BitFlags { +            fn fmt(&self, f: &mut $crate::_core::fmt::Formatter) -> $crate::_core::fmt::Result { +                // This convoluted approach is to handle #[cfg]-based flag +                // omission correctly. For example it needs to support: +                // +                //    #[cfg(unix)] const A: Flag = /* ... */; +                //    #[cfg(windows)] const B: Flag = /* ... */; + +                // Unconditionally define a check for every flag, even disabled +                // ones. +                #[allow(non_snake_case)] +                trait __BitFlags { +                    $( +                        #[inline] +                        fn $Flag(&self) -> bool { false } +                    )+ +                } + +                // Conditionally override the check for just those flags that +                // are not #[cfg]ed away. +                impl __BitFlags for $BitFlags { +                    $( +                        __impl_bitflags! { +                            #[allow(deprecated)] +                            #[inline] +                            $(? #[$attr $($args)*])* +                            fn $Flag(&self) -> bool { +                                if Self::$Flag.bits == 0 && self.bits != 0 { +                                    false +                                } else { +                                    self.bits & Self::$Flag.bits == Self::$Flag.bits +                                } +                            } +                        } +                    )+ +                } + +                let mut first = true; +                $( +                    if <$BitFlags as __BitFlags>::$Flag(self) { +                        if !first { +                            f.write_str(" | ")?; +                        } +                        first = false; +                        f.write_str(__bitflags_stringify!($Flag))?; +                    } +                )+ +                let extra_bits = self.bits & !$BitFlags::all().bits(); +                if extra_bits != 0 { +                    if !first { +                        f.write_str(" | ")?; +                    } +                    first = false; +                    f.write_str("0x")?; +                    $crate::_core::fmt::LowerHex::fmt(&extra_bits, f)?; +                } +                if first { +                    f.write_str("(empty)")?; +                } +                Ok(()) +            } +        } +        impl $crate::_core::fmt::Binary for $BitFlags { +            fn fmt(&self, f: &mut $crate::_core::fmt::Formatter) -> $crate::_core::fmt::Result { +                $crate::_core::fmt::Binary::fmt(&self.bits, f) +            } +        } +        impl $crate::_core::fmt::Octal for $BitFlags { +            fn fmt(&self, f: &mut $crate::_core::fmt::Formatter) -> $crate::_core::fmt::Result { +                $crate::_core::fmt::Octal::fmt(&self.bits, f) +            } +        } +        impl $crate::_core::fmt::LowerHex for $BitFlags { +            fn fmt(&self, f: &mut $crate::_core::fmt::Formatter) -> $crate::_core::fmt::Result { +                $crate::_core::fmt::LowerHex::fmt(&self.bits, f) +            } +        } +        impl $crate::_core::fmt::UpperHex for $BitFlags { +            fn fmt(&self, f: &mut $crate::_core::fmt::Formatter) -> $crate::_core::fmt::Result { +                $crate::_core::fmt::UpperHex::fmt(&self.bits, f) +            } +        } + +        #[allow(dead_code)] +        impl $BitFlags { +            $( +                $(#[$attr $($args)*])* +                pub const $Flag: $BitFlags = $BitFlags { bits: $value }; +            )+ + +            __fn_bitflags! { +                /// Returns an empty set of flags +                #[inline] +                pub const fn empty() -> $BitFlags { +                    $BitFlags { bits: 0 } +                } +            } + +            __fn_bitflags! { +                /// Returns the set containing all flags. +                #[inline] +                pub const fn all() -> $BitFlags { +                    // See `Debug::fmt` for why this approach is taken. +                    #[allow(non_snake_case)] +                    trait __BitFlags { +                        $( +                            const $Flag: $T = 0; +                        )+ +                    } +                    impl __BitFlags for $BitFlags { +                        $( +                            __impl_bitflags! { +                                #[allow(deprecated)] +                                $(? #[$attr $($args)*])* +                                const $Flag: $T = Self::$Flag.bits; +                            } +                        )+ +                    } +                    $BitFlags { bits: $(<$BitFlags as __BitFlags>::$Flag)|+ } +                } +            } + +            __fn_bitflags! { +                /// Returns the raw value of the flags currently stored. +                #[inline] +                pub const fn bits(&self) -> $T { +                    self.bits +                } +            } + +            /// Convert from underlying bit representation, unless that +            /// representation contains bits that do not correspond to a flag. +            #[inline] +            pub fn from_bits(bits: $T) -> $crate::_core::option::Option<$BitFlags> { +                if (bits & !$BitFlags::all().bits()) == 0 { +                    $crate::_core::option::Option::Some($BitFlags { bits }) +                } else { +                    $crate::_core::option::Option::None +                } +            } + +            __fn_bitflags! { +                /// Convert from underlying bit representation, dropping any bits +                /// that do not correspond to flags. +                #[inline] +                pub const fn from_bits_truncate(bits: $T) -> $BitFlags { +                    $BitFlags { bits: bits & $BitFlags::all().bits } +                } +            } + +            __fn_bitflags! { +                /// Convert from underlying bit representation, preserving all +                /// bits (even those not corresponding to a defined flag). +                #[inline] +                pub const unsafe fn from_bits_unchecked(bits: $T) -> $BitFlags { +                    $BitFlags { bits } +                } +            } + +            __fn_bitflags! { +                /// Returns `true` if no flags are currently stored. +                #[inline] +                pub const fn is_empty(&self) -> bool { +                    self.bits() == $BitFlags::empty().bits() +                } +            } + +            __fn_bitflags! { +                /// Returns `true` if all flags are currently set. +                #[inline] +                pub const fn is_all(&self) -> bool { +                    self.bits == $BitFlags::all().bits +                } +            } + +            __fn_bitflags! { +                /// Returns `true` if there are flags common to both `self` and `other`. +                #[inline] +                pub const fn intersects(&self, other: $BitFlags) -> bool { +                    !$BitFlags{ bits: self.bits & other.bits}.is_empty() +                } +            } + +            __fn_bitflags! { +                /// Returns `true` all of the flags in `other` are contained within `self`. +                #[inline] +                pub const fn contains(&self, other: $BitFlags) -> bool { +                    (self.bits & other.bits) == other.bits +                } +            } + +            /// Inserts the specified flags in-place. +            #[inline] +            pub fn insert(&mut self, other: $BitFlags) { +                self.bits |= other.bits; +            } + +            /// Removes the specified flags in-place. +            #[inline] +            pub fn remove(&mut self, other: $BitFlags) { +                self.bits &= !other.bits; +            } + +            /// Toggles the specified flags in-place. +            #[inline] +            pub fn toggle(&mut self, other: $BitFlags) { +                self.bits ^= other.bits; +            } + +            /// Inserts or removes the specified flags depending on the passed value. +            #[inline] +            pub fn set(&mut self, other: $BitFlags, value: bool) { +                if value { +                    self.insert(other); +                } else { +                    self.remove(other); +                } +            } +        } + +        impl $crate::_core::ops::BitOr for $BitFlags { +            type Output = $BitFlags; + +            /// Returns the union of the two sets of flags. +            #[inline] +            fn bitor(self, other: $BitFlags) -> $BitFlags { +                $BitFlags { bits: self.bits | other.bits } +            } +        } + +        impl $crate::_core::ops::BitOrAssign for $BitFlags { + +            /// Adds the set of flags. +            #[inline] +            fn bitor_assign(&mut self, other: $BitFlags) { +                self.bits |= other.bits; +            } +        } + +        impl $crate::_core::ops::BitXor for $BitFlags { +            type Output = $BitFlags; + +            /// Returns the left flags, but with all the right flags toggled. +            #[inline] +            fn bitxor(self, other: $BitFlags) -> $BitFlags { +                $BitFlags { bits: self.bits ^ other.bits } +            } +        } + +        impl $crate::_core::ops::BitXorAssign for $BitFlags { + +            /// Toggles the set of flags. +            #[inline] +            fn bitxor_assign(&mut self, other: $BitFlags) { +                self.bits ^= other.bits; +            } +        } + +        impl $crate::_core::ops::BitAnd for $BitFlags { +            type Output = $BitFlags; + +            /// Returns the intersection between the two sets of flags. +            #[inline] +            fn bitand(self, other: $BitFlags) -> $BitFlags { +                $BitFlags { bits: self.bits & other.bits } +            } +        } + +        impl $crate::_core::ops::BitAndAssign for $BitFlags { + +            /// Disables all flags disabled in the set. +            #[inline] +            fn bitand_assign(&mut self, other: $BitFlags) { +                self.bits &= other.bits; +            } +        } + +        impl $crate::_core::ops::Sub for $BitFlags { +            type Output = $BitFlags; + +            /// Returns the set difference of the two sets of flags. +            #[inline] +            fn sub(self, other: $BitFlags) -> $BitFlags { +                $BitFlags { bits: self.bits & !other.bits } +            } +        } + +        impl $crate::_core::ops::SubAssign for $BitFlags { + +            /// Disables all flags enabled in the set. +            #[inline] +            fn sub_assign(&mut self, other: $BitFlags) { +                self.bits &= !other.bits; +            } +        } + +        impl $crate::_core::ops::Not for $BitFlags { +            type Output = $BitFlags; + +            /// Returns the complement of this set of flags. +            #[inline] +            fn not(self) -> $BitFlags { +                $BitFlags { bits: !self.bits } & $BitFlags::all() +            } +        } + +        impl $crate::_core::iter::Extend<$BitFlags> for $BitFlags { +            fn extend<T: $crate::_core::iter::IntoIterator<Item=$BitFlags>>(&mut self, iterator: T) { +                for item in iterator { +                    self.insert(item) +                } +            } +        } + +        impl $crate::_core::iter::FromIterator<$BitFlags> for $BitFlags { +            fn from_iter<T: $crate::_core::iter::IntoIterator<Item=$BitFlags>>(iterator: T) -> $BitFlags { +                let mut result = Self::empty(); +                result.extend(iterator); +                result +            } +        } +    }; + +    // Every attribute that the user writes on a const is applied to the +    // corresponding const that we generate, but within the implementation of +    // Debug and all() we want to ignore everything but #[cfg] attributes. In +    // particular, including a #[deprecated] attribute on those items would fail +    // to compile. +    // https://github.com/bitflags/bitflags/issues/109 +    // +    // Input: +    // +    //     ? #[cfg(feature = "advanced")] +    //     ? #[deprecated(note = "Use somthing else.")] +    //     ? #[doc = r"High quality documentation."] +    //     fn f() -> i32 { /* ... */ } +    // +    // Output: +    // +    //     #[cfg(feature = "advanced")] +    //     fn f() -> i32 { /* ... */ } +    ( +        $(#[$filtered:meta])* +        ? #[cfg $($cfgargs:tt)*] +        $(? #[$rest:ident $($restargs:tt)*])* +        fn $($item:tt)* +    ) => { +        __impl_bitflags! { +            $(#[$filtered])* +            #[cfg $($cfgargs)*] +            $(? #[$rest $($restargs)*])* +            fn $($item)* +        } +    }; +    ( +        $(#[$filtered:meta])* +        // $next != `cfg` +        ? #[$next:ident $($nextargs:tt)*] +        $(? #[$rest:ident $($restargs:tt)*])* +        fn $($item:tt)* +    ) => { +        __impl_bitflags! { +            $(#[$filtered])* +            // $next filtered out +            $(? #[$rest $($restargs)*])* +            fn $($item)* +        } +    }; +    ( +        $(#[$filtered:meta])* +        fn $($item:tt)* +    ) => { +        $(#[$filtered])* +        fn $($item)* +    }; + +    // Every attribute that the user writes on a const is applied to the +    // corresponding const that we generate, but within the implementation of +    // Debug and all() we want to ignore everything but #[cfg] attributes. In +    // particular, including a #[deprecated] attribute on those items would fail +    // to compile. +    // https://github.com/bitflags/bitflags/issues/109 +    // +    // const version +    // +    // Input: +    // +    //     ? #[cfg(feature = "advanced")] +    //     ? #[deprecated(note = "Use somthing else.")] +    //     ? #[doc = r"High quality documentation."] +    //     const f: i32 { /* ... */ } +    // +    // Output: +    // +    //     #[cfg(feature = "advanced")] +    //     const f: i32 { /* ... */ } +    ( +        $(#[$filtered:meta])* +        ? #[cfg $($cfgargs:tt)*] +        $(? #[$rest:ident $($restargs:tt)*])* +        const $($item:tt)* +    ) => { +        __impl_bitflags! { +            $(#[$filtered])* +            #[cfg $($cfgargs)*] +            $(? #[$rest $($restargs)*])* +            const $($item)* +        } +    }; +    ( +        $(#[$filtered:meta])* +        // $next != `cfg` +        ? #[$next:ident $($nextargs:tt)*] +        $(? #[$rest:ident $($restargs:tt)*])* +        const $($item:tt)* +    ) => { +        __impl_bitflags! { +            $(#[$filtered])* +            // $next filtered out +            $(? #[$rest $($restargs)*])* +            const $($item)* +        } +    }; +    ( +        $(#[$filtered:meta])* +        const $($item:tt)* +    ) => { +        $(#[$filtered])* +        const $($item)* +    }; +} + +// Same as std::stringify but callable from __impl_bitflags, which needs to use +// local_inner_macros so can only directly call macros from this crate. +#[macro_export] +#[doc(hidden)] +macro_rules! __bitflags_stringify { +    ($s:ident) => { +        stringify!($s) +    }; +} + +#[cfg(feature = "example_generated")] +pub mod example_generated; + +#[cfg(test)] +mod tests { +    use std::collections::hash_map::DefaultHasher; +    use std::hash::{Hash, Hasher}; + +    bitflags! { +        #[doc = "> The first principle is that you must not fool yourself — and"] +        #[doc = "> you are the easiest person to fool."] +        #[doc = "> "] +        #[doc = "> - Richard Feynman"] +        struct Flags: u32 { +            const A = 0b00000001; +            #[doc = "<pcwalton> macros are way better at generating code than trans is"] +            const B = 0b00000010; +            const C = 0b00000100; +            #[doc = "* cmr bed"] +            #[doc = "* strcat table"] +            #[doc = "<strcat> wait what?"] +            const ABC = Self::A.bits | Self::B.bits | Self::C.bits; +        } +    } + +    bitflags! { +        struct _CfgFlags: u32 { +            #[cfg(unix)] +            const _CFG_A = 0b01; +            #[cfg(windows)] +            const _CFG_B = 0b01; +            #[cfg(unix)] +            const _CFG_C = Self::_CFG_A.bits | 0b10; +        } +    } + +    bitflags! { +        struct AnotherSetOfFlags: i8 { +            const ANOTHER_FLAG = -1_i8; +        } +    } + +    bitflags! { +        struct LongFlags: u32 { +            const LONG_A = 0b1111111111111111; +        } +    } + +    #[test] +    fn test_bits() { +        assert_eq!(Flags::empty().bits(), 0b00000000); +        assert_eq!(Flags::A.bits(), 0b00000001); +        assert_eq!(Flags::ABC.bits(), 0b00000111); + +        assert_eq!(AnotherSetOfFlags::empty().bits(), 0b00); +        assert_eq!(AnotherSetOfFlags::ANOTHER_FLAG.bits(), !0_i8); +    } + +    #[test] +    fn test_from_bits() { +        assert_eq!(Flags::from_bits(0), Some(Flags::empty())); +        assert_eq!(Flags::from_bits(0b1), Some(Flags::A)); +        assert_eq!(Flags::from_bits(0b10), Some(Flags::B)); +        assert_eq!(Flags::from_bits(0b11), Some(Flags::A | Flags::B)); +        assert_eq!(Flags::from_bits(0b1000), None); + +        assert_eq!( +            AnotherSetOfFlags::from_bits(!0_i8), +            Some(AnotherSetOfFlags::ANOTHER_FLAG) +        ); +    } + +    #[test] +    fn test_from_bits_truncate() { +        assert_eq!(Flags::from_bits_truncate(0), Flags::empty()); +        assert_eq!(Flags::from_bits_truncate(0b1), Flags::A); +        assert_eq!(Flags::from_bits_truncate(0b10), Flags::B); +        assert_eq!(Flags::from_bits_truncate(0b11), (Flags::A | Flags::B)); +        assert_eq!(Flags::from_bits_truncate(0b1000), Flags::empty()); +        assert_eq!(Flags::from_bits_truncate(0b1001), Flags::A); + +        assert_eq!( +            AnotherSetOfFlags::from_bits_truncate(0_i8), +            AnotherSetOfFlags::empty() +        ); +    } + +    #[test] +    fn test_from_bits_unchecked() { +        let extra = unsafe { Flags::from_bits_unchecked(0b1000) }; +        assert_eq!(unsafe { Flags::from_bits_unchecked(0) }, Flags::empty()); +        assert_eq!(unsafe { Flags::from_bits_unchecked(0b1) }, Flags::A); +        assert_eq!(unsafe { Flags::from_bits_unchecked(0b10) }, Flags::B); +        assert_eq!(unsafe { Flags::from_bits_unchecked(0b11) }, (Flags::A | Flags::B)); +        assert_eq!(unsafe { Flags::from_bits_unchecked(0b1000) }, (extra | Flags::empty())); +        assert_eq!(unsafe { Flags::from_bits_unchecked(0b1001) }, (extra | Flags::A)); +    } + +    #[test] +    fn test_is_empty() { +        assert!(Flags::empty().is_empty()); +        assert!(!Flags::A.is_empty()); +        assert!(!Flags::ABC.is_empty()); + +        assert!(!AnotherSetOfFlags::ANOTHER_FLAG.is_empty()); +    } + +    #[test] +    fn test_is_all() { +        assert!(Flags::all().is_all()); +        assert!(!Flags::A.is_all()); +        assert!(Flags::ABC.is_all()); + +        assert!(AnotherSetOfFlags::ANOTHER_FLAG.is_all()); +    } + +    #[test] +    fn test_two_empties_do_not_intersect() { +        let e1 = Flags::empty(); +        let e2 = Flags::empty(); +        assert!(!e1.intersects(e2)); + +        assert!(AnotherSetOfFlags::ANOTHER_FLAG.intersects(AnotherSetOfFlags::ANOTHER_FLAG)); +    } + +    #[test] +    fn test_empty_does_not_intersect_with_full() { +        let e1 = Flags::empty(); +        let e2 = Flags::ABC; +        assert!(!e1.intersects(e2)); +    } + +    #[test] +    fn test_disjoint_intersects() { +        let e1 = Flags::A; +        let e2 = Flags::B; +        assert!(!e1.intersects(e2)); +    } + +    #[test] +    fn test_overlapping_intersects() { +        let e1 = Flags::A; +        let e2 = Flags::A | Flags::B; +        assert!(e1.intersects(e2)); +    } + +    #[test] +    fn test_contains() { +        let e1 = Flags::A; +        let e2 = Flags::A | Flags::B; +        assert!(!e1.contains(e2)); +        assert!(e2.contains(e1)); +        assert!(Flags::ABC.contains(e2)); + +        assert!(AnotherSetOfFlags::ANOTHER_FLAG.contains(AnotherSetOfFlags::ANOTHER_FLAG)); +    } + +    #[test] +    fn test_insert() { +        let mut e1 = Flags::A; +        let e2 = Flags::A | Flags::B; +        e1.insert(e2); +        assert_eq!(e1, e2); + +        let mut e3 = AnotherSetOfFlags::empty(); +        e3.insert(AnotherSetOfFlags::ANOTHER_FLAG); +        assert_eq!(e3, AnotherSetOfFlags::ANOTHER_FLAG); +    } + +    #[test] +    fn test_remove() { +        let mut e1 = Flags::A | Flags::B; +        let e2 = Flags::A | Flags::C; +        e1.remove(e2); +        assert_eq!(e1, Flags::B); + +        let mut e3 = AnotherSetOfFlags::ANOTHER_FLAG; +        e3.remove(AnotherSetOfFlags::ANOTHER_FLAG); +        assert_eq!(e3, AnotherSetOfFlags::empty()); +    } + +    #[test] +    fn test_operators() { +        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 +        assert_eq!(e1 ^ e2, Flags::A | Flags::B); // toggle +        let mut e3 = e1; +        e3.toggle(e2); +        assert_eq!(e3, Flags::A | Flags::B); + +        let mut m4 = AnotherSetOfFlags::empty(); +        m4.toggle(AnotherSetOfFlags::empty()); +        assert_eq!(m4, AnotherSetOfFlags::empty()); +    } + +    #[test] +    fn test_operators_unchecked() { +        let extra = unsafe { Flags::from_bits_unchecked(0b1000) }; +        let e1 = Flags::A | Flags::C | extra; +        let e2 = Flags::B | Flags::C; +        assert_eq!((e1 | e2), (Flags::ABC | extra)); // union +        assert_eq!((e1 & e2), Flags::C); // intersection +        assert_eq!((e1 - e2), (Flags::A | extra)); // set difference +        assert_eq!(!e2, Flags::A); // set complement +        assert_eq!(!e1, Flags::B); // set complement +        assert_eq!(e1 ^ e2, Flags::A | Flags::B | extra); // toggle +        let mut e3 = e1; +        e3.toggle(e2); +        assert_eq!(e3, Flags::A | Flags::B | extra); +    } + +    #[test] +    fn test_set() { +        let mut e1 = Flags::A | Flags::C; +        e1.set(Flags::B, true); +        e1.set(Flags::C, false); + +        assert_eq!(e1, Flags::A | Flags::B); +    } + +    #[test] +    fn test_assignment_operators() { +        let mut m1 = Flags::empty(); +        let e1 = Flags::A | Flags::C; +        // union +        m1 |= Flags::A; +        assert_eq!(m1, Flags::A); +        // intersection +        m1 &= e1; +        assert_eq!(m1, Flags::A); +        // set difference +        m1 -= m1; +        assert_eq!(m1, Flags::empty()); +        // toggle +        m1 ^= e1; +        assert_eq!(m1, e1); +    } + + +    #[cfg(bitflags_const_fn)] +    #[test] +    fn test_const_fn() { +        const _M1: Flags = Flags::empty(); + +        const M2: Flags = Flags::A; +        assert_eq!(M2, Flags::A); + +        const M3: Flags = Flags::C; +        assert_eq!(M3, Flags::C); +    } + +    #[test] +    fn test_extend() { +        let mut flags; + +        flags = Flags::empty(); +        flags.extend([].iter().cloned()); +        assert_eq!(flags, Flags::empty()); + +        flags = Flags::empty(); +        flags.extend([Flags::A, Flags::B].iter().cloned()); +        assert_eq!(flags, Flags::A | Flags::B); + +        flags = Flags::A; +        flags.extend([Flags::A, Flags::B].iter().cloned()); +        assert_eq!(flags, Flags::A | Flags::B); + +        flags = Flags::B; +        flags.extend([Flags::A, Flags::ABC].iter().cloned()); +        assert_eq!(flags, Flags::ABC); +    } + +    #[test] +    fn test_from_iterator() { +        assert_eq!([].iter().cloned().collect::<Flags>(), Flags::empty()); +        assert_eq!( +            [Flags::A, Flags::B].iter().cloned().collect::<Flags>(), +            Flags::A | Flags::B +        ); +        assert_eq!( +            [Flags::A, Flags::ABC].iter().cloned().collect::<Flags>(), +            Flags::ABC +        ); +    } + +    #[test] +    fn test_lt() { +        let mut a = Flags::empty(); +        let mut b = Flags::empty(); + +        assert!(!(a < b) && !(b < a)); +        b = Flags::B; +        assert!(a < b); +        a = Flags::C; +        assert!(!(a < b) && b < a); +        b = Flags::C | Flags::B; +        assert!(a < b); +    } + +    #[test] +    fn test_ord() { +        let mut a = Flags::empty(); +        let mut b = Flags::empty(); + +        assert!(a <= b && a >= b); +        a = Flags::A; +        assert!(a > b && a >= b); +        assert!(b < a && b <= a); +        b = Flags::B; +        assert!(b > a && b >= a); +        assert!(a < b && a <= b); +    } + +    fn hash<T: Hash>(t: &T) -> u64 { +        let mut s = DefaultHasher::new(); +        t.hash(&mut s); +        s.finish() +    } + +    #[test] +    fn test_hash() { +        let mut x = Flags::empty(); +        let mut y = Flags::empty(); +        assert_eq!(hash(&x), hash(&y)); +        x = Flags::all(); +        y = Flags::ABC; +        assert_eq!(hash(&x), hash(&y)); +    } + +    #[test] +    fn test_debug() { +        assert_eq!(format!("{:?}", Flags::A | Flags::B), "A | B"); +        assert_eq!(format!("{:?}", Flags::empty()), "(empty)"); +        assert_eq!(format!("{:?}", Flags::ABC), "A | B | C | ABC"); +        let extra = unsafe { Flags::from_bits_unchecked(0xb8) }; +        assert_eq!(format!("{:?}", extra), "0xb8"); +        assert_eq!(format!("{:?}", Flags::A | extra), "A | 0xb8"); +        assert_eq!(format!("{:?}", Flags::ABC | extra), "A | B | C | ABC | 0xb8"); +    } + +    #[test] +    fn test_binary() { +        assert_eq!(format!("{:b}", Flags::ABC), "111"); +        assert_eq!(format!("{:#b}", Flags::ABC), "0b111"); +        let extra = unsafe { Flags::from_bits_unchecked(0b1010000) }; +        assert_eq!(format!("{:b}", Flags::ABC | extra), "1010111"); +        assert_eq!(format!("{:#b}", Flags::ABC | extra), "0b1010111"); +    } + +    #[test] +    fn test_octal() { +        assert_eq!(format!("{:o}", LongFlags::LONG_A), "177777"); +        assert_eq!(format!("{:#o}", LongFlags::LONG_A), "0o177777"); +        let extra = unsafe { LongFlags::from_bits_unchecked(0o5000000) }; +        assert_eq!(format!("{:o}", LongFlags::LONG_A | extra), "5177777"); +        assert_eq!(format!("{:#o}", LongFlags::LONG_A | extra), "0o5177777"); +    } + +    #[test] +    fn test_lowerhex() { +        assert_eq!(format!("{:x}", LongFlags::LONG_A), "ffff"); +        assert_eq!(format!("{:#x}", LongFlags::LONG_A), "0xffff"); +        let extra = unsafe { LongFlags::from_bits_unchecked(0xe00000) }; +        assert_eq!(format!("{:x}", LongFlags::LONG_A | extra), "e0ffff"); +        assert_eq!(format!("{:#x}", LongFlags::LONG_A | extra), "0xe0ffff"); +    } + +    #[test] +    fn test_upperhex() { +        assert_eq!(format!("{:X}", LongFlags::LONG_A), "FFFF"); +        assert_eq!(format!("{:#X}", LongFlags::LONG_A), "0xFFFF"); +        let extra = unsafe { LongFlags::from_bits_unchecked(0xe00000) }; +        assert_eq!(format!("{:X}", LongFlags::LONG_A | extra), "E0FFFF"); +        assert_eq!(format!("{:#X}", LongFlags::LONG_A | extra), "0xE0FFFF"); +    } + +    mod submodule { +        bitflags! { +            pub struct PublicFlags: i8 { +                const X = 0; +            } +        } +        bitflags! { +            struct PrivateFlags: i8 { +                const Y = 0; +            } +        } + +        #[test] +        fn test_private() { +            let _ = PrivateFlags::Y; +        } +    } + +    #[test] +    fn test_public() { +        let _ = submodule::PublicFlags::X; +    } + +    mod t1 { +        mod foo { +            pub type Bar = i32; +        } + +        bitflags! { +            /// baz +            struct Flags: foo::Bar { +                const A = 0b00000001; +                #[cfg(foo)] +                const B = 0b00000010; +                #[cfg(foo)] +                const C = 0b00000010; +            } +        } +    } + +    #[test] +    fn test_in_function() { +        bitflags! { +           struct Flags: u8 { +                const A = 1; +                #[cfg(any())] // false +                const B = 2; +            } +        } +        assert_eq!(Flags::all(), Flags::A); +        assert_eq!(format!("{:?}", Flags::A), "A"); +    } + +    #[test] +    fn test_deprecated() { +        bitflags! { +            pub struct TestFlags: u32 { +                #[deprecated(note = "Use something else.")] +                const ONE = 1; +            } +        } +    } + +    #[test] +    fn test_pub_crate() { +        mod module { +            bitflags! { +                pub (crate) struct Test: u8 { +                    const FOO = 1; +                } +            } +        } + +        assert_eq!(module::Test::FOO.bits(), 1); +    } + +    #[test] +    fn test_pub_in_module() { +        mod module { +            mod submodule { +                bitflags! { +                    // `pub (in super)` means only the module `module` will +                    // be able to access this. +                    pub (in super) struct Test: u8 { +                        const FOO = 1; +                    } +                } +            } + +            mod test { +                // Note: due to `pub (in super)`, +                // this cannot be accessed directly by the testing code. +                pub(super) fn value() -> u8 { +                    super::submodule::Test::FOO.bits() +                } +            } + +            pub fn value() -> u8 { +                test::value() +            } +        } + +        assert_eq!(module::value(), 1) +    } + +    #[test] +    fn test_zero_value_flags() { +        bitflags! { +            struct Flags: u32 { +                const NONE = 0b0; +                const SOME = 0b1; +            } +        } + +        assert!(Flags::empty().contains(Flags::NONE)); +        assert!(Flags::SOME.contains(Flags::NONE)); +        assert!(Flags::NONE.is_empty()); + +        assert_eq!(format!("{:?}", Flags::empty()), "NONE"); +        assert_eq!(format!("{:?}", Flags::SOME), "SOME"); +    } +} diff --git a/bitflags/test_suite/Cargo.toml b/bitflags/test_suite/Cargo.toml new file mode 100644 index 0000000..2a02d80 --- /dev/null +++ b/bitflags/test_suite/Cargo.toml @@ -0,0 +1,13 @@ +[project] +name = "test_suite" +version = "0.0.0" + +[features] +unstable = ["compiletest_rs"] + +[dependencies] +bitflags = { path = "../" } +compiletest_rs = { version = "0.3.18", optional = true, features=["stable"] } +serde = "1.0" +serde_derive = "1.0" +serde_json = "1.0" diff --git a/bitflags/test_suite/tests/compile-fail/private_flags.rs b/bitflags/test_suite/tests/compile-fail/private_flags.rs new file mode 100644 index 0000000..d31c28d --- /dev/null +++ b/bitflags/test_suite/tests/compile-fail/private_flags.rs @@ -0,0 +1,20 @@ +#[macro_use] +extern crate bitflags; + +mod example { +    bitflags! { +        pub struct Flags1: u32 { +            const FLAG_A = 0b00000001; +        } +    } +    bitflags! { +        struct Flags2: u32 { +            const FLAG_B = 0b00000010; +        } +    } +} + +fn main() { +    let flag1 = example::Flags1::FLAG_A; +    let flag2 = example::Flags2::FLAG_B; //~ ERROR struct `Flags2` is private +} diff --git a/bitflags/test_suite/tests/compiletest.rs b/bitflags/test_suite/tests/compiletest.rs new file mode 100644 index 0000000..2beeae0 --- /dev/null +++ b/bitflags/test_suite/tests/compiletest.rs @@ -0,0 +1,33 @@ +#![cfg(feature = "unstable")] + +extern crate compiletest_rs as compiletest; + +use std::fs; +use std::result::Result; + +use compiletest::common::Mode; + +fn run_mode(mode: Mode) { +    let config = compiletest::Config { +        mode: mode, +        src_base: format!("tests/{}", mode).into(), +        target_rustcflags: fs::read_dir("../target/debug/deps") +            .unwrap() +            .map(Result::unwrap) +            .filter(|entry| { +                let file_name = entry.file_name(); +                let file_name = file_name.to_string_lossy(); +                file_name.starts_with("libbitflags-") && file_name.ends_with(".rlib") +            }) +            .max_by_key(|entry| entry.metadata().unwrap().modified().unwrap()) +            .map(|entry| format!("--extern bitflags={}", entry.path().to_string_lossy())), +        ..Default::default() +    }; + +    compiletest::run_tests(&config); +} + +#[test] +fn compile_test() { +    run_mode(Mode::CompileFail); +} diff --git a/bitflags/test_suite/tests/conflicting_trait_impls.rs b/bitflags/test_suite/tests/conflicting_trait_impls.rs new file mode 100644 index 0000000..eb7a325 --- /dev/null +++ b/bitflags/test_suite/tests/conflicting_trait_impls.rs @@ -0,0 +1,17 @@ +#![no_std] + +#[macro_use] +extern crate bitflags; + +#[allow(unused_imports)] +use core::fmt::Display; + +bitflags! { +    /// baz +    struct Flags: u32 { +        const A = 0b00000001; +    } +} + +#[test] +fn main() {} diff --git a/bitflags/test_suite/tests/external.rs b/bitflags/test_suite/tests/external.rs new file mode 100644 index 0000000..4c88387 --- /dev/null +++ b/bitflags/test_suite/tests/external.rs @@ -0,0 +1,19 @@ +#[macro_use] +extern crate bitflags; + +bitflags! { +    /// baz +    struct Flags: u32 { +        const A = 0b00000001; +        #[doc = "bar"] +        const B = 0b00000010; +        const C = 0b00000100; +        #[doc = "foo"] +        const ABC = Flags::A.bits | Flags::B.bits | Flags::C.bits; +    } +} + +#[test] +fn smoke() { +    assert_eq!(Flags::ABC, Flags::A | Flags::B | Flags::C); +} diff --git a/bitflags/test_suite/tests/external_no_std.rs b/bitflags/test_suite/tests/external_no_std.rs new file mode 100644 index 0000000..31f87e4 --- /dev/null +++ b/bitflags/test_suite/tests/external_no_std.rs @@ -0,0 +1,21 @@ +#![no_std] + +#[macro_use] +extern crate bitflags; + +bitflags! { +    /// baz +    struct Flags: u32 { +        const A = 0b00000001; +        #[doc = "bar"] +        const B = 0b00000010; +        const C = 0b00000100; +        #[doc = "foo"] +        const ABC = Flags::A.bits | Flags::B.bits | Flags::C.bits; +    } +} + +#[test] +fn smoke() { +    assert_eq!(Flags::ABC, Flags::A | Flags::B | Flags::C); +} diff --git a/bitflags/test_suite/tests/i128_bitflags.rs b/bitflags/test_suite/tests/i128_bitflags.rs new file mode 100644 index 0000000..1b6f7c5 --- /dev/null +++ b/bitflags/test_suite/tests/i128_bitflags.rs @@ -0,0 +1,30 @@ +#![cfg(feature = "unstable")] + +#[macro_use] +extern crate bitflags; + +bitflags! { +    /// baz +    struct Flags128: u128 { +        const A = 0x0000_0000_0000_0000_0000_0000_0000_0001; +        const B = 0x0000_0000_0000_1000_0000_0000_0000_0000; +        const C = 0x8000_0000_0000_0000_0000_0000_0000_0000; +        const ABC = Self::A.bits | Self::B.bits | Self::C.bits; +    } +} + +#[test] +fn test_i128_bitflags() { +    assert_eq!(Flags128::ABC, Flags128::A | Flags128::B | Flags128::C); +    assert_eq!(Flags128::A.bits, 0x0000_0000_0000_0000_0000_0000_0000_0001); +    assert_eq!(Flags128::B.bits, 0x0000_0000_0000_1000_0000_0000_0000_0000); +    assert_eq!(Flags128::C.bits, 0x8000_0000_0000_0000_0000_0000_0000_0000); +    assert_eq!( +        Flags128::ABC.bits, +        0x8000_0000_0000_1000_0000_0000_0000_0001 +    ); +    assert_eq!(format!("{:?}", Flags128::A), "A"); +    assert_eq!(format!("{:?}", Flags128::B), "B"); +    assert_eq!(format!("{:?}", Flags128::C), "C"); +    assert_eq!(format!("{:?}", Flags128::ABC), "A | B | C | ABC"); +} diff --git a/bitflags/test_suite/tests/serde.rs b/bitflags/test_suite/tests/serde.rs new file mode 100644 index 0000000..0424af5 --- /dev/null +++ b/bitflags/test_suite/tests/serde.rs @@ -0,0 +1,35 @@ +#[macro_use] +extern crate bitflags; + +#[macro_use] +extern crate serde_derive; +extern crate serde; +extern crate serde_json; + +bitflags! { +    #[derive(Serialize, Deserialize)] +    struct Flags: u32 { +        const A = 1; +        const B = 2; +        const C = 4; +        const D = 8; +    } +} + +#[test] +fn serialize() { +    let flags = Flags::A | Flags::B; + +    let serialized = serde_json::to_string(&flags).unwrap(); + +    assert_eq!(serialized, r#"{"bits":3}"#); +} + +#[test] +fn deserialize() { +    let deserialized: Flags = serde_json::from_str(r#"{"bits":12}"#).unwrap(); + +    let expected = Flags::C | Flags::D; + +    assert_eq!(deserialized.bits, expected.bits); +} | 
