[
  {
    "path": ".github/workflows/rust.yml",
    "content": "name: Rust CI\n\non:\n  pull_request:\n  push:\n    branches:\n      - master\n      - '[0-9]+.[0-9]+'\n\nenv:\n  CARGO_TERM_COLOR: always\n\njobs:\n  lint:\n    name: Lint\n    runs-on: ubuntu-latest\n    steps:\n      - name: Check out code\n        uses: actions/checkout@v4\n      - name: Use cache\n        uses: Swatinem/rust-cache@v2\n        with:\n          shared-key: stable\n          save-if: false\n      - name: Install Rust toolchain\n        uses: dtolnay/rust-toolchain@master\n        with:\n          toolchain: stable\n          components: clippy, rustfmt, llvm-tools-preview\n      - name: Check formatting\n        run: cargo fmt -- --check\n      - name: Run clippy\n        run: cargo clippy --all-targets -- -D warnings\n      - name: Build documentation\n        run: cargo rustdoc -- -D warnings\n\n  test:\n    name: Test on Rust ${{ matrix.rust.name }}\n    runs-on: ubuntu-latest\n    strategy:\n      matrix:\n        rust:\n          - name: stable\n            components: clippy, rustfmt, llvm-tools-preview\n          - name: nightly\n          - name: \"1.76\" # rust-version, msrv\n    steps:\n      - name: Check out code\n        uses: actions/checkout@v4\n      # Using env.HOME or $HOME does not work in the rust-cache workflow step,\n      # so just build the path this way.\n      - name: Find toolchain path\n        id: toolchain_path\n        run: echo \"path=$HOME/.rustup/toolchains/${{ matrix.rust.name }}-x86_64-unknown-linux-gnu\" >> $GITHUB_OUTPUT\n        # Stable toolchain for Rust is already built into the runner image so\n        # only other versions need caching to avoid wasting time and bandwidth\n        # re-downloading them.\n        if: matrix.rust.name != 'stable'\n      - name: Use cache\n        uses: Swatinem/rust-cache@v2\n        with:\n          shared-key: ${{ matrix.rust.name }}\n          cache-on-failure: true\n          cache-directories: ${{ steps.toolchain_path.outputs.path }}\n      - name: Install Rust toolchain\n        uses: dtolnay/rust-toolchain@master\n        with:\n          toolchain: ${{ matrix.rust.name }}\n          components: ${{ matrix.rust.components }}\n      # Building is separated from testing just to more clearly differentiate in\n      # the CI whether the build failed or a test failed\n      - name: Build workspace\n        run: cargo build --lib --tests\n      - name: Run tests\n        # UI tests are compiler-version-sensitive so can only run on one\n        # toolchain\n        run: cargo test ${{ matrix.rust.name != 'stable' && '-- --skip ui_trybuild' || '' }}\n\n  coverage:\n    name: Code coverage\n    runs-on: ubuntu-latest\n    steps:\n      - name: Check out code\n        uses: actions/checkout@v4\n      - name: Use cache\n        uses: Swatinem/rust-cache@v2\n      - name: Install Rust toolchain\n        uses: dtolnay/rust-toolchain@master\n        with:\n          toolchain: stable\n          components: clippy, rustfmt, llvm-tools-preview\n      - name: Install llvm-cov\n        uses: taiki-e/install-action@v2\n        with:\n          tool: cargo-llvm-cov\n      # UI tests do not contribute to coverage since trybuild builds them\n      # independently so they do not get instrumented (even though llvm-cov\n      # tries?), so skip them. They will get passed through runtime-macros\n      # instead\n      - name: Generate coverage data\n        run: cargo llvm-cov test --no-report -- --skip ui_trybuild\n      - name: Show coverage results\n        run: >\n          cargo llvm-cov report\n          --ignore-filename-regex 'benches|tests'\n      # https://github.com/actions/runner/issues/520\n      - name: Determine whether codecov.io secret is available\n        id: has_codecov\n        run: echo 'result=${{ secrets.CODECOV_TOKEN }}' >> $GITHUB_OUTPUT\n      - name: Generate coverage file\n        run: >\n          cargo llvm-cov report\n          --ignore-filename-regex 'benches|tests'\n          --lcov --output-path lcov.info\n        if: steps.has_codecov.outputs.result != 0\n      - name: Upload to codecov.io\n        uses: codecov/codecov-action@v5\n        with:\n          files: lcov.info\n          token: ${{ secrets.CODECOV_TOKEN }}\n        if: steps.has_codecov.outputs.result != 0\n"
  },
  {
    "path": ".gitignore",
    "content": "# Ignore build artifacts from the local tests sub-crate.\n/target/\n/impl/target/\n\n# Ignore backup files creates by cargo fmt.\n**/*.rs.bk\n\n# Remove Cargo.lock when creating an executable, leave it for libraries\n# More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock\nCargo.lock\n\n# Ignore VS Code artifacts.\n**/.vscode/**\n\n# Ignore idea artifacts.\n**/.idea/**\n"
  },
  {
    "path": "Cargo.toml",
    "content": "[workspace]\nmembers = [\n    \"impl\"\n]\ndefault-members = [\"\", \"impl\"]\nresolver = \"2\"\n\n[workspace.package]\nauthors = [\"Robin Freyler <robinfreyler@web.de>\"]\nedition = \"2021\"\nlicense = \"MIT OR Apache-2.0\"\npublish = false # Use `release.sh`\ndocumentation = \"https://docs.rs/modular-bitfield\"\nrepository = \"https://github.com/modular-bitfield/modular-bitfield\"\nrust-version = \"1.76.0\"\nversion = \"0.14.0-pre\"\n\n[package]\nname = \"modular-bitfield\"\ndescription = \"Easily define bitfield types with modular building blocks.\"\ncategories = [\"data-structures\", \"no-std\"]\nkeywords = [\"bitfield\", \"bit\", \"bitfields\"]\nreadme = \"README.md\"\nauthors.workspace = true\ndocumentation.workspace = true\nedition.workspace = true\nlicense.workspace = true\npublish.workspace = true\nrepository.workspace = true\nrust-version.workspace = true\nversion.workspace = true\n\n[dependencies]\nmodular-bitfield-impl = { path = \"impl\", version = \"0.14.0-pre\" }\nstatic_assertions = \"1.1\"\n\n[dev-dependencies]\nbitfield = \"0.19\"\ntiny-bench = \"0.4\"\ntrybuild = \"1.0\"\n\n[lints.rust]\nunexpected_cfgs = { level = \"warn\", check-cfg = ['cfg(coverage)'] }\n\n[[bench]]\nname = \"benchmarks\"\nharness = false\n\n[[bench]]\nname = \"cmp_handwritten\"\nharness = false\n\n[[bench]]\nname = \"cmp_bitfield_crate\"\nharness = false\n\n[[test]]\nname = \"benches_handwritten\"\npath = \"benches/utils/handwritten.rs\"\n\n[profile.bench]\ncodegen-units = 1\n"
  },
  {
    "path": "LICENSE-APACHE",
    "content": "                              Apache License\n                        Version 2.0, January 2004\n                     http://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n   \"License\" shall mean the terms and conditions for use, reproduction,\n   and distribution as defined by Sections 1 through 9 of this document.\n\n   \"Licensor\" shall mean the copyright owner or entity authorized by\n   the copyright owner that is granting the License.\n\n   \"Legal Entity\" shall mean the union of the acting entity and all\n   other entities that control, are controlled by, or are under common\n   control with that entity. For the purposes of this definition,\n   \"control\" means (i) the power, direct or indirect, to cause the\n   direction or management of such entity, whether by contract or\n   otherwise, or (ii) ownership of fifty percent (50%) or more of the\n   outstanding shares, or (iii) beneficial ownership of such entity.\n\n   \"You\" (or \"Your\") shall mean an individual or Legal Entity\n   exercising permissions granted by this License.\n\n   \"Source\" form shall mean the preferred form for making modifications,\n   including but not limited to software source code, documentation\n   source, and configuration files.\n\n   \"Object\" form shall mean any form resulting from mechanical\n   transformation or translation of a Source form, including but\n   not limited to compiled object code, generated documentation,\n   and conversions to other media types.\n\n   \"Work\" shall mean the work of authorship, whether in Source or\n   Object form, made available under the License, as indicated by a\n   copyright notice that is included in or attached to the work\n   (an example is provided in the Appendix below).\n\n   \"Derivative Works\" shall mean any work, whether in Source or Object\n   form, that is based on (or derived from) the Work and for which the\n   editorial revisions, annotations, elaborations, or other modifications\n   represent, as a whole, an original work of authorship. For the purposes\n   of this License, Derivative Works shall not include works that remain\n   separable from, or merely link (or bind by name) to the interfaces of,\n   the Work and Derivative Works thereof.\n\n   \"Contribution\" shall mean any work of authorship, including\n   the original version of the Work and any modifications or additions\n   to that Work or Derivative Works thereof, that is intentionally\n   submitted to Licensor for inclusion in the Work by the copyright owner\n   or by an individual or Legal Entity authorized to submit on behalf of\n   the copyright owner. For the purposes of this definition, \"submitted\"\n   means any form of electronic, verbal, or written communication sent\n   to the Licensor or its representatives, including but not limited to\n   communication on electronic mailing lists, source code control systems,\n   and issue tracking systems that are managed by, or on behalf of, the\n   Licensor for the purpose of discussing and improving the Work, but\n   excluding communication that is conspicuously marked or otherwise\n   designated in writing by the copyright owner as \"Not a Contribution.\"\n\n   \"Contributor\" shall mean Licensor and any individual or Legal Entity\n   on behalf of whom a Contribution has been received by Licensor and\n   subsequently incorporated within the Work.\n\n2. Grant of Copyright License. Subject to the terms and conditions of\n   this License, each Contributor hereby grants to You a perpetual,\n   worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n   copyright license to reproduce, prepare Derivative Works of,\n   publicly display, publicly perform, sublicense, and distribute the\n   Work and such Derivative Works in Source or Object form.\n\n3. Grant of Patent License. Subject to the terms and conditions of\n   this License, each Contributor hereby grants to You a perpetual,\n   worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n   (except as stated in this section) patent license to make, have made,\n   use, offer to sell, sell, import, and otherwise transfer the Work,\n   where such license applies only to those patent claims licensable\n   by such Contributor that are necessarily infringed by their\n   Contribution(s) alone or by combination of their Contribution(s)\n   with the Work to which such Contribution(s) was submitted. If You\n   institute patent litigation against any entity (including a\n   cross-claim or counterclaim in a lawsuit) alleging that the Work\n   or a Contribution incorporated within the Work constitutes direct\n   or contributory patent infringement, then any patent licenses\n   granted to You under this License for that Work shall terminate\n   as of the date such litigation is filed.\n\n4. Redistribution. You may reproduce and distribute copies of the\n   Work or Derivative Works thereof in any medium, with or without\n   modifications, and in Source or Object form, provided that You\n   meet the following conditions:\n\n   (a) You must give any other recipients of the Work or\n       Derivative Works a copy of this License; and\n\n   (b) You must cause any modified files to carry prominent notices\n       stating that You changed the files; and\n\n   (c) You must retain, in the Source form of any Derivative Works\n       that You distribute, all copyright, patent, trademark, and\n       attribution notices from the Source form of the Work,\n       excluding those notices that do not pertain to any part of\n       the Derivative Works; and\n\n   (d) If the Work includes a \"NOTICE\" text file as part of its\n       distribution, then any Derivative Works that You distribute must\n       include a readable copy of the attribution notices contained\n       within such NOTICE file, excluding those notices that do not\n       pertain to any part of the Derivative Works, in at least one\n       of the following places: within a NOTICE text file distributed\n       as part of the Derivative Works; within the Source form or\n       documentation, if provided along with the Derivative Works; or,\n       within a display generated by the Derivative Works, if and\n       wherever such third-party notices normally appear. The contents\n       of the NOTICE file are for informational purposes only and\n       do not modify the License. You may add Your own attribution\n       notices within Derivative Works that You distribute, alongside\n       or as an addendum to the NOTICE text from the Work, provided\n       that such additional attribution notices cannot be construed\n       as modifying the License.\n\n   You may add Your own copyright statement to Your modifications and\n   may provide additional or different license terms and conditions\n   for use, reproduction, or distribution of Your modifications, or\n   for any such Derivative Works as a whole, provided Your use,\n   reproduction, and distribution of the Work otherwise complies with\n   the conditions stated in this License.\n\n5. Submission of Contributions. Unless You explicitly state otherwise,\n   any Contribution intentionally submitted for inclusion in the Work\n   by You to the Licensor shall be under the terms and conditions of\n   this License, without any additional terms or conditions.\n   Notwithstanding the above, nothing herein shall supersede or modify\n   the terms of any separate license agreement you may have executed\n   with Licensor regarding such Contributions.\n\n6. Trademarks. This License does not grant permission to use the trade\n   names, trademarks, service marks, or product names of the Licensor,\n   except as required for reasonable and customary use in describing the\n   origin of the Work and reproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty. Unless required by applicable law or\n   agreed to in writing, Licensor provides the Work (and each\n   Contributor provides its Contributions) on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n   implied, including, without limitation, any warranties or conditions\n   of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n   PARTICULAR PURPOSE. You are solely responsible for determining the\n   appropriateness of using or redistributing the Work and assume any\n   risks associated with Your exercise of permissions under this License.\n\n8. Limitation of Liability. In no event and under no legal theory,\n   whether in tort (including negligence), contract, or otherwise,\n   unless required by applicable law (such as deliberate and grossly\n   negligent acts) or agreed to in writing, shall any Contributor be\n   liable to You for damages, including any direct, indirect, special,\n   incidental, or consequential damages of any character arising as a\n   result of this License or out of the use or inability to use the\n   Work (including but not limited to damages for loss of goodwill,\n   work stoppage, computer failure or malfunction, or any and all\n   other commercial damages or losses), even if such Contributor\n   has been advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability. While redistributing\n   the Work or Derivative Works thereof, You may choose to offer,\n   and charge a fee for, acceptance of support, warranty, indemnity,\n   or other liability obligations and/or rights consistent with this\n   License. However, in accepting such obligations, You may act only\n   on Your own behalf and on Your sole responsibility, not on behalf\n   of any other Contributor, and only if You agree to indemnify,\n   defend, and hold each Contributor harmless for any liability\n   incurred by, or claims asserted against, such Contributor by reason\n   of your accepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\n   To apply the Apache License to your work, attach the following\n   boilerplate notice, with the fields enclosed by brackets \"[]\"\n   replaced with your own identifying information. (Don't include\n   the brackets!)  The text should be enclosed in the appropriate\n   comment syntax for the file format. We also recommend that a\n   file or class name and description of purpose be included on the\n   same \"printed page\" as the copyright notice for easier\n   identification within third-party archives.\n\nCopyright [yyyy] [name of copyright owner]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
  },
  {
    "path": "LICENSE-MIT",
    "content": "Permission is hereby granted, free of charge, to any\nperson obtaining a copy of this software and associated\ndocumentation files (the \"Software\"), to deal in the\nSoftware without restriction, including without\nlimitation the rights to use, copy, modify, merge,\npublish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software\nis furnished to do so, subject to the following\nconditions:\n\nThe above copyright notice and this permission notice\nshall be included in all copies or substantial portions\nof the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF\nANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED\nTO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\nPARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT\nSHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR\nIN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\nDEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# Modular Bitfields for Rust\n\n[![crates](https://img.shields.io/crates/v/modular-bitfield.svg)](https://crates.io/crates/modular-bitfield)\n[![tests](https://github.com/modular-bitfield/modular-bitfield/actions/workflows/rust.yml/badge.svg)](https://github.com/modular-bitfield/modular-bitfield/actions/workflows/rust.yml)\n[![docs.rs](https://docs.rs/modular-bitfield/badge.svg)](https://docs.rs/modular-bitfield)\n[![codecov](https://codecov.io/gh/modular-bitfield/modular-bitfield/graph/badge.svg?token=CVN2VO1fY6)](https://codecov.io/gh/modular-bitfield/modular-bitfield)\n\n- `no_std`: Supports embedded development without `std` library.\n- This crate uses and generates 100% safe Rust code.\n\n## Description\n\nAllows to have bitfield structs and enums as bitfield specifiers that work very similar to C and C++ bitfields.\n\n## Advantages\n\n- **Safety:** Macro embraced enums and structs are checked for valid structure during compilation time.\n- **Speed:** Generated code is as fast as handwritten code. (See benchmarks below.)\n- **Modularity:** Enums can be used modular within bitfield structs.\n\n## Attribution\n\nImplements the `#[bitfield]` macros introduced and specified in David Tolnay's [procedural macro workshop][procedural-macro-workshop].\n\nThanks go to David Tolnay for designing the specification for the macros implemented in this crate.\n\n## Usage\n\nAnnotate a Rust struct with the `#[bitfield]` attribute in order to convert it into a bitfield.\nThe `B1`, `B2`, ... `B128` prelude types can be used as primitives to declare the number of bits per field.\n\n```rust\n#[bitfield]\npub struct PackedData {\n    header: B4,\n    body: B9,\n    is_alive: B1,\n    status: B2,\n}\n ```\n\nThis produces a `new` constructor as well as a variety of getters and setters that\nallows to interact with the bitfield in a safe fashion:\n\n### Example: Constructors\n\n```rust\nlet data = PackedData::new()\n    .with_header(1)\n    .with_body(2)\n    .with_is_alive(0)\n    .with_status(3);\nassert_eq!(data.header(), 1);\nassert_eq!(data.body(), 2);\nassert_eq!(data.is_alive(), 0);\nassert_eq!(data.status(), 3);\n```\n\n### Example: Primitive Types\n\nAny type that implements the `Specifier` trait can be used as a bitfield field.\nBesides the already mentioned `B1`, .. `B128` also the `bool`, `u8`, `u16`, `u32`,\n`u64` or `u128` primitive types can be used from prelude.\n\nWe can use this knowledge to encode our `is_alive` as `bool` type instead of `B1`:\n\n```rust\n#[bitfield]\npub struct PackedData {\n    header: B4,\n    body: B9,\n    is_alive: bool,\n    status: B2,\n}\n\nlet mut data = PackedData::new()\n    .with_is_alive(true);\nassert!(data.is_alive());\ndata.set_is_alive(false);\nassert!(!data.is_alive());\n```\n\n### Example: Enum Specifiers\n\nIt is possible to derive the `Specifier` trait for `enum` types very easily to make\nthem also usable as a field within a bitfield type:\n\n```rust\n#[derive(Specifier)]\npub enum Status {\n    Red, Green, Yellow, None,\n}\n\n#[bitfield]\npub struct PackedData {\n    header: B4,\n    body: B9,\n    is_alive: bool,\n    status: Status,\n}\n```\n\n### Example: Extra Safety Guard\n\nIn order to make sure that our `Status` enum still requires exatly 2 bit we can add\n`#[bits = 2]` to its field:\n\n```rust\n#[bitfield]\npub struct PackedData {\n    header: B4,\n    body: B9,\n    is_alive: bool,\n    #[bits = 2]\n    status: Status,\n}\n```\n\nSetting and getting our new `status` field is naturally as follows:\n\n```rust\nlet mut data = PackedData::new()\n    .with_status(Status::Green);\nassert_eq!(data.status(), Status::Green);\ndata.set_status(Status::Red);\nassert_eq!(data.status(), Status::Red);\n```\n\n### Example: Recursive Bitfields\n\nIt is possible to use `#[bitfield]` structs as fields of `#[bitfield]` structs.\nThis is generally useful if there are some common fields for multiple bitfields\nand is achieved by adding `#[derive(Specifier)]` to the attributes of the\n`#[bitfield]` annotated struct:\n\n```rust\n#[bitfield]\n#[derive(Specifier)]\npub struct Header {\n    is_compact: bool,\n    is_secure: bool,\n    pre_status: Status,\n}\n\n#[bitfield]\npub struct PackedData {\n    header: Header,\n    body: B9,\n    is_alive: bool,\n    status: Status,\n}\n```\n\nWith the `bits: int` parameter of the `#[bitfield]` macro on the `Header` struct and the\n`#[bits: int]` attribute of the `#[derive(Specifier)]` on the `Status` enum we\ncan have additional compile-time guarantees about the bit widths of the resulting entities:\n\n```rust\n#[derive(Specifier)]\n#[bits = 2]\npub enum Status {\n    Red, Green, Yellow\n}\n\n#[bitfield(bits = 4)]\n#[derive(Specifier)]\npub struct Header {\n    is_compact: bool,\n    is_secure: bool,\n    #[bits = 2]\n    pre_status: Status,\n}\n\n#[bitfield(bits = 16)]\npub struct PackedData {\n    #[bits = 4]\n    header: Header,\n    body: B9,\n    is_alive: bool,\n    #[bits = 2]\n    status: Status,\n}\n```\n\n### Example: Advanced Enum Specifiers\n\nFor our `Status` enum we actually just need 3 status variants: `Green`, `Yellow` and `Red`.\nWe introduced the `None` status variants because `Specifier` enums by default are required\nto have a number of variants that is a power of two. We can ship around this by specifying\n`#[bits = 2]` on the top and get rid of our placeholder `None` variant while maintaining\nthe invariant of it requiring 2 bits:\n\n```rust\n# use modular_bitfield::prelude::*;\n\n#[derive(Specifier)]\n#[bits = 2]\npub enum Status {\n    Red, Green, Yellow,\n}\n```\n\nHowever, having such enums now yields the possibility that a bitfield might contain invalid bit\npatterns for such fields. We can safely access those fields with protected getters. For the sake\nof demonstration we will use the generated `from_bytes` constructor with which we can easily\nconstruct bitfields that may contain invalid bit patterns:\n\n```rust\nlet mut data = PackedData::from_bytes([0b0000_0000, 0b1100_0000]);\n//           The 2 status field bits are invalid -----^^\n//           as Red = 0x00, Green = 0x01 and Yellow = 0x10\nassert_eq!(data.status_or_err(), Err(InvalidBitPattern::new(0b11)));\ndata.set_status(Status::Green);\nassert_eq!(data.status_or_err(), Ok(Status::Green));\n```\n\n## Benchmarks\n\nBelow are some benchmarks between the [hand-written code][benchmark-code] and the macro-generated code for some example getters and setters that cover a decent variety of use cases.\n\nWe can conclude that the macro-generated code is as fast as hand-written code would be. Please file a PR if you see a way to improve either side.\n\n- `cargo bench` to run the benchmarks\n- `cargo test --benches` to run the benchmark tests\n\n[Click here to view all benchmark results.][benchmark-results]\n\n[benchmark-code]: https://github.com/modular-bitfield/modular-bitfield/blob/master/benches/handwritten.rs\n[benchmark-results]: https://gist.github.com/Robbepop/bcff4fe149e0e622b752f0eb07b31880\n\n### Summary\n\nThe `modular_bitfield` crate generates bitfields that are ...\n\n- just as efficient as the handwritten alternatives.\n- equally efficient or more efficient than the alternative [bitfield] crate.\n\n[bitfield]: https://crates.io/crates/bitfield\n\n### Showcase: Generated vs Handwritten\n\nWe tested the following `#[bitfield]` `struct`:\n\n```rust\n#[bitfield]\npub struct Generated {\n    pub a: B9,  // Spans 2 bytes.\n    pub b: B6,  // Within 2nd byte.\n    pub c: B13, // Spans 3 bytes.\n    pub d: B1,  // Within 4rd byte.\n    pub e: B3,  // Within 4rd byte.\n    pub f: B32, // Spans rest 4 bytes.\n}\n```\n\n**Note:** All benchmarks timing results sum 10 runs each.\n\n### Getter Performance\n\n```\nget_a/generated     time:   [3.0990 ns 3.1119 ns 3.1263 ns]\nget_a/handwritten   time:   [3.1072 ns 3.1189 ns 3.1318 ns]\n\nget_b/generated     time:   [3.0859 ns 3.0993 ns 3.1140 ns]\nget_b/handwritten   time:   [3.1062 ns 3.1154 ns 3.1244 ns]\n\nget_c/generated     time:   [3.0892 ns 3.1140 ns 3.1491 ns]\nget_c/handwritten   time:   [3.1031 ns 3.1144 ns 3.1266 ns]\n\nget_d/generated     time:   [3.0937 ns 3.1055 ns 3.1182 ns]\nget_d/handwritten   time:   [3.1109 ns 3.1258 ns 3.1422 ns]\n\nget_e/generated     time:   [3.1009 ns 3.1139 ns 3.1293 ns]\nget_e/handwritten   time:   [3.1217 ns 3.1366 ns 3.1534 ns]\n\nget_f/generated     time:   [3.1064 ns 3.1164 ns 3.1269 ns]\nget_f/handwritten   time:   [3.1067 ns 3.1221 ns 3.1404 ns]\n```\n\n### Setter Performance\n\n```\nset_a/generated     time:   [15.784 ns 15.855 ns 15.932 ns]\nset_a/handwritten   time:   [15.841 ns 15.907 ns 15.980 ns]\n\nset_b/generated     time:   [20.496 ns 20.567 ns 20.643 ns]\nset_b/handwritten   time:   [20.319 ns 20.384 ns 20.454 ns]\n\nset_c/generated     time:   [19.155 ns 19.362 ns 19.592 ns]\nset_c/handwritten   time:   [19.265 ns 19.383 ns 19.523 ns]\n\nset_d/generated     time:   [12.325 ns 12.376 ns 12.429 ns]\nset_d/handwritten   time:   [12.416 ns 12.472 ns 12.541 ns]\n\nset_e/generated     time:   [20.460 ns 20.528 ns 20.601 ns]\nset_e/handwritten   time:   [20.473 ns 20.534 ns 20.601 ns]\n\nset_f/generated     time:   [6.1466 ns 6.1769 ns 6.2127 ns]\nset_f/handwritten   time:   [6.1467 ns 6.1962 ns 6.2670 ns]\n```\n\n## License\n\nLicensed under either of <a href=\"LICENSE-APACHE\">Apache License, Version\n2.0</a> or <a href=\"LICENSE-MIT\">MIT license</a> at your option.\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in this codebase by you, as defined in the Apache-2.0 license,\nshall be dual licensed as above, without any additional terms or conditions.\n\n[procedural-macro-workshop]: https://github.com/dtolnay/proc-macro-workshop/blob/master/README.md\n"
  },
  {
    "path": "benches/benchmarks.rs",
    "content": "#![allow(dead_code)]\n\nmod utils;\n\nuse modular_bitfield::{\n    bitfield,\n    specifiers::{B12, B13, B16, B3, B32, B36, B4, B6, B7, B8, B9},\n};\nuse utils::*;\n\n#[bitfield]\npub struct Color {\n    r: B8,\n    g: B8,\n    b: B8,\n    a: B8,\n}\n\n#[bitfield]\npub struct SingleBitsInSingleByte {\n    b0: bool,\n    b1: bool,\n    b2: bool,\n    b3: bool,\n    b4: bool,\n    b5: bool,\n    b6: bool,\n    b7: bool,\n}\n\n#[bitfield]\npub struct TwoHalfBytes {\n    h0: B4,\n    h1: B4,\n}\n\n#[bitfield]\npub struct SingleBitAndRest {\n    head: bool,\n    rest: B7,\n}\n\n#[bitfield]\npub struct B7B1 {\n    b7: B7,\n    b1: bool,\n}\n\n#[bitfield]\npub struct B3B1B4 {\n    b3: B3,\n    b1: bool,\n    b4: B4,\n}\n\n#[bitfield]\npub struct TwoHalfWords {\n    fst: B16,\n    snd: B16,\n}\n\n#[bitfield]\npub struct B6B12B6 {\n    front: B6,\n    middle: B12,\n    back: B6,\n}\n\n#[bitfield]\npub struct B6B36B6 {\n    front: B6,\n    middle: B36,\n    back: B6,\n}\n\n#[bitfield]\npub struct Complex {\n    a: B9,  // 0th and 1st\n    b: B6,  // 1st\n    c: B13, // 1st, 2nd, 3rd\n    d: B4,  // 3rd\n    e: B32, // 4th, .., 7th\n}\n\nfn bench_set_variants() {\n    one_shot(\"set - Color\", &Color::new, |mut input| {\n        repeat(|| {\n            black_box(&mut input).set_r(1);\n            black_box(&mut input).set_g(1);\n            black_box(&mut input).set_b(1);\n            black_box(&mut input).set_a(1);\n        });\n    });\n    one_shot(\n        \"set - SingleBitsInSingleByte\",\n        &SingleBitsInSingleByte::new,\n        |mut input| {\n            repeat(|| {\n                black_box(&mut input).set_b0(true);\n                black_box(&mut input).set_b1(true);\n                black_box(&mut input).set_b2(true);\n                black_box(&mut input).set_b3(true);\n                black_box(&mut input).set_b4(true);\n                black_box(&mut input).set_b5(true);\n                black_box(&mut input).set_b6(true);\n                black_box(&mut input).set_b7(true);\n            });\n        },\n    );\n    one_shot(\"set - TwoHalfBytes\", &TwoHalfBytes::new, |mut input| {\n        repeat(|| {\n            black_box(&mut input).set_h0(1);\n            black_box(&mut input).set_h1(1);\n        });\n    });\n    one_shot(\n        \"set - SingleBitAndRest\",\n        &SingleBitAndRest::new,\n        |mut input| {\n            repeat(|| {\n                black_box(&mut input).set_head(true);\n                black_box(&mut input).set_rest(1);\n            });\n        },\n    );\n    one_shot(\"set - B7B1\", &B7B1::new, |mut input| {\n        repeat(|| {\n            black_box(&mut input).set_b7(1);\n            black_box(&mut input).set_b1(true);\n        });\n    });\n    one_shot(\"set - B3B1B4\", &B3B1B4::new, |mut input| {\n        repeat(|| {\n            black_box(&mut input).set_b3(1);\n            black_box(&mut input).set_b1(true);\n            black_box(&mut input).set_b4(1);\n        });\n    });\n    one_shot(\"set - TwoHalfWords\", &TwoHalfWords::new, |mut input| {\n        repeat(|| {\n            black_box(&mut input).set_fst(1);\n            black_box(&mut input).set_snd(1);\n        });\n    });\n    one_shot(\"set - B6B12B6\", &B6B12B6::new, |mut input| {\n        repeat(|| {\n            black_box(&mut input).set_front(1);\n            black_box(&mut input).set_middle(1);\n            black_box(&mut input).set_back(1);\n        });\n    });\n    one_shot(\"set - B6B36B6\", &B6B36B6::new, |mut input| {\n        repeat(|| {\n            black_box(&mut input).set_front(1);\n            black_box(&mut input).set_middle(1);\n            black_box(&mut input).set_back(1);\n        });\n    });\n    one_shot(\"set - Complex\", &Complex::new, |mut input| {\n        repeat(|| {\n            black_box(&mut input).set_a(1);\n            black_box(&mut input).set_b(1);\n            black_box(&mut input).set_c(1);\n            black_box(&mut input).set_d(1);\n            black_box(&mut input).set_e(1);\n        });\n    });\n}\n\nfn bench_get_variants() {\n    one_shot(\"get - Color\", &Color::new, |input| {\n        repeat(|| {\n            black_box(input.r());\n            black_box(input.g());\n            black_box(input.b());\n            black_box(input.a());\n        });\n    });\n    one_shot(\n        \"get - SingleBitsInSingleByte\",\n        &SingleBitsInSingleByte::new,\n        |input| {\n            repeat(|| {\n                black_box(input.b0());\n                black_box(input.b1());\n                black_box(input.b2());\n                black_box(input.b3());\n                black_box(input.b4());\n                black_box(input.b5());\n                black_box(input.b6());\n                black_box(input.b7());\n            });\n        },\n    );\n    one_shot(\"get - TwoHalfBytes\", &TwoHalfBytes::new, |input| {\n        repeat(|| {\n            black_box(input.h0());\n            black_box(input.h1());\n        });\n    });\n    one_shot(\"get - SingleBitAndRest\", &SingleBitAndRest::new, |input| {\n        repeat(|| {\n            black_box(input.head());\n            black_box(input.rest());\n        });\n    });\n    one_shot(\"get - B7B1\", &B7B1::new, |input| {\n        repeat(|| {\n            black_box(input.b7());\n            black_box(input.b1());\n        });\n    });\n    one_shot(\"get - B3B1B4\", &B3B1B4::new, |input| {\n        repeat(|| {\n            black_box(input.b3());\n            black_box(input.b1());\n            black_box(input.b4());\n        });\n    });\n    one_shot(\"get - TwoHalfWords\", &TwoHalfWords::new, |input| {\n        repeat(|| {\n            black_box(input.fst());\n            black_box(input.snd());\n        });\n    });\n    one_shot(\"get - B6B12B6\", &B6B12B6::new, |input| {\n        repeat(|| {\n            black_box(input.front());\n            black_box(input.middle());\n            black_box(input.back());\n        });\n    });\n    one_shot(\"get - B6B36B6\", &B6B36B6::new, |input| {\n        repeat(|| {\n            black_box(input.front());\n            black_box(input.middle());\n            black_box(input.back());\n        });\n    });\n    one_shot(\"get - Complex\", &Complex::new, |input| {\n        repeat(|| {\n            black_box(input.a());\n            black_box(input.b());\n            black_box(input.c());\n            black_box(input.d());\n            black_box(input.e());\n        });\n    });\n}\n\nfn main() {\n    bench_set_variants();\n    bench_get_variants();\n}\n"
  },
  {
    "path": "benches/cmp_bitfield_crate.rs",
    "content": "//! In this benchmark we compare our `modular_bitfield` crate generated bitfields\n//! with the ones generated by the popular `bitfield` crate.\n//!\n//! We want to find out which crate produces the more efficient code for different\n//! use cases and scenarios.\n\nmod utils;\n\nuse bitfield::bitfield as bitfield_crate;\nuse modular_bitfield::prelude::*;\nuse utils::*;\n\nbitfield_crate! {\n    pub struct OtherBitfield(u32);\n\n    #[inline]\n    pub a, set_a: 8, 0;\n    #[inline]\n    pub b, set_b: 14, 9;\n    #[inline]\n    pub c, set_c: 27, 15;\n    #[inline]\n    pub d, set_d: 28, 28;\n    #[inline]\n    pub e, set_e: 31, 29;\n}\n\n#[bitfield]\npub struct ModularBitfield {\n    pub a: B9,\n    pub b: B6,\n    pub c: B13,\n    pub d: B1,\n    pub e: B3,\n}\n\nmacro_rules! generate_cmp_benchmark_for {\n    (\n        test($test_name_get:ident, $test_name_set:ident) {\n            fn $fn_get:ident($name_get:literal);\n            fn $fn_set:ident($name_set:literal);\n        }\n    ) => {\n        fn $test_name_get() {\n            println!();\n            compare(\n                $name_get,\n                || OtherBitfield(0),\n                |input| {\n                    repeat(|| {\n                        black_box(input.$fn_get());\n                    });\n                },\n            );\n            compare($name_get, &ModularBitfield::new, |input| {\n                repeat(|| {\n                    black_box(input.$fn_get());\n                });\n            });\n        }\n\n        fn $test_name_set() {\n            println!();\n            compare(\n                $name_set,\n                || OtherBitfield(0),\n                |mut input| {\n                    repeat(|| {\n                        black_box(black_box(&mut input).$fn_set(1));\n                    });\n                },\n            );\n            compare($name_set, &ModularBitfield::new, |mut input| {\n                repeat(|| {\n                    black_box(black_box(&mut input).$fn_set(1));\n                });\n            });\n        }\n    };\n}\ngenerate_cmp_benchmark_for!(\n    test(bench_get_a, bench_set_a) {\n        fn a(\"bitfield vs modular-bitfield - get_a\");\n        fn set_a(\"bitfield vs modular-bitfield - set_a\");\n    }\n);\ngenerate_cmp_benchmark_for!(\n    test(bench_get_b, bench_set_b) {\n        fn b(\"bitfield vs modular-bitfield - get_b\");\n        fn set_b(\"bitfield vs modular-bitfield - set_b\");\n    }\n);\ngenerate_cmp_benchmark_for!(\n    test(bench_get_c, bench_set_c) {\n        fn c(\"bitfield vs modular-bitfield - get_c\");\n        fn set_c(\"bitfield vs modular-bitfield - set_c\");\n    }\n);\ngenerate_cmp_benchmark_for!(\n    test(bench_get_d, bench_set_d) {\n        fn d(\"bitfield vs modular-bitfield - get_d\");\n        fn set_d(\"bitfield vs modular-bitfield - set_d\");\n    }\n);\ngenerate_cmp_benchmark_for!(\n    test(bench_get_e, bench_set_e) {\n        fn e(\"bitfield vs modular-bitfield - get_e\");\n        fn set_e(\"bitfield vs modular-bitfield - set_e\");\n    }\n);\n\nfn main() {\n    bench_get_a();\n    bench_get_b();\n    bench_get_c();\n    bench_get_d();\n    bench_get_e();\n    bench_set_a();\n    bench_set_b();\n    bench_set_c();\n    bench_set_d();\n    bench_set_e();\n}\n"
  },
  {
    "path": "benches/cmp_handwritten.rs",
    "content": "//! In this benchmark we compare the macro generated code for\n//! setters and getters to some hand-written code for the same\n//! data structure.\n//!\n//! We do a performance analysis for the getter and setter of\n//! all fields of both structs.\n//!\n//! Also we test here that our hand-written code and the macro\n//! generated code actually are semantically equivalent.\n//! This allows us to further enhance the hand-written code\n//! and to eventually come up with new optimization tricks\n//! for the macro generated code while staying correct.\n\nmod utils;\n\nuse utils::{\n    handwritten::{Generated, Handwritten},\n    *,\n};\n\nmacro_rules! generate_cmp_benchmark_for {\n    (\n        test($test_name_get:ident, $test_name_set:ident) {\n            fn $fn_get:ident($name_get:literal);\n            fn $fn_set:ident($name_set:literal);\n        }\n    ) => {\n        fn $test_name_get() {\n            println!();\n            compare($name_get, &Generated::new, |input| {\n                repeat(|| {\n                    black_box(input.$fn_get());\n                });\n            });\n            compare($name_get, &Handwritten::new, |input| {\n                repeat(|| {\n                    black_box(input.$fn_get());\n                });\n            });\n        }\n\n        fn $test_name_set() {\n            println!();\n            compare($name_set, &Generated::new, |mut input| {\n                repeat(|| {\n                    black_box(black_box(&mut input).$fn_set(1));\n                });\n            });\n            compare($name_set, &Handwritten::new, |mut input| {\n                repeat(|| {\n                    black_box(black_box(&mut input).$fn_set(1));\n                });\n            });\n        }\n    };\n}\ngenerate_cmp_benchmark_for!(\n    test(bench_get_a, bench_set_a) {\n        fn a(\"handwritten vs modular-bitfield - get_a\");\n        fn set_a(\"handwritten vs modular-bitfield - set_a\");\n    }\n);\ngenerate_cmp_benchmark_for!(\n    test(bench_get_b, bench_set_b) {\n        fn b(\"handwritten vs modular-bitfield - get_b\");\n        fn set_b(\"handwritten vs modular-bitfield - set_b\");\n    }\n);\ngenerate_cmp_benchmark_for!(\n    test(bench_get_c, bench_set_c) {\n        fn c(\"handwritten vs modular-bitfield - get_c\");\n        fn set_c(\"handwritten vs modular-bitfield - set_c\");\n    }\n);\ngenerate_cmp_benchmark_for!(\n    test(bench_get_d, bench_set_d) {\n        fn d(\"handwritten vs modular-bitfield - get_d\");\n        fn set_d(\"handwritten vs modular-bitfield - set_d\");\n    }\n);\ngenerate_cmp_benchmark_for!(\n    test(bench_get_e, bench_set_e) {\n        fn e(\"handwritten vs modular-bitfield - get_e\");\n        fn set_e(\"handwritten vs modular-bitfield - set_e\");\n    }\n);\ngenerate_cmp_benchmark_for!(\n    test(bench_get_f, bench_set_f) {\n        fn f(\"handwritten vs modular-bitfield - get_f\");\n        fn set_f(\"handwritten vs modular-bitfield - set_f\");\n    }\n);\n\nfn main() {\n    bench_get_a();\n    bench_get_b();\n    bench_get_c();\n    bench_get_d();\n    bench_get_e();\n    bench_get_f();\n    bench_set_a();\n    bench_set_b();\n    bench_set_c();\n    bench_set_d();\n    bench_set_e();\n    bench_set_f();\n}\n"
  },
  {
    "path": "benches/utils/handwritten.rs",
    "content": "//! In this benchmark we compare the macro generated code for\n//! setters and getters to some hand-written code for the same\n//! data structure.\n//!\n//! We do a performance analysis for the getter and setter of\n//! all fields of both structs.\n//!\n//! Also we test here that our hand-written code and the macro\n//! generated code actually are semantically equivalent.\n//! This allows us to further enhance the hand-written code\n//! and to eventually come up with new optimization tricks\n//! for the macro generated code while staying correct.\n\nuse modular_bitfield::prelude::*;\n\n/// This generates code by the macros that we are going to test.\n///\n/// For every field a getter `get_*` and a setter `set_*` is generated\n/// where `*` is the name of the field.\n///\n/// Note that this tests the following cases:\n///\n/// - `a`: Spans 2 bytes where the first byte is used fully and the\n///        second byte stores only one of its bits.\n/// - `b`: Fits into one byte but doesn't reach the bounds on either side.\n/// - `c`: Spans across 3 bytes in total and uses only 1 bit and 4 bits in\n///        the respective first and last byte.\n/// - `d`: Spans 3 whole bytes in total.\n///\n/// More cases could be missing and might be added in the future.\n#[bitfield]\npub struct Generated {\n    pub a: B9,\n    pub b: B6,\n    pub c: B13,\n    pub d: B1,\n    pub e: B3,\n    pub f: B32,\n}\n\n/// This is the hand-written part that the macro generated getters\n/// and setters are compared against.\n///\n/// We try to encode the handwritten setters and getters as good as\n/// we can while trying to stay within reasonable bounds of readability.\n///\n/// This code should perform as good as the macro generated code and vice versa.\npub struct Handwritten {\n    data: [u8; 8],\n}\n\nimpl Handwritten {\n    /// Creates a new hand-written struct initialized with all zeros.\n    #[allow(clippy::new_without_default)]\n    pub fn new() -> Self {\n        Self { data: [0x00; 8] }\n    }\n\n    /// Returns the value of `a`.\n    pub fn a(&self) -> u16 {\n        u16::from_le_bytes([self.data[0], self.data[1] & 0x01])\n    }\n\n    /// Sets the value of `a`.\n    pub fn set_a(&mut self, new_val: u16) {\n        assert!(new_val < (0x01 << 9));\n        let [ls, ms] = new_val.to_le_bytes();\n        self.data[0] = ls;\n        self.data[1] = (self.data[1] & (!0x01)) | (ms & 0x01);\n    }\n\n    /// Returns the value of `b`.\n    pub fn b(&self) -> u8 {\n        (self.data[1] >> 1) & 0b0011_1111\n    }\n\n    /// Sets the value of `b`.\n    pub fn set_b(&mut self, new_val: u8) {\n        assert!(new_val < (0x01 << 6));\n        self.data[1] = (self.data[1] & 0x81) | (new_val << 1);\n    }\n\n    /// Returns the value of `c`.\n    pub fn c(&self) -> u16 {\n        let mut res = 0;\n        res |= (self.data[1] >> 7) as u16;\n        res |= (self.data[2] as u16) << 1;\n        res |= ((self.data[3] & 0b0000_1111) as u16) << 9;\n        res\n    }\n\n    /// Sets the value of `c`.\n    pub fn set_c(&mut self, new_val: u16) {\n        assert!(new_val < (0x01 << 13));\n        self.data[1] = (self.data[1] & !0x80) | (((new_val & 0x01) << 7) as u8);\n        self.data[2] = ((new_val >> 1) & 0xFF) as u8;\n        self.data[3] = (self.data[3] & !0x0F) | (((new_val >> 9) & 0x0F) as u8);\n    }\n\n    /// Returns the value of `d`.\n    pub fn d(&self) -> u8 {\n        (self.data[3] >> 4) & 0b0000_0001\n    }\n\n    /// Sets the value of `d`.\n    pub fn set_d(&mut self, new_val: u8) {\n        self.data[3] = (self.data[3] & (!0b0001_0000)) | ((new_val & 0b0000_0001) << 4)\n    }\n\n    /// Returns the value of `e`.\n    pub fn e(&self) -> u8 {\n        (self.data[3] >> 5) & 0b0000_0111\n    }\n\n    /// Sets the value of `e`.\n    pub fn set_e(&mut self, new_val: u8) {\n        assert!(new_val < (0x01 << 3));\n        self.data[3] = (self.data[3] & !0b1110_0000) | ((new_val & 0b0000_0111) << 5)\n    }\n\n    /// Returns the value of `f`.\n    pub fn f(&self) -> u32 {\n        u32::from_le_bytes([self.data[4], self.data[5], self.data[6], self.data[7]])\n    }\n\n    /// Sets the value of `e`.\n    pub fn set_f(&mut self, new_val: u32) {\n        assert!((new_val as u64) < (0x01_u64 << 32));\n        let le_bytes = new_val.to_le_bytes();\n        self.data[4..].copy_from_slice(&le_bytes[..]);\n    }\n}\n\nmacro_rules! impl_getter_setter_tests {\n    ( $( ($name:ident, $getter:ident, $setter:ident, $n:expr), )* ) => {\n        #[cfg(test)]\n        mod generated_is_equal_to_handwritten {\n            $(\n                #[test]\n                fn $name() {\n                    let mut macro_struct = super::Generated::new();\n                    let mut hand_struct = super::Handwritten::new();\n                    assert_eq!(hand_struct.$getter(), macro_struct.$getter());\n                    macro_struct.$setter($n);\n                    hand_struct.$setter($n);\n                    assert_eq!(hand_struct.$getter(), $n);\n                    assert_eq!(macro_struct.$getter(), $n);\n                    macro_struct.$setter(0);\n                    hand_struct.$setter(0);\n                    assert_eq!(hand_struct.$getter(), 0);\n                    assert_eq!(macro_struct.$getter(), 0);\n                }\n            )*\n        }\n    }\n}\nimpl_getter_setter_tests!(\n    (get_set_a, a, set_a, 0b0001_1111_1111),\n    (get_set_b, b, set_b, 0b0011_1111),\n    (get_set_c, c, set_c, 0b0001_1111_1111_1111),\n    (get_set_d, d, set_d, 0b0001),\n    (get_set_e, e, set_e, 0b0111),\n    (get_set_f, f, set_f, u32::MAX),\n);\n"
  },
  {
    "path": "benches/utils/mod.rs",
    "content": "#![allow(dead_code)]\n\npub mod handwritten;\n\npub use tiny_bench::black_box;\n\n/// Runs a benchmark without extremely slow and unnecessary warm-up.\npub fn bench<T, R, F, S>(label: &'static str, setup: S, closure: F, compare: bool)\nwhere\n    F: FnMut(R) -> T,\n    S: FnMut() -> R,\n{\n    let cfg = tiny_bench::BenchmarkConfig {\n        dump_results_to_disk: compare,\n        warm_up_time: core::time::Duration::ZERO,\n        ..Default::default()\n    };\n\n    tiny_bench::bench_with_setup_configuration_labeled(label, &cfg, setup, closure);\n}\n\n/// Runs a benchmark that compares two or more runs with the same label.\n/// To do this, tiny-bench just records the last run to disk and then reads it\n/// back, so multiple runs without clearing target data will generate a delta on\n/// each subsequent run.\npub fn compare<T, R, F, S>(label: &'static str, setup: S, closure: F)\nwhere\n    F: FnMut(R) -> T,\n    S: FnMut() -> R,\n{\n    bench(label, setup, closure, true);\n}\n\n/// Runs a one-shot benchmark.\npub fn one_shot<T, R, F, S>(label: &'static str, setup: S, closure: F)\nwhere\n    F: FnMut(R) -> T,\n    S: FnMut() -> R,\n{\n    bench(label, setup, closure, false);\n}\n\n/// Repeats the given closure several times.\n///\n/// We do this in order to measure benchmarks that require at least some\n/// amount of nanoseconds to run through.\n#[inline(always)]\npub fn repeat<F>(mut f: F)\nwhere\n    F: FnMut(),\n{\n    for _ in 0..10 {\n        f();\n    }\n}\n"
  },
  {
    "path": "docs/bitfield.md",
    "content": "Applicable to structs to turn their fields into compact bitfields.\n\n# Generated API\n\nBy default this generates the following API:\n\n- **Constructors:**\n\n    1. `new()`: Initializes all bits to 0 even if 0 bits may be invalid.\n       Note that invalid bit patterns are supported in that getters and setters will\n       be protecting accesses.\n\n- **Getters:**\n\n    For every field `f` we generate the following getters:\n\n    1. `f()`: Returns the value of `f` and might panic\n       if the value contains an invalid bit pattern.\n    2. `f_or_err()`: Returns the value of `f` or an error\n       if the value contains an invalid bit pattern.\n\n- **Setters:**\n\n    For every field `f` we generate the following setters:\n\n    1. `set_f(new_value)`: Sets the value of `f` to `new_value` and might panic\n       if `new_value` is out of bounds for the bit width of `f`.\n    2. `set_f_checked(new_value)`: Sets the value of `f` to `new` or returns an error\n       if `new_value` if out of bounds for the bit width of `f`.\n    3. `with_f(new_value)`: Similar to `set_f` but consumes and returns `Self`.\n       Primarily useful for method chaining.\n    4. `with_f_checked(new_value)`: Similar to `set_f_checked` but consumes and returns `Self`.\n       Primarily useful for method chaining.\n\n- **Conversions:**\n\n    - `from_bytes(bytes)`: Allows to constructor the bitfield type from a fixed array of bytes.\n    - `into_bytes()`: Allows to convert the bitfield into its underlying byte representation.\n\n# Parameters\n\nThe following parameters for the `#[bitfield]` macro are supported:\n\n## Parameter: `bytes = N`\n\nThis ensures at compilation time that the resulting `#[bitfield]` struct consists of\nexactly `N` bytes. Yield a compilation error if this does not hold true.\n\n### Example\n\n```\n# use modular_bitfield::prelude::*;\n#[bitfield(bytes = 2)]\npub struct SingedInt {\n    sign: bool, //  1 bit\n    value: B15, // 15 bits\n}\n```\n\n## Parameter: `filled: bool`\n\nIf `filled` is `true` ensures that the `#[bitfield]` struct defines all bits and\ntherefore has a bitwidth that is divisible by 8. If `filled` is `false` ensures the\nexact opposite.\n\nThe default value is: `true`\n\n### Example\n\n```\n# use modular_bitfield::prelude::*;\n#[bitfield(filled = false)]\npub struct Package {\n    is_received: bool, // 1 bit\n    is_alive: bool,    // 1 bit\n    status: B2,        // 2 bits\n}\n```\n\n## Parameter: `bits = N`\n\nWith the `bits: int` parameter it is possible to control the targeted bit width of\na `#[bitfield]` annoated struct. Using `bits = N` guarantees that the resulting bitfield\nstruct will have a bit width of exactly `N`.\n\n### Example 1\n\n```\n# use modular_bitfield::prelude::*;\n#[bitfield(bits = 16)]\npub struct Package {\n    is_received: bool, // 1 bit\n    is_alive: bool,    // 1 bit\n    status: B14,       // 14 bits\n}\n```\n\n### Example 2\n\nThe `bits: int` parameter is especially useful when using this in conjunction with\n`#[derive(Specifier)]` and `filled = false` as shown in the below example.\n\n```\n# use modular_bitfield::prelude::*;\n#[bitfield(bits = 5)]\n#[derive(Specifier)]\npub struct Package {\n    is_received: bool, // 1 bit\n    is_alive: bool,    // 1 bit\n    status: B3,        // 3 bits\n}\n```\n\n## Field Parameter: `#[bits = N]`\n\nTo ensure at compile time that a field of a `#[bitfield]` struct has a bit width of exactly\n`N` a user may add `#[bits = N]` to the field in question.\n\n### Example\n\n```\n# use modular_bitfield::prelude::*;\n# #[bitfield(filled = false)]\n# #[derive(Specifier)]\n# pub struct Header {\n#     is_received: bool, // 1 bit\n#     is_alive: bool,    // 1 bit\n#     status: B2,        // 2 bits\n# }\n#[bitfield]\npub struct Base {\n    #[bits = 4]\n    header: Header, //  4 bits\n    content: B28,   // 28 bits\n}\n```\n\n## Field Parameter: `#[skip(..)]`\n\nIt is possible to skip the entire code generation for getters or setters with the `#[skip]`\nfield attribute.\nThis is useful if a field just needs to be read or written exclusively. Skipping both\nsetters and getters is useful if you want to have undefined blocks within your bitfields.\n\n### Example\n\n```\n# use modular_bitfield::prelude::*;\n#[bitfield]\npub struct Sparse {\n    #[skip(getters)]\n    no_getters: B4,\n    #[skip(setters)]\n    no_setters: B4,\n    #[skip]\n    skipped_entirely: B4,\n    #[skip(getters, setters)]\n    skipped_entirely_2: B2,\n    #[skip(getters)] #[skip(setters)]\n    skipped_entirely_2: B2,\n}\n```\n\n### Trick: Wildcards\n\nIf you are completely uninterested in a field of a bitfield, for example when specifying\nsome undefined bits in your bitfield you can use double wildcards as their names:\n\n```\n# use modular_bitfield::prelude::*;\n#[bitfield]\npub struct Sparse {\n    #[skip] __: B10,\n    a: bool,\n    #[skip] __: B10,\n    b: bool,\n    #[skip] __: B10,\n}\n```\n\n# Features\n\n## Support: `#[derive(Specifier)]`\n\nIf a `#[bitfield]` struct is annotated with a `#[derive(Specifier)]` attribute\nan implementation of the `Specifier` trait will be generated for it. This has the effect\nthat the bitfield struct itself can be used as the type of a field of another bitfield type.\n\nThis feature is limited to bitfield types that have a total bit width of 128 bit or fewer.\nThis restriction is ensured at compile time.\n\n### Example\n\n```\n# use modular_bitfield::prelude::*;\n#[bitfield(filled = false)]\n#[derive(Specifier)]\npub struct Header {\n    is_received: bool, // 1 bit\n    is_alive: bool,    // 1 bit\n    status: B2,        // 2 bits\n}\n```\n\nNow the above `Header` bitfield type can be used in yet another `#[bitfield]` annotated type:\n\n```\n# use modular_bitfield::prelude::*;\n# #[bitfield(filled = false)]\n# #[derive(Specifier)]\n# pub struct Header {\n#     is_received: bool, // 1 bit\n#     is_alive: bool,    // 1 bit\n#     status: B2,        // 2 bits\n# }\n#[bitfield]\npub struct Base {\n    header: Header, //  4 bits\n    content: B28,   // 28 bits\n}\n```\n\n## Support: `#[derive(Debug)]`\n\nIf a `#[derive(Debug)]` is found by the `#[bitfield]` a naturally formatting implementation\nis going to be generated that clearly displays all the fields and their values as the user\nwould expect.\nAlso invalid bit patterns for fields are clearly displayed under this implementation.\n\n### Example\n\n```\n# use modular_bitfield::prelude::*;\n#[bitfield]\n#[derive(Debug)]\npub struct Package {\n    is_received: bool, // 1 bit\n    is_alive: bool,    // 1 bit\n    status: B6,        // 6 bits\n}\n\nlet package = Package::new()\n    .with_is_received(false)\n    .with_is_alive(true)\n    .with_status(3);\nprintln!(\"{:?}\", package);\nassert_eq!(\n    format!(\"{:?}\", package),\n    \"Package { is_received: false, is_alive: true, status: 3 }\",\n);\n```\n\n## Support: `#[repr(uN)]`\n\nIt is possible to additionally annotate a `#[bitfield]` annotated struct with `#[repr(uN)]`\nwhere `uN` is one of `u8`, `u16`, `u32`, `u64` or `u128` in order to make it conveniently\ninterchangeable with such an unsigned integer value.\n\nAs an effect to the user this implements `From` implementations between the chosen primitive\nand the bitfield as well as ensuring at compile time that the bit width of the bitfield struct\nmatches the bit width of the primitive.\n\n### Example\n\n```\n# use modular_bitfield::prelude::*;\n#[bitfield]\n#[repr(u16)]\npub struct SignedU16 {\n    sign: bool,     //  1 bit\n    abs_value: B15, // 15 bits\n}\n\nlet sint = SignedU16::from(0b0111_0001);\nassert_eq!(sint.sign(), true);\nassert_eq!(sint.abs_value(), 0b0011_1000);\nassert_eq!(u16::from(sint), 0b0111_0001_u16);\n```\n"
  },
  {
    "path": "docs/bitfield_specifier.md",
    "content": "Derive macro generating an impl of the trait [`Specifier`].\n\nThis macro can be used on all unit enums and structs annotated with\n`#[bitfield]`. The enum or struct can be up to 128 bits in size; anything larger\nwill cause a compilation error.\n\n# Options\n\n* `#[bits = N]`: Explicitly specifies the number of bits used by a unit enum.\n  This attribute is required when an enum does not have a power-of-two number of\n  variants, but can be used for extra validation no matter what.\n\n# Examples\n\n## Basic usage\n\nIn this example, an extra variant (`Invalid`) is required because otherwise the\nenum would not contain a power-of-two number of variants. The power-of-two\nrequirement ensures conversion from raw bits is infallible.\n\n```\nuse modular_bitfield::prelude::*;\n\n#[derive(Specifier)]\npub enum Weekday {\n    Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday, Invalid\n}\n```\n\n## Using `#[bits = N]`\n\nTo eliminate the power-of-two requirement, add the `#[bits]` attribute:\n\n```\n# use modular_bitfield::prelude::*;\n#\n#[derive(Specifier)]\n#[bits = 3]\npub enum Weekday {\n    Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday\n}\n```\n\n## Discriminants\n\nDiscriminants can be used normally to explicitly override certain values:\n\n```\n# use modular_bitfield::prelude::*;\n#\n#[derive(Specifier)]\n#[bits = 3]\npub enum Weekday {\n    Monday = 1,\n    Tuesday /* 2 … */,\n    Wednesday,\n    Thursday,\n    Friday,\n    Saturday,\n    Sunday = 0,\n}\n```\n\n## With `#[bitfield]`\n\nAn enum that implements `Specifier` can be used normally as a field type in a\n`#[bitfield]` struct:\n\n```\n# use modular_bitfield::prelude::*;\n#\n# #[derive(Debug, Eq, PartialEq, Specifier)]\n# #[bits = 3]\n# pub enum Weekday {\n#     Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday\n# }\n#[bitfield]\npub struct MeetingTimeSlot {\n    day: Weekday,\n    from: B6,\n    to: B6,\n    expired: bool,\n}\n\nlet mut slot = MeetingTimeSlot::new()\n    .with_day(Weekday::Friday)\n    .with_from(14) // 14:00\n    .with_to(15); // 15:00\nassert_eq!(slot.day(), Weekday::Friday);\nassert_eq!(slot.from(), 14);\nassert_eq!(slot.to(), 15);\nassert!(!slot.expired());\n```\n"
  },
  {
    "path": "docs/index.md",
    "content": "Provides macros to support bitfield structs allowing for modular use of bit-enums.\n\nThe mainly provided macros are [`#[bitfield]`](bitfield) for structs and\n[`#[derive(Specifier)]`](Specifier) for enums that shall be usable\nwithin bitfield structs.\n\nThere are preset bitfield specifiers such as `B1`, `B2`,..,`B64`\nthat allow for easy bitfield usage in structs very similar to how\nthey work in C or C++.\n\n- Performance of the macro generated code is as fast as its hand-written\n  alternative.\n- Compile-time checks allow for safe usage of bitfield structs and enums.\n\n### Usage\n\nAnnotate a Rust struct with the [`#[bitfield]`](bitfield) attribute in order to convert it into a bitfield,\nwith [optional parameters](bitfield#parameters) that control how the bitfield is generated.\nThe `B1`, `B2`, ... `B128` prelude types can be used as primitives to declare the number of bits per field.\n\n```\n# use modular_bitfield::prelude::*;\n#\n#[bitfield]\npub struct PackedData {\n    header: B4,\n    body: B9,\n    is_alive: B1,\n    status: B2,\n}\n```\n\nThis produces a `new` constructor as well as a variety of getters and setters that\nallows to interact with the bitfield in a safe fashion:\n\n#### Example: Constructors\n\n```\n# use modular_bitfield::prelude::*;\n#\n# #[bitfield]\n# pub struct PackedData {\n#     header: B4,\n#     body: B9,\n#     is_alive: B1,\n#     status: B2,\n# }\nlet data = PackedData::new()\n    .with_header(1)\n    .with_body(2)\n    .with_is_alive(0)\n    .with_status(3);\nassert_eq!(data.header(), 1);\nassert_eq!(data.body(), 2);\nassert_eq!(data.is_alive(), 0);\nassert_eq!(data.status(), 3);\n```\n\n#### Example: Primitive Types\n\nAny type that implements the `Specifier` trait can be used as a bitfield field.\nBesides the already mentioned `B1`, .. `B128` also the `bool`, `u8`, `u16`, `u32`,\n`u64` or `u128` primitive types can be used from prelude.\n\nWe can use this knowledge to encode our `is_alive` as `bool` type instead of `B1`:\n\n```\n# use modular_bitfield::prelude::*;\n#\n#[bitfield]\npub struct PackedData {\n    header: B4,\n    body: B9,\n    is_alive: bool,\n    status: B2,\n}\n\nlet mut data = PackedData::new()\n    .with_is_alive(true);\nassert!(data.is_alive());\ndata.set_is_alive(false);\nassert!(!data.is_alive());\n```\n\n#### Example: Enum Specifiers\n\nIt is possible to derive the `Specifier` trait for `enum` types very easily to make\nthem also usable as a field within a bitfield type:\n\n```\n# use modular_bitfield::prelude::*;\n#\n#[derive(Specifier)]\npub enum Status {\n    Red, Green, Yellow, None,\n}\n\n#[bitfield]\npub struct PackedData {\n    header: B4,\n    body: B9,\n    is_alive: bool,\n    status: Status,\n}\n```\n\n#### Example: Extra Safety Guard\n\nIn order to make sure that our `Status` enum still requires exatly 2 bit we can add\n`#[bits = 2]` to its field:\n\n```\n# use modular_bitfield::prelude::*;\n#\n# #[derive(Specifier)]\n# pub enum Status {\n#     Red, Green, Yellow, None,\n# }\n#\n#[bitfield]\npub struct PackedData {\n    header: B4,\n    body: B9,\n    is_alive: bool,\n    #[bits = 2]\n    status: Status,\n}\n```\n\nSetting and getting our new `status` field is naturally as follows:\n\n```\n# use modular_bitfield::prelude::*;\n#\n# #[derive(Specifier)]\n# #[derive(Debug, PartialEq, Eq)]\n# pub enum Status {\n#     Red, Green, Yellow, None,\n# }\n#\n# #[bitfield]\n# pub struct PackedData {\n#     header: B4,\n#     body: B9,\n#     is_alive: bool,\n#     #[bits = 2]\n#     status: Status,\n# }\n#\nlet mut data = PackedData::new()\n    .with_status(Status::Green);\nassert_eq!(data.status(), Status::Green);\ndata.set_status(Status::Red);\nassert_eq!(data.status(), Status::Red);\n```\n\n#### Example: Skipping Fields\n\nIt might make sense to only allow users to set or get information from a field or\neven to entirely disallow interaction with a bitfield. For this the `#[skip]` attribute\ncan be used on a bitfield of a `#[bitfield]` annotated struct.\n\n```\n# use modular_bitfield::prelude::*;\n#\n#[bitfield]\npub struct SomeBitsUndefined {\n    #[skip(setters)]\n    read_only: bool,\n    #[skip(getters)]\n    write_only: bool,\n    #[skip]\n    unused: B6,\n}\n```\n\nIt is possible to use `#[skip(getters, setters)]` or `#[skip(getters)]` followed by a `#[skip(setters)]`\nattribute applied on the same bitfield. The effects are the same. When skipping both, getters and setters,\nit is possible to completely avoid having to specify a name:\n\n```\n# use modular_bitfield::prelude::*;\n#\n#[bitfield]\npub struct SomeBitsUndefined {\n    #[skip] __: B2,\n    is_activ: bool,\n    #[skip] __: B2,\n    is_received: bool,\n    #[skip] __: B2,\n}\n```\n\n#### Example: Unfilled Bitfields\n\nSometimes it might be useful to not be required to construct a bitfield that defines\nall bits and therefore is required to have a bit width divisible by 8. In this case\nyou can use the `filled: bool` parameter of the `#[bitfield]` macro in order to toggle\nthis for your respective bitfield:\n\n```\n# use modular_bitfield::prelude::*;\n#\n#[bitfield(filled = false)]\npub struct SomeBitsUndefined {\n    is_compact: bool,\n    is_secure: bool,\n    pre_status: B3,\n}\n```\n\nIn the above example `SomeBitsUndefined` only defines the first 5 bits and leaves the rest\n3 bits of its entire 8 bits undefined. The consequences are that its generated `from_bytes`\nmethod is fallible since it must guard against those undefined bits.\n\n#### Example: Recursive Bitfields\n\nIt is possible to use `#[bitfield]` structs as fields of `#[bitfield]` structs.\nThis is generally useful if there are some common fields for multiple bitfields\nand is achieved by adding the `#[derive(Specifier)]` attribute to the struct\nannotated with `#[bitfield]`:\n\n```\n# use modular_bitfield::prelude::*;\n#\n# #[derive(Specifier)]\n# pub enum Status {\n#     Red, Green, Yellow, None,\n# }\n#\n#[bitfield(filled = false)]\n#[derive(Specifier)]\npub struct Header {\n    is_compact: bool,\n    is_secure: bool,\n    pre_status: Status,\n}\n\n#[bitfield]\npub struct PackedData {\n    header: Header,\n    body: B9,\n    is_alive: bool,\n    status: Status,\n}\n```\n\nWith the `bits: int` parameter of the `#[bitfield]` macro on the `Header` struct and the\n`#[bits: int]` attribute of the `#[derive(Specifier)]` on the `Status` enum we\ncan have additional compile-time guarantees about the bit widths of the resulting entities:\n\n```\n# use modular_bitfield::prelude::*;\n#\n#[derive(Specifier)]\n#[bits = 2]\npub enum Status {\n    Red, Green, Yellow, None,\n}\n\n#[bitfield(bits = 4)]\n#[derive(Specifier)]\npub struct Header {\n    is_compact: bool,\n    is_secure: bool,\n    #[bits = 2]\n    pre_status: Status,\n}\n\n#[bitfield(bits = 16)]\npub struct PackedData {\n    #[bits = 4]\n    header: Header,\n    body: B9,\n    is_alive: bool,\n    #[bits = 2]\n    status: Status,\n}\n```\n\n#### Example: Advanced Enum Specifiers\n\nFor our `Status` enum we actually just need 3 status variants: `Green`, `Yellow` and `Red`.\nWe introduced the `None` status variants because `Specifier` enums by default are required\nto have a number of variants that is a power of two. We can ship around this by specifying\n`#[bits = 2]` on the top and get rid of our placeholder `None` variant while maintaining\nthe invariant of it requiring 2 bits:\n\n```\n# use modular_bitfield::prelude::*;\n\n#[derive(Specifier)]\n#[bits = 2]\npub enum Status {\n    Red, Green, Yellow,\n}\n```\n\nHowever, having such enums now yields the possibility that a bitfield might contain invalid bit\npatterns for such fields. We can safely access those fields with protected getters. For the sake\nof demonstration we will use the generated `from_bytes` constructor with which we can easily\nconstruct bitfields that may contain invalid bit patterns:\n\n```\n# use modular_bitfield::prelude::*;\n# use modular_bitfield::error::InvalidBitPattern;\n#\n# #[derive(Specifier)]\n# #[derive(Debug, PartialEq, Eq)]\n# #[bits = 2]\n# pub enum Status {\n#     Red, Green, Yellow,\n# }\n#\n# #[bitfield(filled = false)]\n# #[derive(Specifier)]\n# pub struct Header {\n#     is_compact: bool,\n#     is_secure: bool,\n#     pre_status: Status,\n# }\n#\n# #[bitfield]\n# pub struct PackedData {\n#     header: Header,\n#     body: B9,\n#     is_alive: bool,\n#     status: Status,\n# }\n#\nlet mut data = PackedData::from_bytes([0b0000_0000, 0b1100_0000]);\n//           The 2 status field bits are invalid -----^^\n//           as Red = 0x00, Green = 0x01 and Yellow = 0x10\nassert_eq!(data.status_or_err(), Err(InvalidBitPattern::new(0b11)));\ndata.set_status(Status::Green);\nassert_eq!(data.status_or_err(), Ok(Status::Green));\n```\n\n## Generated Implementations\n\nFor the example `#[bitfield]` struct the following implementations are going to be generated:\n\n```\n# use modular_bitfield::prelude::*;\n#\n#[bitfield]\npub struct Example {\n    a: bool,\n    b: B7,\n}\n```\n\n| Signature | Description |\n|:--|:--|\n| `fn new() -> Self` | Creates a new instance of the bitfield with all bits initialized to 0. |\n| `fn from_bytes([u8; 1]) -> Self` | Creates a new instance of the bitfield from the given raw bytes. |\n| `fn into_bytes(self) -> [u8; 1]` | Returns the underlying bytes of the bitfield. |\n\nAnd below the generated signatures for field `a`:\n\n| Signature | Description |\n|:--|:--|\n| `fn a() -> bool` | Returns the value of `a` or panics if invalid. |\n| `fn a_or_err() -> Result<bool, InvalidBitPattern<u8>>` | Returns the value of `a` of an error providing information about the invalid bits. |\n| `fn set_a(&mut self, new_value: bool)` | Sets `a` to the new value or panics if `new_value` contains invalid bits. |\n| `fn set_a_checked(&mut self, new_value: bool) -> Result<(), OutOfBounds>` | Sets `a` to the new value of returns an out of bounds error. |\n| `fn with_a(self, new_value: bool) -> Self` | Similar to `set_a` but useful for method chaining. |\n| `fn with_a_checked(self, new_value: bool) -> Result<Self, OutOfBounds>` | Similar to `set_a_checked` but useful for method chaining. |\n\nGetters for unnamed fields in tuple-like structs are prefixed with `get_`\n(e.g. `get_0()`, `get_1_or_err()`, etc.).\n\n## Generated Structure\n\nFrom David Tolnay's procedural macro workshop:\n\nThe macro conceptualizes given structs as a sequence of bits 0..N.\nThe bits are grouped into fields in the order specified by the struct written by the user.\n\nThe `#[bitfield]` attribute rewrites the caller's struct into a private byte array representation\nwith public getter and setter methods for each field.\nThe total number of bits N is required to be a multiple of 8: This is checked at compile time.\n\n### Example\n\nThe following invocation builds a struct with a total size of 32 bits or 4 bytes.\nIt places field `a` in the least significant bit of the first byte,\nfield `b` in the next three least significant bits,\nfield `c` in the remaining four most significant bits of the first byte,\nand field `d` spanning the next three bytes.\n\n```rust\nuse modular_bitfield::prelude::*;\n\n#[bitfield]\npub struct MyFourBytes {\n    a: B1,\n    b: B3,\n    c: B4,\n    d: B24,\n}\n```\n```text\n                               least significant bit of third byte\n                                 ┊           most significant\n                                 ┊             ┊\n                                 ┊             ┊\n║  first byte   ║  second byte  ║  third byte   ║  fourth byte  ║\n╟───────────────╫───────────────╫───────────────╫───────────────╢\n║▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒║\n╟─╫─────╫───────╫───────────────────────────────────────────────╢\n║a║  b  ║   c   ║                       d                       ║\n                 ┊                                             ┊\n                 ┊                                             ┊\n               least significant bit of d         most significant\n```\n"
  },
  {
    "path": "impl/Cargo.toml",
    "content": "[package]\nname = \"modular-bitfield-impl\"\ndescription = \"Derive macro for modular-bitfield\"\nauthors.workspace = true\ndocumentation.workspace = true\nedition.workspace = true\nlicense.workspace = true\npublish.workspace = true\nrepository.workspace = true\nrust-version.workspace = true\nversion.workspace = true\n\n[lib]\nproc-macro = true\n\n[dependencies]\nquote = \"1\"\nsyn = { version = \"2\", features = [\"full\"] }\nproc-macro2 = \"1\"\n\n[dev-dependencies]\nglob = \"0.3\"\nruntime-macros = \"1.1.1\"\n\n[lints.rust]\nunexpected_cfgs = { level = \"warn\", check-cfg = ['cfg(coverage)'] }\n"
  },
  {
    "path": "impl/src/bitfield/analyse.rs",
    "content": "use super::{\n    config::{Config, ReprKind},\n    field_config::{FieldConfig, SkipWhich},\n    raise_skip_error, BitfieldStruct,\n};\nuse core::convert::TryFrom;\nuse quote::quote;\nuse syn::{self, parse::Result, punctuated::Punctuated, spanned::Spanned as _};\n\nimpl TryFrom<(&mut Config, syn::ItemStruct)> for BitfieldStruct {\n    type Error = syn::Error;\n\n    fn try_from((config, item_struct): (&mut Config, syn::ItemStruct)) -> Result<Self> {\n        Self::ensure_has_fields(&item_struct)?;\n        Self::ensure_valid_generics(&item_struct)?;\n        Self::extract_attributes(&item_struct.attrs, config)?;\n        Self::analyse_config_for_fields(&item_struct, config)?;\n        config.ensure_no_conflicts()?;\n        Ok(Self { item_struct })\n    }\n}\n\nimpl BitfieldStruct {\n    /// Returns an error if the input struct does not have any fields.\n    fn ensure_has_fields(item_struct: &syn::ItemStruct) -> Result<()> {\n        if matches!(&item_struct.fields, syn::Fields::Unit)\n            || matches!(&item_struct.fields, syn::Fields::Unnamed(f) if f.unnamed.is_empty())\n            || matches!(&item_struct.fields, syn::Fields::Named(f) if f.named.is_empty())\n        {\n            return Err(format_err_spanned!(\n                item_struct,\n                \"encountered invalid bitfield struct without fields\"\n            ));\n        }\n        Ok(())\n    }\n\n    /// Returns an error if the input struct contains generics that cannot be\n    /// used in a const expression.\n    fn ensure_valid_generics(item_struct: &syn::ItemStruct) -> Result<()> {\n        if item_struct.generics.type_params().next().is_some()\n            || item_struct.generics.lifetimes().next().is_some()\n        {\n            return Err(format_err_spanned!(\n                item_struct.generics,\n                \"bitfield structs can only use const generics\"\n            ));\n        }\n        Ok(())\n    }\n\n    /// Extracts the `#[repr(uN)]` annotations from the given `#[bitfield]` struct.\n    fn extract_repr_attribute(attr: &syn::Attribute, config: &mut Config) -> Result<()> {\n        let list = attr.meta.require_list()?;\n        let repr_arguments: Punctuated<syn::Meta, syn::Token![,]> =\n            attr.parse_args_with(Punctuated::parse_terminated)?;\n        let mut retained_reprs = Vec::new();\n        for meta in repr_arguments {\n            match meta {\n                syn::Meta::Path(path) => {\n                    let repr_kind = if path.is_ident(\"u8\") {\n                        Some(ReprKind::U8)\n                    } else if path.is_ident(\"u16\") {\n                        Some(ReprKind::U16)\n                    } else if path.is_ident(\"u32\") {\n                        Some(ReprKind::U32)\n                    } else if path.is_ident(\"u64\") {\n                        Some(ReprKind::U64)\n                    } else if path.is_ident(\"u128\") {\n                        Some(ReprKind::U128)\n                    } else {\n                        // If other repr such as `transparent` or `C` have been found we\n                        // are going to re-expand them into a new `#[repr(..)]` that is\n                        // ignored by the rest of this macro.\n                        retained_reprs.push(path.clone().into());\n                        None\n                    };\n                    if let Some(repr_kind) = repr_kind {\n                        config.repr(repr_kind, path.span())?;\n                    }\n                }\n                other => retained_reprs.push(other),\n            }\n        }\n        if !retained_reprs.is_empty() {\n            // We only push back another re-generated `#[repr(..)]` if its contents\n            // contained some non-bitfield representations and thus is not empty.\n            let retained_reprs_tokens = quote! {\n                #( #retained_reprs ),*\n            };\n            config.push_retained_attribute(syn::Attribute {\n                pound_token: attr.pound_token,\n                style: attr.style,\n                bracket_token: attr.bracket_token,\n                meta: syn::Meta::List(syn::MetaList {\n                    path: list.path.clone(),\n                    delimiter: list.delimiter.clone(),\n                    tokens: retained_reprs_tokens,\n                }),\n            });\n        }\n        Ok(())\n    }\n\n    /// Extracts the `#[derive(Debug)]` annotations from the given `#[bitfield]` struct.\n    fn extract_derive_debug_attribute(attr: &syn::Attribute, config: &mut Config) -> Result<()> {\n        let list = attr.meta.require_list()?;\n        let mut retained_derives = vec![];\n        attr.parse_nested_meta(|meta| {\n            let path = &meta.path;\n            if path.is_ident(\"Debug\") {\n                config.derive_debug(path.span())?;\n            } else if path.is_ident(\"Specifier\") {\n                config.derive_specifier(path.span())?;\n            } else {\n                // Other derives are going to be re-expanded them into a new\n                // `#[derive(..)]` that is ignored by the rest of this macro.\n                retained_derives.push(path.clone());\n            }\n            Ok(())\n        })?;\n        if !retained_derives.is_empty() {\n            // We only push back another re-generated `#[derive(..)]` if its contents\n            // contain some remaining derives and thus is not empty.\n            let retained_derives_tokens = quote! {\n                #( #retained_derives ),*\n            };\n            config.push_retained_attribute(syn::Attribute {\n                pound_token: attr.pound_token,\n                style: attr.style,\n                bracket_token: attr.bracket_token,\n                meta: syn::Meta::List(syn::MetaList {\n                    path: list.path.clone(),\n                    delimiter: list.delimiter.clone(),\n                    tokens: retained_derives_tokens,\n                }),\n            });\n        }\n        Ok(())\n    }\n\n    /// Analyses and extracts the `#[repr(uN)]` or other annotations from the given struct.\n    fn extract_attributes(attributes: &[syn::Attribute], config: &mut Config) -> Result<()> {\n        for attr in attributes {\n            if attr.path().is_ident(\"repr\") {\n                Self::extract_repr_attribute(attr, config)?;\n            } else if attr.path().is_ident(\"derive\") {\n                Self::extract_derive_debug_attribute(attr, config)?;\n            } else {\n                config.push_retained_attribute(attr.clone());\n            }\n        }\n        Ok(())\n    }\n\n    /// Analyses and extracts the configuration for all bitfield fields.\n    fn analyse_config_for_fields(item_struct: &syn::ItemStruct, config: &mut Config) -> Result<()> {\n        for (index, field) in Self::fields(item_struct) {\n            let span = field.span();\n            let field_config = Self::extract_field_config(field)?;\n            config.field_config(index, span, field_config)?;\n        }\n        Ok(())\n    }\n\n    /// Extracts the `#[bits = N]` and `#[skip(..)]` attributes for a given field.\n    fn extract_field_config(field: &syn::Field) -> Result<FieldConfig> {\n        let mut config = FieldConfig::default();\n        for attr in &field.attrs {\n            if attr.path().is_ident(\"bits\") {\n                let name_value = attr.meta.require_name_value()?;\n                let span = name_value.span();\n                match &name_value.value {\n                    syn::Expr::Lit(syn::ExprLit {\n                        lit: syn::Lit::Int(lit_int),\n                        ..\n                    }) => {\n                        config.bits(lit_int.base10_parse::<usize>()?, span)?;\n                    }\n                    value => {\n                        return Err(format_err!(\n                            value.span(),\n                            \"encountered invalid value type for #[bits = N]\"\n                        ))\n                    }\n                }\n            } else if attr.path().is_ident(\"skip\") {\n                match &attr.meta {\n                    syn::Meta::Path(path) => {\n                        assert!(path.is_ident(\"skip\"));\n                        config.skip(SkipWhich::All, path.span())?;\n                    }\n                    syn::Meta::List(meta_list) => {\n                        let (mut getters, mut setters) = (None, None);\n                        meta_list.parse_nested_meta(|meta| {\n                            let path = &meta.path;\n                            if path.is_ident(\"getters\") {\n                                if let Some(previous) = getters {\n                                    return raise_skip_error(\"(getters)\", path.span(), previous);\n                                }\n                                getters = Some(path.span());\n                            } else if path.is_ident(\"setters\") {\n                                if let Some(previous) = setters {\n                                    return raise_skip_error(\"(setters)\", path.span(), previous);\n                                }\n                                setters = Some(path.span());\n                            } else {\n                                return Err(meta.error(\n                                    \"encountered unknown or unsupported #[skip(..)] specifier\",\n                                ));\n                            }\n                            Ok(())\n                        })?;\n                        if getters.is_some() == setters.is_some() {\n                            config.skip(SkipWhich::All, meta_list.path.span())?;\n                        } else if getters.is_some() {\n                            config.skip(SkipWhich::Getters, meta_list.path.span())?;\n                        } else {\n                            config.skip(SkipWhich::Setters, meta_list.path.span())?;\n                        }\n                    }\n                    meta @ syn::Meta::NameValue(..) => {\n                        return Err(format_err!(\n                            meta.span(),\n                            \"encountered invalid format for #[skip] field attribute\"\n                        ))\n                    }\n                }\n            } else {\n                config.retain_attr(attr.clone());\n            }\n        }\n        Ok(config)\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use quote::ToTokens as _;\n\n    #[test]\n    fn retain_repr_arguments() {\n        let attr: syn::Attribute = syn::parse_quote!(#[repr(C, align(8))]);\n        let mut config = Config::default();\n\n        BitfieldStruct::extract_repr_attribute(&attr, &mut config).unwrap();\n\n        assert_eq!(config.retained_attributes.len(), 1);\n        let retained = &config.retained_attributes[0];\n        assert_eq!(\n            retained.to_token_stream().to_string(),\n            attr.to_token_stream().to_string(),\n            \"repr arguments should be preserved when re-emitting retained repr attributes\"\n        );\n    }\n}\n"
  },
  {
    "path": "impl/src/bitfield/config.rs",
    "content": "use super::field_config::FieldConfig;\nuse crate::errors::CombineError;\nuse core::any::TypeId;\nuse proc_macro2::Span;\nuse std::collections::{hash_map::Entry, HashMap};\nuse syn::parse::Result;\n\n/// The configuration for the `#[bitfield]` macro.\n#[derive(Default)]\npub struct Config {\n    pub bytes: Option<ConfigValue<usize>>,\n    pub bits: Option<ConfigValue<usize>>,\n    pub filled: Option<ConfigValue<bool>>,\n    pub repr: Option<ConfigValue<ReprKind>>,\n    pub derive_debug: Option<ConfigValue<()>>,\n    pub derive_specifier: Option<ConfigValue<()>>,\n    pub retained_attributes: Vec<syn::Attribute>,\n    pub field_configs: HashMap<usize, ConfigValue<FieldConfig>>,\n}\n\n/// Kinds of `#[repr(uN)]` annotations for a `#[bitfield]` struct.\n#[derive(Copy, Clone)]\npub enum ReprKind {\n    /// Found a `#[repr(u8)]` annotation.\n    U8,\n    /// Found a `#[repr(u16)]` annotation.\n    U16,\n    /// Found a `#[repr(u32)]` annotation.\n    U32,\n    /// Found a `#[repr(u64)]` annotation.\n    U64,\n    /// Found a `#[repr(u128)]` annotation.\n    U128,\n}\n\nimpl ReprKind {\n    /// Returns the amount of bits required to have for the bitfield to satisfy the `#[repr(uN)]`.\n    pub fn bits(self) -> usize {\n        match self {\n            Self::U8 => 8,\n            Self::U16 => 16,\n            Self::U32 => 32,\n            Self::U64 => 64,\n            Self::U128 => 128,\n        }\n    }\n}\n\nimpl core::fmt::Debug for ReprKind {\n    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {\n        write!(f, \"#[repr(u{})]\", self.bits())\n    }\n}\n\n/// A configuration value and its originating span.\n#[derive(Clone)]\npub struct ConfigValue<T> {\n    /// The actual value of the config.\n    pub value: T,\n    /// The originating span of the config.\n    pub span: Span,\n}\n\nimpl<T> ConfigValue<T> {\n    /// Creates a new config value.\n    pub fn new(value: T, span: Span) -> Self {\n        Self { value, span }\n    }\n}\n\nimpl Config {\n    /// Returns the value of the `filled` parameter if provided and otherwise `true`.\n    pub fn filled_enabled(&self) -> bool {\n        self.filled.as_ref().map_or(true, |config| config.value)\n    }\n\n    fn ensure_no_bits_and_repr_conflict(&self) -> Result<()> {\n        if let (Some(bits), Some(repr)) = (self.bits.as_ref(), self.repr.as_ref()) {\n            if bits.value != repr.value.bits() {\n                return Err(format_err!(\n                    Span::call_site(),\n                    \"encountered conflicting `bits = {}` and {:?} parameters\",\n                    bits.value,\n                    repr.value,\n                )\n                .into_combine(\n                    format_err!(bits.span, \"conflicting `bits = {}` here\", bits.value,)\n                        .into_combine(format_err!(repr.span, \"conflicting {:?} here\", repr.value)),\n                ));\n            }\n        }\n        Ok(())\n    }\n\n    fn ensure_no_bits_and_bytes_conflict(&self) -> Result<()> {\n        if let (Some(bits), Some(bytes)) = (self.bits.as_ref(), self.bytes.as_ref()) {\n            fn next_div_by_8(value: usize) -> usize {\n                ((value.saturating_sub(1) / 8) + 1) * 8\n            }\n            if next_div_by_8(bits.value) / 8 != bytes.value {\n                return Err(format_err!(\n                    Span::call_site(),\n                    \"encountered conflicting `bits = {}` and `bytes = {}` parameters\",\n                    bits.value,\n                    bytes.value,\n                )\n                .into_combine(format_err!(\n                    bits.span,\n                    \"conflicting `bits = {}` here\",\n                    bits.value\n                ))\n                .into_combine(format_err!(\n                    bytes.span,\n                    \"conflicting `bytes = {}` here\",\n                    bytes.value,\n                )));\n            }\n        }\n        Ok(())\n    }\n\n    pub fn ensure_no_repr_and_filled_conflict(&self) -> Result<()> {\n        if let (Some(repr), Some(filled @ ConfigValue { value: false, .. })) =\n            (self.repr.as_ref(), self.filled.as_ref())\n        {\n            return Err(format_err!(\n                Span::call_site(),\n                \"encountered conflicting `{:?}` and `filled = {}` parameters\",\n                repr.value,\n                filled.value,\n            )\n            .into_combine(format_err!(\n                repr.span,\n                \"conflicting `{:?}` here\",\n                repr.value\n            ))\n            .into_combine(format_err!(\n                filled.span,\n                \"conflicting `filled = {}` here\",\n                filled.value,\n            )));\n        }\n        Ok(())\n    }\n\n    /// Ensures that there are no conflicting configuration parameters.\n    pub fn ensure_no_conflicts(&self) -> Result<()> {\n        self.ensure_no_bits_and_repr_conflict()?;\n        self.ensure_no_bits_and_bytes_conflict()?;\n        self.ensure_no_repr_and_filled_conflict()?;\n        Ok(())\n    }\n\n    /// Returns an error showing both the duplicate as well as the previous parameters.\n    fn raise_duplicate_error<T>(name: &str, span: Span, previous: &ConfigValue<T>) -> syn::Error\n    where\n        T: core::fmt::Debug + 'static,\n    {\n        if TypeId::of::<T>() == TypeId::of::<()>() {\n            format_err!(span, \"encountered duplicate `{}` parameter\", name,)\n        } else {\n            format_err!(\n                span,\n                \"encountered duplicate `{}` parameter: duplicate set to {:?}\",\n                name,\n                previous.value\n            )\n        }\n        .into_combine(format_err!(\n            previous.span,\n            \"previous `{}` parameter here\",\n            name\n        ))\n    }\n\n    /// Sets the `bytes: int` #[bitfield] parameter to the given value.\n    ///\n    /// # Errors\n    ///\n    /// If the specifier has already been set.\n    pub fn bytes(&mut self, value: usize, span: Span) -> Result<()> {\n        match &self.bytes {\n            Some(previous) => return Err(Self::raise_duplicate_error(\"bytes\", span, previous)),\n            None => self.bytes = Some(ConfigValue::new(value, span)),\n        }\n        Ok(())\n    }\n\n    /// Sets the `bits: int` #[bitfield] parameter to the given value.\n    ///\n    /// # Errors\n    ///\n    /// If the specifier has already been set.\n    pub fn bits(&mut self, value: usize, span: Span) -> Result<()> {\n        match &self.bits {\n            Some(previous) => return Err(Self::raise_duplicate_error(\"bits\", span, previous)),\n            None => self.bits = Some(ConfigValue::new(value, span)),\n        }\n        Ok(())\n    }\n\n    /// Sets the `filled: bool` #[bitfield] parameter to the given value.\n    ///\n    /// # Errors\n    ///\n    /// If the specifier has already been set.\n    pub fn filled(&mut self, value: bool, span: Span) -> Result<()> {\n        match &self.filled {\n            Some(previous) => return Err(Self::raise_duplicate_error(\"filled\", span, previous)),\n            None => self.filled = Some(ConfigValue::new(value, span)),\n        }\n        Ok(())\n    }\n\n    /// Registers the `#[repr(uN)]` attribute for the #[bitfield] macro.\n    ///\n    /// # Errors\n    ///\n    /// If a `#[repr(uN)]` attribute has already been found.\n    pub fn repr(&mut self, value: ReprKind, span: Span) -> Result<()> {\n        match &self.repr {\n            Some(previous) => {\n                return Err(Self::raise_duplicate_error(\"#[repr(uN)]\", span, previous))\n            }\n            None => self.repr = Some(ConfigValue::new(value, span)),\n        }\n        Ok(())\n    }\n\n    /// Registers the `#[derive(Debug)]` attribute for the #[bitfield] macro.\n    ///\n    /// # Errors\n    ///\n    /// If a `#[derive(Debug)]` attribute has already been found.\n    pub fn derive_debug(&mut self, span: Span) -> Result<()> {\n        match &self.derive_debug {\n            Some(previous) => {\n                return Err(Self::raise_duplicate_error(\n                    \"#[derive(Debug)]\",\n                    span,\n                    previous,\n                ))\n            }\n            None => self.derive_debug = Some(ConfigValue::new((), span)),\n        }\n        Ok(())\n    }\n\n    /// Registers the `#[derive(Specifier)]` attribute for the #[bitfield] macro.\n    ///\n    /// # Errors\n    ///\n    /// If a `#[derive(Specifier)]` attribute has already been found.\n    pub fn derive_specifier(&mut self, span: Span) -> Result<()> {\n        match &self.derive_specifier {\n            Some(previous) => {\n                return Err(Self::raise_duplicate_error(\n                    \"#[derive(Specifier)]\",\n                    span,\n                    previous,\n                ))\n            }\n            None => self.derive_specifier = Some(ConfigValue::new((), span)),\n        }\n        Ok(())\n    }\n\n    /// Pushes another retained attribute that the #[bitfield] macro is going to re-expand and ignore.\n    pub fn push_retained_attribute(&mut self, retained_attr: syn::Attribute) {\n        self.retained_attributes.push(retained_attr);\n    }\n\n    /// Sets the field configuration and retained attributes for the given field.\n    ///\n    /// By convention we use the fields name to identify the field if existing.\n    /// Otherwise we turn the fields discriminant into an appropriate string.\n    ///\n    /// # Errors\n    ///\n    /// If duplicate field configurations have been found for a field.\n    pub fn field_config(&mut self, index: usize, span: Span, config: FieldConfig) -> Result<()> {\n        match self.field_configs.entry(index) {\n            Entry::Occupied(occupied) => {\n                return Err(format_err!(span, \"encountered duplicate config for field\")\n                    .into_combine(format_err!(occupied.get().span, \"previous config here\")))\n            }\n            Entry::Vacant(vacant) => {\n                vacant.insert(ConfigValue::new(config, span));\n            }\n        }\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "impl/src/bitfield/expand.rs",
    "content": "use super::{\n    config::{Config, ReprKind},\n    field_info::FieldInfo,\n    BitfieldStruct,\n};\nuse proc_macro2::TokenStream as TokenStream2;\nuse quote::{format_ident, quote_spanned, ToTokens};\nuse syn::{self, punctuated::Punctuated, spanned::Spanned as _, Token};\n\nimpl BitfieldStruct {\n    /// Expands the given `#[bitfield]` struct into an actual bitfield definition.\n    pub fn expand(&self, config: &Config) -> TokenStream2 {\n        let span = self.item_struct.span();\n        let check_filled = self.generate_check_for_filled(config);\n        let struct_definition = self.generate_struct(config);\n        let constructor_definition = self.generate_constructor(config);\n        let specifier_impl = self.generate_specifier_impl(config);\n\n        let byte_conversion_impls = self.expand_byte_conversion_impls(config);\n        let getters_and_setters = self.expand_getters_and_setters(config);\n        let bytes_check = self.expand_optional_bytes_check(config);\n        let repr_impls_and_checks = self.expand_repr_from_impls_and_checks(config);\n        let debug_impl = self.generate_debug_impl(config);\n\n        quote_spanned!(span=>\n            #struct_definition\n            #check_filled\n            #constructor_definition\n            #byte_conversion_impls\n            #getters_and_setters\n            #specifier_impl\n            #bytes_check\n            #repr_impls_and_checks\n            #debug_impl\n        )\n    }\n\n    /// Expands to the `Specifier` impl for the `#[bitfield]` struct if the\n    /// `#[derive(Specifier)]` attribute is applied to it as well.\n    ///\n    /// Otherwise returns `None`.\n    pub fn generate_specifier_impl(&self, config: &Config) -> Option<TokenStream2> {\n        config.derive_specifier.as_ref()?;\n\n        let span = self.item_struct.span();\n        let ident = &self.item_struct.ident;\n        let (impl_generics, ty_generics, where_clause) = self.item_struct.generics.split_for_impl();\n        let bits = self.generate_target_or_actual_bitfield_size(config);\n        let next_divisible_by_8 = Self::next_divisible_by_8(&bits);\n\n        Some(quote_spanned!(span=>\n            const _: () = {\n                impl #impl_generics ::modular_bitfield::private::checks::CheckSpecifierHasAtMost128Bits for #ident #ty_generics #where_clause {\n                    type CheckType = ::modular_bitfield::private::checks::BitCount<{(#bits <= 128) as ::core::primitive::usize}>;\n                }\n            };\n\n            impl #impl_generics ::modular_bitfield::Specifier for #ident #ty_generics #where_clause {\n                const BITS: ::core::primitive::usize = #bits;\n\n                type Bytes = <::modular_bitfield::private::checks::BitCount<{if #bits > 128 { 128 } else { #bits }}> as ::modular_bitfield::private::SpecifierBytes>::Bytes;\n                type InOut = Self;\n\n                #[inline]\n                fn into_bytes(\n                    value: Self::InOut,\n                ) -> ::core::result::Result<Self::Bytes, ::modular_bitfield::error::OutOfBounds> {\n                    ::core::result::Result::Ok(\n                        <::modular_bitfield::private::checks::BitCount<{#next_divisible_by_8}> as ::modular_bitfield::private::ArrayBytesConversion>::array_into_bytes(\n                            value.bytes\n                        )\n                    )\n                }\n\n                #[inline]\n                fn from_bytes(\n                    bytes: Self::Bytes,\n                ) -> ::core::result::Result<Self::InOut, ::modular_bitfield::error::InvalidBitPattern<Self::Bytes>>\n                {\n                    // Truncation of BITS is always valid due to maximum of 128\n                    #[allow(clippy::cast_possible_truncation)]\n                    let __bf_max_value: Self::Bytes = (1 as Self::Bytes)\n                        .checked_shl(Self::BITS as ::core::primitive::u32)\n                        .unwrap_or(<Self::Bytes>::MAX);\n                    if bytes <= __bf_max_value {\n                        let __bf_bytes = bytes.to_le_bytes();\n                        ::core::result::Result::Ok(Self {\n                            bytes: <::modular_bitfield::private::checks::BitCount<{#next_divisible_by_8}> as ::modular_bitfield::private::ArrayBytesConversion>::bytes_into_array(bytes)\n                        })\n                    } else {\n                        ::core::result::Result::Err(::modular_bitfield::error::InvalidBitPattern::new(bytes))\n                    }\n                }\n            }\n        ))\n    }\n\n    /// Generates the `core::fmt::Debug` impl if `#[derive(Debug)]` is included.\n    pub fn generate_debug_impl(&self, config: &Config) -> Option<TokenStream2> {\n        config.derive_debug.as_ref()?;\n        let span = self.item_struct.span();\n        let ident = &self.item_struct.ident;\n        let (impl_generics, ty_generics, where_clause) = self.item_struct.generics.split_for_impl();\n        let is_tuple = matches!(self.item_struct.fields, syn::Fields::Unnamed(_));\n        let builder_name = if is_tuple {\n            quote_spanned!(span=> debug_tuple)\n        } else {\n            quote_spanned!(span=> debug_struct)\n        };\n        let fields = self.field_infos(config).map(|info| {\n            let FieldInfo {\n                index: _,\n                field,\n                config,\n            } = &info;\n            if config.skip_getters() {\n                return None;\n            }\n            let field_span = field.span();\n            let field_name = if field.ident.is_some() {\n                let field_name = info.name();\n                quote_spanned!(field_span=> #field_name,)\n            } else {\n                <_>::default()\n            };\n            let field_ident = info.ident_frag();\n            let field_getter = field.ident.as_ref().map_or_else(\n                || format_ident!(\"get_{}_or_err\", field_ident),\n                |_| format_ident!(\"{}_or_err\", field_ident),\n            );\n            Some(quote_spanned!(field_span=>\n                .field(\n                    #field_name\n                    self.#field_getter()\n                        .as_ref()\n                        .map_or_else(\n                            |__bf_err| __bf_err as &dyn ::core::fmt::Debug,\n                            |__bf_field| __bf_field as &dyn ::core::fmt::Debug\n                        )\n                )\n            ))\n        });\n        Some(quote_spanned!(span=>\n            impl #impl_generics ::core::fmt::Debug for #ident #ty_generics #where_clause {\n                fn fmt(&self, __bf_f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {\n                    __bf_f.#builder_name(::core::stringify!(#ident))\n                        #( #fields )*\n                        .finish()\n                }\n            }\n        ))\n    }\n\n    /// Generates the expression denoting the sum of all field bit specifier sizes.\n    ///\n    /// # Example\n    ///\n    /// For the following struct:\n    ///\n    /// ```no_compile\n    /// #[bitfield]\n    /// pub struct Color {\n    ///     r: B8,\n    ///     g: B8,\n    ///     b: B8,\n    ///     a: bool,\n    ///     rest: B7,\n    /// }\n    /// ```\n    ///\n    /// We generate the following tokens:\n    ///\n    /// ```no_compile\n    /// <B8 as ::modular_bitfield::Specifier>::BITS +\n    /// <B8 as ::modular_bitfield::Specifier>::BITS +\n    /// <B8 as ::modular_bitfield::Specifier>::BITS +\n    /// <bool as ::modular_bitfield::Specifier>::BITS +\n    /// <B7 as ::modular_bitfield::Specifier>::BITS\n    /// ```\n    ///\n    /// Which is a compile time evaluatable expression.\n    fn generate_bitfield_size(&self) -> TokenStream2 {\n        self.item_struct\n            .fields\n            .iter()\n            .map(|field| -> syn::Expr {\n                let span = field.span();\n                let ty = &field.ty;\n                syn::parse_quote_spanned!(span=>\n                    <#ty as ::modular_bitfield::Specifier>::BITS\n                )\n            })\n            .collect::<Punctuated<syn::Expr, Token![+]>>()\n            .into_token_stream()\n    }\n\n    /// Generates the expression denoting the actual configured or implied bit width.\n    fn generate_target_or_actual_bitfield_size(&self, config: &Config) -> TokenStream2 {\n        config.bits.as_ref().map_or_else(\n            || self.generate_bitfield_size(),\n            |bits_config| {\n                let span = bits_config.span;\n                let value = bits_config.value;\n                quote_spanned!(span=>\n                    #value\n                )\n            },\n        )\n    }\n\n    /// Generates a check in case `bits = N` is unset to verify that the actual amount of bits is either\n    ///\n    /// - ... equal to `N`, if `filled = true` or\n    /// - ... smaller than `N`, if `filled = false`\n    fn generate_filled_check_for_unaligned_bits(\n        &self,\n        config: &Config,\n        required_bits: usize,\n    ) -> TokenStream2 {\n        let span = self.item_struct.span();\n        let ident = &self.item_struct.ident;\n        let (impl_generics, ty_generics, where_clause) = self.item_struct.generics.split_for_impl();\n        let actual_bits = self.generate_bitfield_size();\n        let check_ident = if config.filled_enabled() {\n            quote_spanned!(span=> CheckFillsUnalignedBits)\n        } else {\n            quote_spanned!(span=> CheckDoesNotFillUnalignedBits)\n        };\n        let comparator = if config.filled_enabled() {\n            quote_spanned!(span=> ==)\n        } else {\n            quote_spanned!(span=> >)\n        };\n        quote_spanned!(span=>\n            const _: () = {\n                impl #impl_generics ::modular_bitfield::private::checks::#check_ident for #ident #ty_generics #where_clause {\n                    type CheckType = ::modular_bitfield::private::checks::BitCount<{(#required_bits #comparator #actual_bits) as ::core::primitive::usize}>;\n                }\n            };\n        )\n    }\n\n    /// Generates a check in case `bits = N` is unset to verify that the actual amount of bits is either\n    ///\n    /// - ... divisible by 8, if `filled = true` or\n    /// - ... not divisible by 8, if `filled = false`\n    fn generate_filled_check_for_aligned_bits(&self, config: &Config) -> TokenStream2 {\n        let span = self.item_struct.span();\n        let ident = &self.item_struct.ident;\n        let (impl_generics, ty_generics, where_clause) = self.item_struct.generics.split_for_impl();\n        let actual_bits = self.generate_bitfield_size();\n        let check_ident = if config.filled_enabled() {\n            quote_spanned!(span=> CheckTotalSizeMultipleOf8)\n        } else {\n            quote_spanned!(span=> CheckTotalSizeIsNotMultipleOf8)\n        };\n        quote_spanned!(span=>\n            const _: () = {\n                impl #impl_generics ::modular_bitfield::private::checks::#check_ident for #ident #ty_generics #where_clause {\n                    type Size = ::modular_bitfield::private::checks::TotalSize<::modular_bitfield::private::checks::BitCount<{(#actual_bits) % 8}>>;\n                }\n            };\n        )\n    }\n\n    /// Generate check for either of the following two cases:\n    ///\n    /// - `filled = true`: Check if the total number of required bits is\n    ///   - ... the same as `N` if `bits = N` was provided or\n    ///   - ... a multiple of 8, otherwise\n    /// - `filled = false`: Check if the total number of required bits is\n    ///   - ... smaller than `N` if `bits = N` was provided or\n    ///   - ... NOT a multiple of 8, otherwise\n    fn generate_check_for_filled(&self, config: &Config) -> TokenStream2 {\n        match config.bits.as_ref() {\n            Some(bits_config) => {\n                self.generate_filled_check_for_unaligned_bits(config, bits_config.value)\n            }\n            None => self.generate_filled_check_for_aligned_bits(config),\n        }\n    }\n\n    /// Returns a token stream representing the next greater value divisible by 8.\n    fn next_divisible_by_8(value: &TokenStream2) -> TokenStream2 {\n        let span = value.span();\n        quote_spanned!(span=>\n            (((#value - 1) / 8) + 1) * 8\n        )\n    }\n\n    /// Generates the actual item struct definition for the `#[bitfield]`.\n    ///\n    /// Internally it only contains a byte array equal to the minimum required\n    /// amount of bytes to compactly store the information of all its bit fields.\n    fn generate_struct(&self, config: &Config) -> TokenStream2 {\n        let span = self.item_struct.span();\n        let attrs = &config.retained_attributes;\n        let vis = &self.item_struct.vis;\n        let ident = &self.item_struct.ident;\n        let generics = &self.item_struct.generics;\n        let size = self.generate_target_or_actual_bitfield_size(config);\n        let next_divisible_by_8 = Self::next_divisible_by_8(&size);\n        quote_spanned!(span=>\n            #( #attrs )*\n            #vis struct #ident #generics\n            {\n                bytes: [::core::primitive::u8; #next_divisible_by_8 / 8],\n            }\n        )\n    }\n\n    /// Generates the constructor for the bitfield that initializes all bytes to zero.\n    fn generate_constructor(&self, config: &Config) -> TokenStream2 {\n        let span = self.item_struct.span();\n        let ident = &self.item_struct.ident;\n        let (impl_generics, ty_generics, where_clause) = self.item_struct.generics.split_for_impl();\n        let size = self.generate_target_or_actual_bitfield_size(config);\n        let next_divisible_by_8 = Self::next_divisible_by_8(&size);\n        quote_spanned!(span=>\n            impl #impl_generics #ident #ty_generics #where_clause\n            {\n                /// Returns an instance with zero initialized data.\n                #[allow(clippy::new_without_default)]\n                #[must_use]\n                pub const fn new() -> Self {\n                    Self {\n                        bytes: [0_u8; #next_divisible_by_8 / 8],\n                    }\n                }\n            }\n        )\n    }\n\n    /// Generates the compile-time assertion if the optional `byte` parameter has been set.\n    fn expand_optional_bytes_check(&self, config: &Config) -> Option<TokenStream2> {\n        let ident = &self.item_struct.ident;\n        config.bytes.as_ref().map(|config| {\n            let bytes = config.value;\n            quote_spanned!(config.span=>\n                const _: () = {\n                    struct ExpectedBytes { __bf_unused: [::core::primitive::u8; #bytes] }\n\n                    ::modular_bitfield::private::static_assertions::assert_eq_size!(\n                        ExpectedBytes,\n                        #ident\n                    );\n                };\n            )\n        })\n    }\n\n    /// Generates `From` impls for a `#[repr(uN)]` annotated #[bitfield] struct.\n    fn expand_repr_from_impls_and_checks(&self, config: &Config) -> Option<TokenStream2> {\n        let ident = &self.item_struct.ident;\n        let (impl_generics, ty_generics, where_clause) = self.item_struct.generics.split_for_impl();\n        let where_predicates = where_clause.map(|w| &w.predicates);\n        config.repr.as_ref().map(|repr| {\n            let kind = &repr.value;\n            let span = repr.span;\n            let prim = match kind {\n                ReprKind::U8 => quote_spanned!(span=> ::core::primitive::u8),\n                ReprKind::U16 => quote_spanned!(span=> ::core::primitive::u16),\n                ReprKind::U32 => quote_spanned!(span=> ::core::primitive::u32),\n                ReprKind::U64 => quote_spanned!(span=> ::core::primitive::u64),\n                ReprKind::U128 => quote_spanned!(span=> ::core::primitive::u128),\n            };\n            let actual_bits = self.generate_target_or_actual_bitfield_size(config);\n            let trait_check_ident = match kind {\n                ReprKind::U8 => quote_spanned!(span=> IsU8Compatible),\n                ReprKind::U16 => quote_spanned!(span=> IsU16Compatible),\n                ReprKind::U32 => quote_spanned!(span=> IsU32Compatible),\n                ReprKind::U64 => quote_spanned!(span=> IsU64Compatible),\n                ReprKind::U128 => quote_spanned!(span=> IsU128Compatible),\n            };\n            quote_spanned!(span=>\n                impl #impl_generics ::core::convert::From<#prim> for #ident #ty_generics\n                where\n                    ::modular_bitfield::private::checks::BitCount<{#actual_bits}>: ::modular_bitfield::private::#trait_check_ident,\n                    #where_predicates\n                {\n                    #[inline]\n                    fn from(__bf_prim: #prim) -> Self {\n                        Self { bytes: <#prim>::to_le_bytes(__bf_prim) }\n                    }\n                }\n\n                impl #impl_generics ::core::convert::From<#ident #ty_generics> for #prim\n                where\n                    ::modular_bitfield::private::checks::BitCount<{#actual_bits}>: ::modular_bitfield::private::#trait_check_ident,\n                    #where_predicates\n                {\n                    #[inline]\n                    fn from(__bf_bitfield: #ident #ty_generics) -> Self {\n                        <Self>::from_le_bytes(__bf_bitfield.bytes)\n                    }\n                }\n            )\n        })\n    }\n\n    /// Generates routines to allow conversion from and to bytes for the `#[bitfield]` struct.\n    fn expand_byte_conversion_impls(&self, config: &Config) -> TokenStream2 {\n        let span = self.item_struct.span();\n        let ident = &self.item_struct.ident;\n        let (impl_generics, ty_generics, where_clause) = self.item_struct.generics.split_for_impl();\n        let size = self.generate_target_or_actual_bitfield_size(config);\n        let next_divisible_by_8 = Self::next_divisible_by_8(&size);\n        let bytes_ty = quote_spanned!(span=> [::core::primitive::u8; #next_divisible_by_8 / 8]);\n        let (from_bytes, from_impl) = if config.filled_enabled() {\n            (\n                quote_spanned!(span=>\n                    /// Converts the given bytes directly into the bitfield struct.\n                    #[inline]\n                    #[must_use]\n                    pub const fn from_bytes(bytes: #bytes_ty) -> Self {\n                        Self { bytes }\n                    }\n                ),\n                quote_spanned!(span=>\n                    impl #impl_generics ::core::convert::From<#bytes_ty> for #ident #ty_generics #where_clause {\n                        fn from(bytes: #bytes_ty) -> Self {\n                            Self::from_bytes(bytes)\n                        }\n                    }\n                ),\n            )\n        } else {\n            (\n                quote_spanned!(span=>\n                    /// Converts the given bytes directly into the bitfield struct.\n                    ///\n                    /// # Errors\n                    ///\n                    /// If the given bytes contain bits at positions that are undefined for `Self`.\n                    #[inline]\n                    pub fn from_bytes(\n                        bytes: #bytes_ty\n                    ) -> ::core::result::Result<Self, ::modular_bitfield::error::OutOfBounds> {\n                        #[allow(clippy::identity_op)]\n                        if ::core::primitive::u16::from(bytes[(#next_divisible_by_8 / 8) - 1]) < (1 << (8 - (#next_divisible_by_8 - (#size)))) {\n                            ::core::result::Result::Ok(Self { bytes })\n                        } else {\n                            ::core::result::Result::Err(::modular_bitfield::error::OutOfBounds)\n                        }\n                    }\n                ),\n                quote_spanned!(span=>\n                    impl #impl_generics ::core::convert::TryFrom<#bytes_ty> for #ident #ty_generics #where_clause {\n                        type Error = ::modular_bitfield::error::OutOfBounds;\n\n                        #[inline]\n                        fn try_from(bytes: #bytes_ty) -> ::core::result::Result<Self, Self::Error> {\n                            Self::from_bytes(bytes)\n                        }\n                    }\n                ),\n            )\n        };\n        quote_spanned!(span=>\n            #from_impl\n\n            impl #impl_generics ::core::convert::From<#ident #ty_generics> for #bytes_ty #where_clause {\n                #[inline]\n                fn from(bytes: #ident #ty_generics) -> Self {\n                    bytes.into_bytes()\n                }\n            }\n\n            impl #impl_generics #ident #ty_generics #where_clause {\n                /// Returns the underlying bits.\n                ///\n                /// # Layout\n                ///\n                /// The returned byte array is layed out in the same way as described\n                /// [here](https://docs.rs/modular-bitfield/#generated-structure).\n                #[inline]\n                pub const fn into_bytes(self) -> #bytes_ty {\n                    self.bytes\n                }\n\n                #from_bytes\n            }\n        )\n    }\n\n    /// Generates code to check for the bit size arguments of bitfields.\n    fn expand_bits_checks_for_field(field_info: FieldInfo<'_>) -> TokenStream2 {\n        let FieldInfo {\n            index: _,\n            field,\n            config,\n        } = field_info;\n        config.bits.as_ref().map(|bits| {\n            let ty = &field.ty;\n            let expected_bits = bits.value;\n            let expected_span = bits.span;\n            let actual_span = field.ty.span();\n            let actual_ty = quote_spanned!(actual_span=>\n                ::modular_bitfield::private::checks::BitCount<{<#ty as ::modular_bitfield::Specifier>::BITS}>\n            );\n            quote_spanned!(expected_span=>\n                let _: #actual_ty = ::modular_bitfield::private::checks::BitCount::<{#expected_bits}>;\n            )\n        }).unwrap_or_default()\n    }\n\n    fn expand_getters_for_field(\n        &self,\n        offset: &TokenStream2,\n        info: &FieldInfo<'_>,\n    ) -> Option<TokenStream2> {\n        let FieldInfo {\n            index: _,\n            field,\n            config,\n        } = info;\n        if config.skip_getters() {\n            return None;\n        }\n        let struct_ident = &self.item_struct.ident;\n        let span = field.span();\n        let ident = info.ident_frag();\n        let name = info.name();\n\n        let retained_attrs = &config.retained_attrs;\n        let get_ident = field\n            .ident\n            .clone()\n            .unwrap_or_else(|| format_ident!(\"get_{}\", ident));\n        let get_checked_ident = field.ident.as_ref().map_or_else(\n            || format_ident!(\"get_{}_or_err\", ident),\n            |_| format_ident!(\"{}_or_err\", ident),\n        );\n        let ty = &field.ty;\n        let vis = &field.vis;\n        let get_assert_msg =\n            format!(\"value contains invalid bit pattern for field {struct_ident}.{name}\");\n\n        let getter_docs = format!(\"Returns the value of `{name}`.\");\n        let checked_getter_docs = format!(\n            \"Returns the value of `{name}`.\\n\\n\\\n             # Errors\\n\\n\\\n             If the returned value contains an invalid bit pattern for `{name}`.\",\n        );\n        let getters = quote_spanned!(span=>\n            #[doc = #getter_docs]\n            #[inline]\n            #[must_use]\n            #( #retained_attrs )*\n            #vis fn #get_ident(&self) -> <#ty as ::modular_bitfield::Specifier>::InOut {\n                self.#get_checked_ident().expect(#get_assert_msg)\n            }\n\n            #[doc = #checked_getter_docs]\n            #[inline]\n            #[allow(dead_code)]\n            #( #retained_attrs )*\n            #vis fn #get_checked_ident(\n                &self,\n            ) -> ::core::result::Result<\n                <#ty as ::modular_bitfield::Specifier>::InOut,\n                ::modular_bitfield::error::InvalidBitPattern<<#ty as ::modular_bitfield::Specifier>::Bytes>\n            > {\n                let __bf_read: <#ty as ::modular_bitfield::Specifier>::Bytes = {\n                    ::modular_bitfield::private::read_specifier::<#ty>(&self.bytes[..], #offset)\n                };\n                <#ty as ::modular_bitfield::Specifier>::from_bytes(__bf_read)\n            }\n        );\n        Some(getters)\n    }\n\n    fn expand_setters_for_field(\n        &self,\n        offset: &TokenStream2,\n        info: &FieldInfo<'_>,\n    ) -> Option<TokenStream2> {\n        let FieldInfo {\n            index: _,\n            field,\n            config,\n        } = info;\n        if config.skip_setters() {\n            return None;\n        }\n        let struct_ident = &self.item_struct.ident;\n        let span = field.span();\n        let retained_attrs = &config.retained_attrs;\n\n        let ident = info.ident_frag();\n        let name = info.name();\n        let ty = &field.ty;\n        let vis = &field.vis;\n\n        let set_ident = format_ident!(\"set_{}\", ident);\n        let set_checked_ident = format_ident!(\"set_{}_checked\", ident);\n        let with_ident = format_ident!(\"with_{}\", ident);\n        let with_checked_ident = format_ident!(\"with_{}_checked\", ident);\n\n        let set_assert_msg = format!(\"value out of bounds for field {struct_ident}.{name}\");\n        let setter_docs = format!(\n            \"Sets the value of `{name}` to the given value.\\n\\n\\\n             # Panics\\n\\n\\\n             If the given value is out of bounds for `{name}`.\",\n        );\n        let checked_setter_docs = format!(\n            \"Sets the value of `{name}` to the given value.\\n\\n\\\n             # Errors\\n\\n\\\n             If the given value is out of bounds for `{name}`.\",\n        );\n        let with_docs = format!(\n            \"Returns a copy of the bitfield with the value of `{name}` \\\n             set to the given value.\\n\\n\\\n             # Panics\\n\\n\\\n             If the given value is out of bounds for `{name}`.\",\n        );\n        let checked_with_docs = format!(\n            \"Returns a copy of the bitfield with the value of `{name}` \\\n             set to the given value.\\n\\n\\\n             # Errors\\n\\n\\\n             If the given value is out of bounds for `{name}`.\",\n        );\n        let setters = quote_spanned!(span=>\n            #[doc = #with_docs]\n            #[inline]\n            #[allow(dead_code)]\n            #[must_use]\n            #( #retained_attrs )*\n            #vis fn #with_ident(\n                mut self,\n                new_val: <#ty as ::modular_bitfield::Specifier>::InOut\n            ) -> Self {\n                self.#set_ident(new_val);\n                self\n            }\n\n            #[doc = #checked_with_docs]\n            #[inline]\n            #[allow(dead_code)]\n            #( #retained_attrs )*\n            #vis fn #with_checked_ident(\n                mut self,\n                new_val: <#ty as ::modular_bitfield::Specifier>::InOut,\n            ) -> ::core::result::Result<Self, ::modular_bitfield::error::OutOfBounds> {\n                self.#set_checked_ident(new_val)?;\n                ::core::result::Result::Ok(self)\n            }\n\n            #[doc = #setter_docs]\n            #[inline]\n            #[allow(dead_code)]\n            #( #retained_attrs )*\n            #vis fn #set_ident(&mut self, new_val: <#ty as ::modular_bitfield::Specifier>::InOut) {\n                self.#set_checked_ident(new_val).expect(#set_assert_msg);\n            }\n\n            #[doc = #checked_setter_docs]\n            #[inline]\n            #( #retained_attrs )*\n            #vis fn #set_checked_ident(\n                &mut self,\n                new_val: <#ty as ::modular_bitfield::Specifier>::InOut\n            ) -> ::core::result::Result<(), ::modular_bitfield::error::OutOfBounds> {\n                const __BF_BASE_BITS: ::core::primitive::usize =\n                    ::core::mem::size_of::<<#ty as ::modular_bitfield::Specifier>::Bytes>() * 8;\n                const __BF_MAX_VALUE: <#ty as ::modular_bitfield::Specifier>::Bytes =\n                    !0 >> (__BF_BASE_BITS - <#ty as ::modular_bitfield::Specifier>::BITS);\n                let __bf_raw_val =\n                    <#ty as ::modular_bitfield::Specifier>::into_bytes(new_val)?;\n                // Value comparison to const guarantees the optimiser eliminates\n                // branching entirely when the maximum value is the same as the\n                // maximum value of the underlying type.\n                #[allow(clippy::absurd_extreme_comparisons)]\n                if __bf_raw_val <= __BF_MAX_VALUE {\n                    ::modular_bitfield::private::write_specifier::<#ty>(&mut self.bytes[..], #offset, __bf_raw_val);\n                    ::core::result::Result::Ok(())\n                } else {\n                    ::core::result::Result::Err(::modular_bitfield::error::OutOfBounds)\n                }\n            }\n        );\n        Some(setters)\n    }\n\n    fn expand_getters_and_setters_for_field(\n        &self,\n        offset: &mut Punctuated<syn::Expr, syn::Token![+]>,\n        info: &FieldInfo<'_>,\n    ) -> TokenStream2 {\n        let field = info.field;\n        let span = field.span();\n        let ty = &field.ty;\n        let offset_ts = if offset.is_empty() {\n            quote_spanned!(span=> 0)\n        } else {\n            offset.to_token_stream()\n        };\n        let getters = self.expand_getters_for_field(&offset_ts, info);\n        let setters = self.expand_setters_for_field(&offset_ts, info);\n        let getters_and_setters = quote_spanned!(span=>\n            #getters\n            #setters\n        );\n        offset.push(syn::parse_quote_spanned!(span=> <#ty as ::modular_bitfield::Specifier>::BITS));\n        getters_and_setters\n    }\n\n    fn expand_getters_and_setters(&self, config: &Config) -> TokenStream2 {\n        let span = self.item_struct.span();\n        let ident = &self.item_struct.ident;\n        let (impl_generics, ty_generics, where_clause) = self.item_struct.generics.split_for_impl();\n        let mut offset = Punctuated::<syn::Expr, Token![+]>::new();\n        let bits_checks = self\n            .field_infos(config)\n            .map(|field_info| Self::expand_bits_checks_for_field(field_info));\n        let setters_and_getters = self\n            .field_infos(config)\n            .map(|field_info| self.expand_getters_and_setters_for_field(&mut offset, &field_info));\n        quote_spanned!(span=>\n            const _: () = {\n                #( #bits_checks )*\n            };\n\n            impl #impl_generics #ident #ty_generics #where_clause {\n                #( #setters_and_getters )*\n            }\n        )\n    }\n}\n"
  },
  {
    "path": "impl/src/bitfield/field_config.rs",
    "content": "use super::{config::ConfigValue, raise_skip_error};\nuse crate::errors::CombineError;\nuse proc_macro2::Span;\n\n#[derive(Default, Clone)]\npub struct FieldConfig {\n    /// Attributes that are re-expanded and going to be ignored by the rest of the `#[bitfield]` invocation.\n    pub retained_attrs: Vec<syn::Attribute>,\n    /// An encountered `#[bits = N]` attribute on a field.\n    pub bits: Option<ConfigValue<usize>>,\n    /// An encountered `#[skip]` attribute on a field.\n    pub skip: Option<ConfigValue<SkipWhich>>,\n}\n\n/// Controls which parts of the code generation to skip.\n#[derive(PartialEq, Eq, Hash, Copy, Clone)]\npub enum SkipWhich {\n    /// Skip code generation of getters and setters.\n    All,\n    /// Skip code generation of only getters.\n    ///\n    /// For field `f` these include:\n    ///\n    /// - `f`\n    /// - `f_or_err`\n    Getters,\n    /// Skip code generation of only setters.\n    ///\n    /// For field `f` these include:\n    ///\n    /// - `set_f`\n    /// - `set_f_checked`\n    /// - `with_f`\n    /// - `with_f_checked`\n    Setters,\n}\n\nimpl SkipWhich {\n    /// Returns `true` if code generation of getters should be skipped.\n    pub fn skip_getters(self) -> bool {\n        matches!(self, Self::All | Self::Getters)\n    }\n\n    /// Returns `true` if code generation of setters should be skipped.\n    pub fn skip_setters(self) -> bool {\n        matches!(self, Self::All | Self::Setters)\n    }\n}\n\nimpl FieldConfig {\n    /// Registers the given attribute to be re-expanded and further ignored.\n    pub fn retain_attr(&mut self, attr: syn::Attribute) {\n        self.retained_attrs.push(attr);\n    }\n\n    /// Sets the `#[bits = N]` if found for a `#[bitfield]` annotated field.\n    ///\n    /// # Errors\n    ///\n    /// If previously already registered a `#[bits = N]`.\n    pub fn bits(&mut self, amount: usize, span: Span) -> Result<(), syn::Error> {\n        match self.bits {\n            Some(ref previous) => {\n                return Err(format_err!(\n                    span,\n                    \"encountered duplicate `#[bits = N]` attribute for field\"\n                )\n                .into_combine(format_err!(previous.span, \"duplicate `#[bits = N]` here\")))\n            }\n            None => {\n                self.bits = Some(ConfigValue {\n                    value: amount,\n                    span,\n                });\n            }\n        }\n        Ok(())\n    }\n\n    /// Sets the `#[skip(which)]` if found for a `#[bitfield]` annotated field.\n    ///\n    /// # Syntax\n    ///\n    /// - `#[skip]` defaults to `SkipWhich::All`.\n    /// - `#[skip(getters)]` is `SkipWhich::Getters`.\n    /// - `#[skip(setters)]` is `SkipWhich::Setters`.\n    /// - `#[skip(getters, setters)]` is the same as `#[skip]`.\n    /// - `#[skip(getters)] #[skip(setters)]` is the same as `#[skip]`.\n    ///\n    /// # Errors\n    ///\n    /// If previously already registered a `#[skip]` that overlaps with the previous.\n    /// E.g. when skipping getters or setters twice. Note that skipping getters followed\n    /// by skipping setters is fine.\n    pub fn skip(&mut self, which: SkipWhich, span: Span) -> Result<(), syn::Error> {\n        match self.skip {\n            Some(ref previous) => {\n                match which {\n                    SkipWhich::All => return raise_skip_error(\"\", span, previous.span),\n                    SkipWhich::Getters => {\n                        if previous.value == SkipWhich::Getters || previous.value == SkipWhich::All\n                        {\n                            return raise_skip_error(\"(getters)\", span, previous.span);\n                        }\n                    }\n                    SkipWhich::Setters => {\n                        if previous.value == SkipWhich::Setters || previous.value == SkipWhich::All\n                        {\n                            return raise_skip_error(\"(setters)\", span, previous.span);\n                        }\n                    }\n                }\n                self.skip = Some(ConfigValue {\n                    value: SkipWhich::All,\n                    span: span.join(previous.span).unwrap_or(span),\n                });\n            }\n            None => self.skip = Some(ConfigValue { value: which, span }),\n        }\n        Ok(())\n    }\n\n    /// Returns `true` if the config demands that code generation for setters should be skipped.\n    pub fn skip_setters(&self) -> bool {\n        self.skip\n            .as_ref()\n            .is_some_and(|config| SkipWhich::skip_setters(config.value))\n    }\n\n    /// Returns `true` if the config demands that code generation for getters should be skipped.\n    pub fn skip_getters(&self) -> bool {\n        self.skip\n            .as_ref()\n            .is_some_and(|config| SkipWhich::skip_getters(config.value))\n    }\n}\n"
  },
  {
    "path": "impl/src/bitfield/field_info.rs",
    "content": "use super::{field_config::FieldConfig, BitfieldStruct, Config};\n\n/// Compactly stores all shared and useful information about a single `#[bitfield]` field.\npub struct FieldInfo<'a> {\n    /// The index of the field.\n    pub index: usize,\n    /// The actual field.\n    pub field: &'a syn::Field,\n    /// The configuration of the field.\n    pub config: FieldConfig,\n}\n\nimpl<'a> FieldInfo<'a> {\n    /// Creates a new field info.\n    pub fn new(id: usize, field: &'a syn::Field, config: FieldConfig) -> Self {\n        Self {\n            index: id,\n            field,\n            config,\n        }\n    }\n\n    /// Returns the ident fragment for this field.\n    pub fn ident_frag(&self) -> &dyn quote::IdentFragment {\n        match &self.field.ident {\n            Some(ident) => ident,\n            None => &self.index,\n        }\n    }\n\n    /// Returns the field's identifier as `String`.\n    pub fn name(&self) -> String {\n        Self::ident_as_string(self.field, self.index)\n    }\n\n    /// Returns the field's identifier at the given index as `String`.\n    pub fn ident_as_string(field: &'a syn::Field, index: usize) -> String {\n        field\n            .ident\n            .as_ref()\n            .map_or_else(|| format!(\"{index}\"), ToString::to_string)\n    }\n}\n\nimpl BitfieldStruct {\n    /// Returns an iterator over the names of the fields.\n    ///\n    /// If a field has no name it is replaced by its field number.\n    pub fn fields(item_struct: &syn::ItemStruct) -> impl Iterator<Item = (usize, &syn::Field)> {\n        item_struct.fields.iter().enumerate()\n    }\n\n    /// Returns an iterator over the names of the fields.\n    ///\n    /// If a field has no name it is replaced by its field number.\n    pub fn field_infos<'a, 'b: 'a>(\n        &'a self,\n        config: &'b Config,\n    ) -> impl Iterator<Item = FieldInfo<'a>> {\n        Self::fields(&self.item_struct).map(move |(n, field)| {\n            let field_config = config\n                .field_configs\n                .get(&n)\n                .map(|config| &config.value)\n                .cloned()\n                .unwrap_or_default();\n            FieldInfo::new(n, field, field_config)\n        })\n    }\n}\n"
  },
  {
    "path": "impl/src/bitfield/mod.rs",
    "content": "mod analyse;\nmod config;\nmod expand;\nmod field_config;\nmod field_info;\nmod params;\n\nuse self::{config::Config, params::ParamArgs};\nuse core::convert::TryFrom;\nuse proc_macro2::{Span, TokenStream as TokenStream2};\nuse syn::{self, parse::Result};\n\n/// Analyzes the given token stream for `#[bitfield]` properties and expands code if valid.\npub fn analyse_and_expand(args: TokenStream2, input: TokenStream2) -> TokenStream2 {\n    match analyse_and_expand_or_error(args, input) {\n        Ok(output) => output,\n        Err(err) => err.to_compile_error(),\n    }\n}\n\n/// Analyzes the given token stream for `#[bitfield]` properties and expands code if valid.\n///\n/// # Errors\n///\n/// If the given token stream does not yield a valid `#[bitfield]` specifier.\nfn analyse_and_expand_or_error(args: TokenStream2, input: TokenStream2) -> Result<TokenStream2> {\n    let input = syn::parse2::<syn::ItemStruct>(input)?;\n    let params = syn::parse2::<ParamArgs>(args)?;\n    let mut config = Config::default();\n    config.feed_params(params)?;\n    let bitfield = BitfieldStruct::try_from((&mut config, input))?;\n    Ok(bitfield.expand(&config))\n}\n\n/// Type used to guide analysis and expansion of `#[bitfield]` structs.\nstruct BitfieldStruct {\n    /// The input `struct` item.\n    item_struct: syn::ItemStruct,\n}\n\nfn raise_skip_error(skip_params: &str, span: Span, previous: Span) -> Result<()> {\n    Err(crate::errors::CombineError::into_combine(\n        format_err!(\n            span,\n            \"encountered duplicate `#[skip{}]` attribute for field\",\n            skip_params\n        ),\n        format_err!(previous, \"duplicate `#[skip{}]` here\", skip_params),\n    ))\n}\n"
  },
  {
    "path": "impl/src/bitfield/params.rs",
    "content": "use super::config::Config;\nuse proc_macro2::Span;\nuse syn::{parse::Result, spanned::Spanned};\n\n/// The parameters given to the `#[bitfield]` proc. macro.\npub struct ParamArgs {\n    args: Vec<syn::MetaNameValue>,\n}\n\nimpl syn::parse::Parse for ParamArgs {\n    fn parse(input: syn::parse::ParseStream<'_>) -> Result<Self> {\n        let punctuated = <syn::punctuated::Punctuated<_, syn::Token![,]>>::parse_terminated(input)?;\n        Ok(Self {\n            args: punctuated.into_iter().collect(),\n        })\n    }\n}\n\nimpl IntoIterator for ParamArgs {\n    type Item = syn::MetaNameValue;\n    type IntoIter = std::vec::IntoIter<syn::MetaNameValue>;\n\n    fn into_iter(self) -> Self::IntoIter {\n        self.args.into_iter()\n    }\n}\n\nimpl Config {\n    /// Feeds a parameter that takes an integer value to the `#[bitfield]` configuration.\n    fn feed_int_param<F>(name_value: &syn::MetaNameValue, name: &str, on_success: F) -> Result<()>\n    where\n        F: FnOnce(usize, Span) -> Result<()>,\n    {\n        assert!(name_value.path.is_ident(name));\n        match &name_value.value {\n            syn::Expr::Lit(syn::ExprLit {\n                lit: syn::Lit::Int(lit_int),\n                ..\n            }) => {\n                let span = lit_int.span();\n                let value = lit_int.base10_parse::<usize>().map_err(|err| {\n                    format_err!(\n                        span,\n                        \"encountered malformatted integer value for `{}` parameter: {}\",\n                        name,\n                        err\n                    )\n                })?;\n                on_success(value, name_value.span())?;\n            }\n            invalid => {\n                return Err(format_err!(\n                    invalid,\n                    \"encountered invalid value argument for #[bitfield] `{}` parameter\",\n                    name\n                ))\n            }\n        }\n        Ok(())\n    }\n\n    /// Feeds a `bytes: int` parameter to the `#[bitfield]` configuration.\n    fn feed_bytes_param(&mut self, name_value: &syn::MetaNameValue) -> Result<()> {\n        Self::feed_int_param(name_value, \"bytes\", |value, span| self.bytes(value, span))\n    }\n\n    /// Feeds a `bytes: int` parameter to the `#[bitfield]` configuration.\n    fn feed_bits_param(&mut self, name_value: &syn::MetaNameValue) -> Result<()> {\n        Self::feed_int_param(name_value, \"bits\", |value, span| self.bits(value, span))\n    }\n\n    /// Feeds a `filled: bool` parameter to the `#[bitfield]` configuration.\n    fn feed_filled_param(&mut self, name_value: &syn::MetaNameValue) -> Result<()> {\n        assert!(name_value.path.is_ident(\"filled\"));\n        match &name_value.value {\n            syn::Expr::Lit(syn::ExprLit {\n                lit: syn::Lit::Bool(lit_bool),\n                ..\n            }) => {\n                self.filled(lit_bool.value, name_value.span())?;\n            }\n            invalid => {\n                return Err(format_err!(\n                    invalid,\n                    \"encountered invalid value argument for #[bitfield] `filled` parameter\",\n                ))\n            }\n        }\n        Ok(())\n    }\n\n    /// Feeds the given parameters to the `#[bitfield]` configuration.\n    ///\n    /// # Errors\n    ///\n    /// If a parameter is malformatted, unexpected, duplicate or in conflict.\n    pub fn feed_params<'a, P>(&mut self, params: P) -> Result<()>\n    where\n        P: IntoIterator<Item = syn::MetaNameValue> + 'a,\n    {\n        for name_value in params {\n            if name_value.path.is_ident(\"bytes\") {\n                self.feed_bytes_param(&name_value)?;\n            } else if name_value.path.is_ident(\"bits\") {\n                self.feed_bits_param(&name_value)?;\n            } else if name_value.path.is_ident(\"filled\") {\n                self.feed_filled_param(&name_value)?;\n            } else {\n                return Err(format_err!(\n                    name_value,\n                    \"encountered unsupported #[bitfield] attribute\"\n                ));\n            }\n        }\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "impl/src/bitfield_specifier.rs",
    "content": "use proc_macro2::TokenStream as TokenStream2;\nuse quote::quote_spanned;\nuse syn::spanned::Spanned as _;\n\npub fn generate(input: TokenStream2) -> TokenStream2 {\n    match generate_or_error(input) {\n        Ok(output) => output,\n        Err(err) => err.to_compile_error(),\n    }\n}\n\nfn generate_or_error(input: TokenStream2) -> syn::Result<TokenStream2> {\n    let input = syn::parse2::<syn::DeriveInput>(input)?;\n    match input.data {\n        syn::Data::Enum(data_enum) => generate_enum(&syn::ItemEnum {\n            attrs: input.attrs,\n            vis: input.vis,\n            enum_token: data_enum.enum_token,\n            ident: input.ident,\n            generics: input.generics,\n            brace_token: data_enum.brace_token,\n            variants: data_enum.variants,\n        }),\n        syn::Data::Struct(_) => Err(format_err!(\n            input,\n            \"structs are not supported as bitfield specifiers\",\n        )),\n        syn::Data::Union(_) => Err(format_err!(\n            input,\n            \"unions are not supported as bitfield specifiers\",\n        )),\n    }\n}\nstruct Attributes {\n    bits: Option<usize>,\n}\n\nfn parse_attrs(attrs: &[syn::Attribute]) -> syn::Result<Attributes> {\n    let attributes = attrs\n        .iter()\n        .filter(|attr| attr.path().is_ident(\"bits\"))\n        .try_fold(Attributes { bits: None }, |mut acc, attr| {\n            if acc.bits.is_some() {\n                return Err(format_err_spanned!(\n                    attr,\n                    \"More than one 'bits' attribute is not permitted\",\n                ));\n            }\n            let meta = attr.meta.require_name_value()?;\n            acc.bits = if let syn::Expr::Lit(syn::ExprLit {\n                lit: syn::Lit::Int(lit),\n                ..\n            }) = &meta.value\n            {\n                Some(lit.base10_parse::<usize>()?)\n            } else {\n                return Err(format_err_spanned!(\n                    attr,\n                    \"could not parse 'bits' attribute\",\n                ));\n            };\n            Ok(acc)\n        })?;\n    Ok(attributes)\n}\n\nfn generate_enum(input: &syn::ItemEnum) -> syn::Result<TokenStream2> {\n    let span = input.span();\n    let attributes = parse_attrs(&input.attrs)?;\n    let enum_ident = &input.ident;\n    let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();\n\n    let bits = if let Some(bits) = attributes.bits {\n        bits\n    } else {\n        let count_variants = input.variants.iter().count();\n        if !count_variants.is_power_of_two() {\n            return Err(format_err!(\n                span,\n                \"#[derive(Specifier)] expected a number of variants which is a power of 2, specify #[bits = {}] if that was your intent\",\n                count_variants.next_power_of_two().trailing_zeros(),\n            ));\n        }\n        // We can take `trailing_zeros` returns type as the required amount of bits.\n        if let Some(power_of_two) = count_variants.checked_next_power_of_two() {\n            power_of_two.trailing_zeros() as usize\n        } else {\n            return Err(format_err!(\n                span,\n                \"#[derive(Specifier)] has too many variants to pack into a bitfield\",\n            ));\n        }\n    };\n\n    let variants = input\n        .variants\n        .iter()\n        .filter_map(|variant| match &variant.fields {\n            syn::Fields::Unit => Some(&variant.ident),\n            _ => None,\n        })\n        .collect::<Vec<_>>();\n\n    let check_discriminants = variants.iter().map(|ident| {\n        let span = ident.span();\n        quote_spanned!(span=>\n            impl #impl_generics ::modular_bitfield::private::checks::CheckDiscriminantInRange<\n                ::modular_bitfield::private::checks::BitCount<{Self::#ident as ::core::primitive::usize}>\n            > for #enum_ident #ty_generics #where_clause {\n                type CheckType = ::modular_bitfield::private::checks::BitCount<{\n                    ((Self::#ident as ::core::primitive::usize) < (1 << #bits)) as ::core::primitive::usize\n                }>;\n            }\n        )\n    });\n    let from_bytes_arms = variants.iter().map(|ident| {\n        let span = ident.span();\n        quote_spanned!(span=>\n            __bitfield_binding if __bitfield_binding == Self::#ident as <Self as ::modular_bitfield::Specifier>::Bytes => {\n                ::core::result::Result::Ok(Self::#ident)\n            }\n        )\n    });\n\n    Ok(quote_spanned!(span=>\n        #( #check_discriminants )*\n\n        impl #impl_generics ::modular_bitfield::Specifier for #enum_ident #ty_generics #where_clause {\n            const BITS: ::core::primitive::usize = #bits;\n            type Bytes = <::modular_bitfield::private::checks::BitCount<#bits> as ::modular_bitfield::private::SpecifierBytes>::Bytes;\n            type InOut = Self;\n\n            #[inline]\n            fn into_bytes(input: <Self as ::modular_bitfield::Specifier>::InOut) -> ::core::result::Result<<Self as ::modular_bitfield::Specifier>::Bytes, ::modular_bitfield::error::OutOfBounds> {\n                ::core::result::Result::Ok(input as <Self as ::modular_bitfield::Specifier>::Bytes)\n            }\n\n            #[inline]\n            fn from_bytes(bytes: <Self as ::modular_bitfield::Specifier>::Bytes) -> ::core::result::Result<<Self as ::modular_bitfield::Specifier>::InOut, ::modular_bitfield::error::InvalidBitPattern<<Self as ::modular_bitfield::Specifier>::Bytes>> {\n                match bytes {\n                    #( #from_bytes_arms ),*\n                    invalid_bytes => {\n                        ::core::result::Result::Err(\n                            <::modular_bitfield::error::InvalidBitPattern<<Self as ::modular_bitfield::Specifier>::Bytes>>::new(invalid_bytes)\n                        )\n                    }\n                }\n            }\n        }\n    ))\n}\n"
  },
  {
    "path": "impl/src/define_specifiers.rs",
    "content": "use proc_macro2::TokenStream as TokenStream2;\nuse quote::{format_ident, quote};\n\npub fn generate(_input: TokenStream2) -> TokenStream2 {\n    let specifiers = (1..=128).map(generate_specifier_for);\n    quote! {\n        #( #specifiers )*\n    }\n}\n\nfn generate_specifier_for(bits: usize) -> TokenStream2 {\n    let in_out = match bits {\n        1..=8 => quote! { ::core::primitive::u8 },\n        9..=16 => quote! { ::core::primitive::u16 },\n        17..=32 => quote! { ::core::primitive::u32 },\n        33..=64 => quote! { ::core::primitive::u64 },\n        65..=128 => quote! { ::core::primitive::u128 },\n        _ => unreachable!(),\n    };\n    let ident = format_ident!(\"B{bits}\");\n    let doc_comment = if bits == 1 {\n        \"Specifier for a single bit.\".to_string()\n    } else {\n        format!(\"Specifier for {bits} bits.\")\n    };\n    let max_value = if bits.is_power_of_two() && bits >= 8 {\n        // The compiler can eliminate a check against `x > MAX` entirely\n        // so this will yield a no-op in release mode builds.\n        quote! {{ <#in_out>::MAX }}\n    } else {\n        quote! {{ ((1 as #in_out) << #bits) - 1 }}\n    };\n    quote! {\n        #[doc = #doc_comment]\n        #[derive(Copy, Clone)]\n        pub enum #ident {}\n\n        impl crate::Specifier for #ident {\n            const BITS: usize = #bits;\n            type Bytes = #in_out;\n            type InOut = #in_out;\n\n            #[inline]\n            fn into_bytes(input: Self::InOut) -> Result<Self::Bytes, crate::OutOfBounds> {\n                if input <= #max_value {\n                    Ok(input)\n                } else {\n                    Err(crate::OutOfBounds)\n                }\n            }\n\n            #[inline]\n            fn from_bytes(bytes: Self::Bytes) -> Result<Self::InOut, crate::InvalidBitPattern<Self::Bytes>> {\n                if bytes <= #max_value {\n                    Ok(bytes)\n                } else {\n                    Err(crate::InvalidBitPattern::new(bytes))\n                }\n            }\n        }\n\n        impl crate::private::SpecifierBytes for crate::private::checks::BitCount<#bits> {\n            type Bytes = #in_out;\n        }\n        impl crate::private::checks::private::Sealed for crate::private::checks::BitCount<#bits> {}\n    }\n}\n"
  },
  {
    "path": "impl/src/errors.rs",
    "content": "/// Creates a [`syn::Error`] with the format message and infers the\n/// [`Span`](`proc_macro2::Span`) using [`ToTokens`](`quote::ToTokens`).\n///\n/// # Parameters\n///\n/// - The first argument must implement [`quote::ToTokens`] in order to\n///   infer a [`Span`](`proc_macro2::Span`).\n/// - The second argument is a format string.\n/// - The rest are format string arguments.\n///\n/// # Note\n///\n/// On stable Rust this might yield higher quality error span information to the user\n/// than [`format_err`].\n/// - Source:\n///   [`syn::Error::new_spanned`](https://docs.rs/syn/1.0.33/syn/struct.Error.html#method.new_spanned)\n/// - Tracking issue: [`#54725`](https://github.com/rust-lang/rust/issues/54725)\nmacro_rules! format_err_spanned {\n    ( $tokens:expr, $($msg:tt)* ) => {{\n        ::syn::Error::new_spanned(\n            &$tokens,\n            format_args!($($msg)*)\n        )\n    }}\n}\n\n/// Creates a [`syn::Error`] with the format message and infers the\n/// [`Span`](`proc_macro2::Span`) using [`Spanned`](`syn::spanned::Spanned`).\n///\n/// # Parameters\n///\n/// - The first argument must be a type that implements [`syn::spanned::Spanned`].\n/// - The second argument is a format string.\n/// - The rest are format string arguments.\n///\n/// # Note\n///\n/// On stable Rust this might yield worse error span information to the user\n/// than [`format_err_spanned`].\n/// - Source:\n///   [`syn::Error::new_spanned`](https://docs.rs/syn/1.0.33/syn/struct.Error.html#method.new_spanned)\n/// - Tracking issue: [`#54725`](https://github.com/rust-lang/rust/issues/54725)\nmacro_rules! format_err {\n    ( $spanned:expr, $($msg:tt)* ) => {{\n        ::syn::Error::new(\n            <_ as ::syn::spanned::Spanned>::span(&$spanned),\n            format_args!($($msg)*)\n        )\n    }}\n}\n\npub trait CombineError {\n    /// Combines `self` with the given `another` error and returns back combined `self`.\n    fn into_combine(self, another: syn::Error) -> Self;\n}\n\nimpl CombineError for syn::Error {\n    fn into_combine(mut self, another: syn::Error) -> Self {\n        self.combine(another);\n        self\n    }\n}\n"
  },
  {
    "path": "impl/src/lib.rs",
    "content": "#![recursion_limit = \"256\"]\n#![forbid(unsafe_code)]\n#![warn(clippy::pedantic, rust_2018_idioms)]\n\n#[macro_use]\nmod errors;\nmod bitfield;\nmod bitfield_specifier;\nmod define_specifiers;\n\nuse proc_macro::TokenStream;\n\n/// Generates the `B1`, `B2`, ..., `B128` bitfield specifiers.\n///\n/// Only of use witihn the `modular_bitfield` crate itself.\n#[proc_macro]\npub fn define_specifiers(input: TokenStream) -> TokenStream {\n    define_specifiers::generate(input.into()).into()\n}\n\n#[proc_macro_attribute]\npub fn bitfield(args: TokenStream, input: TokenStream) -> TokenStream {\n    bitfield::analyse_and_expand(args.into(), input.into()).into()\n}\n\n#[proc_macro_derive(Specifier, attributes(bits))]\npub fn specifier(input: TokenStream) -> TokenStream {\n    bitfield_specifier::generate(input.into()).into()\n}\n\n#[cfg(coverage)]\n#[test]\nfn ui_code_coverage() {\n    use runtime_macros::{emulate_attributelike_macro_expansion, emulate_derive_macro_expansion};\n    use std::fs::File;\n\n    let mut run_success = true;\n    for entry in glob::glob(\"../tests/ui/**/*.rs\").unwrap() {\n        let entry = entry.unwrap();\n        run_success &= emulate_attributelike_macro_expansion(\n            File::open(entry.as_path()).unwrap(),\n            &[(\"bitfield\", bitfield::analyse_and_expand)],\n        )\n        .is_ok();\n        run_success &= emulate_derive_macro_expansion(\n            File::open(entry.as_path()).unwrap(),\n            &[(\"Specifier\", bitfield_specifier::generate)],\n        )\n        .is_ok();\n    }\n\n    assert!(run_success);\n}\n"
  },
  {
    "path": "release.sh",
    "content": "#!/usr/bin/env bash\n\nset -ueo pipefail\n\nDEFAULT_REPO=modular-bitfield/modular-bitfield\nDEFAULT_BRANCH=master\n\nusage() {\n\techo \"Usage: $0 [branch] [version]\"\n\techo\n\techo \"Specifying a branch will create a new patch release from that branch.\"\n\techo \"Otherwise, a new release will be created from '$DEFAULT_BRANCH'.\"\n\techo\n\techo \"Specifying a version will create a release with that specific version.\"\n\techo \"Otherwise, the version number for the release will be adapted from\"\n\techo \"Cargo.toml.\"\n\techo\n\techo \"After tagging, the version number in Cargo.toml will automatically be\"\n\techo \"bumped unless a pre-release version number was passed explicitly to\"\n\techo \"this script, in which case the version number in Cargo.toml will be\"\n\techo \"restored.\"\n\techo\n\techo \"If the version number for the new release ends in .0, a new minor\"\n\techo \"release branch will also be created.\"\n\techo\n\techo \"Supported environment variables:\"\n\techo \"  REPO: The GitHub repository (user/repo) to use for the release.\"\n\techo \"        Defaults to $DEFAULT_REPO.\"\n\texit 0\n}\n\nset_package_publish() {\n\tsed -i'' -e \"s/^\\\\(publish[[:space:]]*=[[:space:]]*\\\\).*$/\\\\1$1/\" Cargo.toml\n}\n\nset_package_version() {\n\tsed -i'' -e \"s/^\\\\(version[[:space:]]*=[[:space:]]*\\\\)\\\"[^\\\"]*\\\"/\\\\1\\\"$1\\\"/\" Cargo.toml\n\tsed -i'' -e \"s/^\\\\(modular-bitfield-impl[[:space:]]*=.*version[[:space:]]*=[[:space:]]*\\\\)\\\"[^\\\"]*\\\"/\\\\1\\\"$1\\\"/\" Cargo.toml\n}\n\nif [ \"${1-}\" == \"--help\" ]; then\n\tusage\nelif [ -n \"${1-}\" ]; then\n\tBRANCH=$1\nelse\n\tBRANCH=$DEFAULT_BRANCH\nfi\n\nif [ -n \"${2-}\" ]; then\n\tVERSION=$2\n\tif [[ ! \"$VERSION\" =~ ^[0-9]+\\.[0-9]+\\.[0-9]+(-.*)?$ ]]; then\n\t\techo \"Invalid version '$VERSION'; versions must be in the form\"\n\t\techo \"\\`major.minor.patch[-extra]\\`.\"\n\t\texit 1\n\tfi\nelse\n\tVERSION=\nfi\n\nREPO=${REPO:-$DEFAULT_REPO}\nROOT_DIR=$(cd \"$(dirname \"$0\")\" && pwd)\nBUILD_DIR=\"$ROOT_DIR/build-release\"\n\nif [ -d \"$BUILD_DIR\" ]; then\n\techo \"Existing build directory detected at $BUILD_DIR\"\n\techo \"Aborted.\"\n\texit 1\nfi\n\necho \"This is an internal modular-bitfield release script!\"\necho -n \"Press 'y' to create a new modular-bitfield release from $REPO branch $BRANCH\"\nif [ -z \"$VERSION\" ]; then\n\techo \".\"\nelse\n\techo -e \"\\nwith version override $VERSION.\"\nfi\necho \"(You can abort pushing upstream later on if something goes wrong.)\"\nread -r -s -n 1\n\nif [ \"$REPLY\" != \"y\" ]; then\n\techo \"Aborted.\"\n\texit 0\nfi\n\n# Using a pristine copy of the repo for the release to avoid local changes\n# making their way into the release process, and to avoid polluting the local\n# repo with wrong changes if the release process is aborted\ncd \"$ROOT_DIR\"\nmkdir \"$BUILD_DIR\"\ngit clone --recursive \"git@github.com:$REPO\" \"$BUILD_DIR\"\n\ncd \"$BUILD_DIR\"\n\n# Newly created tags and updated branches are stored so they can be pushed all\n# at once at the end after the other work is guaranteed to be successful\nPUSH_BRANCHES=\"$BRANCH\"\n\necho -e \"\\nBuilding $BRANCH branch...\\n\"\n\ngit checkout \"$BRANCH\"\n\n# head is needed in case the version number was manually updated to something\n# which has a tag with a number in it, otherwise there will be multiple matches\n# on the line instead of just the first one\nVERSION_CARGO_NO_TAGS=$(grep -o '^version[[:space:]]*=[[:space:]]*\"[^\"]*\"' Cargo.toml | grep -o \"[0-9][0-9.]*\" | head -1)\n\nif [ -z \"$VERSION\" ]; then\n\tVERSION=$VERSION_CARGO_NO_TAGS\n\tVERSION_NO_TAGS=$VERSION_CARGO_NO_TAGS\nelse\n\tVERSION_NO_TAGS=$(echo \"$VERSION\" | grep -o \"[0-9][0-9.]*\")\nfi\n\n# Converting the version number to an array to auto-generate the next\n# release version number\nIFS=\".\" read -r -a PRE_VERSION_SPLIT <<< \"$VERSION_NO_TAGS\"\n\nif [[ \"$VERSION\" =~ ^[0-9][0-9.]*\\.0$ ]]; then\n\t# Minor release gets a branch\n\tMAKE_BRANCH=\"${PRE_VERSION_SPLIT[0]}.${PRE_VERSION_SPLIT[1]}\"\n\tBRANCH_VERSION=\"${PRE_VERSION_SPLIT[0]}.${PRE_VERSION_SPLIT[1]}.$((PRE_VERSION_SPLIT[2] + 1))-pre\"\n\n\t# The next release is usually going to be a minor release; if the next\n\t# version is to be a major release, the package version in Git will need\n\t# to be manually updated or someone will have to pass a major version number\n\t# to the release script at the last second\n\tPRE_VERSION=\"${PRE_VERSION_SPLIT[0]}.$((PRE_VERSION_SPLIT[1] + 1)).0-pre\"\nelse\n\t# Patch releases do not get branches\n\tMAKE_BRANCH=\n\tBRANCH_VERSION=\n\n\tif [[ \"$VERSION\" == \"$VERSION_NO_TAGS\" ]]; then\n\t\t# The next release version will always be another patch version\n\t\tPRE_VERSION=\"${PRE_VERSION_SPLIT[0]}.${PRE_VERSION_SPLIT[1]}.$((PRE_VERSION_SPLIT[2] + 1))-pre\"\n\telse\n\t\t# The version being released is a pre-release, so do not bump anything\n\t\tPRE_VERSION=\"$VERSION_CARGO_NO_TAGS-pre\"\n\tfi\nfi\n\nTAG_VERSION=\"v$VERSION\"\n\n# At this point:\n# $VERSION is the version of modular-bitfield that is being released\n# $TAG_VERSION is the name that will be used for the Git tag for the release\n# $PRE_VERSION is the next pre-release version of modular-bitfield that will be\n# set on the original branch after tagging\n# $MAKE_BRANCH is the name of the new minor release branch that should be\n# created (if this is not a patch release)\n# $BRANCH_VERSION is the pre-release version of modular-bitfield that will be\n# set on the minor release branch\n\n# Something is messed up and this release has already happened\nif [ \"$(git tag | grep -c \"^$TAG_VERSION$\")\" -gt 0 ]; then\n\techo -e \"\\nTag $TAG_VERSION already exists! Please check the branch.\\n\"\n\texit 1\nfi\n\nset_package_version \"$VERSION\"\nset_package_publish \"true\"\n\ngit commit -m \"Updating metadata for $VERSION\" -m \"[ci skip]\" Cargo.toml\ngit tag -s -m \"Release $VERSION\" \"$TAG_VERSION\"\n\nset_package_version \"$PRE_VERSION\"\nset_package_publish \"false # Use \\`release.sh\\`\"\n\ngit commit -m \"Updating source version to $PRE_VERSION\" -m \"[ci skip]\" Cargo.toml\n\nif [ \"$MAKE_BRANCH\" != \"\" ]; then\n\tgit checkout -b \"$MAKE_BRANCH\" \"$TAG_VERSION\"\n\tset_package_version \"$BRANCH_VERSION\"\n\tset_package_publish \"false # Use \\`release.sh\\`\"\n\n\tgit commit -m \"Updating source version to $BRANCH_VERSION\" -m \"[ci skip]\" Cargo.toml\n\tPUSH_BRANCHES=\"$PUSH_BRANCHES $MAKE_BRANCH\"\n\tPUSH_BRANCHES_MSG=\" and branches ${PUSH_BRANCHES}\"\nfi\n\necho -e \"\\nDone!\\n\"\necho \"Please confirm packaging success, then press 'y', ENTER to push\"\necho \"tags $TAG_VERSION${PUSH_BRANCHES_MSG:-}, or any other key to bail.\"\nread -r -p \"> \"\n\nif [ \"$REPLY\" != \"y\" ]; then\n\techo \"Aborted.\"\n\texit 0\nfi\n\nfor BRANCH in $PUSH_BRANCHES; do\n\tgit push origin \"$BRANCH\"\ndone\n\ngit push origin --tags\ngit checkout \"$TAG_VERSION\"\ncargo publish -p modular-bitfield-impl\ncargo publish -p modular-bitfield\n\ncd \"$ROOT_DIR\"\nrm -rf \"$BUILD_DIR\"\n\necho -e \"\\nAll done! Yay!\"\n"
  },
  {
    "path": "src/error.rs",
    "content": "//! Errors that can occur while operating on modular bitfields.\n\nuse core::fmt::Debug;\n\n/// The given value was out of range for the bitfield.\n#[derive(Clone, Copy, Debug, PartialEq, Eq)]\npub struct OutOfBounds;\n\nimpl core::fmt::Display for OutOfBounds {\n    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {\n        write!(f, \"encountered an out of bounds value\")\n    }\n}\n\n/// The bitfield contained an invalid bit pattern.\n#[derive(Clone, Copy, Debug, PartialEq, Eq)]\npub struct InvalidBitPattern<Bytes> {\n    /// The invalid bits.\n    invalid_bytes: Bytes,\n}\n\nimpl<Bytes> core::fmt::Display for InvalidBitPattern<Bytes>\nwhere\n    Bytes: Debug,\n{\n    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {\n        write!(\n            f,\n            \"encountered an invalid bit pattern: 0x{:X?}\",\n            self.invalid_bytes\n        )\n    }\n}\n\nimpl<Bytes> InvalidBitPattern<Bytes> {\n    /// Creates a new invalid bit pattern error.\n    #[inline]\n    pub fn new(invalid_bytes: Bytes) -> Self {\n        Self { invalid_bytes }\n    }\n\n    /// Returns the invalid bit pattern.\n    #[inline]\n    pub fn invalid_bytes(self) -> Bytes {\n        self.invalid_bytes\n    }\n}\n"
  },
  {
    "path": "src/lib.rs",
    "content": "#![doc = include_str!(\"../docs/index.md\")]\n#![no_std]\n#![forbid(unsafe_code)]\n#![warn(clippy::pedantic, missing_docs, rust_2018_idioms)]\n\npub mod error;\n#[doc(hidden)]\npub mod private;\n\nuse self::error::{InvalidBitPattern, OutOfBounds};\n\n#[doc = include_str!(\"../docs/bitfield.md\")]\npub use modular_bitfield_impl::bitfield;\n\n#[doc = include_str!(\"../docs/bitfield_specifier.md\")]\npub use modular_bitfield_impl::Specifier;\n\n/// The prelude: `use modular_bitfield::prelude::*;`\npub mod prelude {\n    pub use super::{bitfield, specifiers::*, Specifier};\n}\n\n/// The `Specifier` trait describes a sequence of bits stored in an integer\n/// primitive (the [`Bytes`](Self::Bytes) type) and how to convert them to/from\n/// a more convenient higher-level interface type (the [`InOut`](Self::InOut)\n/// type).\n///\n/// For example:\n///\n/// * The specifier for `bool` converts between a `u8` with a 1 or 0 bit in\n///   the lowest bit position and a native `bool`.\n/// * The specifier for a unit enum with variants `{0, 1, 14}` converts\n///   between a `u16` matching those variants and the enum type.\n/// * The specifier for a 20-bit struct converts between a `u32` and the\n///   struct type.\n///\n/// All types used in a `#[bitfield]` struct must implement this trait, and it\n/// should usually only be implemented with\n/// [`#[derive(Specifier)]`](macro@crate::Specifier).\npub trait Specifier {\n    /// The number of bits used by the `Specifier`.\n    const BITS: usize;\n\n    /// The storage type. This is typically the smallest integer primitive that\n    /// can store all possible values of the [`InOut`](Self::InOut) type.\n    type Bytes;\n\n    /// The interface type. This type is used by getters and setters. For\n    /// integers, this is the same as the [`Bytes`](Self::Bytes) type; for other\n    /// types with more logical representations, like an enum or struct, this is\n    /// the enum or struct.\n    type InOut;\n\n    /// Converts an interface type into its storage type.\n    ///\n    /// # Errors\n    ///\n    /// If the input value is out of bounds, an error will be returned. For\n    /// example, the value `b100_u8` cannot be converted with `B2` because it is\n    /// three bits wide.\n    fn into_bytes(input: Self::InOut) -> Result<Self::Bytes, OutOfBounds>;\n\n    /// Converts a storage type into its interface type.\n    ///\n    /// # Errors\n    ///\n    /// If the given bit pattern is invalid for the interface type, an error\n    /// will be returned. For example, `3_u8` cannot be converted to an enum\n    /// which only has variants `{0, 1, 2}`.\n    fn from_bytes(bytes: Self::Bytes) -> Result<Self::InOut, InvalidBitPattern<Self::Bytes>>;\n}\n\n/// The default set of predefined specifiers.\npub mod specifiers {\n    ::modular_bitfield_impl::define_specifiers!();\n}\n"
  },
  {
    "path": "src/private/array_bytes_conv.rs",
    "content": "use crate::private::{checks::BitCount, SpecifierBytes};\n\npub trait ArrayBytesConversion {\n    type Array;\n    type Bytes;\n\n    fn bytes_into_array(bytes: Self::Bytes) -> Self::Array;\n    fn array_into_bytes(bytes: Self::Array) -> Self::Bytes;\n}\n\nmacro_rules! impl_array_bytes_conversion_for_prim {\n    ( $( $prim:ty ),* ) => {\n        $(\n            impl ArrayBytesConversion for BitCount<{::core::mem::size_of::<$prim>() * 8}> {\n                type Array = [u8; ::core::mem::size_of::<$prim>()];\n                type Bytes = <Self as SpecifierBytes>::Bytes;\n\n                fn bytes_into_array(bytes: Self::Bytes) -> Self::Array {\n                    bytes.to_le_bytes()\n                }\n\n                fn array_into_bytes(bytes: Self::Array) -> Self::Bytes {\n                    <BitCount<{::core::mem::size_of::<$prim>() * 8}> as SpecifierBytes>::Bytes::from_le_bytes(bytes)\n                }\n            }\n        )*\n    };\n}\nimpl_array_bytes_conversion_for_prim!(u8, u16, u32, u64, u128);\n\nmacro_rules! impl_array_bytes_conversion_for_size {\n    ( $( $size:literal ),* ) => {\n        $(\n            impl ArrayBytesConversion for BitCount<$size> {\n                type Array = [u8; $size / 8];\n                type Bytes = <Self as SpecifierBytes>::Bytes;\n\n                #[inline]\n                fn bytes_into_array(bytes: Self::Bytes) -> Self::Array {\n                    let array = bytes.to_le_bytes();\n                    debug_assert!(array[($size / 8)..].iter().all(|&byte| byte == 0));\n                    let mut result = <Self::Array>::default();\n                    result.copy_from_slice(&array[0..($size / 8)]);\n                    result\n                }\n\n                #[inline]\n                fn array_into_bytes(bytes: Self::Array) -> Self::Bytes {\n                    let array: Self::Array = bytes;\n                    let mut result = [0; ::core::mem::size_of::<Self::Bytes>()];\n                    result[0..($size / 8)].copy_from_slice(&array[..]);\n                    <Self::Bytes>::from_le_bytes(result)\n                }\n            }\n        )*\n    };\n}\nimpl_array_bytes_conversion_for_size!(24, 40, 48, 56, 72, 80, 88, 96, 104, 112, 120);\n"
  },
  {
    "path": "src/private/checks.rs",
    "content": "pub(crate) mod private {\n    /// Prevents internal traits from being implemented from dependencies.\n    pub trait Sealed {}\n}\n\nmacro_rules! impl_sealed_for {\n    ( $($primitive:ty),* ) => {\n        $(\n            impl private::Sealed for $primitive {}\n        )*\n    }\n}\nimpl_sealed_for!(bool, u8, u16, u32, u64, u128);\n\n/// Helper trait to check whether the size of bitfield structs\n/// is a multiple of 8 to form complete bytes.\npub trait TotalSizeIsMultipleOfEightBits: private::Sealed {}\n\n/// Helper trait used to check whether a bitfield struct does not\n/// fill its entire value space, e.g. has undefined bits.\npub trait TotalSizeIsNotMultipleOfEightBits: private::Sealed {}\n\n/// Helper trait to improve compile error messages.\npub trait RenameSizeType: private::Sealed {\n    type CheckType;\n}\n\n/// Helper type to sum up bit size of a bitfield at compile time.\npub struct TotalSize<T>(::core::marker::PhantomData<T>);\n\nmacro_rules! impl_total_size_for {\n    ( $(($n:expr, $name:ident)),* ) => {\n        $(\n            pub enum $name {}\n            impl private::Sealed for TotalSize<BitCount<$n>> {}\n            impl private::Sealed for $name {}\n            impl RenameSizeType for TotalSize<BitCount<$n>> {\n                type CheckType = $name;\n            }\n        )*\n    }\n}\n\nimpl_total_size_for!(\n    (0, ZeroMod8),\n    (1, OneMod8),\n    (2, TwoMod8),\n    (3, ThreeMod8),\n    (4, FourMod8),\n    (5, FiveMod8),\n    (6, SixMod8),\n    (7, SevenMod8)\n);\n\nimpl TotalSizeIsMultipleOfEightBits for ZeroMod8 {}\n\nimpl TotalSizeIsNotMultipleOfEightBits for OneMod8 {}\nimpl TotalSizeIsNotMultipleOfEightBits for TwoMod8 {}\nimpl TotalSizeIsNotMultipleOfEightBits for ThreeMod8 {}\nimpl TotalSizeIsNotMultipleOfEightBits for FourMod8 {}\nimpl TotalSizeIsNotMultipleOfEightBits for FiveMod8 {}\nimpl TotalSizeIsNotMultipleOfEightBits for SixMod8 {}\nimpl TotalSizeIsNotMultipleOfEightBits for SevenMod8 {}\n\n/// Public facing trait implemented by bitfield structs in order to let the compiler\n/// check if their sizes match a multiple of 8.\npub trait CheckTotalSizeMultipleOf8\nwhere\n    <Self::Size as RenameSizeType>::CheckType: TotalSizeIsMultipleOfEightBits,\n{\n    type Size: RenameSizeType;\n}\n\n/// Public facing trait implemented by bitfield structs in order to let the compiler\n/// check if their sizes does not match a multiple of 8.\npub trait CheckTotalSizeIsNotMultipleOf8\nwhere\n    <Self::Size as RenameSizeType>::CheckType: TotalSizeIsNotMultipleOfEightBits,\n{\n    type Size: RenameSizeType;\n}\n\n/// Helper trait to check if an enum discriminant of a bitfield specifier\n/// is within valid bounds.\npub trait DiscriminantInRange: private::Sealed {}\n\n/// Helper trait to check if a `#[derive(Specifier)]` flagged bitfield\n/// requires\n/// at most 128 bits.\npub trait SpecifierHasAtMost128Bits: private::Sealed {}\n\n/// Helper type to state that something is `true`.\n///\n/// # Note\n///\n/// Used for some compile time evaluation contexts.\npub enum True {}\n\n/// Helper type to state that something is `false`.\n///\n/// # Note\n///\n/// Used for some compile time evaluation contexts.\npub enum False {}\n\nimpl private::Sealed for True {}\nimpl DiscriminantInRange for True {}\nimpl SpecifierHasAtMost128Bits for True {}\nimpl FillsUnalignedBits for True {}\nimpl DoesNotFillUnalignedBits for True {}\n\n/// Helper trait to improve compile time error messages.\npub trait DispatchTrueFalse: private::Sealed {\n    type Out;\n}\n\n/// Helper type for compile time evaluation of the number of bits.\npub struct BitCount<const N: usize>;\n\nimpl private::Sealed for BitCount<0> {}\nimpl DispatchTrueFalse for BitCount<0> {\n    type Out = False;\n}\n\n// impl private::Sealed for BitCount<1> {} // <-- Already implemented by `define_specifiers` macro!\nimpl DispatchTrueFalse for BitCount<1> {\n    type Out = True;\n}\n\n/// Public facing trait that is implemented by bitfield specifiers to\n/// let the compiler check if all its variant discriminants are within\n/// valid bounds.\npub trait CheckDiscriminantInRange<A>\nwhere\n    <Self::CheckType as DispatchTrueFalse>::Out: DiscriminantInRange,\n{\n    type CheckType: DispatchTrueFalse;\n}\n\n/// Traits to check at compile-time if a `#[derive(Specifier)]` type requires\n/// no more than 128 bits.\npub trait CheckSpecifierHasAtMost128Bits\nwhere\n    <Self::CheckType as DispatchTrueFalse>::Out: SpecifierHasAtMost128Bits,\n{\n    type CheckType: DispatchTrueFalse;\n}\n\npub trait CheckFillsUnalignedBits\nwhere\n    <Self::CheckType as DispatchTrueFalse>::Out: FillsUnalignedBits,\n{\n    type CheckType: DispatchTrueFalse;\n}\n\npub trait FillsUnalignedBits {}\n\npub trait CheckDoesNotFillUnalignedBits\nwhere\n    <Self::CheckType as DispatchTrueFalse>::Out: DoesNotFillUnalignedBits,\n{\n    type CheckType: DispatchTrueFalse;\n}\n\npub trait DoesNotFillUnalignedBits {}\n"
  },
  {
    "path": "src/private/impls.rs",
    "content": "use crate::{\n    error::{InvalidBitPattern, OutOfBounds},\n    Specifier,\n};\n\nimpl Specifier for bool {\n    const BITS: usize = 1;\n    type Bytes = u8;\n    type InOut = bool;\n\n    #[inline]\n    fn into_bytes(input: Self::InOut) -> Result<Self::Bytes, OutOfBounds> {\n        Ok(input.into())\n    }\n\n    #[inline]\n    fn from_bytes(bytes: Self::Bytes) -> Result<Self::InOut, InvalidBitPattern<Self::Bytes>> {\n        match bytes {\n            0 => Ok(false),\n            1 => Ok(true),\n            invalid_bytes => Err(InvalidBitPattern::new(invalid_bytes)),\n        }\n    }\n}\n\nmacro_rules! impl_specifier_for_primitive {\n    ( $( ($prim:ty: $bits:literal) ),* $(,)? ) => {\n        $(\n            impl Specifier for $prim {\n                const BITS: usize = $bits;\n                type Bytes = $prim;\n                type InOut = $prim;\n\n                #[inline]\n                fn into_bytes(input: Self::InOut) -> Result<Self::Bytes, OutOfBounds> {\n                    Ok(input)\n                }\n\n                #[inline]\n                fn from_bytes(bytes: Self::Bytes) -> Result<Self::InOut, InvalidBitPattern<Self::Bytes>> {\n                    Ok(bytes)\n                }\n            }\n        )*\n    };\n}\nimpl_specifier_for_primitive!(\n    (u8: 8),\n    (u16: 16),\n    (u32: 32),\n    (u64: 64),\n    (u128: 128),\n);\n"
  },
  {
    "path": "src/private/mod.rs",
    "content": "mod array_bytes_conv;\npub mod checks;\nmod impls;\nmod proc;\nmod push_pop;\nmod traits;\n\npub mod static_assertions {\n    pub use static_assertions::*;\n}\npub use self::{\n    array_bytes_conv::ArrayBytesConversion,\n    proc::{read_specifier, write_specifier},\n    push_pop::{PopBuffer, PushBuffer},\n    traits::{\n        IsU128Compatible, IsU16Compatible, IsU32Compatible, IsU64Compatible, IsU8Compatible,\n        PopBits, PushBits, SpecifierBytes,\n    },\n};\n"
  },
  {
    "path": "src/private/proc.rs",
    "content": "use crate::{\n    private::{PopBits, PopBuffer, PushBits, PushBuffer},\n    Specifier,\n};\n\n/// Creates a new push buffer with all bits initialized to 0.\n#[inline]\nfn push_buffer<T>() -> PushBuffer<<T as Specifier>::Bytes>\nwhere\n    T: Specifier,\n    PushBuffer<T::Bytes>: Default,\n{\n    <PushBuffer<<T as Specifier>::Bytes> as Default>::default()\n}\n\n#[doc(hidden)]\n#[inline]\n#[must_use]\npub fn read_specifier<T>(bytes: &[u8], offset: usize) -> <T as Specifier>::Bytes\nwhere\n    T: Specifier,\n    PushBuffer<T::Bytes>: Default + PushBits,\n{\n    let end = offset + <T as Specifier>::BITS;\n    let ls_byte = offset / 8; // compile-time\n    let ms_byte = (end - 1) / 8; // compile-time\n\n    // Truncation is always valid due to mod 8 value range\n    #[allow(clippy::cast_possible_truncation)]\n    let lsb_offset = (offset % 8) as u32; // compile-time\n    #[allow(clippy::cast_possible_truncation)]\n    let msb_offset = (end % 8) as u32; // compile-time\n    let msb_offset = if msb_offset == 0 { 8 } else { msb_offset };\n\n    let mut buffer = push_buffer::<T>();\n\n    if lsb_offset == 0 && msb_offset == 8 {\n        // Edge-case for whole bytes manipulation.\n        for byte in bytes[ls_byte..=ms_byte].iter().rev() {\n            buffer.push_bits(8, *byte);\n        }\n    } else {\n        if ls_byte != ms_byte {\n            // Most-significant byte\n            buffer.push_bits(msb_offset, bytes[ms_byte]);\n        }\n        if ms_byte - ls_byte >= 2 {\n            // Middle bytes\n            for byte in bytes[(ls_byte + 1)..ms_byte].iter().rev() {\n                buffer.push_bits(8, *byte);\n            }\n        }\n        if ls_byte == ms_byte {\n            buffer.push_bits(\n                u32::try_from(<T as Specifier>::BITS).unwrap(),\n                bytes[ls_byte] >> lsb_offset,\n            );\n        } else {\n            buffer.push_bits(8 - lsb_offset, bytes[ls_byte] >> lsb_offset);\n        }\n    }\n    buffer.into_bytes()\n}\n\n#[doc(hidden)]\n#[inline]\npub fn write_specifier<T>(bytes: &mut [u8], offset: usize, new_val: <T as Specifier>::Bytes)\nwhere\n    T: Specifier,\n    PopBuffer<T::Bytes>: PopBits,\n{\n    let end = offset + <T as Specifier>::BITS;\n    let ls_byte = offset / 8; // compile-time\n    let ms_byte = (end - 1) / 8; // compile-time\n\n    // Truncation is always valid due to mod 8 value range\n    #[allow(clippy::cast_possible_truncation)]\n    let lsb_offset = (offset % 8) as u32; // compile-time\n    #[allow(clippy::cast_possible_truncation)]\n    let msb_offset = (end % 8) as u32; // compile-time\n    let msb_offset = if msb_offset == 0 { 8 } else { msb_offset };\n\n    let mut buffer = <PopBuffer<T::Bytes>>::from_bytes(new_val);\n\n    if lsb_offset == 0 && msb_offset == 8 {\n        // Edge-case for whole bytes manipulation.\n        for byte in &mut bytes[ls_byte..=ms_byte] {\n            *byte = buffer.pop_bits(8);\n        }\n    } else {\n        // Least-significant byte\n        let stays_same = bytes[ls_byte]\n            & (if ls_byte == ms_byte && msb_offset != 8 {\n                !((1 << msb_offset) - 1)\n            } else {\n                0u8\n            } | ((1 << lsb_offset) - 1));\n        let overwrite = buffer.pop_bits(8 - lsb_offset);\n        bytes[ls_byte] = stays_same | (overwrite << lsb_offset);\n        if ms_byte - ls_byte >= 2 {\n            // Middle bytes\n            for byte in &mut bytes[(ls_byte + 1)..ms_byte] {\n                *byte = buffer.pop_bits(8);\n            }\n        }\n        if ls_byte != ms_byte {\n            // Most-significant byte\n            if msb_offset == 8 {\n                // We don't need to respect what was formerly stored in the byte.\n                bytes[ms_byte] = buffer.pop_bits(msb_offset);\n            } else {\n                // All bits that do not belong to this field should be preserved.\n                let stays_same = bytes[ms_byte] & !((1 << msb_offset) - 1);\n                let overwrite = buffer.pop_bits(msb_offset);\n                bytes[ms_byte] = stays_same | overwrite;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/private/push_pop.rs",
    "content": "use crate::private::{checks::private::Sealed, PopBits, PushBits};\n\n/// A bit buffer that allows to pop bits from it.\npub struct PopBuffer<T> {\n    bytes: T,\n}\n\nimpl<T> PopBuffer<T> {\n    /// Creates a new pop buffer from the given bytes.\n    #[inline]\n    pub(super) fn from_bytes(bytes: T) -> Self {\n        Self { bytes }\n    }\n}\n\nimpl Sealed for PopBuffer<u8> {}\n\nimpl PopBits for PopBuffer<u8> {\n    #[inline]\n    fn pop_bits(&mut self, amount: u32) -> u8 {\n        let Self { bytes } = self;\n        let orig_ones = bytes.count_ones();\n        debug_assert!((1..=8).contains(&amount));\n        // Truncation is always valid due to shift range\n        #[allow(clippy::cast_possible_truncation)]\n        let res = *bytes & (1_u16.wrapping_shl(amount).wrapping_sub(1) as u8);\n        *bytes = bytes.checked_shr(amount).unwrap_or(0);\n        debug_assert_eq!(res.count_ones() + bytes.count_ones(), orig_ones);\n        res\n    }\n}\n\nmacro_rules! impl_pop_bits {\n    ( $($type:ty),+ ) => {\n        $(\n            impl Sealed for PopBuffer<$type> {}\n\n            impl PopBits for PopBuffer<$type> {\n                #[inline]\n                fn pop_bits(&mut self, amount: u32) -> u8 {\n                    let Self { bytes } = self;\n                    let orig_ones = bytes.count_ones();\n                    debug_assert!((1..=8).contains(&amount));\n                    let bitmask = 0xFF >> (8 - amount);\n                    // Truncation is always valid due to mask size\n                    #[allow(clippy::cast_possible_truncation)]\n                    let res = (*bytes as u8) & bitmask;\n                    *bytes = bytes.checked_shr(amount).unwrap_or(0);\n                    debug_assert_eq!(res.count_ones() + bytes.count_ones(), orig_ones);\n                    res\n                }\n            }\n        )+\n    };\n}\nimpl_pop_bits!(u16, u32, u64, u128);\n\n/// A bit buffer that allows to push bits onto it.\npub struct PushBuffer<T> {\n    bytes: T,\n}\n\nimpl<T> PushBuffer<T> {\n    /// Returns the underlying bytes of the push buffer.\n    #[inline]\n    pub(super) fn into_bytes(self) -> T {\n        self.bytes\n    }\n}\n\nmacro_rules! impl_push_bits {\n    ( $($type:ty),+ ) => {\n        $(\n            impl Sealed for PushBuffer<$type> {}\n\n            impl Default for PushBuffer<$type> {\n                #[inline]\n                fn default() -> Self {\n                    Self { bytes: <$type as Default>::default() }\n                }\n            }\n\n            impl PushBits for PushBuffer<$type> {\n                #[inline]\n                fn push_bits(&mut self, amount: u32, bits: u8) {\n                    let Self { bytes } = self;\n                    let orig_ones = bytes.count_ones();\n                    debug_assert!((1..=8).contains(&amount));\n                    let bitmask = 0xFF >> (8 - amount);\n                    *bytes = bytes.wrapping_shl(amount) | <$type>::from(bits & bitmask);\n                    debug_assert_eq!((bits & bitmask).count_ones() + orig_ones, bytes.count_ones());\n                }\n            }\n        )+\n    }\n}\nimpl_push_bits!(u8, u16, u32, u64, u128);\n"
  },
  {
    "path": "src/private/traits.rs",
    "content": "use super::checks;\n\n/// Helper trait for underlying primitives handling of bitfields.\n///\n/// # Note\n///\n/// Must not and cannot be implemented by dependencies.\n#[doc(hidden)]\npub trait PushBits: checks::private::Sealed {\n    fn push_bits(&mut self, amount: u32, bits: u8);\n}\n\n/// Helper trait for underlying primitives handling of bitfields.\n///\n/// # Note\n///\n/// Must not and cannot be implemented by dependencies.\n#[doc(hidden)]\npub trait PopBits: checks::private::Sealed {\n    fn pop_bits(&mut self, amount: u32) -> u8;\n}\n\n/// Trait implemented by primitives that drive bitfield manipulations generically.\n#[doc(hidden)]\npub trait SpecifierBytes: checks::private::Sealed {\n    /// The base type that the specifier is operating on.\n    type Bytes;\n}\n\npub trait IsU8Compatible: checks::private::Sealed {}\npub trait IsU16Compatible: checks::private::Sealed {}\npub trait IsU32Compatible: checks::private::Sealed {}\npub trait IsU64Compatible: checks::private::Sealed {}\npub trait IsU128Compatible: checks::private::Sealed {}\n\nimpl IsU8Compatible for checks::BitCount<8> {}\nimpl IsU16Compatible for checks::BitCount<16> {}\nimpl IsU32Compatible for checks::BitCount<32> {}\nimpl IsU64Compatible for checks::BitCount<64> {}\nimpl IsU128Compatible for checks::BitCount<128> {}\n"
  },
  {
    "path": "tests/bitfield/bits_param.rs",
    "content": "//! Tests for `#[bitfield(bits = N)]`\n\nuse modular_bitfield::prelude::*;\n\n#[test]\nfn bits_non_filled_1() {\n    #[bitfield(bits = 32, filled = false)]\n    #[derive(Specifier)]\n    pub struct SignIntegerShort {\n        sign: bool,\n        value: B7,\n    }\n\n    assert_eq!(<SignIntegerShort as Specifier>::BITS, 32);\n}\n\n#[test]\nfn bits_non_filled_2() {\n    #[bitfield(bits = 32, filled = false)]\n    #[derive(Specifier)]\n    pub struct SignIntegerLong {\n        sign: bool,\n        value: B30,\n    }\n\n    assert_eq!(<SignIntegerLong as Specifier>::BITS, 32);\n}\n\n#[test]\nfn complex_use_case() {\n    #[derive(Specifier)]\n    #[bits = 2]\n    pub enum Status {\n        Red,\n        Green,\n        Yellow,\n    }\n\n    #[bitfield(bits = 4)]\n    #[derive(Specifier)]\n    pub struct Header {\n        is_compact: bool,\n        is_secure: bool,\n        #[bits = 2]\n        pre_status: Status,\n    }\n\n    #[bitfield(bits = 16, bytes = 2, filled = false)]\n    #[derive(Specifier)]\n    pub struct PackedData {\n        #[bits = 4]\n        header: Header,\n        body: B9,\n        #[bits = 2]\n        status: Status,\n    }\n\n    assert_eq!(<Status as Specifier>::BITS, 2);\n    assert_eq!(<Header as Specifier>::BITS, 4);\n    assert_eq!(<PackedData as Specifier>::BITS, 16);\n}\n\n#[test]\nfn low_bits_filled() {\n    #[bitfield(bits = 4)]\n    #[derive(Specifier)]\n    pub struct Header {\n        is_compact: bool,\n        is_secure: bool,\n        #[bits = 2]\n        pre_status: B2,\n    }\n\n    assert_eq!(<Header as Specifier>::BITS, 4);\n}\n\n#[test]\nfn valid_use_1() {\n    #[bitfield(bits = 32)]\n    pub struct SignInteger {\n        sign: bool,\n        value: B31,\n    }\n}\n\n#[test]\nfn valid_use_2() {\n    #[bitfield(bits = 32)]\n    #[repr(u32)]\n    pub struct SignInteger {\n        sign: bool,\n        value: B31,\n    }\n}\n\n#[test]\nfn valid_use_3() {\n    #[bitfield(bits = 32, bytes = 4)]\n    #[repr(u32)]\n    pub struct SignInteger {\n        sign: bool,\n        value: B31,\n    }\n}\n\n#[test]\nfn valid_use_4() {\n    #[bitfield(bits = 32, bytes = 4)]\n    #[repr(u32)]\n    #[derive(Debug, Specifier)]\n    pub struct SignInteger {\n        sign: bool,\n        value: B31,\n    }\n}\n"
  },
  {
    "path": "tests/bitfield/bytes_param.rs",
    "content": "//! Tests for `bytes = N` #[bitfield] parameter\n\nuse modular_bitfield::prelude::*;\n\n#[test]\nfn valid_bitfield() {\n    // Just requires exactly 32 bits (4 bytes) as expected.\n    #[bitfield(bytes = 4)]\n    pub struct Base {\n        a: B2,\n        b: B6,\n        c: u8,\n        d: u16,\n    }\n\n    assert_eq!(core::mem::size_of::<Base>(), 4);\n}\n\n#[test]\nfn valid_specifier_bitfield() {\n    // Is only 9 bits, so will be 2 bytes in size.\n    #[bitfield(bytes = 2, filled = false)]\n    #[derive(Specifier)]\n    pub struct Header {\n        a: B6,\n        b: bool,\n        c: bool,\n        d: bool,\n    }\n\n    assert_eq!(core::mem::size_of::<Header>(), 2);\n}\n"
  },
  {
    "path": "tests/bitfield/derive_bitfield_specifier.rs",
    "content": "//! Tests specific to the `#[derive(Specifier)]` proc. macro\n\nuse modular_bitfield::prelude::*;\n\n// For some bitfield members, working with them as enums will make more sense to\n// the user than working with them as integers. We will require enums that have\n// a power-of-two number of variants so that they exhaustively cover a fixed\n// range of bits.\n//\n//     // Works like B3, but getter and setter signatures will use\n//     // the enum instead of u8.\n//     #[derive(Specifier)]\n//     enum DeliveryMode {\n//         Fixed = 0b000,\n//         Lowest = 0b001,\n//         SMI = 0b010,\n//         RemoteRead = 0b011,\n//         NMI = 0b100,\n//         Init = 0b101,\n//         Startup = 0b110,\n//         External = 0b111,\n//     }\n//\n// For this test case it is okay to require that every enum variant has an\n// explicit discriminant that is an integer literal. We will relax this\n// requirement in a later test case.\n//\n// Additionally, enums may support a \"bits\" attribute which allows to enum to\n// have a number of variants that is not a power of two. If the #[bits = N]\n// attribute is specified, like so:\n//\n//     #[derive(Specifier)]\n//     #[bits = 4]\n//     enum SmallPrime {\n//         Two = 0b0010,\n//         Three = 0b0011,\n//         Five = 0b0101,\n//         Seven = 0b0111,\n//         Eleven = 0b1011,\n//         Thirteen = 0b1101,\n//     }\n//\n// then the number of bits required to represent the struct is coerced to N.\n//\n//     let mut bitfield = MyBitfield::new();\n//     assert_eq!(0, bitfield.small_prime_or_err().unwrap_err().invalid_bytes());\n//\n//     bitfield.set_small_prime(SmallPrime::Seven);\n//     let p = bitfield.small_prime_or_err().unwrap_or(SmallPrime::Two);\n#[test]\nfn enums() {\n    use modular_bitfield::error::InvalidBitPattern;\n\n    #[bitfield]\n    pub struct RedirectionTableEntry {\n        acknowledged: bool,\n        trigger_mode: TriggerMode,\n        delivery_mode: DeliveryMode,\n        small_prime: SmallPrime,\n        reserved: B3,\n        another_small_prime: SmallPrime,\n    }\n\n    #[derive(Specifier, Debug, PartialEq)]\n    pub enum TriggerMode {\n        Edge = 0,\n        Level = 1,\n    }\n\n    #[derive(Specifier, Debug, PartialEq)]\n    pub enum DeliveryMode {\n        Fixed = 0b000,\n        Lowest = 0b001,\n        Smi = 0b010,\n        RemoteRead = 0b011,\n        Nmi = 0b100,\n        Init = 0b101,\n        Startup = 0b110,\n        External = 0b111,\n    }\n\n    #[derive(Specifier, Debug, PartialEq)]\n    #[bits = 4]\n    pub enum SmallPrime {\n        Two = 0b0010,\n        Three = 0b0011,\n        Five = 0b0101,\n        Seven = 0b0111,\n        Eleven = 0b1011,\n        Thirteen = 0b1101,\n    }\n\n    assert_eq!(core::mem::size_of::<RedirectionTableEntry>(), 2);\n\n    // Initialized to all 0 bits.\n    let mut entry = RedirectionTableEntry::new();\n    assert!(!entry.acknowledged());\n    assert_eq!(entry.trigger_mode(), TriggerMode::Edge);\n    assert_eq!(entry.delivery_mode(), DeliveryMode::Fixed);\n    assert_eq!(entry.small_prime_or_err(), Err(InvalidBitPattern::new(0)));\n    assert_eq!(entry.small_prime_or_err().unwrap_err().invalid_bytes(), 0);\n\n    entry.set_acknowledged(true);\n    entry.set_delivery_mode(DeliveryMode::Smi);\n    entry.set_small_prime(SmallPrime::Five);\n    assert!(entry.acknowledged());\n    assert_eq!(entry.trigger_mode(), TriggerMode::Edge);\n    assert_eq!(entry.delivery_mode(), DeliveryMode::Smi);\n    assert_eq!(entry.small_prime(), SmallPrime::Five);\n    assert_eq!(entry.small_prime_or_err(), Ok(SmallPrime::Five));\n}\n\n#[test]\nfn name_conflict() {\n    #[derive(Specifier)]\n    pub enum SuspiciouslyAmbiguous {\n        Bytes,\n        InOut,\n    }\n}\n\n// For bitfield use limited to a single binary, such as a space optimization for\n// some in-memory data structure, we may not care what exact bit representation\n// is used for enums.\n//\n// Make your Specifier derive macro for enums use the underlying\n// discriminant determined by the Rust compiler as the bit representation. Do\n// not assume that the compiler uses any particular scheme like PREV+1 for\n// implicit discriminants; make sure your implementation respects Rust's choice\n// of discriminant regardless of what scheme Rust uses. This is important for\n// performance so that the getter and setter both compile down to very simple\n// machine code after optimizations.\n//\n// Do not worry about what happens if discriminants are outside of the range\n// 0..2^BITS. We will do a compile-time check in a later test case to ensure\n// they are in range.\n#[test]\nfn optional_discriminant() {\n    #[bitfield]\n    pub struct RedirectionTableEntry {\n        delivery_mode: DeliveryMode,\n        reserved: B5,\n    }\n\n    const F: isize = 3;\n    const G: isize = 0;\n\n    #[derive(Specifier, Debug, PartialEq)]\n    pub enum DeliveryMode {\n        Fixed = F,\n        Lowest,\n        Smi,\n        RemoteRead,\n        Nmi,\n        Init = G,\n        Startup,\n        External,\n    }\n\n    assert_eq!(core::mem::size_of::<RedirectionTableEntry>(), 1);\n\n    // Initialized to all 0 bits.\n    let mut entry = RedirectionTableEntry::new();\n    assert_eq!(entry.delivery_mode(), DeliveryMode::Init);\n\n    entry.set_delivery_mode(DeliveryMode::Lowest);\n    assert_eq!(entry.delivery_mode(), DeliveryMode::Lowest);\n}\n"
  },
  {
    "path": "tests/bitfield/derive_debug.rs",
    "content": "//! Tests for `#[derive(Debug)]`\n\nextern crate alloc;\nuse alloc::format;\nuse modular_bitfield::prelude::*;\n\n#[test]\nfn print_invalid_bits() {\n    #[derive(Specifier, Debug)]\n    #[bits = 2]\n    pub enum Status {\n        Green = 0,\n        Yellow = 1,\n        Red = 2, // 0x11 (= 3) is undefined here for Status!\n    }\n\n    #[bitfield]\n    #[derive(Debug)]\n    pub struct DataPackage {\n        status: Status,\n        contents: B4,\n        is_alive: bool,\n        is_received: bool,\n    }\n\n    let package = DataPackage::from_bytes([0b0101_1011]);\n    assert_eq!(\n        format!(\"{package:?}\"),\n        \"DataPackage { status: InvalidBitPattern { invalid_bytes: 3 }, contents: 6, is_alive: true, is_received: false }\",\n    );\n    assert_eq!(\n        format!(\"{package:#X?}\"),\n        \"DataPackage {\\n    \\\n            status: InvalidBitPattern {\\n        \\\n                invalid_bytes: 0x3,\\n    \\\n            },\\n    \\\n            contents: 0x6,\\n    \\\n            is_alive: true,\\n    \\\n            is_received: false,\\n\\\n        }\",\n    );\n}\n\n#[test]\nfn respects_other_derives() {\n    #[bitfield]\n    #[derive(Debug, Clone, PartialEq, Eq)]\n    pub struct Color {\n        r: B6,\n        g: B6,\n        b: B6,\n        a: B6,\n    }\n\n    let color1 = Color::new().with_r(63).with_g(32).with_b(16).with_a(8);\n    let color2 = color1.clone();\n    assert_eq!(color1, color2);\n    assert_eq!(format!(\"{color1:?}\"), \"Color { r: 63, g: 32, b: 16, a: 8 }\",);\n    assert_eq!(\n        format!(\"{color2:#x?}\"),\n        \"Color {\\n    r: 0x3f,\\n    g: 0x20,\\n    b: 0x10,\\n    a: 0x8,\\n}\",\n    );\n}\n\n#[test]\nfn valid_use_2() {\n    #[derive(Specifier, Debug)]\n    pub enum Status {\n        Green,\n        Yellow,\n        Red,\n        None,\n    }\n\n    #[bitfield]\n    #[derive(Debug)]\n    pub struct DataPackage {\n        status: Status,\n        contents: B60,\n        is_alive: bool,\n        is_received: bool,\n    }\n\n    let package = DataPackage::new()\n        .with_status(Status::Green)\n        .with_contents(0xC0DE_CAFE)\n        .with_is_alive(true)\n        .with_is_received(false);\n    assert_eq!(\n        format!(\"{package:?}\"),\n        \"DataPackage { status: Green, contents: 3235826430, is_alive: true, is_received: false }\",\n    );\n    assert_eq!(\n        format!(\"{package:#X?}\"),\n        \"DataPackage {\\n    status: Green,\\n    contents: 0xC0DECAFE,\\n    is_alive: true,\\n    is_received: false,\\n}\",\n    );\n}\n\n#[test]\nfn valid_use_specifier() {\n    #[bitfield(filled = false)] // Requires just 4 bits!\n    #[derive(Specifier, Debug)]\n    pub struct Header {\n        status: B2,\n        is_alive: bool,\n        is_received: bool,\n    }\n\n    let header = Header::new()\n        .with_status(1)\n        .with_is_alive(true)\n        .with_is_received(false);\n    assert_eq!(\n        format!(\"{header:?}\"),\n        \"Header { status: 1, is_alive: true, is_received: false }\",\n    );\n    assert_eq!(\n        format!(\"{header:#X?}\"),\n        \"Header {\\n    status: 0x1,\\n    is_alive: true,\\n    is_received: false,\\n}\",\n    );\n}\n\n#[test]\nfn valid_use() {\n    #[bitfield]\n    #[derive(Debug)]\n    pub struct Color {\n        r: B6,\n        g: B6,\n        b: B6,\n        a: B6,\n    }\n\n    let color = Color::new().with_r(63).with_g(32).with_b(16).with_a(8);\n    assert_eq!(format!(\"{color:?}\"), \"Color { r: 63, g: 32, b: 16, a: 8 }\",);\n    assert_eq!(\n        format!(\"{color:#x?}\"),\n        \"Color {\\n    r: 0x3f,\\n    g: 0x20,\\n    b: 0x10,\\n    a: 0x8,\\n}\",\n    );\n}\n\n#[test]\nfn valid_use_tuple() {\n    #[bitfield]\n    #[derive(Debug)]\n    pub struct Color(B6, B6, B6, B6);\n\n    let color = Color::new().with_0(63).with_1(32).with_2(16).with_3(8);\n    assert_eq!(format!(\"{color:?}\"), \"Color(63, 32, 16, 8)\",);\n    assert_eq!(\n        format!(\"{color:#x?}\"),\n        \"Color(\\n    0x3f,\\n    0x20,\\n    0x10,\\n    0x8,\\n)\",\n    );\n}\n"
  },
  {
    "path": "tests/bitfield/derive_specifier.rs",
    "content": "//! Tests for `#[derive(Specifier)]` using `#[bitfield]`\n\nuse modular_bitfield::prelude::*;\n\n#[test]\nfn struct_in_struct() {\n    #[bitfield(filled = false)]\n    #[derive(Specifier, Debug, PartialEq, Eq, Copy, Clone)]\n    pub struct Header {\n        a: B2,\n        b: B3,\n    }\n\n    #[bitfield]\n    #[derive(Debug, PartialEq, Eq)]\n    pub struct Base {\n        pub header: Header,\n        pub rest: B3,\n    }\n\n    let mut base = Base::new();\n    assert_eq!(base.header(), Header::new());\n    let h = Header::new().with_a(1).with_b(2);\n    base.set_header(h);\n    let h2 = base.header();\n    assert_eq!(h2, h);\n    assert_eq!(h2.a(), 1);\n    assert_eq!(h2.b(), 2);\n}\n\n#[test]\nfn unfilled_from_bytes() {\n    use modular_bitfield::error::OutOfBounds;\n\n    #[bitfield(filled = false)]\n    #[derive(Specifier, Debug, PartialEq, Eq, Copy, Clone)]\n    pub struct Unfilled {\n        a: B2,\n    }\n\n    assert_eq!(Unfilled::from_bytes([0x00]), Ok(Unfilled::new()));\n    assert_eq!(\n        Unfilled::from_bytes([0b0000_0001]),\n        Ok(Unfilled::new().with_a(1))\n    );\n    assert_eq!(\n        Unfilled::from_bytes([0b0000_0010]),\n        Ok(Unfilled::new().with_a(2))\n    );\n    assert_eq!(\n        Unfilled::from_bytes([0b0000_0011]),\n        Ok(Unfilled::new().with_a(3))\n    );\n    assert_eq!(Unfilled::from_bytes([0b0000_0100]), Err(OutOfBounds));\n}\n\n#[test]\nfn valid_use() {\n    #[bitfield]\n    #[derive(Specifier)]\n    pub struct Header {\n        live: bool,\n        received: bool,\n        status: B2,\n        rest: B4,\n    }\n\n    assert_eq!(<Header as Specifier>::BITS, 8);\n}\n"
  },
  {
    "path": "tests/bitfield/filled_param.rs",
    "content": "//! Tests for `filled: bool` #[bitfield] parameter\n\nuse modular_bitfield::prelude::*;\n\n#[test]\nfn valid_bitfield_1() {\n    // The bitfield has only 7 bits and therefore is unfilled.\n    #[bitfield(filled = false)]\n    pub struct UnfilledBitfield {\n        a: B7,\n    }\n}\n\n#[test]\nfn valid_bitfield_2() {\n    // The bitfield has exactly 8 bits and therefore is filled.\n    #[bitfield(filled = true)]\n    pub struct UnfilledBitfield {\n        a: B8,\n    }\n}\n\n#[test]\nfn valid_bitfield_specifier_1() {\n    // The bitfield only has 23 bits and therefore is unfilled.\n    #[bitfield(filled = false)]\n    #[derive(Specifier)]\n    pub struct UnfilledSpecifier {\n        a: B7,\n        b: u16,\n    }\n}\n\n#[test]\nfn valid_bitfield_specifier_2() {\n    // The bitfield has 24 bits and therefore is filled.\n    #[bitfield(filled = true)]\n    #[derive(Specifier, Debug, PartialEq, Eq, Clone, Copy)]\n    pub struct FilledSpecifier {\n        a: B8,\n        b: u16,\n    }\n\n    // Testing impl_array_bytes_conversion_for_size\n    let value = FilledSpecifier::new().with_a(1).with_b(0x302);\n    assert_eq!(\n        <FilledSpecifier as Specifier>::from_bytes(0x0003_0201),\n        Ok(value)\n    );\n    assert_eq!(\n        <FilledSpecifier as Specifier>::into_bytes(value),\n        Ok(0x0003_0201)\n    );\n}\n"
  },
  {
    "path": "tests/bitfield/mod.rs",
    "content": "mod bits_param;\nmod bytes_param;\nmod derive_bitfield_specifier;\nmod derive_debug;\nmod derive_specifier;\nmod filled_param;\nmod no_implicit_prelude;\nmod regressions;\nmod repr;\nmod skip;\n\nuse modular_bitfield::prelude::*;\n\n#[test]\nfn accessors() {\n    #[bitfield]\n    pub struct MyFourBytes {\n        a: B1,\n        b: B3,\n        c: B4,\n        d: B24,\n    }\n\n    let mut bitfield = MyFourBytes::new();\n    assert_eq!(0, bitfield.a());\n    assert_eq!(0, bitfield.b());\n    assert_eq!(0, bitfield.c());\n    assert_eq!(0, bitfield.d());\n\n    bitfield.set_c(14);\n    assert_eq!(0, bitfield.a());\n    assert_eq!(0, bitfield.b());\n    assert_eq!(14, bitfield.c());\n    assert_eq!(0, bitfield.d());\n}\n\n#[test]\n// Bad names are fine, it is just a test\n#[allow(clippy::many_single_char_names)]\nfn accessor_signatures() {\n    use core::mem::size_of_val;\n\n    // For getters and setters, we would like for the signature to be in terms of\n    // the narrowest unsigned integer type that can hold the right number of bits.\n    // That means the accessors for B1 through B8 would use u8, B9 through B16 would\n    // use u16 etc.\n\n    type A = B1;\n    type B = B3;\n    type C = B4;\n    type D = B24;\n\n    #[bitfield]\n    pub struct MyFourBytes {\n        a: A,\n        b: B,\n        c: C,\n        d: D,\n    }\n\n    let mut x = MyFourBytes::new();\n\n    // I am testing the signatures in this roundabout way to avoid making it\n    // possible to pass this test with a generic signature that is inconvenient\n    // for callers, such as `fn a<T: From<u64>>(&self) -> T`.\n\n    let a = 1;\n    x.set_a(a); // expect fn(&mut MyFourBytes, u8)\n    let b = 1;\n    x.set_b(b);\n    let c = 1;\n    x.set_c(c);\n    let d = 1;\n    x.set_d(d); // expect fn(&mut MyFourBytes, u32)\n\n    assert_eq!(size_of_val(&a), 1);\n    assert_eq!(size_of_val(&b), 1);\n    assert_eq!(size_of_val(&c), 1);\n    assert_eq!(size_of_val(&d), 4);\n\n    assert_eq!(size_of_val(&x.a()), 1); // expect fn(&MyFourBytes) -> u8\n    assert_eq!(size_of_val(&x.b()), 1);\n    assert_eq!(size_of_val(&x.c()), 1);\n    assert_eq!(size_of_val(&x.d()), 4); // expect fn(&MyFourBytes) -> u32\n}\n\n// This test is equivalent to accessors but with some fields spanning across\n// byte boundaries. This may or may not already work depending on how your\n// implementation has been done so far.\n//\n//\n//     ║  first byte   ║  second byte  ║  third byte   ║  fourth byte  ║\n//     ╟───────────────╫───────────────╫───────────────╫───────────────╢\n//     ║▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒║\n//     ╟─────────────────╫───────────╫─────────────────────────╫───────╢\n//     ║        a        ║     b     ║            c            ║   d   ║\n#[test]\nfn accessors_edge() {\n    #[bitfield]\n    pub struct EdgeCaseBytes {\n        a: B9,\n        b: B6,\n        c: B13,\n        d: B4,\n    }\n\n    let mut bitfield = EdgeCaseBytes::new();\n    assert_eq!(0, bitfield.a());\n    assert_eq!(0, bitfield.b());\n    assert_eq!(0, bitfield.c());\n    assert_eq!(0, bitfield.d());\n\n    let a = 0b1_1000_0111;\n    let b = 0b101_010;\n    let c = 0x1675;\n    let d = 0b1110;\n\n    bitfield.set_a(a);\n    bitfield.set_b(b);\n    bitfield.set_c(c);\n    bitfield.set_d(d);\n\n    assert_eq!(a, bitfield.a());\n    assert_eq!(b, bitfield.b());\n    assert_eq!(c, bitfield.c());\n    assert_eq!(d, bitfield.d());\n}\n\n// We also want to allow for tuple structs to be accepted by the `#[bitfield]` macro.\n//\n// For this we generate getters and setters in a way that refer to the corresponding\n// number of the field within the annotated tuple struct.\n#[test]\nfn tuple_structs() {\n    #[bitfield]\n    struct MyTwoBytes(bool, B7, B8);\n\n    let mut test = MyTwoBytes::new();\n\n    assert!(!test.get_0());\n    assert_eq!(test.get_1(), 0);\n    assert_eq!(test.get_2(), 0);\n\n    test.set_0(true);\n    test.set_1(42);\n    test.set_2(0xFF);\n\n    assert!(test.get_0());\n    assert_eq!(test.get_1(), 42);\n    assert_eq!(test.get_2(), 0xFF);\n}\n\n#[test]\nfn bool_specifier() {\n    assert_eq!(bool::from_bytes(0), Ok(false));\n    assert_eq!(bool::from_bytes(1), Ok(true));\n    assert_eq!(\n        bool::from_bytes(2),\n        Err(modular_bitfield::error::InvalidBitPattern::new(2))\n    );\n}\n\n// Tests to check for correct execution of checked setters.\n#[test]\nfn checked_setters() {\n    use modular_bitfield::error::OutOfBounds;\n\n    #[bitfield]\n    #[derive(Debug, PartialEq)]\n    pub struct MyTwoBytes {\n        a: B1,\n        b: B2,\n        c: B13,\n    }\n\n    let mut bitfield = MyTwoBytes::new();\n\n    // Everything is initialized to zero.\n    assert_eq!(bitfield.a(), 0);\n    assert_eq!(bitfield.b(), 0);\n    assert_eq!(bitfield.c(), 0);\n\n    // Do some invalid manipulations.\n    assert_eq!(bitfield.set_a_checked(2), Err(OutOfBounds));\n    assert_eq!(bitfield.set_b_checked(4), Err(OutOfBounds));\n    assert_eq!(bitfield.set_c_checked(12345), Err(OutOfBounds));\n\n    // Asserts that nothing has changed.\n    assert_eq!(bitfield.a(), 0);\n    assert_eq!(bitfield.b(), 0);\n    assert_eq!(bitfield.c(), 0);\n\n    // Do some valid manipulations.\n    assert_eq!(bitfield.set_a_checked(1), Ok(()));\n    assert_eq!(bitfield.set_b_checked(3), Ok(()));\n    assert_eq!(bitfield.set_c_checked(42), Ok(()));\n\n    // Asserts that the valid manipulation has had effect.\n    assert_eq!(bitfield.a(), 1);\n    assert_eq!(bitfield.b(), 3);\n    assert_eq!(bitfield.c(), 42);\n\n    // Check the checked with statement throws error\n    assert_eq!(MyTwoBytes::new().with_a_checked(2), Err(OutOfBounds));\n    assert_eq!(\n        MyTwoBytes::new()\n            .with_a_checked(1)\n            .unwrap()\n            .with_b_checked(4),\n        Err(OutOfBounds)\n    );\n\n    // Check that with_checked populates values without touching other fields\n    let bitfield = bitfield\n        .with_a_checked(0)\n        .unwrap()\n        .with_b_checked(2)\n        .unwrap();\n\n    assert_eq!(bitfield.a(), 0);\n    assert_eq!(bitfield.b(), 2);\n    assert_eq!(bitfield.c(), 42);\n}\n\n#[test]\nfn errors() {\n    extern crate alloc;\n    use alloc::format;\n\n    let msg = format!(\"{}\", modular_bitfield::error::OutOfBounds);\n    assert!(\n        msg.contains(\"out of bounds\"),\n        \"unexpected error text: {msg}\"\n    );\n\n    let msg = format!(\n        \"{}\",\n        modular_bitfield::error::InvalidBitPattern::new(0x1234_5678)\n    );\n    assert!(\n        msg.contains(\"invalid bit pattern\"),\n        \"unexpected error text: {msg}\"\n    );\n    assert!(msg.contains(\"0x12345678\"), \"unexpected error text: {msg}\");\n}\n\n// Tests if it is possible to manually reset the bitfields again.\n#[test]\nfn manual_reset() {\n    #[bitfield]\n    pub struct MyTwoBytes {\n        a: B1,\n        b: B2,\n        c: B13,\n    }\n\n    let mut bitfield = MyTwoBytes::new();\n\n    // Everything is initialized to zero.\n    assert_eq!(bitfield.a(), 0);\n    assert_eq!(bitfield.b(), 0);\n    assert_eq!(bitfield.c(), 0);\n\n    // Manipulate bitfield.\n    bitfield.set_a(1);\n    bitfield.set_b(3);\n    bitfield.set_c(42);\n\n    // Check that manipulation was successful.\n    assert_eq!(bitfield.a(), 1);\n    assert_eq!(bitfield.b(), 3);\n    assert_eq!(bitfield.c(), 42);\n\n    // Manually reset the bitfield.\n    bitfield.set_a(0);\n    bitfield.set_b(0);\n    bitfield.set_c(0);\n\n    // Check if reset was successful.\n    assert_eq!(bitfield.a(), 0);\n    assert_eq!(bitfield.b(), 0);\n    assert_eq!(bitfield.c(), 0);\n}\n\n// Tests bitfield specifiers of more than 64 bit.\n#[test]\nfn u128_specifier() {\n    #[bitfield]\n    pub struct SomeMoreBytes {\n        a: B47,\n        b: B65,\n        c: B128,\n    }\n\n    let mut bitfield = SomeMoreBytes::new();\n\n    // Everything is initialized to zero.\n    assert_eq!(bitfield.a(), 0);\n    assert_eq!(bitfield.b(), 0);\n    assert_eq!(bitfield.c(), 0);\n\n    // Manipulate bitfield.\n    assert_eq!(bitfield.set_a_checked(1), Ok(()));\n    assert_eq!(bitfield.set_b_checked(3), Ok(()));\n    assert_eq!(bitfield.set_c_checked(42), Ok(()));\n\n    // Check that manipulation was successful.\n    assert_eq!(bitfield.a(), 1);\n    assert_eq!(bitfield.b(), 3);\n    assert_eq!(bitfield.c(), 42);\n\n    // // Manually reset the bitfield.\n    bitfield.set_a(0);\n    bitfield.set_b(0);\n    bitfield.set_c(0);\n\n    // // Check if reset was successful.\n    assert_eq!(bitfield.a(), 0);\n    assert_eq!(bitfield.b(), 0);\n    assert_eq!(bitfield.c(), 0);\n}\n\n// These tests check the conversions from and to bytes.\n#[test]\nfn byte_conversions() {\n    #[bitfield]\n    #[derive(PartialEq, Eq, Debug)]\n    pub struct MyFourBytes {\n        a: bool,\n        b: B2,\n        c: B13,\n        d: B16,\n    }\n\n    let mut bitfield_1 = MyFourBytes::new();\n\n    bitfield_1.set_a(true);\n    bitfield_1.set_b(0b11);\n    bitfield_1.set_c(444);\n    bitfield_1.set_d(1337);\n\n    assert!(bitfield_1.a());\n    assert_eq!(bitfield_1.b(), 3);\n    assert_eq!(bitfield_1.c(), 444);\n    assert_eq!(bitfield_1.d(), 1337);\n\n    let bytes = bitfield_1.into_bytes();\n    assert_eq!(bytes, [231, 13, 57, 5]);\n\n    let bitfield2 = MyFourBytes::from_bytes(bytes);\n\n    assert!(bitfield2.a());\n    assert_eq!(bitfield2.b(), 3);\n    assert_eq!(bitfield2.c(), 444);\n    assert_eq!(bitfield2.d(), 1337);\n}\n\n#[test]\nfn within_single_byte() {\n    #[derive(Specifier, Debug, PartialEq, Copy, Clone)]\n    pub enum Mode {\n        A = 0b00,\n        B = 0b01,\n        C = 0b10,\n        D = 0b11,\n    }\n\n    #[bitfield]\n    #[derive(Debug)]\n    pub struct StatFlag {\n        x: bool,\n        y: bool,\n        z: B2,\n        #[bits = 2]\n        mode: Mode,\n        w: B2,\n    }\n\n    let mut flag = StatFlag::new();\n\n    assert!(!flag.x());\n    assert!(!flag.y());\n    assert_eq!(flag.z(), 0);\n    assert_eq!(flag.w(), 0);\n    assert_eq!(flag.mode(), Mode::A);\n\n    let new_mode = Mode::B;\n\n    flag.set_mode(new_mode);\n    assert!(!flag.x());\n    assert!(!flag.y());\n    assert_eq!(flag.z(), 0);\n    assert_eq!(flag.w(), 0);\n    assert_eq!(flag.mode(), new_mode);\n\n    flag.set_x(true);\n    assert!(flag.x());\n    assert!(!flag.y());\n    assert_eq!(flag.z(), 0);\n    assert_eq!(flag.w(), 0);\n    assert_eq!(flag.mode(), new_mode);\n\n    flag.set_y(true);\n    assert!(flag.x());\n    assert!(flag.y());\n    assert_eq!(flag.z(), 0);\n    assert_eq!(flag.w(), 0);\n    assert_eq!(flag.mode(), new_mode);\n\n    flag.set_z(0b11);\n    assert!(flag.x());\n    assert!(flag.y());\n    assert_eq!(flag.z(), 0b11);\n    assert_eq!(flag.w(), 0);\n    assert_eq!(flag.mode(), new_mode);\n\n    flag.set_w(0b01);\n    assert!(flag.x());\n    assert!(flag.y());\n    assert_eq!(flag.z(), 0b11);\n    assert_eq!(flag.w(), 0b01);\n    assert_eq!(flag.mode(), new_mode);\n}\n\n#[test]\nfn get_spanning_data() {\n    #[bitfield]\n    #[derive(Copy, Clone, Eq, PartialEq)]\n    pub struct ColorEntry {\n        r: B5,\n        g: B5,\n        b: B5,\n        unused: B1,\n    }\n\n    for i in 0..=u16::MAX {\n        let entry = ColorEntry::from_bytes(i.to_le_bytes());\n        let mut new = ColorEntry::new();\n        new.set_r(entry.r());\n        assert_eq!(new.r(), entry.r());\n        new.set_g(entry.g());\n        assert_eq!(new.g(), entry.g());\n        new.set_b(entry.b());\n        assert_eq!(new.b(), entry.b());\n        new.set_unused(entry.unused());\n\n        assert_eq!(new.r(), entry.r());\n        assert_eq!(new.g(), entry.g());\n        assert_eq!(new.b(), entry.b());\n        assert_eq!(new.unused(), entry.unused());\n    }\n}\n\n#[test]\nfn raw_identifiers() {\n    #[bitfield]\n    struct RawIdentifiers {\n        r#struct: B5,\n        r#bool: B3,\n    }\n\n    let r = RawIdentifiers::new();\n    let _ = r.r#struct();\n    let _ = r.r#bool();\n}\n\n// Generate getters and.with() setters that manipulate the right range of bits\n// corresponding to each field.\n//\n//\n//     ║  first byte   ║  second byte  ║  third byte   ║  fourth byte  ║\n//     ╟───────────────╫───────────────╫───────────────╫───────────────╢\n//     ║▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒║\n//     ╟─╫─────╫───────╫───────────────────────────────────────────────╢\n//     ║a║  b  ║   c   ║                       d                       ║\n#[test]\nfn with_setter() {\n    #[bitfield]\n    pub struct MyFourBytes {\n        a: bool,\n        b: B3,\n        c: B4,\n        d: B24,\n    }\n\n    let bitfield = MyFourBytes::new()\n        .with_a(true)\n        .with_b(2)\n        .with_c(14)\n        .with_d(1_000_000);\n\n    assert!(bitfield.a());\n    assert_eq!(bitfield.b(), 2);\n    assert_eq!(bitfield.c(), 14);\n    assert_eq!(bitfield.d(), 1_000_000);\n}\n\n// Checks that no implicit paths are generated by the `#[bitfield]` proc. macro\n// and `#[derive(Specifier)]` derive macro.\n#[test]\nfn primitives_as_specifiers() {\n    #[bitfield]\n    pub struct PrimitivesBitfield {\n        a: bool,\n        b: u8,\n        c: u16,\n        d: u32,\n        e: u64,\n        f: u128,\n        rest: B7,\n    }\n}\n\n// Validates that in a degenerate case with a single bit, non-power-of-two enums\n// behave as expected.\n#[test]\nfn single_bit_enum() {\n    use modular_bitfield::error::InvalidBitPattern;\n\n    #[bitfield]\n    pub struct UselessStruct {\n        reserved: B3,\n        field: ForciblyTrue,\n        reserved2: B4,\n    }\n\n    #[derive(Specifier, Debug, PartialEq)]\n    #[bits = 1]\n    pub enum ForciblyTrue {\n        True = 1,\n    }\n\n    assert_eq!(core::mem::size_of::<UselessStruct>(), 1);\n\n    // Initialized to all 0 bits.\n    let entry = UselessStruct::new();\n    assert_eq!(entry.field_or_err(), Err(InvalidBitPattern::new(0)));\n\n    let entry = UselessStruct::new().with_field(ForciblyTrue::True);\n    assert_eq!(entry.field_or_err(), Ok(ForciblyTrue::True));\n}\n\n#[test]\nfn generic() {\n    #[bitfield]\n    struct Generic<const N: u8> {\n        v: u8,\n    }\n}\n\n#[test]\nfn impl_from_trait() {\n    #[bitfield]\n    #[derive(Clone, Copy)]\n    struct Test {\n        value: u8,\n    }\n\n    let v = Test::from([127]);\n    assert_eq!(v.value(), 127);\n    let v: [u8; 1] = v.into();\n    assert_eq!(v, [127]);\n}\n\n#[test]\nfn impl_try_from_trait() {\n    #[bitfield(filled = false)]\n    #[derive(Clone, Copy, Debug)]\n    struct Test {\n        value: B7,\n    }\n\n    Test::try_from([128]).unwrap_err();\n    let v = Test::try_from([127]).unwrap();\n    assert_eq!(v.value(), 127);\n    let v: [u8; 1] = v.into();\n    assert_eq!(v, [127]);\n}\n"
  },
  {
    "path": "tests/bitfield/no_implicit_prelude.rs",
    "content": "//! Checks that no implicit paths are generated by the `#[bitfield]` proc. macro\n//! and `#[derive(Specifier)]` derive macro.\n\n#![no_implicit_prelude]\n\nstruct OverrideLanguagePrelude;\nmacro_rules! override_language_primitives {\n    ($($ty:ident),* $(,)?) => {\n        $(\n            #[allow(non_camel_case_types)]\n            type $ty = OverrideLanguagePrelude;\n        )*\n    }\n}\noverride_language_primitives!(\n    bool, char, str, i8, i16, i32, i64, i128, u8, u16, u32, u64, u128, isize, usize, f32, f64\n);\n\n#[test]\nfn no_implicit_prelude() {\n    #[::modular_bitfield::bitfield]\n    pub struct TestBitfield {\n        a: ::core::primitive::bool,\n        b: ::modular_bitfield::specifiers::B3,\n        c: ::modular_bitfield::specifiers::B4,\n        d: ::modular_bitfield::specifiers::B24,\n    }\n\n    #[derive(::modular_bitfield::Specifier, Debug)]\n    pub enum TestSpecifier {\n        A = 0,\n        B = 1,\n    }\n}\n\n#[test]\nfn no_implicit_prelude_2() {\n    #[::modular_bitfield::bitfield]\n    #[derive(Specifier, Debug)]\n    pub struct TestBitfield {\n        a: ::core::primitive::bool,\n        b: ::modular_bitfield::specifiers::B3,\n        c: ::modular_bitfield::specifiers::B4,\n        d: ::modular_bitfield::specifiers::B24,\n    }\n}\n"
  },
  {
    "path": "tests/bitfield/regressions.rs",
    "content": "//! Tests for regressions found in published versions\n\nuse modular_bitfield::prelude::*;\n\n#[test]\nfn deny_elided_lifetime() {\n    #[bitfield]\n    #[derive(Debug)]\n    #[repr(u8)]\n    struct KeyFlags {\n        certify: bool,\n        fill: B7,\n    }\n}\n\n#[test]\nfn regression_issue_8() {\n    #[derive(Specifier, Debug, PartialEq, Copy, Clone)]\n    pub enum Mode {\n        A = 0b00,\n        B = 0b01,\n        C = 0b10,\n        D = 0b11,\n    }\n\n    #[bitfield]\n    #[derive(Debug)]\n    pub struct StatFlag {\n        x: bool,\n        y: bool,\n        z: B4,\n        #[bits = 2]\n        mode: Mode,\n    }\n\n    let mut flag = StatFlag::new();\n\n    assert!(!flag.x());\n    assert!(!flag.y());\n    assert_eq!(flag.z(), 0);\n    assert_eq!(flag.mode(), Mode::A);\n\n    let new_mode = Mode::B;\n\n    flag.set_mode(new_mode);\n    assert_eq!(flag.mode(), new_mode);\n\n    flag.set_x(true);\n    assert!(flag.x());\n    assert_eq!(flag.mode(), new_mode);\n\n    flag.set_y(true);\n    assert!(flag.y());\n    assert_eq!(flag.mode(), new_mode);\n\n    flag.set_z(0b01);\n    assert_eq!(flag.z(), 0b01);\n    assert_eq!(flag.mode(), new_mode);\n\n    flag.set_z(0b11);\n    assert_eq!(flag.z(), 0b11);\n    assert_eq!(flag.mode(), new_mode);\n}\n\n#[test]\nfn regression_v0_11() {\n    #[bitfield(bits = 8)]\n    #[derive(Copy, Clone)]\n    pub struct Flags {\n        pub a: bool,\n        #[skip]\n        __: bool,\n        pub b: bool,\n        #[skip]\n        __: B5,\n    }\n\n    let mut flags = Flags::new();\n    assert!(!flags.a());\n    assert!(!flags.b());\n    assert_eq!(flags.into_bytes(), [0b0000_0000]);\n    flags.set_a(true);\n    flags.set_b(true);\n    assert!(flags.a());\n    assert!(flags.b());\n    assert_eq!(flags.into_bytes(), [0b0000_0101]);\n}\n\n#[test]\nfn regression_issue_132() {\n    #[repr(C, align(1024))]\n    #[bitfield]\n    pub struct PackedData {\n        header: B4,\n        body: B9,\n        is_alive: B1,\n        status: B2,\n    }\n\n    // check alignment of PackedData\n    assert_eq!(core::mem::align_of::<PackedData>(), 1024);\n}\n"
  },
  {
    "path": "tests/bitfield/repr.rs",
    "content": "//! Tests for `#[repr(uN)]` and `#[cfg_attr(cond, repr(uN))]`\n\nuse modular_bitfield::prelude::*;\n\n#[test]\nfn complex_use() {\n    #[bitfield]\n    #[repr(u32)]\n    #[derive(Debug, PartialEq, Eq)]\n    struct TtResp {\n        mregion: u8,\n        sregion: u8,\n        mrvalid: bool,\n        srvalid: bool,\n        r: bool,\n        rw: bool,\n        nsr: bool,\n        nsrw: bool,\n        s: bool,\n        irvalid: bool,\n        iregion: u8,\n    }\n\n    let mut rsp = TtResp::new();\n    rsp.set_mregion(u8::MAX);\n    rsp.set_sregion(0xEE);\n    rsp.set_mrvalid(true);\n    rsp.set_srvalid(true);\n    rsp.set_r(true);\n    rsp.set_rw(true);\n    rsp.set_nsr(true);\n    rsp.set_nsrw(true);\n    rsp.set_s(true);\n    rsp.set_irvalid(true);\n    rsp.set_iregion(0xDD);\n    assert_eq!(rsp, TtResp::from(0xDDFF_EEFF_u32));\n    assert_eq!(rsp.mregion(), u8::MAX);\n    assert_eq!(rsp.sregion(), 0xEE);\n    assert!(rsp.mrvalid());\n    assert!(rsp.srvalid());\n    assert!(rsp.r());\n    assert!(rsp.rw());\n    assert!(rsp.nsr());\n    assert!(rsp.nsrw());\n    assert!(rsp.s());\n    assert!(rsp.irvalid());\n    assert_eq!(rsp.iregion(), 0xDD);\n    rsp.set_mregion(0);\n    rsp.set_sregion(0);\n    rsp.set_mrvalid(false);\n    rsp.set_srvalid(false);\n    rsp.set_r(false);\n    rsp.set_rw(false);\n    rsp.set_nsr(false);\n    rsp.set_nsrw(false);\n    rsp.set_s(false);\n    rsp.set_irvalid(false);\n    rsp.set_iregion(0x00);\n    assert_eq!(rsp, TtResp::new());\n}\n\n#[test]\nfn generic_repr() {\n    #[bitfield]\n    #[repr(u8)]\n    struct Generic<const N: u8> {\n        v: u8,\n    }\n}\n\n#[test]\nfn multiple_valid_reprs_1() {\n    #[bitfield]\n    #[repr(C, u32)] // The macro simply ignores `repr(C)`\n    pub struct SignedInt {\n        sign: bool,\n        value: B31,\n    }\n}\n\n#[test]\nfn multiple_valid_reprs_2() {\n    #[bitfield]\n    #[repr(u32)]\n    #[repr(C)] // The macro simply ignores `repr(C)`\n    pub struct SignedInt {\n        sign: bool,\n        value: B31,\n    }\n}\n\n#[test]\nfn valid_cond_use() {\n    #[bitfield]\n    #[cfg_attr(all(), repr(u32))]\n    #[derive(Debug, PartialEq, Eq)]\n    pub struct SignedInt {\n        sign: bool,\n        value: B31,\n    }\n\n    let i1 = SignedInt::new().with_sign(true).with_value(0b1001_0011);\n    let i2 = SignedInt::from(0b0000_0000_0000_0000_0000_0001_0010_0111_u32);\n    assert_eq!(i1, i2);\n    assert_eq!(i1.sign(), i2.sign());\n    assert_eq!(i1.value(), i2.value());\n}\n\nmacro_rules! valid_use {\n    ($(($name:ident, $repr_ty:ty, $value_ty:ty)),*$(,)?) => {\n        $(#[test]\n        fn $name() {\n            #[bitfield]\n            #[repr($repr_ty)]\n            #[derive(Debug, PartialEq, Eq)]\n            pub struct SignedInt {\n                value: $value_ty,\n                sign: bool,\n            }\n\n            let value = 0b101_0011;\n            let bits = (1 << (<$repr_ty>::BITS - 1)) | value;\n\n            let i1 = SignedInt::new().with_sign(true).with_value(value);\n            let i2 = SignedInt::from(bits);\n            assert_eq!(i1, i2);\n            assert_eq!(i1.sign(), i2.sign());\n            assert_eq!(i1.value(), i2.value());\n        })*\n    }\n}\n\nvalid_use!(\n    (valid_use_u8, u8, B7),\n    (valid_use_u16, u16, B15),\n    (valid_use_u32, u32, B31),\n    (valid_use_u64, u64, B63),\n    (valid_use_u128, u128, B127)\n);\n"
  },
  {
    "path": "tests/bitfield/skip.rs",
    "content": "//! Tests for `#[skip(..)]`\n\nextern crate alloc;\nuse alloc::format;\nuse modular_bitfield::prelude::*;\n\n#[test]\nfn double_wildcards_1() {\n    #[bitfield]\n    pub struct Sparse {\n        #[skip]\n        __: B10,\n        a: bool,\n        #[skip]\n        __: B10,\n        b: bool,\n        #[skip]\n        __: B10,\n    }\n}\n\n#[test]\nfn double_wildcards_2() {\n    #[bitfield]\n    pub struct Sparse {\n        #[skip(getters, setters)]\n        __: B10,\n        a: bool,\n        #[skip(getters, setters)]\n        __: B10,\n        b: bool,\n        #[skip(getters, setters)]\n        __: B10,\n    }\n}\n\n#[test]\nfn skip_default() {\n    #[bitfield]\n    pub struct Sparse {\n        #[skip]\n        unused_1: B10,\n        a: bool,\n        #[skip]\n        unused_2: B10,\n        b: bool,\n        #[skip]\n        unused_3: B10,\n    }\n\n    let mut sparse = Sparse::new();\n    assert!(!sparse.a());\n    assert!(!sparse.b());\n    sparse.set_a(true);\n    sparse.set_b(true);\n    assert!(sparse.a());\n    assert!(sparse.b());\n}\n\n#[test]\nfn skip_getters_and_setters_1() {\n    #[bitfield]\n    pub struct Sparse {\n        #[skip(getters, setters)]\n        unused_1: B10,\n        a: bool,\n        #[skip(getters, setters)]\n        unused_2: B10,\n        b: bool,\n        #[skip(getters, setters)]\n        unused_3: B10,\n    }\n\n    let mut sparse = Sparse::new();\n    assert!(!sparse.a());\n    assert!(!sparse.b());\n    sparse.set_a(true);\n    sparse.set_b(true);\n    assert!(sparse.a());\n    assert!(sparse.b());\n}\n\n#[test]\nfn skip_getters_and_setters_2() {\n    #[bitfield]\n    pub struct Sparse {\n        #[skip(getters)]\n        #[skip(setters)]\n        unused_1: B10,\n        a: bool,\n        #[skip(setters)]\n        #[skip(getters)]\n        unused_2: B10,\n        b: bool,\n        #[skip(getters)]\n        #[skip(setters)]\n        unused_3: B10,\n    }\n\n    let mut sparse = Sparse::new();\n    assert!(!sparse.a());\n    assert!(!sparse.b());\n    sparse.set_a(true);\n    sparse.set_b(true);\n    assert!(sparse.a());\n    assert!(sparse.b());\n}\n\n#[test]\nfn skip_getters() {\n    #[bitfield]\n    #[derive(Debug)]\n    pub struct Sparse {\n        #[skip(getters)]\n        unused_1: B10,\n        a: bool,\n        #[skip(getters)]\n        unused_2: B10,\n        b: bool,\n        #[skip(getters)]\n        unused_3: B10,\n    }\n\n    let mut sparse = Sparse::new();\n    assert!(!sparse.a());\n    assert!(!sparse.b());\n    sparse.set_a(true);\n    sparse.set_b(true);\n    assert!(sparse.a());\n    assert!(sparse.b());\n\n    // Use setters of fields with skipped getters:\n    sparse.set_unused_1(0b0011_1111_1111);\n    sparse.set_unused_2(0b0011_1111_1111);\n    sparse.set_unused_3(0b0011_1111_1111);\n\n    assert_eq!(sparse.into_bytes(), [0xFF; 4]);\n}\n\n#[test]\nfn skip_setters() {\n    #[bitfield]\n    #[derive(Debug)]\n    pub struct Sparse {\n        #[skip(setters)]\n        unused_1: B10,\n        a: bool,\n        #[skip(setters)]\n        unused_2: B10,\n        b: bool,\n        #[skip(setters)]\n        unused_3: B10,\n    }\n\n    let mut sparse = Sparse::new();\n    assert!(!sparse.a());\n    assert!(!sparse.b());\n    sparse.set_a(true);\n    sparse.set_b(true);\n    assert!(sparse.a());\n    assert!(sparse.b());\n\n    // Use setters of fields with skipped getters:\n    assert_eq!(sparse.unused_1(), 0);\n    assert_eq!(sparse.unused_2(), 0);\n    assert_eq!(sparse.unused_3(), 0);\n}\n\n#[test]\nfn skip_with_debug() {\n    #[bitfield]\n    #[derive(Debug)]\n    pub struct Sparse {\n        #[skip(getters)]\n        no_getters: B10,\n        a: bool,\n        #[skip(setters)]\n        no_setters: B10,\n        b: bool,\n        #[skip]\n        skipped: B10,\n    }\n\n    let sparse = Sparse::new().with_a(true).with_b(false);\n    assert_eq!(\n        format!(\"{sparse:?}\"),\n        \"Sparse { a: true, no_setters: 0, b: false }\",\n    );\n    assert_eq!(\n        format!(\"{sparse:#X?}\"),\n        \"Sparse {\\n    a: true,\\n    no_setters: 0x0,\\n    b: false,\\n}\",\n    );\n}\n"
  },
  {
    "path": "tests/lib.rs",
    "content": "#![no_std]\n#![deny(elided_lifetimes_in_paths)]\n#![warn(clippy::pedantic, rust_2018_idioms)]\n#![allow(dead_code)]\n\nmod bitfield;\n"
  },
  {
    "path": "tests/panic_tests.rs",
    "content": "#![allow(dead_code)]\n\nuse modular_bitfield::prelude::*;\n\n#[bitfield]\npub struct EdgeCaseBytes {\n    a: B9,\n    b: B6,\n    c: B13,\n    d: B4,\n}\n\n#[test]\n#[should_panic(expected = \"value out of bounds for field EdgeCaseBytes.a\")]\nfn invalid_access_a() {\n    let mut bytes = EdgeCaseBytes::new();\n    bytes.set_a(0b0010_0000_0000_u16);\n}\n\n#[test]\n#[should_panic(expected = \"value out of bounds for field EdgeCaseBytes.b\")]\nfn invalid_access_b() {\n    let mut bytes = EdgeCaseBytes::new();\n    bytes.set_b(0b0000_0100_0000_u8);\n}\n\n#[test]\n#[should_panic(expected = \"value out of bounds for field EdgeCaseBytes.c\")]\nfn invalid_access_c() {\n    let mut bytes = EdgeCaseBytes::new();\n    bytes.set_c(0x2000_u16);\n}\n\n#[test]\n#[should_panic(expected = \"value out of bounds for field EdgeCaseBytes.d\")]\nfn invalid_access_d() {\n    let mut bytes = EdgeCaseBytes::new();\n    bytes.set_d(0b0001_0000_u8);\n}\n"
  },
  {
    "path": "tests/ui/access_test.rs",
    "content": "mod inner {\n    use modular_bitfield::prelude::*;\n    #[bitfield]\n    #[derive(Copy, Clone, Eq, PartialEq, Default)]\n    pub struct ColorEntry {\n        a: B5,\n        pub(crate) b: B3,\n    }\n}\nuse inner::*;\n\nfn main() {\n    let c = ColorEntry::new();\n    let _ = c.a();\n    // Notice no error for calling b\n    let _ = c.b();\n    // Also no error for using default\n    let c = ColorEntry::default();\n}\n"
  },
  {
    "path": "tests/ui/access_test.stderr",
    "content": "error[E0624]: method `a` is private\n  --> tests/ui/access_test.rs:14:15\n   |\n 6 |         a: B5,\n   |         - private method defined here\n...\n14 |     let _ = c.a();\n   |               ^ private method\n"
  },
  {
    "path": "tests/ui/bitfield_attribute_wrong.rs",
    "content": "use modular_bitfield::prelude::*;\n\n#[bitfield(unknown_attribute = 0)]\nstruct Foo {\n    value: u8,\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/bitfield_attribute_wrong.stderr",
    "content": "error: encountered unsupported #[bitfield] attribute\n --> tests/ui/bitfield_attribute_wrong.rs:3:12\n  |\n3 | #[bitfield(unknown_attribute = 0)]\n  |            ^^^^^^^^^^^^^^^^^\n"
  },
  {
    "path": "tests/ui/bits_attribute_wrong.rs",
    "content": "use modular_bitfield::prelude::*;\n\n#[derive(Specifier, Debug)]\npub enum TriggerMode {\n    Edge = 0,\n    Level = 1,\n}\n\n#[bitfield]\npub struct MismatchedTypes {\n    #[bits = 9]\n    trigger_mode: TriggerMode,\n    reserved: B7,\n}\n\nconst NOT_A_LITERAL: u32 = 9;\n\n#[bitfield]\npub struct InvalidValueType {\n    #[bits = NOT_A_LITERAL]\n    trigger_mode: TriggerMode,\n    reserved: B7,\n}\n\n#[bitfield]\npub struct DuplicateAttribute {\n    #[bits = 1]\n    #[bits = 1]\n    trigger_mode: TriggerMode,\n    reserved: B7,\n}\n\n#[bitfield]\npub struct NotANameValue {\n    #[bits(1)]\n    trigger_mode: TriggerMode,\n    reserved: B7,\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/bits_attribute_wrong.stderr",
    "content": "error: encountered invalid value type for #[bits = N]\n  --> tests/ui/bits_attribute_wrong.rs:20:14\n   |\n20 |     #[bits = NOT_A_LITERAL]\n   |              ^^^^^^^^^^^^^\n\nerror: encountered duplicate `#[bits = N]` attribute for field\n  --> tests/ui/bits_attribute_wrong.rs:28:7\n   |\n28 |     #[bits = 1]\n   |       ^^^^\n\nerror: duplicate `#[bits = N]` here\n  --> tests/ui/bits_attribute_wrong.rs:27:7\n   |\n27 |     #[bits = 1]\n   |       ^^^^\n\nerror: expected `=`\n  --> tests/ui/bits_attribute_wrong.rs:35:11\n   |\n35 |     #[bits(1)]\n   |           ^\n\nerror[E0308]: mismatched types\n  --> tests/ui/bits_attribute_wrong.rs:11:7\n   |\n11 |     #[bits = 9]\n   |       ^^^^ expected `1`, found `9`\n12 |     trigger_mode: TriggerMode,\n   |                   ----------- expected due to this\n   |\n   = note: expected struct `BitCount<1>`\n              found struct `BitCount<9>`\n"
  },
  {
    "path": "tests/ui/bits_param/conflicting_params.rs",
    "content": "use modular_bitfield::prelude::*;\n\n#[bitfield(bits = 16, bytes = 4)]\npub struct SignInteger {\n    sign: bool,\n    value: B31,\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/bits_param/conflicting_params.stderr",
    "content": "error: encountered conflicting `bits = 16` and `bytes = 4` parameters\n --> tests/ui/bits_param/conflicting_params.rs:3:1\n  |\n3 | #[bitfield(bits = 16, bytes = 4)]\n  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n  |\n  = note: this error originates in the attribute macro `bitfield` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: conflicting `bits = 16` here\n --> tests/ui/bits_param/conflicting_params.rs:3:12\n  |\n3 | #[bitfield(bits = 16, bytes = 4)]\n  |            ^^^^\n\nerror: conflicting `bytes = 4` here\n --> tests/ui/bits_param/conflicting_params.rs:3:23\n  |\n3 | #[bitfield(bits = 16, bytes = 4)]\n  |                       ^^^^^\n"
  },
  {
    "path": "tests/ui/bits_param/conflicting_repr.rs",
    "content": "use modular_bitfield::prelude::*;\n\n#[bitfield(bits = 16)]\n#[repr(u32)]\npub struct SignInteger {\n    sign: bool,\n    value: B31,\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/bits_param/conflicting_repr.stderr",
    "content": "error: encountered conflicting `bits = 16` and #[repr(u32)] parameters\n --> tests/ui/bits_param/conflicting_repr.rs:3:1\n  |\n3 | #[bitfield(bits = 16)]\n  | ^^^^^^^^^^^^^^^^^^^^^^\n  |\n  = note: this error originates in the attribute macro `bitfield` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: conflicting `bits = 16` here\n --> tests/ui/bits_param/conflicting_repr.rs:3:12\n  |\n3 | #[bitfield(bits = 16)]\n  |            ^^^^\n\nerror: conflicting #[repr(u32)] here\n --> tests/ui/bits_param/conflicting_repr.rs:4:8\n  |\n4 | #[repr(u32)]\n  |        ^^^\n"
  },
  {
    "path": "tests/ui/bits_param/duplicate_param_1.rs",
    "content": "use modular_bitfield::prelude::*;\n\n#[bitfield(bits = 32, bits = 32)]\npub struct SignInteger {\n    sign: bool,\n    value: B31,\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/bits_param/duplicate_param_1.stderr",
    "content": "error: encountered duplicate `bits` parameter: duplicate set to 32\n --> tests/ui/bits_param/duplicate_param_1.rs:3:23\n  |\n3 | #[bitfield(bits = 32, bits = 32)]\n  |                       ^^^^\n\nerror: previous `bits` parameter here\n --> tests/ui/bits_param/duplicate_param_1.rs:3:12\n  |\n3 | #[bitfield(bits = 32, bits = 32)]\n  |            ^^^^\n"
  },
  {
    "path": "tests/ui/bits_param/duplicate_param_2.rs",
    "content": "use modular_bitfield::prelude::*;\n\n#[bitfield(bits = 32, bits = 16)]\npub struct SignInteger {\n    sign: bool,\n    value: B31,\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/bits_param/duplicate_param_2.stderr",
    "content": "error: encountered duplicate `bits` parameter: duplicate set to 32\n --> tests/ui/bits_param/duplicate_param_2.rs:3:23\n  |\n3 | #[bitfield(bits = 32, bits = 16)]\n  |                       ^^^^\n\nerror: previous `bits` parameter here\n --> tests/ui/bits_param/duplicate_param_2.rs:3:12\n  |\n3 | #[bitfield(bits = 32, bits = 16)]\n  |            ^^^^\n"
  },
  {
    "path": "tests/ui/bits_param/invalid_param_type.rs",
    "content": "use modular_bitfield::prelude::*;\n\nconst NOT_LITERAL: u32 = 32;\n\n#[bitfield(bits = NOT_LITERAL)]\npub struct SignInteger {\n    sign: bool,\n    value: B31,\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/bits_param/invalid_param_type.stderr",
    "content": "error: encountered invalid value argument for #[bitfield] `bits` parameter\n --> tests/ui/bits_param/invalid_param_type.rs:5:19\n  |\n5 | #[bitfield(bits = NOT_LITERAL)]\n  |                   ^^^^^^^^^^^\n"
  },
  {
    "path": "tests/ui/bits_param/invalid_param_value_1.rs",
    "content": "use modular_bitfield::prelude::*;\n\n#[bitfield(bits = true)]\npub struct SignInteger {\n    sign: bool,\n    value: B31,\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/bits_param/invalid_param_value_1.stderr",
    "content": "error: encountered invalid value argument for #[bitfield] `bits` parameter\n --> tests/ui/bits_param/invalid_param_value_1.rs:3:19\n  |\n3 | #[bitfield(bits = true)]\n  |                   ^^^^\n"
  },
  {
    "path": "tests/ui/bits_param/invalid_param_value_2.rs",
    "content": "use modular_bitfield::prelude::*;\n\n#[bitfield(bits = -1)]\npub struct SignInteger {\n    sign: bool,\n    value: B31,\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/bits_param/invalid_param_value_2.stderr",
    "content": "error: encountered malformatted integer value for `bits` parameter: invalid digit found in string\n --> tests/ui/bits_param/invalid_param_value_2.rs:3:19\n  |\n3 | #[bitfield(bits = -1)]\n  |                   ^\n"
  },
  {
    "path": "tests/ui/bits_param/missing_param_value.rs",
    "content": "use modular_bitfield::prelude::*;\n\n#[bitfield(bits)]\npub struct Missing {\n    sign: bool,\n    value: B31,\n}\n\n#[bitfield(bits(32))]\npub struct WrongMetaType {\n    sign: bool,\n    value: B31,\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/bits_param/missing_param_value.stderr",
    "content": "error: expected `=`\n --> tests/ui/bits_param/missing_param_value.rs:3:1\n  |\n3 | #[bitfield(bits)]\n  | ^^^^^^^^^^^^^^^^^\n  |\n  = note: this error originates in the attribute macro `bitfield` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: expected `=`\n --> tests/ui/bits_param/missing_param_value.rs:9:16\n  |\n9 | #[bitfield(bits(32))]\n  |                ^\n"
  },
  {
    "path": "tests/ui/bits_param/too_few_bits.rs",
    "content": "use modular_bitfield::prelude::*;\n\n#[bitfield(bits = 16)]\npub struct SignInteger {\n    sign: bool,\n    value: B31,\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/bits_param/too_few_bits.stderr",
    "content": "error[E0277]: the trait bound `False: FillsUnalignedBits` is not satisfied\n --> tests/ui/bits_param/too_few_bits.rs:4:1\n  |\n4 | pub struct SignInteger {\n  | ^^^ the trait `FillsUnalignedBits` is not implemented for `False`\n  |\n  = help: the trait `FillsUnalignedBits` is implemented for `True`\nnote: required by a bound in `CheckFillsUnalignedBits::CheckType`\n --> src/private/checks.rs\n  |\n  |     <Self::CheckType as DispatchTrueFalse>::Out: FillsUnalignedBits,\n  |                                                  ^^^^^^^^^^^^^^^^^^ required by this bound in `CheckFillsUnalignedBits::CheckType`\n  | {\n  |     type CheckType: DispatchTrueFalse;\n  |          --------- required by a bound in this associated type\n\nerror[E0277]: the trait bound `False: FillsUnalignedBits` is not satisfied\n --> tests/ui/bits_param/too_few_bits.rs:4:1\n  |\n4 | pub struct SignInteger {\n  | ^^^ the trait `FillsUnalignedBits` is not implemented for `False`\n  |\n  = help: the trait `FillsUnalignedBits` is implemented for `True`\nnote: required by a bound in `CheckFillsUnalignedBits`\n --> src/private/checks.rs\n  |\n  | pub trait CheckFillsUnalignedBits\n  |           ----------------------- required by a bound in this trait\n  | where\n  |     <Self::CheckType as DispatchTrueFalse>::Out: FillsUnalignedBits,\n  |                                                  ^^^^^^^^^^^^^^^^^^ required by this bound in `CheckFillsUnalignedBits`\n  = note: `CheckFillsUnalignedBits` is a \"sealed trait\", because to implement it you also need to implement `modular_bitfield::private::checks::FillsUnalignedBits`, which is not accessible; this is usually done to force you to use one of the provided types that already implement it\n  = help: the following type implements the trait:\n            modular_bitfield::private::checks::True\n"
  },
  {
    "path": "tests/ui/bits_param/too_many_bits.rs",
    "content": "use modular_bitfield::prelude::*;\n\n#[bitfield(bits = 33)]\npub struct SignInteger {\n    sign: bool,\n    value: B31,\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/bits_param/too_many_bits.stderr",
    "content": "error[E0277]: the trait bound `False: FillsUnalignedBits` is not satisfied\n --> tests/ui/bits_param/too_many_bits.rs:4:1\n  |\n4 | pub struct SignInteger {\n  | ^^^ the trait `FillsUnalignedBits` is not implemented for `False`\n  |\n  = help: the trait `FillsUnalignedBits` is implemented for `True`\nnote: required by a bound in `CheckFillsUnalignedBits::CheckType`\n --> src/private/checks.rs\n  |\n  |     <Self::CheckType as DispatchTrueFalse>::Out: FillsUnalignedBits,\n  |                                                  ^^^^^^^^^^^^^^^^^^ required by this bound in `CheckFillsUnalignedBits::CheckType`\n  | {\n  |     type CheckType: DispatchTrueFalse;\n  |          --------- required by a bound in this associated type\n\nerror[E0277]: the trait bound `False: FillsUnalignedBits` is not satisfied\n --> tests/ui/bits_param/too_many_bits.rs:4:1\n  |\n4 | pub struct SignInteger {\n  | ^^^ the trait `FillsUnalignedBits` is not implemented for `False`\n  |\n  = help: the trait `FillsUnalignedBits` is implemented for `True`\nnote: required by a bound in `CheckFillsUnalignedBits`\n --> src/private/checks.rs\n  |\n  | pub trait CheckFillsUnalignedBits\n  |           ----------------------- required by a bound in this trait\n  | where\n  |     <Self::CheckType as DispatchTrueFalse>::Out: FillsUnalignedBits,\n  |                                                  ^^^^^^^^^^^^^^^^^^ required by this bound in `CheckFillsUnalignedBits`\n  = note: `CheckFillsUnalignedBits` is a \"sealed trait\", because to implement it you also need to implement `modular_bitfield::private::checks::FillsUnalignedBits`, which is not accessible; this is usually done to force you to use one of the provided types that already implement it\n  = help: the following type implements the trait:\n            modular_bitfield::private::checks::True\n"
  },
  {
    "path": "tests/ui/bytes_param/duplicate_parameters.rs",
    "content": "use modular_bitfield::prelude::*;\n\n// There are 2 duplicate bytes parameters.\n#[bitfield(bytes = 4, bytes = 4)]\npub struct Base {\n    a: B2,\n    b: B6,\n    c: u8,\n    d: u16,\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/bytes_param/duplicate_parameters.stderr",
    "content": "error: encountered duplicate `bytes` parameter: duplicate set to 4\n --> tests/ui/bytes_param/duplicate_parameters.rs:4:23\n  |\n4 | #[bitfield(bytes = 4, bytes = 4)]\n  |                       ^^^^^\n\nerror: previous `bytes` parameter here\n --> tests/ui/bytes_param/duplicate_parameters.rs:4:12\n  |\n4 | #[bitfield(bytes = 4, bytes = 4)]\n  |            ^^^^^\n"
  },
  {
    "path": "tests/ui/bytes_param/fewer_bytes_than_expected.rs",
    "content": "use modular_bitfield::prelude::*;\n\n// Requires 3 bytes in total instead of 4.\n#[bitfield(bytes = 4)]\npub struct Base {\n    a: B2,\n    b: B6,\n    c: u8,\n    d: u8,\n}\n\nfn main() {\n    assert_eq!(core::mem::size_of::<Base>(), 3)\n}\n"
  },
  {
    "path": "tests/ui/bytes_param/fewer_bytes_than_expected.stderr",
    "content": "error[E0512]: cannot transmute between types of different sizes, or dependently-sized types\n --> tests/ui/bytes_param/fewer_bytes_than_expected.rs:4:12\n  |\n4 | #[bitfield(bytes = 4)]\n  |            ^^^^^\n  |\n  = note: source type: `ExpectedBytes` (32 bits)\n  = note: target type: `Base` (24 bits)\n  = note: this error originates in the macro `::modular_bitfield::private::static_assertions::assert_eq_size` (in Nightly builds, run with -Z macro-backtrace for more info)\n"
  },
  {
    "path": "tests/ui/bytes_param/invalid_int_value.rs",
    "content": "use modular_bitfield::prelude::*;\n\n// The integer value cannot be parsed into a `usize` since it is negative.\n#[bitfield(bytes = -1)]\npub struct Base {\n    a: B2,\n    b: B6,\n    c: u8,\n    d: u32,\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/bytes_param/invalid_int_value.stderr",
    "content": "error: encountered malformatted integer value for `bytes` parameter: invalid digit found in string\n --> tests/ui/bytes_param/invalid_int_value.rs:4:20\n  |\n4 | #[bitfield(bytes = -1)]\n  |                    ^\n"
  },
  {
    "path": "tests/ui/bytes_param/invalid_type.rs",
    "content": "use modular_bitfield::prelude::*;\n\n// The bytes parameter is required to have an integer value.\n#[bitfield(bytes = true)]\npub struct Base {\n    a: B2,\n    b: B6,\n    c: u8,\n    d: u32,\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/bytes_param/invalid_type.stderr",
    "content": "error: encountered invalid value argument for #[bitfield] `bytes` parameter\n --> tests/ui/bytes_param/invalid_type.rs:4:20\n  |\n4 | #[bitfield(bytes = true)]\n  |                    ^^^^\n"
  },
  {
    "path": "tests/ui/bytes_param/more_bytes_than_expected.rs",
    "content": "use modular_bitfield::prelude::*;\n\n// Requires 6 bytes in total instead of 4.\n#[bitfield(bytes = 4)]\npub struct Base {\n    a: B2,\n    b: B6,\n    c: u8,\n    d: u32,\n}\n\nfn main() {\n    assert_eq!(core::mem::size_of::<Base>(), 6)\n}\n"
  },
  {
    "path": "tests/ui/bytes_param/more_bytes_than_expected.stderr",
    "content": "error[E0512]: cannot transmute between types of different sizes, or dependently-sized types\n --> tests/ui/bytes_param/more_bytes_than_expected.rs:4:12\n  |\n4 | #[bitfield(bytes = 4)]\n  |            ^^^^^\n  |\n  = note: source type: `ExpectedBytes` (32 bits)\n  = note: target type: `Base` (48 bits)\n  = note: this error originates in the macro `::modular_bitfield::private::static_assertions::assert_eq_size` (in Nightly builds, run with -Z macro-backtrace for more info)\n"
  },
  {
    "path": "tests/ui/derive_bitfield_specifier/invalid_bits_attribute.rs",
    "content": "use modular_bitfield::prelude::*;\n\n#[derive(Specifier)]\n#[bits = 1]\n#[bits = 1]\nenum TooManyAttrs {\n    Zero = 0,\n    One = 1,\n}\n\n#[derive(Specifier)]\n#[bits = 1.0]\nenum NotAnInt {\n    Zero = 0,\n    One = 1,\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/derive_bitfield_specifier/invalid_bits_attribute.stderr",
    "content": "error: More than one 'bits' attribute is not permitted\n --> tests/ui/derive_bitfield_specifier/invalid_bits_attribute.rs:5:1\n  |\n5 | #[bits = 1]\n  | ^^^^^^^^^^^\n\nerror: could not parse 'bits' attribute\n  --> tests/ui/derive_bitfield_specifier/invalid_bits_attribute.rs:12:1\n   |\n12 | #[bits = 1.0]\n   | ^^^^^^^^^^^^^\n"
  },
  {
    "path": "tests/ui/derive_bitfield_specifier/non_power_of_two.rs",
    "content": "// Bitfield enums with a number of variants other than a power of two should\n// fail to compile.\n//\n// (Or, if you implemented the optional #[bits = N] enum approach mentioned in\n// the explanation of test case 06, then enums with non-power-of-two variants\n// without a #[bits = N] attribute should fail to compile.)\n\nuse modular_bitfield::prelude::*;\n\n#[derive(Specifier)]\npub enum Bad {\n    Zero,\n    One,\n    Two,\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/derive_bitfield_specifier/non_power_of_two.stderr",
    "content": "error: #[derive(Specifier)] expected a number of variants which is a power of 2, specify #[bits = 2] if that was your intent\n  --> tests/ui/derive_bitfield_specifier/non_power_of_two.rs:11:1\n   |\n11 | pub enum Bad {\n   | ^^^\n"
  },
  {
    "path": "tests/ui/derive_bitfield_specifier/variant_out_of_range.rs",
    "content": "// Bitfield enums with any discriminant (implicit or explicit) outside of the\n// range 0..2^BITS should fail to compile.\n\nuse modular_bitfield::prelude::*;\n\nconst F: isize = 1;\n\n#[derive(Specifier)]\npub enum DeliveryMode {\n    Fixed = F,\n    Lowest,\n    SMI,\n    RemoteRead,\n    NMI,\n    Init,\n    Startup,\n    External,\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/derive_bitfield_specifier/variant_out_of_range.stderr",
    "content": "error[E0277]: the trait bound `False: DiscriminantInRange` is not satisfied\n  --> tests/ui/derive_bitfield_specifier/variant_out_of_range.rs:17:5\n   |\n17 |     External,\n   |     ^^^^^^^^ the trait `DiscriminantInRange` is not implemented for `False`\n   |\n   = help: the trait `DiscriminantInRange` is implemented for `True`\nnote: required by a bound in `CheckDiscriminantInRange::CheckType`\n  --> src/private/checks.rs\n   |\n   |     <Self::CheckType as DispatchTrueFalse>::Out: DiscriminantInRange,\n   |                                                  ^^^^^^^^^^^^^^^^^^^ required by this bound in `CheckDiscriminantInRange::CheckType`\n   | {\n   |     type CheckType: DispatchTrueFalse;\n   |          --------- required by a bound in this associated type\n\nerror[E0277]: the trait bound `False: DiscriminantInRange` is not satisfied\n  --> tests/ui/derive_bitfield_specifier/variant_out_of_range.rs:17:5\n   |\n17 |     External,\n   |     ^^^^^^^^ the trait `DiscriminantInRange` is not implemented for `False`\n   |\n   = help: the trait `DiscriminantInRange` is implemented for `True`\nnote: required by a bound in `CheckDiscriminantInRange`\n  --> src/private/checks.rs\n   |\n   | pub trait CheckDiscriminantInRange<A>\n   |           ------------------------ required by a bound in this trait\n   | where\n   |     <Self::CheckType as DispatchTrueFalse>::Out: DiscriminantInRange,\n   |                                                  ^^^^^^^^^^^^^^^^^^^ required by this bound in `CheckDiscriminantInRange`\n   = note: `CheckDiscriminantInRange` is a \"sealed trait\", because to implement it you also need to implement `modular_bitfield::private::checks::DiscriminantInRange`, which is not accessible; this is usually done to force you to use one of the provided types that already implement it\n   = help: the following type implements the trait:\n             modular_bitfield::private::checks::True\n"
  },
  {
    "path": "tests/ui/derive_debug/duplicate_derive_debug.rs",
    "content": "use modular_bitfield::prelude::*;\n\n#[bitfield]\n#[derive(Debug)] #[derive(Debug)]\npub struct SignedInt {\n    sign: bool,\n    value: B31,\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/derive_debug/duplicate_derive_debug.stderr",
    "content": "error: encountered duplicate `#[derive(Debug)]` parameter\n --> tests/ui/derive_debug/duplicate_derive_debug.rs:4:27\n  |\n4 | #[derive(Debug)] #[derive(Debug)]\n  |                           ^^^^^\n\nerror: previous `#[derive(Debug)]` parameter here\n --> tests/ui/derive_debug/duplicate_derive_debug.rs:4:10\n  |\n4 | #[derive(Debug)] #[derive(Debug)]\n  |          ^^^^^\n"
  },
  {
    "path": "tests/ui/derive_debug/duplicate_derive_debug_2.rs",
    "content": "use modular_bitfield::prelude::*;\n\n#[bitfield]\n#[derive(Debug, Debug)]\npub struct SignedInt {\n    sign: bool,\n    value: B31,\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/derive_debug/duplicate_derive_debug_2.stderr",
    "content": "error: encountered duplicate `#[derive(Debug)]` parameter\n --> tests/ui/derive_debug/duplicate_derive_debug_2.rs:4:17\n  |\n4 | #[derive(Debug, Debug)]\n  |                 ^^^^^\n\nerror: previous `#[derive(Debug)]` parameter here\n --> tests/ui/derive_debug/duplicate_derive_debug_2.rs:4:10\n  |\n4 | #[derive(Debug, Debug)]\n  |          ^^^^^\n"
  },
  {
    "path": "tests/ui/derive_specifier/duplicate_derive_1.rs",
    "content": "use modular_bitfield::prelude::*;\n\n#[bitfield]\n#[derive(Specifier, Specifier)]\npub struct SignedInt {\n    sign: bool,\n    value: B31,\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/derive_specifier/duplicate_derive_1.stderr",
    "content": "error: encountered duplicate `#[derive(Specifier)]` parameter\n --> tests/ui/derive_specifier/duplicate_derive_1.rs:4:21\n  |\n4 | #[derive(Specifier, Specifier)]\n  |                     ^^^^^^^^^\n\nerror: previous `#[derive(Specifier)]` parameter here\n --> tests/ui/derive_specifier/duplicate_derive_1.rs:4:10\n  |\n4 | #[derive(Specifier, Specifier)]\n  |          ^^^^^^^^^\n"
  },
  {
    "path": "tests/ui/derive_specifier/duplicate_derive_2.rs",
    "content": "use modular_bitfield::prelude::*;\n\n#[bitfield]\n#[derive(Specifier)] #[derive(Specifier)]\npub struct SignedInt {\n    sign: bool,\n    value: B31,\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/derive_specifier/duplicate_derive_2.stderr",
    "content": "error: encountered duplicate `#[derive(Specifier)]` parameter\n --> tests/ui/derive_specifier/duplicate_derive_2.rs:4:31\n  |\n4 | #[derive(Specifier)] #[derive(Specifier)]\n  |                               ^^^^^^^^^\n\nerror: previous `#[derive(Specifier)]` parameter here\n --> tests/ui/derive_specifier/duplicate_derive_2.rs:4:10\n  |\n4 | #[derive(Specifier)] #[derive(Specifier)]\n  |          ^^^^^^^^^\n"
  },
  {
    "path": "tests/ui/derive_specifier/out_of_bounds.rs",
    "content": "use modular_bitfield::prelude::*;\n\n#[bitfield(filled = false)]\n#[derive(Specifier, Debug)]\npub struct Header {\n    a: B1,\n    b: B128,\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/derive_specifier/out_of_bounds.stderr",
    "content": "error[E0277]: the trait bound `False: SpecifierHasAtMost128Bits` is not satisfied\n --> tests/ui/derive_specifier/out_of_bounds.rs:4:1\n  |\n4 | #[derive(Specifier, Debug)]\n  | ^ the trait `SpecifierHasAtMost128Bits` is not implemented for `False`\n  |\n  = help: the trait `SpecifierHasAtMost128Bits` is implemented for `True`\nnote: required by a bound in `CheckSpecifierHasAtMost128Bits::CheckType`\n --> src/private/checks.rs\n  |\n  |     <Self::CheckType as DispatchTrueFalse>::Out: SpecifierHasAtMost128Bits,\n  |                                                  ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `CheckSpecifierHasAtMost128Bits::CheckType`\n  | {\n  |     type CheckType: DispatchTrueFalse;\n  |          --------- required by a bound in this associated type\n\nerror[E0277]: the trait bound `False: SpecifierHasAtMost128Bits` is not satisfied\n --> tests/ui/derive_specifier/out_of_bounds.rs:4:1\n  |\n4 | #[derive(Specifier, Debug)]\n  | ^ the trait `SpecifierHasAtMost128Bits` is not implemented for `False`\n  |\n  = help: the trait `SpecifierHasAtMost128Bits` is implemented for `True`\nnote: required by a bound in `CheckSpecifierHasAtMost128Bits`\n --> src/private/checks.rs\n  |\n  | pub trait CheckSpecifierHasAtMost128Bits\n  |           ------------------------------ required by a bound in this trait\n  | where\n  |     <Self::CheckType as DispatchTrueFalse>::Out: SpecifierHasAtMost128Bits,\n  |                                                  ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `CheckSpecifierHasAtMost128Bits`\n  = note: `CheckSpecifierHasAtMost128Bits` is a \"sealed trait\", because to implement it you also need to implement `modular_bitfield::private::checks::SpecifierHasAtMost128Bits`, which is not accessible; this is usually done to force you to use one of the provided types that already implement it\n  = help: the following type implements the trait:\n            modular_bitfield::private::checks::True\n\nerror[E0277]: the trait bound `BitCount<136>: ArrayBytesConversion` is not satisfied\n --> tests/ui/derive_specifier/out_of_bounds.rs:4:1\n  |\n4 | #[derive(Specifier, Debug)]\n  | ^ the trait `ArrayBytesConversion` is not implemented for `BitCount<136>`\n  |\n  = help: the following other types implement trait `ArrayBytesConversion`:\n            BitCount<104>\n            BitCount<112>\n            BitCount<120>\n            BitCount<128>\n            BitCount<16>\n            BitCount<24>\n            BitCount<32>\n            BitCount<40>\n          and $N others\n"
  },
  {
    "path": "tests/ui/empty.rs",
    "content": "use modular_bitfield::prelude::*;\n\n#[bitfield]\nstruct Unit;\n\n#[bitfield]\nstruct Named {}\n\n#[bitfield]\nstruct Unnamed();\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/empty.stderr",
    "content": "error: encountered invalid bitfield struct without fields\n --> tests/ui/empty.rs:4:1\n  |\n4 | struct Unit;\n  | ^^^^^^^^^^^^\n\nerror: encountered invalid bitfield struct without fields\n --> tests/ui/empty.rs:7:1\n  |\n7 | struct Named {}\n  | ^^^^^^^^^^^^^^^\n\nerror: encountered invalid bitfield struct without fields\n  --> tests/ui/empty.rs:10:1\n   |\n10 | struct Unnamed();\n   | ^^^^^^^^^^^^^^^^^\n"
  },
  {
    "path": "tests/ui/filled_param/duplicate_parameters.rs",
    "content": "use modular_bitfield::prelude::*;\n\n// There are 2 duplicate `filled` parameters.\n#[bitfield(filled = true, filled = true)]\npub struct Base {\n    a: B2,\n    b: B6,\n    c: u8,\n    d: u16,\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/filled_param/duplicate_parameters.stderr",
    "content": "error: encountered duplicate `filled` parameter: duplicate set to true\n --> tests/ui/filled_param/duplicate_parameters.rs:4:27\n  |\n4 | #[bitfield(filled = true, filled = true)]\n  |                           ^^^^^^\n\nerror: previous `filled` parameter here\n --> tests/ui/filled_param/duplicate_parameters.rs:4:12\n  |\n4 | #[bitfield(filled = true, filled = true)]\n  |            ^^^^^^\n"
  },
  {
    "path": "tests/ui/filled_param/invalid_bool_value.rs",
    "content": "use modular_bitfield::prelude::*;\n\n// The boolean value cannot be parsed from a string.\n#[bitfield(filled = \"yes\")]\npub struct Base {\n    a: B2,\n    b: B6,\n    c: u8,\n    d: u32,\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/filled_param/invalid_bool_value.stderr",
    "content": "error: encountered invalid value argument for #[bitfield] `filled` parameter\n --> tests/ui/filled_param/invalid_bool_value.rs:4:21\n  |\n4 | #[bitfield(filled = \"yes\")]\n  |                     ^^^^^\n"
  },
  {
    "path": "tests/ui/filled_param/invalid_specified_as_filled.rs",
    "content": "use modular_bitfield::prelude::*;\n\n// The bitfield has exactly 15 bits and therefore is unfilled but not specified as such.\n#[bitfield(filled = true)]\npub struct UnfilledBitfield {\n    a: B7,\n    b: u8,\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/filled_param/invalid_specified_as_filled.stderr",
    "content": "error[E0277]: the trait bound `SevenMod8: TotalSizeIsMultipleOfEightBits` is not satisfied\n --> tests/ui/filled_param/invalid_specified_as_filled.rs:5:1\n  |\n5 | pub struct UnfilledBitfield {\n  | ^^^ the trait `TotalSizeIsMultipleOfEightBits` is not implemented for `SevenMod8`\n  |\n  = help: the trait `TotalSizeIsMultipleOfEightBits` is implemented for `ZeroMod8`\nnote: required by a bound in `CheckTotalSizeMultipleOf8::Size`\n --> src/private/checks.rs\n  |\n  |     <Self::Size as RenameSizeType>::CheckType: TotalSizeIsMultipleOfEightBits,\n  |                                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `CheckTotalSizeMultipleOf8::Size`\n  | {\n  |     type Size: RenameSizeType;\n  |          ---- required by a bound in this associated type\n\nerror[E0277]: the trait bound `SevenMod8: TotalSizeIsMultipleOfEightBits` is not satisfied\n --> tests/ui/filled_param/invalid_specified_as_filled.rs:5:1\n  |\n5 | pub struct UnfilledBitfield {\n  | ^^^ the trait `TotalSizeIsMultipleOfEightBits` is not implemented for `SevenMod8`\n  |\n  = help: the trait `TotalSizeIsMultipleOfEightBits` is implemented for `ZeroMod8`\nnote: required by a bound in `CheckTotalSizeMultipleOf8`\n --> src/private/checks.rs\n  |\n  | pub trait CheckTotalSizeMultipleOf8\n  |           ------------------------- required by a bound in this trait\n  | where\n  |     <Self::Size as RenameSizeType>::CheckType: TotalSizeIsMultipleOfEightBits,\n  |                                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `CheckTotalSizeMultipleOf8`\n  = note: `CheckTotalSizeMultipleOf8` is a \"sealed trait\", because to implement it you also need to implement `modular_bitfield::private::checks::TotalSizeIsMultipleOfEightBits`, which is not accessible; this is usually done to force you to use one of the provided types that already implement it\n  = help: the following type implements the trait:\n            modular_bitfield::private::checks::ZeroMod8\n"
  },
  {
    "path": "tests/ui/filled_param/invalid_specified_as_unfilled.rs",
    "content": "use modular_bitfield::prelude::*;\n\n// The bitfield has exactly 16 bits and therefore is filled but not specified as such.\n#[bitfield(filled = false)]\npub struct UnfilledBitfield {\n    a: B8,\n    b: u8,\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/filled_param/invalid_specified_as_unfilled.stderr",
    "content": "error[E0277]: the trait bound `ZeroMod8: TotalSizeIsNotMultipleOfEightBits` is not satisfied\n --> tests/ui/filled_param/invalid_specified_as_unfilled.rs:5:1\n  |\n5 | pub struct UnfilledBitfield {\n  | ^^^ the trait `TotalSizeIsNotMultipleOfEightBits` is not implemented for `ZeroMod8`\n  |\n  = help: the following other types implement trait `TotalSizeIsNotMultipleOfEightBits`:\n            FiveMod8\n            FourMod8\n            OneMod8\n            SevenMod8\n            SixMod8\n            ThreeMod8\n            TwoMod8\nnote: required by a bound in `CheckTotalSizeIsNotMultipleOf8::Size`\n --> src/private/checks.rs\n  |\n  |     <Self::Size as RenameSizeType>::CheckType: TotalSizeIsNotMultipleOfEightBits,\n  |                                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `CheckTotalSizeIsNotMultipleOf8::Size`\n  | {\n  |     type Size: RenameSizeType;\n  |          ---- required by a bound in this associated type\n\nerror[E0277]: the trait bound `ZeroMod8: TotalSizeIsNotMultipleOfEightBits` is not satisfied\n --> tests/ui/filled_param/invalid_specified_as_unfilled.rs:5:1\n  |\n5 | pub struct UnfilledBitfield {\n  | ^^^ the trait `TotalSizeIsNotMultipleOfEightBits` is not implemented for `ZeroMod8`\n  |\n  = help: the following other types implement trait `TotalSizeIsNotMultipleOfEightBits`:\n            FiveMod8\n            FourMod8\n            OneMod8\n            SevenMod8\n            SixMod8\n            ThreeMod8\n            TwoMod8\nnote: required by a bound in `CheckTotalSizeIsNotMultipleOf8`\n --> src/private/checks.rs\n  |\n  | pub trait CheckTotalSizeIsNotMultipleOf8\n  |           ------------------------------ required by a bound in this trait\n  | where\n  |     <Self::Size as RenameSizeType>::CheckType: TotalSizeIsNotMultipleOfEightBits,\n  |                                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `CheckTotalSizeIsNotMultipleOf8`\n  = note: `CheckTotalSizeIsNotMultipleOf8` is a \"sealed trait\", because to implement it you also need to implement `modular_bitfield::private::checks::TotalSizeIsNotMultipleOfEightBits`, which is not accessible; this is usually done to force you to use one of the provided types that already implement it\n  = help: the following types implement the trait:\n            modular_bitfield::private::checks::OneMod8\n            modular_bitfield::private::checks::TwoMod8\n            modular_bitfield::private::checks::ThreeMod8\n            modular_bitfield::private::checks::FourMod8\n            modular_bitfield::private::checks::FiveMod8\n            modular_bitfield::private::checks::SixMod8\n            modular_bitfield::private::checks::SevenMod8\n"
  },
  {
    "path": "tests/ui/generic.rs",
    "content": "use modular_bitfield::prelude::*;\n\n#[bitfield]\nstruct Generic<T> {\n    t: core::marker::PhantomData<T>,\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/generic.stderr",
    "content": "error: bitfield structs can only use const generics\n --> tests/ui/generic.rs:4:15\n  |\n4 | struct Generic<T> {\n  |               ^^^\n"
  },
  {
    "path": "tests/ui/invalid_struct_specifier.rs",
    "content": "use modular_bitfield::prelude::*;\n\n#[derive(Specifier)]\npub struct InvalidStructSpecifier {\n    a: bool,\n    b: B7,\n    c: u8,\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/invalid_struct_specifier.stderr",
    "content": "error: structs are not supported as bitfield specifiers\n --> tests/ui/invalid_struct_specifier.rs:4:1\n  |\n4 | pub struct InvalidStructSpecifier {\n  | ^^^\n"
  },
  {
    "path": "tests/ui/invalid_union_specifier.rs",
    "content": "use modular_bitfield::prelude::*;\n\n#[derive(Specifier)]\npub union InvalidUnionSpecifier {\n    a: bool,\n    b: B7,\n    c: u8,\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/invalid_union_specifier.stderr",
    "content": "error: unions are not supported as bitfield specifiers\n --> tests/ui/invalid_union_specifier.rs:4:1\n  |\n4 | pub union InvalidUnionSpecifier {\n  | ^^^\n"
  },
  {
    "path": "tests/ui/multiple_of_8bits.rs",
    "content": "// Make it so that a bitfield with a size not a multiple of 8 bits will not\n// compile.\n//\n// Aim to make the error message as relevant and free of distractions as you can\n// get. The stderr file next to this test case should give some idea as to the\n// approach taken by the reference implementation for this project, but feel\n// free to overwrite the stderr file to match the implementation you come up\n// with.\n//\n// ---\n// Tangent\n//\n// There is only one profound insight about Rust macro development, and this\n// test case begins to touch on it: what makes someone an \"expert at macros\"\n// mostly has nothing to do with how good they are \"at macros\".\n//\n// 95% of what enables people to write powerful and user-friendly macro\n// libraries is in their mastery of everything else about Rust outside of\n// macros, and their creativity to put together ordinary language features in\n// interesting ways that may not occur in handwritten code.\n//\n// You may occasionally come across procedural macros that you feel are really\n// advanced or magical. If you ever feel this way, I encourage you to take a\n// closer look and you'll discover that as far as the macro implementation\n// itself is concerned, none of those libraries are doing anything remotely\n// interesting. They always just parse some input in a boring way, crawl some\n// syntax trees in a boring way to find out about the input, and paste together\n// some output code in a boring way exactly like what you've been doing so far.\n// In fact once you've made it this far in the workshop, it's okay to assume you\n// basically know everything there is to know about the mechanics of writing\n// procedural macros.\n//\n// To the extent that there are any tricks to macro development, all of them\n// revolve around *what* code the macros emit, not *how* the macros emit the\n// code. This realization can be surprising to people who entered into macro\n// development with a vague notion of procedural macros as a \"compiler plugin\"\n// which they imagine must imply all sorts of complicated APIs for *how* to\n// integrate with the rest of the compiler. That's not how it works. The only\n// thing macros do is emit code that could have been written by hand. If you\n// couldn't have come up with some piece of tricky code from one of those\n// magical macros, learning more \"about macros\" won't change that; but learning\n// more about every other part of Rust will. Inversely, once you come up with\n// what code you want to generate, writing the macro to generate it is generally\n// the easy part.\n\nuse modular_bitfield::prelude::*;\n\ntype A = B1;\ntype B = B3;\ntype C = B4;\ntype D = B23;\n\n#[bitfield]\npub struct NotQuiteFourBytes {\n    a: A,\n    b: B,\n    c: C,\n    d: D,\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/multiple_of_8bits.stderr",
    "content": "error[E0277]: the trait bound `SevenMod8: TotalSizeIsMultipleOfEightBits` is not satisfied\n  --> tests/ui/multiple_of_8bits.rs:54:1\n   |\n54 | pub struct NotQuiteFourBytes {\n   | ^^^ the trait `TotalSizeIsMultipleOfEightBits` is not implemented for `SevenMod8`\n   |\n   = help: the trait `TotalSizeIsMultipleOfEightBits` is implemented for `ZeroMod8`\nnote: required by a bound in `CheckTotalSizeMultipleOf8::Size`\n  --> src/private/checks.rs\n   |\n   |     <Self::Size as RenameSizeType>::CheckType: TotalSizeIsMultipleOfEightBits,\n   |                                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `CheckTotalSizeMultipleOf8::Size`\n   | {\n   |     type Size: RenameSizeType;\n   |          ---- required by a bound in this associated type\n\nerror[E0277]: the trait bound `SevenMod8: TotalSizeIsMultipleOfEightBits` is not satisfied\n  --> tests/ui/multiple_of_8bits.rs:54:1\n   |\n54 | pub struct NotQuiteFourBytes {\n   | ^^^ the trait `TotalSizeIsMultipleOfEightBits` is not implemented for `SevenMod8`\n   |\n   = help: the trait `TotalSizeIsMultipleOfEightBits` is implemented for `ZeroMod8`\nnote: required by a bound in `CheckTotalSizeMultipleOf8`\n  --> src/private/checks.rs\n   |\n   | pub trait CheckTotalSizeMultipleOf8\n   |           ------------------------- required by a bound in this trait\n   | where\n   |     <Self::Size as RenameSizeType>::CheckType: TotalSizeIsMultipleOfEightBits,\n   |                                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `CheckTotalSizeMultipleOf8`\n   = note: `CheckTotalSizeMultipleOf8` is a \"sealed trait\", because to implement it you also need to implement `modular_bitfield::private::checks::TotalSizeIsMultipleOfEightBits`, which is not accessible; this is usually done to force you to use one of the provided types that already implement it\n   = help: the following type implements the trait:\n             modular_bitfield::private::checks::ZeroMod8\n"
  },
  {
    "path": "tests/ui/regressions/invalid_bits_field_attr.rs",
    "content": "\nuse modular_bitfield::prelude::*;\n\n#[bitfield]\npub struct SignInt {\n    #[bits = 1] // This one is valid.\n    sign: bool,\n    #[whoat_bits = 31] // Should error!\n    value: B31,\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/regressions/invalid_bits_field_attr.stderr",
    "content": "error: cannot find attribute `whoat_bits` in this scope\n --> $DIR/invalid_bits_field_attr.rs:8:7\n  |\n8 |     #[whoat_bits = 31] // Should error!\n  |       ^^^^^^^^^^\n"
  },
  {
    "path": "tests/ui/repr/conflicting_ignored_reprs.rs",
    "content": "use modular_bitfield::prelude::*;\n\n#[bitfield]\n#[repr(C, transparent, u32)] // The macro simply ignores `repr(C)` and `repr(transparent)`\npub struct SignedInt {\n    sign: bool,\n    value: B31,\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/repr/conflicting_ignored_reprs.stderr",
    "content": "error[E0692]: transparent struct cannot have other repr hints\n --> tests/ui/repr/conflicting_ignored_reprs.rs:4:8\n  |\n4 | #[repr(C, transparent, u32)] // The macro simply ignores `repr(C)` and `repr(transparent)`\n  |        ^  ^^^^^^^^^^^\n"
  },
  {
    "path": "tests/ui/repr/duplicate_repr_1.rs",
    "content": "use modular_bitfield::prelude::*;\n\n#[bitfield]\n#[repr(u32)]\n#[repr(u32)]\npub struct SignedInt {\n    sign: bool,\n    value: B31,\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/repr/duplicate_repr_1.stderr",
    "content": "error: encountered duplicate `#[repr(uN)]` parameter: duplicate set to #[repr(u32)]\n --> tests/ui/repr/duplicate_repr_1.rs:5:8\n  |\n5 | #[repr(u32)]\n  |        ^^^\n\nerror: previous `#[repr(uN)]` parameter here\n --> tests/ui/repr/duplicate_repr_1.rs:4:8\n  |\n4 | #[repr(u32)]\n  |        ^^^\n"
  },
  {
    "path": "tests/ui/repr/duplicate_repr_2.rs",
    "content": "use modular_bitfield::prelude::*;\n\n#[bitfield]\n#[cfg_attr(not(test), repr(u32))]\n#[cfg_attr(not(test), repr(u32))]\npub struct SignedInt {\n    sign: bool,\n    value: B31,\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/repr/duplicate_repr_2.stderr",
    "content": "error: encountered duplicate `#[repr(uN)]` parameter: duplicate set to #[repr(u32)]\n --> tests/ui/repr/duplicate_repr_2.rs:5:28\n  |\n5 | #[cfg_attr(not(test), repr(u32))]\n  |                            ^^^\n\nerror: previous `#[repr(uN)]` parameter here\n --> tests/ui/repr/duplicate_repr_2.rs:4:28\n  |\n4 | #[cfg_attr(not(test), repr(u32))]\n  |                            ^^^\n"
  },
  {
    "path": "tests/ui/repr/duplicate_repr_3.rs",
    "content": "use modular_bitfield::prelude::*;\n\n#[bitfield]\n#[repr(u32)]\n#[cfg_attr(not(test), repr(u32))]\npub struct SignedInt {\n    sign: bool,\n    value: B31,\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/repr/duplicate_repr_3.stderr",
    "content": "error: encountered duplicate `#[repr(uN)]` parameter: duplicate set to #[repr(u32)]\n --> tests/ui/repr/duplicate_repr_3.rs:5:28\n  |\n5 | #[cfg_attr(not(test), repr(u32))]\n  |                            ^^^\n\nerror: previous `#[repr(uN)]` parameter here\n --> tests/ui/repr/duplicate_repr_3.rs:4:8\n  |\n4 | #[repr(u32)]\n  |        ^^^\n"
  },
  {
    "path": "tests/ui/repr/invalid_repr_1.rs",
    "content": "use modular_bitfield::prelude::*;\n\n#[bitfield]\n#[repr(invalid)]\npub struct SignedInt {\n    sign: bool,\n    value: B31,\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/repr/invalid_repr_1.stderr",
    "content": "error[E0552]: unrecognized representation hint\n --> tests/ui/repr/invalid_repr_1.rs:4:8\n  |\n4 | #[repr(invalid)]\n  |        ^^^^^^^\n  |\n  = help: valid reprs are `Rust` (default), `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize`\n  = note: for more information, visit <https://doc.rust-lang.org/reference/type-layout.html?highlight=repr#representations>\n"
  },
  {
    "path": "tests/ui/repr/invalid_repr_2.rs",
    "content": "use modular_bitfield::prelude::*;\n\n#[bitfield]\n#[cfg_attr(all(), repr(invalid))]\npub struct SignedInt {\n    sign: bool,\n    value: B31,\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/repr/invalid_repr_2.stderr",
    "content": "error[E0552]: unrecognized representation hint\n --> tests/ui/repr/invalid_repr_2.rs:4:24\n  |\n4 | #[cfg_attr(all(), repr(invalid))]\n  |                        ^^^^^^^\n  |\n  = help: valid reprs are `Rust` (default), `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize`\n  = note: for more information, visit <https://doc.rust-lang.org/reference/type-layout.html?highlight=repr#representations>\n"
  },
  {
    "path": "tests/ui/repr/invalid_repr_unfilled.rs",
    "content": "use modular_bitfield::prelude::*;\n\n#[bitfield(filled = false)]\n#[repr(u32)]\npub struct SignedInt {\n    sign: bool,\n    value: B30,\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/repr/invalid_repr_unfilled.stderr",
    "content": "error: encountered conflicting `#[repr(u32)]` and `filled = false` parameters\n --> tests/ui/repr/invalid_repr_unfilled.rs:3:1\n  |\n3 | #[bitfield(filled = false)]\n  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n  |\n  = note: this error originates in the attribute macro `bitfield` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: conflicting `#[repr(u32)]` here\n --> tests/ui/repr/invalid_repr_unfilled.rs:4:8\n  |\n4 | #[repr(u32)]\n  |        ^^^\n\nerror: conflicting `filled = false` here\n --> tests/ui/repr/invalid_repr_unfilled.rs:3:12\n  |\n3 | #[bitfield(filled = false)]\n  |            ^^^^^^\n"
  },
  {
    "path": "tests/ui/repr/invalid_repr_width_1.rs",
    "content": "use modular_bitfield::prelude::*;\n\n#[bitfield]\n#[repr(u16)] // Too few bits!\npub struct SignedInt {\n    sign: bool,\n    value: B31,\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/repr/invalid_repr_width_1.stderr",
    "content": "error[E0277]: the trait bound `BitCount<32>: IsU16Compatible` is not satisfied\n --> tests/ui/repr/invalid_repr_width_1.rs:4:8\n  |\n4 | #[repr(u16)] // Too few bits!\n  |        ^^^ the trait `IsU16Compatible` is not implemented for `BitCount<32>`\n  |\n  = help: the trait `IsU16Compatible` is implemented for `BitCount<16>`\n  = help: see issue #48214\n\nerror[E0308]: mismatched types\n --> tests/ui/repr/invalid_repr_width_1.rs:4:8\n  |\n4 | #[repr(u16)] // Too few bits!\n  |        ^^^ expected an array with a size of 4, found one with a size of 2\n\nerror[E0308]: mismatched types\n --> tests/ui/repr/invalid_repr_width_1.rs:4:8\n  |\n4 | #[repr(u16)] // Too few bits!\n  |        ^^^\n  |        |\n  |        expected an array with a size of 2, found one with a size of 4\n  |        arguments to this function are incorrect\n  |\nnote: associated function defined here\n --> $RUST/core/src/num/mod.rs\n  = note: this error originates in the macro `uint_impl` (in Nightly builds, run with -Z macro-backtrace for more info)\n"
  },
  {
    "path": "tests/ui/repr/invalid_repr_width_2.rs",
    "content": "use modular_bitfield::prelude::*;\n\n#[bitfield]\n#[repr(u64)] // Too many bits!\npub struct SignedInt {\n    sign: bool,\n    value: B31,\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/repr/invalid_repr_width_2.stderr",
    "content": "error[E0277]: the trait bound `BitCount<32>: IsU64Compatible` is not satisfied\n --> tests/ui/repr/invalid_repr_width_2.rs:4:8\n  |\n4 | #[repr(u64)] // Too many bits!\n  |        ^^^ the trait `IsU64Compatible` is not implemented for `BitCount<32>`\n  |\n  = help: the trait `IsU64Compatible` is implemented for `BitCount<64>`\n  = help: see issue #48214\n\nerror[E0308]: mismatched types\n --> tests/ui/repr/invalid_repr_width_2.rs:4:8\n  |\n4 | #[repr(u64)] // Too many bits!\n  |        ^^^ expected an array with a size of 4, found one with a size of 8\n\nerror[E0308]: mismatched types\n --> tests/ui/repr/invalid_repr_width_2.rs:4:8\n  |\n4 | #[repr(u64)] // Too many bits!\n  |        ^^^\n  |        |\n  |        expected an array with a size of 8, found one with a size of 4\n  |        arguments to this function are incorrect\n  |\nnote: associated function defined here\n --> $RUST/core/src/num/mod.rs\n  = note: this error originates in the macro `uint_impl` (in Nightly builds, run with -Z macro-backtrace for more info)\n"
  },
  {
    "path": "tests/ui/skip/duplicate_attr.rs",
    "content": "use modular_bitfield::prelude::*;\n\n#[bitfield]\npub struct TwoExplicitAll {\n    #[skip]\n    #[skip]\n    unused_1: B15,\n    a: bool,\n}\n\n#[bitfield]\npub struct TwoExplicitListAll {\n    #[skip()]\n    #[skip()]\n    unused_1: B15,\n    a: bool,\n}\n\n#[bitfield]\npub struct TwoExplicitGetters {\n    #[skip(getters)]\n    #[skip(getters)]\n    unused_1: B15,\n    a: bool,\n}\n\n#[bitfield]\npub struct TwoExplicitListGetters {\n    #[skip(getters, getters)]\n    unused_1: B15,\n    a: bool,\n}\n\n#[bitfield]\npub struct ImplicitExplicitGetters {\n    #[skip]\n    #[skip(getters)]\n    unused_1: B15,\n    a: bool,\n}\n\n#[bitfield]\npub struct ExplicitImplicitGetters {\n    #[skip(getters)]\n    #[skip]\n    unused_1: B15,\n    a: bool,\n}\n\n#[bitfield]\npub struct TwoExplicitSetters {\n    #[skip(setters)]\n    #[skip(setters)]\n    unused_1: B15,\n    a: bool,\n}\n\n#[bitfield]\npub struct TwoExplicitListSetters {\n    #[skip(setters, setters)]\n    unused_1: B15,\n    a: bool,\n}\n\n#[bitfield]\npub struct ImplicitExplicitSetters {\n    #[skip]\n    #[skip(setters)]\n    unused_1: B15,\n    a: bool,\n}\n\n#[bitfield]\npub struct ExplicitImplicitSetters {\n    #[skip(setters)]\n    #[skip]\n    unused_1: B15,\n    a: bool,\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/skip/duplicate_attr.stderr",
    "content": "error: encountered duplicate `#[skip]` attribute for field\n --> tests/ui/skip/duplicate_attr.rs:6:7\n  |\n6 |     #[skip]\n  |       ^^^^\n\nerror: duplicate `#[skip]` here\n --> tests/ui/skip/duplicate_attr.rs:5:7\n  |\n5 |     #[skip]\n  |       ^^^^\n\nerror: encountered duplicate `#[skip]` attribute for field\n  --> tests/ui/skip/duplicate_attr.rs:14:7\n   |\n14 |     #[skip()]\n   |       ^^^^\n\nerror: duplicate `#[skip]` here\n  --> tests/ui/skip/duplicate_attr.rs:13:7\n   |\n13 |     #[skip()]\n   |       ^^^^\n\nerror: encountered duplicate `#[skip(getters)]` attribute for field\n  --> tests/ui/skip/duplicate_attr.rs:22:7\n   |\n22 |     #[skip(getters)]\n   |       ^^^^\n\nerror: duplicate `#[skip(getters)]` here\n  --> tests/ui/skip/duplicate_attr.rs:21:7\n   |\n21 |     #[skip(getters)]\n   |       ^^^^\n\nerror: encountered duplicate `#[skip(getters)]` attribute for field\n  --> tests/ui/skip/duplicate_attr.rs:29:21\n   |\n29 |     #[skip(getters, getters)]\n   |                     ^^^^^^^\n\nerror: duplicate `#[skip(getters)]` here\n  --> tests/ui/skip/duplicate_attr.rs:29:12\n   |\n29 |     #[skip(getters, getters)]\n   |            ^^^^^^^\n\nerror: encountered duplicate `#[skip(getters)]` attribute for field\n  --> tests/ui/skip/duplicate_attr.rs:37:7\n   |\n37 |     #[skip(getters)]\n   |       ^^^^\n\nerror: duplicate `#[skip(getters)]` here\n  --> tests/ui/skip/duplicate_attr.rs:36:7\n   |\n36 |     #[skip]\n   |       ^^^^\n\nerror: encountered duplicate `#[skip]` attribute for field\n  --> tests/ui/skip/duplicate_attr.rs:45:7\n   |\n45 |     #[skip]\n   |       ^^^^\n\nerror: duplicate `#[skip]` here\n  --> tests/ui/skip/duplicate_attr.rs:44:7\n   |\n44 |     #[skip(getters)]\n   |       ^^^^\n\nerror: encountered duplicate `#[skip(setters)]` attribute for field\n  --> tests/ui/skip/duplicate_attr.rs:53:7\n   |\n53 |     #[skip(setters)]\n   |       ^^^^\n\nerror: duplicate `#[skip(setters)]` here\n  --> tests/ui/skip/duplicate_attr.rs:52:7\n   |\n52 |     #[skip(setters)]\n   |       ^^^^\n\nerror: encountered duplicate `#[skip(setters)]` attribute for field\n  --> tests/ui/skip/duplicate_attr.rs:60:21\n   |\n60 |     #[skip(setters, setters)]\n   |                     ^^^^^^^\n\nerror: duplicate `#[skip(setters)]` here\n  --> tests/ui/skip/duplicate_attr.rs:60:12\n   |\n60 |     #[skip(setters, setters)]\n   |            ^^^^^^^\n\nerror: encountered duplicate `#[skip(setters)]` attribute for field\n  --> tests/ui/skip/duplicate_attr.rs:68:7\n   |\n68 |     #[skip(setters)]\n   |       ^^^^\n\nerror: duplicate `#[skip(setters)]` here\n  --> tests/ui/skip/duplicate_attr.rs:67:7\n   |\n67 |     #[skip]\n   |       ^^^^\n\nerror: encountered duplicate `#[skip]` attribute for field\n  --> tests/ui/skip/duplicate_attr.rs:76:7\n   |\n76 |     #[skip]\n   |       ^^^^\n\nerror: duplicate `#[skip]` here\n  --> tests/ui/skip/duplicate_attr.rs:75:7\n   |\n75 |     #[skip(setters)]\n   |       ^^^^\n"
  },
  {
    "path": "tests/ui/skip/invalid_specifier.rs",
    "content": "use modular_bitfield::prelude::*;\n\n#[bitfield]\npub struct InvalidSpecifier {\n    #[skip(invalid_specifier)]\n    unused_1: B10,\n    a: bool,\n    #[skip]\n    unused_2: B10,\n    b: bool,\n    #[skip]\n    unused_3: B10,\n}\n\n#[bitfield]\npub struct InvalidFormat {\n    #[skip = 1]\n    unused_1: B10,\n    a: bool,\n    #[skip]\n    unused_2: B10,\n    b: bool,\n    #[skip]\n    unused_3: B10,\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/skip/invalid_specifier.stderr",
    "content": "error: encountered unknown or unsupported #[skip(..)] specifier\n --> tests/ui/skip/invalid_specifier.rs:5:12\n  |\n5 |     #[skip(invalid_specifier)]\n  |            ^^^^^^^^^^^^^^^^^\n\nerror: encountered invalid format for #[skip] field attribute\n  --> tests/ui/skip/invalid_specifier.rs:17:7\n   |\n17 |     #[skip = 1]\n   |       ^^^^\n"
  },
  {
    "path": "tests/ui/skip/use_skipped_getter_1.rs",
    "content": "use modular_bitfield::prelude::*;\n\n#[bitfield]\n#[derive(Debug)]\npub struct Sparse {\n    #[skip(getters)]\n    unused_1: B7,\n    a: bool,\n}\n\nfn main() {\n    let sparse = Sparse::from_bytes([0xFF; 1]);\n    sparse.set_unused_1(0);\n    assert_eq!(sparse.unused_1(), 0); // ERROR!\n}\n"
  },
  {
    "path": "tests/ui/skip/use_skipped_getter_1.stderr",
    "content": "error[E0599]: no method named `unused_1` found for struct `Sparse` in the current scope\n  --> tests/ui/skip/use_skipped_getter_1.rs:14:23\n   |\n 4 | / #[derive(Debug)]\n 5 | | pub struct Sparse {\n   | |___- method `unused_1` not found for this struct\n...\n14 |       assert_eq!(sparse.unused_1(), 0); // ERROR!\n   |                         ^^^^^^^^\n   |\nhelp: there is a method `set_unused_1` with a similar name, but with different arguments\n  --> tests/ui/skip/use_skipped_getter_1.rs:6:5\n   |\n 6 |     #[skip(getters)]\n   |     ^\n"
  },
  {
    "path": "tests/ui/skip/use_skipped_getter_2.rs",
    "content": "use modular_bitfield::prelude::*;\n\n#[bitfield]\n#[derive(Debug)]\npub struct Sparse {\n    #[skip(getters, setters)]\n    unused_1: B7,\n    a: bool,\n}\n\nfn main() {\n    let sparse = Sparse::from_bytes([0xFF; 1]);\n    assert_eq!(sparse.unused_1(), 0xFE); // ERROR!\n}\n"
  },
  {
    "path": "tests/ui/skip/use_skipped_getter_2.stderr",
    "content": "error[E0599]: no method named `unused_1` found for struct `Sparse` in the current scope\n  --> tests/ui/skip/use_skipped_getter_2.rs:13:23\n   |\n 4 | / #[derive(Debug)]\n 5 | | pub struct Sparse {\n   | |___- method `unused_1` not found for this struct\n...\n13 |       assert_eq!(sparse.unused_1(), 0xFE); // ERROR!\n   |                         ^^^^^^^^ method not found in `Sparse`\n"
  },
  {
    "path": "tests/ui/skip/use_skipped_getter_3.rs",
    "content": "use modular_bitfield::prelude::*;\n\n#[bitfield]\n#[derive(Debug)]\npub struct Sparse {\n    #[skip(getters)] #[skip(setters)]\n    unused_1: B7,\n    a: bool,\n}\n\nfn main() {\n    let sparse = Sparse::from_bytes([0xFF; 1]);\n    assert_eq!(sparse.unused_1(), 0xFE); // ERROR!\n}\n"
  },
  {
    "path": "tests/ui/skip/use_skipped_getter_3.stderr",
    "content": "error[E0599]: no method named `unused_1` found for struct `Sparse` in the current scope\n  --> tests/ui/skip/use_skipped_getter_3.rs:13:23\n   |\n 4 | / #[derive(Debug)]\n 5 | | pub struct Sparse {\n   | |___- method `unused_1` not found for this struct\n...\n13 |       assert_eq!(sparse.unused_1(), 0xFE); // ERROR!\n   |                         ^^^^^^^^ method not found in `Sparse`\n"
  },
  {
    "path": "tests/ui/skip/use_skipped_setter_1.rs",
    "content": "use modular_bitfield::prelude::*;\n\n#[bitfield]\n#[derive(Debug)]\npub struct Sparse {\n    #[skip(setters)]\n    unused_1: B7,\n    a: bool,\n}\n\nfn main() {\n    let sparse = Sparse::new();\n    assert_eq!(sparse.unused_1(), 0);\n    sparse.set_unused_1(0b11_1111_1111); // ERROR!\n}\n"
  },
  {
    "path": "tests/ui/skip/use_skipped_setter_1.stderr",
    "content": "error[E0599]: no method named `set_unused_1` found for struct `Sparse` in the current scope\n  --> tests/ui/skip/use_skipped_setter_1.rs:14:12\n   |\n 4 | / #[derive(Debug)]\n 5 | | pub struct Sparse {\n   | |___- method `set_unused_1` not found for this struct\n...\n14 |       sparse.set_unused_1(0b11_1111_1111); // ERROR!\n   |              ^^^^^^^^^^^^\n   |\nhelp: there is a method `unused_1` with a similar name, but with different arguments\n  --> tests/ui/skip/use_skipped_setter_1.rs:6:5\n   |\n 6 |     #[skip(setters)]\n   |     ^\n"
  },
  {
    "path": "tests/ui/skip/use_skipped_setter_2.rs",
    "content": "use modular_bitfield::prelude::*;\n\n#[bitfield]\n#[derive(Debug)]\npub struct Sparse {\n    #[skip(getters, setters)]\n    unused_1: B7,\n    a: bool,\n}\n\nfn main() {\n    let sparse = Sparse::from_bytes([0xFF; 1]);\n    sparse.set_unused_1(0); // ERROR!\n}\n"
  },
  {
    "path": "tests/ui/skip/use_skipped_setter_2.stderr",
    "content": "error[E0599]: no method named `set_unused_1` found for struct `Sparse` in the current scope\n  --> tests/ui/skip/use_skipped_setter_2.rs:13:12\n   |\n 4 | / #[derive(Debug)]\n 5 | | pub struct Sparse {\n   | |___- method `set_unused_1` not found for this struct\n...\n13 |       sparse.set_unused_1(0); // ERROR!\n   |              ^^^^^^^^^^^^ method not found in `Sparse`\n"
  },
  {
    "path": "tests/ui/skip/use_skipped_setter_3.rs",
    "content": "use modular_bitfield::prelude::*;\n\n#[bitfield]\n#[derive(Debug)]\npub struct Sparse {\n    #[skip(getters)] #[skip(setters)]\n    unused_1: B7,\n    a: bool,\n}\n\nfn main() {\n    let sparse = Sparse::from_bytes([0xFF; 1]);\n    sparse.set_unused_1(0); // ERROR!\n}\n"
  },
  {
    "path": "tests/ui/skip/use_skipped_setter_3.stderr",
    "content": "error[E0599]: no method named `set_unused_1` found for struct `Sparse` in the current scope\n  --> tests/ui/skip/use_skipped_setter_3.rs:13:12\n   |\n 4 | / #[derive(Debug)]\n 5 | | pub struct Sparse {\n   | |___- method `set_unused_1` not found for this struct\n...\n13 |       sparse.set_unused_1(0); // ERROR!\n   |              ^^^^^^^^^^^^ method not found in `Sparse`\n"
  },
  {
    "path": "tests/ui/unused_must_use.rs",
    "content": "#![deny(unused_must_use)]\n\nuse modular_bitfield::prelude::*;\n\n#[bitfield]\nstruct Foo {\n    a: B8,\n}\n\nfn main() {\n    Foo::new();\n    Foo::new().with_a(0);\n    Foo::new().a();\n    Foo::from_bytes([0]);\n}\n"
  },
  {
    "path": "tests/ui/unused_must_use.stderr",
    "content": "error: unused return value of `Foo::new` that must be used\n  --> tests/ui/unused_must_use.rs:11:5\n   |\n11 |     Foo::new();\n   |     ^^^^^^^^^^\n   |\nnote: the lint level is defined here\n  --> tests/ui/unused_must_use.rs:1:9\n   |\n 1 | #![deny(unused_must_use)]\n   |         ^^^^^^^^^^^^^^^\nhelp: use `let _ = ...` to ignore the resulting value\n   |\n11 |     let _ = Foo::new();\n   |     +++++++\n\nerror: unused return value of `Foo::with_a` that must be used\n  --> tests/ui/unused_must_use.rs:12:5\n   |\n12 |     Foo::new().with_a(0);\n   |     ^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `let _ = ...` to ignore the resulting value\n   |\n12 |     let _ = Foo::new().with_a(0);\n   |     +++++++\n\nerror: unused return value of `Foo::a` that must be used\n  --> tests/ui/unused_must_use.rs:13:5\n   |\n13 |     Foo::new().a();\n   |     ^^^^^^^^^^^^^^\n   |\nhelp: use `let _ = ...` to ignore the resulting value\n   |\n13 |     let _ = Foo::new().a();\n   |     +++++++\n\nerror: unused return value of `Foo::from_bytes` that must be used\n  --> tests/ui/unused_must_use.rs:14:5\n   |\n14 |     Foo::from_bytes([0]);\n   |     ^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `let _ = ...` to ignore the resulting value\n   |\n14 |     let _ = Foo::from_bytes([0]);\n   |     +++++++\n"
  },
  {
    "path": "tests/ui.rs",
    "content": "//! Tests for emitted diagnostics\n\n#[cfg(all(test, not(miri)))]\n#[test]\nfn ui_trybuild() {\n    let t = trybuild::TestCases::new();\n    t.compile_fail(\"tests/ui/**/*.rs\");\n}\n"
  }
]