[
  {
    "path": ".github/workflows/rust.yml",
    "content": "name: Rust\n\non: \n  push:\n  pull_request:\n  schedule:\n    - cron: '0 0 1 * *'\n\nenv:\n  CARGO_TERM_COLOR: always\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n\n    strategy:\n      max-parallel: 2\n      matrix:\n        rust: [stable, beta, nightly, 1.71.0, 1.83.0]\n\n    steps:\n    - uses: actions/checkout@v2\n    - name: ci-all-versions\n      run: |\n        rustup override set ${{ matrix.rust }}\n        cargo update\n          \n        cd \"${{github.workspace}}/const_format_proc_macros/\"\n        cargo test\n\n        cd \"${{github.workspace}}/const_format/\"\n        cargo test --features \"__test\"\n\n        cargo test --features \"__test assertcp\"\n\n    - uses: actions/checkout@v2\n    - name: ci-non-msrv\n      if: ${{ matrix.rust != '1.71.0' }}\n      run: |\n        rustup override set ${{ matrix.rust }}\n\n        cargo update\n\n        cd \"${{github.workspace}}/const_format/\"\n        \n        cargo test --features \"__test\"\n        cargo test --features \"__test more_str_macros\"\n        cargo test --features \"__test assertcp\"\n        cargo test --features \"__test fmt\"\n        cargo test --features \"__test assertc\"\n        cargo test --features \"__test derive\"\n        cargo test --features \"__test constant_time_as_str\"\n        cargo test --features \"__test rust_1_83\"\n        cargo test --features \"__test derive constant_time_as_str\"\n        cargo test --features \"__test derive constant_time_as_str assertc\"\n        cargo test --features \"__test derive constant_time_as_str assertc more_str_macros rust_1_83\"\n\n    - uses: actions/checkout@v2\n    - name: ci-nighly\n      if: ${{ matrix.rust == 'nightly' && runner.os == 'Linux' }}\n      run: |\n        rustup override set ${{ matrix.rust }}\n\n        cargo update -Z minimal-versions\n        \n        cd \"${{github.workspace}}/const_format_proc_macros/\"\n        cargo test\n\n        cd \"${{github.workspace}}/const_format/\"\n\n        # enable `__inline_const_pat_tests` feature if `const {...}` pats are allowed\n        cargo test --features \"__test derive constant_time_as_str assertc more_str_macros rust_1_83\"\n\n        MIRI_NIGHTLY=nightly-$(curl -s https://rust-lang.github.io/rustup-components-history/x86_64-unknown-linux-gnu/miri)\n        MIRIFLAGS=\"-Zmiri-strict-provenance -Zmiri-check-number-validity -Zmiri-symbolic-alignment-check\"\n        echo \"Installing latest nightly with Miri\"\n        echo \"$MIRI_NIGHTLY\"\n        rustup set profile minimal\n        rustup default \"$MIRI_NIGHTLY\"\n        rustup override set \"$MIRI_NIGHTLY\"\n        rustup component add miri\n        cargo miri setup\n\n        cargo clean \n\n        # tests the crate without the constant_time_as_str feature \n        # (and also without any feature that implies it)\n        cargo miri test --tests --features \"__test derive fmt assertc\"\n        \n        # tests the crate with every feature, including constant_time_as_str \n        # enable `__inline_const_pat_tests` feature if `const {...}` pats are allowed\n        cargo miri test \\\n        --features \"__test derive constant_time_as_str assertc more_str_macros rust_1_83\"\n"
  },
  {
    "path": ".gitignore",
    "content": "/target\n**/*.rs.bk\n**/*.7z\nCargo.lock\n__ignored__*"
  },
  {
    "path": "Cargo.toml",
    "content": "[workspace]\nmembers=[\n    \"const_format\",\n    \"const_format_proc_macros\",\n    \"print_errors\",\n    \"print_warnings\",\n]\nresolver = \"2\""
  },
  {
    "path": "Changelog.md",
    "content": "This is the changelog,summarising changes in each version(some minor changes may be ommited).\n\n# 0.2 \n\n### 0.2.36\n\nBreaking change: bumped Minimum Supported Rust Version to Rust 1.71. This change is motivated by `quote` increasing its MSRV to 1.71.\n\nNow the `\"rust_1_64\"` feature is effectively always enabled, so these items are always enabled:\n- `const_format::str_split`\n\nDeprecated these items because their replacements now take constant time to run:\n- `const_format::fmt::StrWriter::as_bytes_alt`: superceeded by `as_bytes`\n- `const_format::fmt::StrWriter::as_str_alt`: superceeded by `as_str`\n- `const_format::fmt::StrWriterMut::as_bytes_alt`: superceeded by `as_bytes`\n- `const_format::fmt::StrWriterMut::as_str_alt`: superceeded by `as_str`\n- `const_format::utils::slice_up_to_len_alt`: superceeded by `slice_up_to_len`\n\nChanged these methods from being conditionally const (by requiring the `\"rust_1_64\"` feature to be const) to being unconditionally const:\n- `const_format::fmt::StrWriter::as_bytes`\n- `const_format::fmt::StrWriter::as_str`\n- `const_format::fmt::StrWriterMut::as_bytes`\n- `const_format::fmt::StrWriterMut::as_str`\n\nChanged this method to be `const`:\n- `const_format::AsciiStr::as_str`\n\nFixed nightly 2026-04-09 compatibility when `cargo update -Z minimal-versions` is used by bumping `konst` internal dependency to `\"0.2.20\"` version\n\n### 0.2.35\n\nBreaking change: bumped Minimum Supported Rust Version to Rust 1.60. This change is motivated by `quote` increasing its MSRV to 1.60.\n\n### 0.2.34\n\nNow all features that used to require nightly only require Rust 1.83.0\n\nAdded `\"rust_1_83\"` feature that enables `\"rust_1_64\"` feature\n\nChanged `\"fmt\"` feature to enable `\"rust_1_83\"` feature\n\nMade many macros forward compatible with inline const patterns(when the `\"rust_1_83\"` feature is enabled):\n- `concatc`\n- `concatcp`\n- `formatc`\n- `formatcp`\n- `map_ascii_case`\n- `str_get`\n- `str_index`\n- `str_repeat`\n- `str_replace`\n\nAdded these macros:\n- `str_splice_out`\n- `str_split_alt`\n\n### 0.2.33\n\nFixed Rust Analyzer style warning for assertion macros.\n\n### 0.2.32\n\nBreaking change: bumped Minimum Supported Rust Version to Rust 1.57 and changed crate's edition to 2021. This change is motivated by proc-macro2 increasing its MSRV to 1.56.\n\nChanged these items that needed the `\"rust_1_51\"` feature into always being enabled:\n- `map_ascii_case`\n- `str_replace`\n\n### 0.2.31\n\nAdded a workaround for rustdoc bug (https://github.com/rust-lang/rust/issues/112085).\n\n### 0.2.29\n\nAdded lowercase hexadecimal formatting support.\n    \nBreaking: to add lowercase hexadecimal formatting, this crate changed the uppercase hexadecimal formatter from `{:x}` to `{:X}`\n\n\n### 0.2.27\n\nReplacing existing features with these:\n- `\"rust_1_64\"`: superceeding the soft-deprecated `\"more_str_macros\"` feature.\n- `\"rust_1_51\"`: superceeding the soft-deprecated `\"const_generics\"` feature.\nThe new features are enabled by the feature they superceede.\n\nNow the `\"fmt\"` feature enables the `\"rust_1_64\"` feature.\n\n### 0.2.26 \n\nAdded `\"more_str_macros\"` crate feature.\n\nAdded `str_split` macro, conditional on the `\"more_str_macros\"` feature.\n\nAdded `char` pattern support to `str_replace`.\n\n### 0.2.25\n\nFixed the `clippy::double_parens` (false positive) warning by \nencoding the `&'static str` type annotation some other way.\n\nMade `SplicedStr`, `Formatting`, and `NumberFormatting` derive `Eq` .\n\n### 0.2.24\n\nFixed error that caused formatting macros not to be usable in statement position.\n\n### 0.2.23\n\nAdded type annotations to `concatp`, `concatcp`, `formatc` and `formatcp` macros to help IDEs infer the type.\n\n### 0.2.22\n\n\nAdded the `assertcp`, `assertcp_ne`, and `assertcp_eq` macros under the \"assertcp\"  feature.\n\nAdded `const_eq` methods for `PWrapper<&[char]>` and `PWrapper<Option<char>>`\n\nAdded the \"assertcp\" feature, which enables the `assertcp*` macros.\n\nAliased \"assert\" crate feature to \"assertc\", and removed old name from docs to reduce confusion.\n\n### 0.2.21\n\nRewrote assertion macros to:\n- Have more concise error messages\n- Point to all their arguments when the assertion fails\n- Resemble std error messages more\n\n### 0.2.19\n\nAdded `char` support to all formatting macros.\n\nAdded `char`, `&[char]`, and `Option<char>` impls of FormatMarker trait, with debug formatting methods.\n\nAdded `Formatter::{write_char, write_char_debug}` methods.\n\nAdded `StrWriterMut::{as_str_alt, write_char, write_char_debug}` methods.\n\nAdded `StrWriter::{as_str_alt, unsize}` methods.\n\nDeprecated `strwriter_as_str` macro, superceded by `StrWriter::as_str_alt`.\n\nBumped the minimum required nightly version to 2021-07-05 due to use of const-stabilized `core::str::from_utf8_unchecked`.\n\n### 0.2.18\n\nFixed potential soundness bug where unions used to do pointer casts were not `#[repr(C)]`\n\n### 0.2.16\n\nAdded these macros that act like `str` methods:\n- `str_get`\n- `str_index`\n- `str_repeat`\n- `str_replace`\n- `str_splice`\n\nAdded the `SplicedStr` struct.\n\n### 0.2.15\n\nAdded `map_ascii_case` macro to convert the casing style of a `&'static str`.\n\nAdded the `Case` enum.\n\nFixed \"constant_time_as_str\" crate feature in newer nightlies,\nthis will break code that uses the feature and hasn't updated the nightly compiler\nto a release post mid-july 2021.\n\n### 0.2.14\n\nFixed a few documentation issues.\n\nMade the `const_format::fmt` API that uses const generics unconditional, since const generics were stabilized in late 2020 and the `fmt` API requires the nightly compiler.\n\nRepurposed the \"const_generics\" feature to generate less code in the `concatcp` and `formatcp` macros,\nby moving some of their implementation to a function that uses const generics.\n\n### 0.2.13\n\nFixed the assertion macros not to use `std::panic`, using `core::panic` instead, since `core::panic` changed to allow passing a non-literal `&'static str` argument.\n\n### 0.2.11\n\nFixed the documentation in case that the https://github.com/rust-lang/rust/pull/80243 \nrustc pull request is merged.\n\n### 0.2.8\n\nAdded minimal const generic support, for use in the added methods.\n\nAdded these methods to `StrWriter<[u8; N]>`:\n- `r`: for casting it to a `StrWriter<[u8]>`\n- `as_mut`: for casting it to a `StrWriterMut`.\n\nAdded \"const_generics\" and \"nightly_const_generics\" features.\n\nFixed hygiene bug in assertion macros.\n\nBumped version number to 0.2.8 .\n\n### 0.2.6\n\nMade the macros in `const_format` usable when the crate is renamed.\n\nAdded a `#[cdeb(crate = \"foo\")]` helper attribute to\npass the path to `const_format` to `ConstDebug`, useful when reexporting the derive macro.\n\nDocumented that `writec!(buff, \"{foo}\")` (where `foo` is a local variable) works,\nand is equivelent to `writec!(buff, \"{}\", foo)`.\n\n### 0.2.5\n\nAdded the \"assert\" cargo feature,\ndefining the `assertc`/`assertc_eq`/`assertc_ne` macros for \ncompile-time assertions with formatting.\n\nAdded custom formatting support in the `const_format::fmt`-based formatting macros,\nby prefixing any argument with `|identifier|`,\naccessing a `Formatter` to format that argument however one wants.\n\nAdded `concatc` macro for concatenating std/user-defined types into a `&'static str` constant.\n\nAdded `const_format::Result` alias for `std::result::Result<(), const_format::Error>`.\n\nAdded `const_format::fmt::ToResult` type for converting  \n`()` and `const_format::Result` to `const_format::Result`.\n\nAdded `Pwrapper::const_eq` methods for comparing many std types in \nthe `assertc_eq`/`assertc_ne` macros.\n\nAdded `Pwrapper::const_display_fmt` methods for `NonZero*` types.\n\nAdded support for passing `concat!(....)` as the format string.\n\n### 0.2.0\n\nEvery single new item added requires Rust nightly to use, with at least the \"fmt\" cargo feature enabled.\n\nDefined a `core::fmt`-like API with these these types:\n`ComputeStrLength`, `DebugList`, `DebugSet`, `DebugStruct`, `DebugTuple`, `Error`, `Formatter`, `FormattingFlags`, `NumberFormatting`, `StrWriter`, `StrWriterMut`, `NoEncoding`, `Utf8Encoding`.\n\nAdded `formatc` macro, for formatting std and user-defined types into a `&'static str` constant.\n\nAdded `writec` macro, for writing formatted std and user-defined types, \ninto a type that implements `WriteMarker`.\n\nAdded `marker_traits::FormatMarker` trait, for types that implement const formatting,\nwith either the `const_debug_fmt`, or `const_display_fmt` inherent methods.\n\nAdded `ConstDebug` derive macro, for implementing `FormatMarker`,\nand implement the `const_debug_fmt` inherent method.\n\nAdded `marker_traits::WriteMarker` trait, for types that can be written into,\ndefining the `borrow_mutably` and `make_formatter` methods.\n\nAdded these type in `marker_traits` module: `IsAFormatMarker`, `IsAStrWriter`, `IsAWriteMarker`, \n`IsArrayKind`, `IsNotAStrWriter`, `IsNotStdKind`, `IsStdKind`\n\nAdded hexadecimal and binary formatting to the `formatcp` macro\n(also usable in `formatc`, and `writec`)\n\nDefined the `AsciiStr` type, a wrapper type for `&[u8]` slices which are valid ascii,\nwith an `ascii_str` macro for constructing it at compile-time,\nand `wrapper_types::NotAsciiError` returned by the fallible constructor.\n\nExposed the `PWrapper` type, wrapper for std types to call some methods on them.\n\nDefined the `Sliced` type, to output a slice from a `&str`.\n\nDefined these macros for implementing/doing compile-time formatting:\n`call_debug_fmt`, `coerce_to_fmt`, `impl_fmt`\n\nDefined the `strwriter_as_str` macro to cast a `&'static StrWriter` to a `&'static str`\n\nDefined these error handling macros: `try_`, `unwrap`, `unwrap_or_else`\n\nDefined the `for_examples` module with examples of types that implement const formatting.\n\nDefined these utility functions in the `utils` module: \n`slice_up_to_len`, `slice_up_to_len_alt`, `str_eq u8`, `slice_eq `\n\nFixed error reporting in `formatcp` and `concatcp` macros,\nnow compiler errors point at the argument that caused an error rather than the whole macro invocation.\n\nAdded the \"fmt\" cargo feature, to enable the `fmt`-like API, and every other thing that depends on it.\n\nAdded the \"derive\" cargo feature, to enable the `ConstDebug` macro.\n\nAdded the \"constant_time_as_str\", to optimize some methods, requires additional nightly features.\n\nMade `syn` an optional dependency, only enabled when the \"derive\" feature is used.\n\nAdded `unicode-xid` dependency.\n\n# 0.1\n\nCreated `const_format` crate,\n`const_format_proc_macros` crate(implementation detail of `const_format`)\n\nDefined the concatcp macro,\nfor concatenating constants of primitive types into a `&'static str` constant.\n\nDefined the formatcp macro,\nfor formatting constants of primitive types into a `&'static str` constant.\n\nAdded dependencies: syn with none of the expensive features, quote, proc_macro2\n\n"
  },
  {
    "path": "LICENSE-ZLIB.md",
    "content": "Copyright (c) 2020 Matias Rodriguez.\n\nThis software is provided 'as-is', without any express or implied\nwarranty. In no event will the authors be held liable for any damages\narising from the use of this software.\n\nPermission is granted to anyone to use this software for any purpose,\nincluding commercial applications, and to alter it and redistribute it\nfreely, subject to the following restrictions:\n\n1. The origin of this software must not be misrepresented; you must not\n   claim that you wrote the original software. If you use this software\n   in a product, an acknowledgment in the product documentation would be\n   appreciated but is not required.\n2. Altered source versions must be plainly marked as such, and must not be\n   misrepresented as being the original software.\n3. This notice may not be removed or altered from any source distribution."
  },
  {
    "path": "README.md",
    "content": "\n\n[![Rust](https://github.com/rodrimati1992/const_format_crates/workflows/Rust/badge.svg)](https://github.com/rodrimati1992/const_format_crates/actions)\n[![crates-io](https://img.shields.io/crates/v/const_format.svg)](https://crates.io/crates/const_format)\n[![api-docs](https://docs.rs/const_format/badge.svg)](https://docs.rs/const_format/*)\n\n\nCompile-time string formatting.\n\nThis crate provides types and macros for formatting strings at compile-time.\n\n# Rust versions\n\nThere are some features that require a variety of Rust versions,\nthe sections below describe the features that are available for each version.\n\n### Rust 1.71.0\n\nThese macros are available in Rust 1.71.0:\n\n- [`concatcp`]:\nConcatenates `integers`, `bool`, `char`, and `&str` constants into a `&'static str` constant.\n\n- [`formatcp`]:\n[`format`]-like formatting which takes `integers`, `bool`, `char`, and `&str` constants,\nand emits a `&'static str` constant.\n\n- [`str_get`]:\nIndexes a `&'static str` constant, returning `None` when the index is out of bounds.\n\n- [`str_index`]:\nIndexes a `&'static str` constant.\n\n- [`str_repeat`]:\nCreates a `&'static str` by repeating a `&'static str` constant `times` times.\n\n- [`str_splice`]:\nReplaces a substring in a `&'static str` constant.\n\n- [`map_ascii_case`]:\nConverts a `&'static str` constant to a different casing style,\ndetermined by a [`Case`] argument.\n\n- [`str_replace`]:\nReplaces all the instances of a pattern in a `&'static str` constant with\nanother `&'static str` constant.\n\n-  [`str_split`]: \nSplits a string constant\n\n\nThe `\"assertcp\"` feature enables the [`assertcp`], [`assertcp_eq`],\nand [`assertcp_ne`] macros.\nThese macros are like the standard library assert macros,\nbut evaluated at compile-time,\nwith the limitation that they can only have primitive types as arguments\n(just like [`concatcp`] and [`formatcp`]).\n\n### Rust 1.83.0\n\nBy enabling the \"fmt\" feature, you can use a [`std::fmt`]-like API.\n\nThis requires Rust 1.83.0, because it uses mutable references in const fn.\n\nAll the other features of this crate are implemented on top of the [`const_format::fmt`] API:\n\n- [`concatc`]:\nConcatenates many standard library and user defined types into a `&'static str` constant.\n\n- [`formatc`]:\n[`format`]-like macro that can format many standard library and user defined types into\na `&'static str` constant.\n\n- [`writec`]:\n[`write`]-like macro that can format many standard library and user defined types\ninto a type that implements [`WriteMarker`].\n\nThe `\"derive\"` feature enables the [`ConstDebug`] macro,\nand the `\"fmt\"` feature.<br>\n[`ConstDebug`] derives the [`FormatMarker`] trait,\nand implements an inherent `const_debug_fmt` method for compile-time debug formatting.\n\nThe `\"assertc\"` feature enables the [`assertc`], [`assertc_eq`], [`assertc_ne`] macros,\nand the `\"fmt\"` feature.<br>\nThese macros are like the standard library assert macros, but evaluated at compile-time.\n\n# Examples\n\n### Concatenation of primitive types\n\n```rust\nuse const_format::concatcp;\n\nconst NAME: &str = \"Bob\";\nconst FOO: &str = concatcp!(NAME, \", age \", 21u8,\"!\");\n\nassert_eq!(FOO, \"Bob, age 21!\");\n```\n\n### Formatting primitive types\n\n```rust\nuse const_format::formatcp;\n\nconst NAME: &str = \"John\";\n\nconst FOO: &str = formatcp!(\"{NAME}, age {}!\", compute_age(NAME));\n\nassert_eq!(FOO, \"John, age 24!\");\n\nconst fn compute_age(s: &str) -> usize { s.len() * 6 }\n```\n\n### Formatting custom types\n\nThis example demonstrates how you can use the [`ConstDebug`] derive macro,\nand then format the type into a `&'static str` constant.\n\nThis example requires Rust 1.83.0, and the `\"derive\"` feature.\n\n```rust\nuse const_format::{ConstDebug, formatc};\n\n#[derive(ConstDebug)]\nstruct Message{\n    ip: [Octet; 4],\n    value: &'static str,\n}\n\n#[derive(ConstDebug)]\nstruct Octet(u8);\n\nconst MSG: Message = Message{\n    ip: [Octet(127), Octet(0), Octet(0), Octet(1)],\n    value: \"Hello, World!\",\n};\n\nconst FOO: &str = formatc!(\"{:?}\", MSG);\n\nassert_eq!(\n    FOO,\n    \"Message { ip: [Octet(127), Octet(0), Octet(0), Octet(1)], value: \\\"Hello, World!\\\" }\"\n);\n\n```\n\n### Formatted const assertions\n\nThis example demonstrates how you can use the [`assertcp_ne`] macro to\ndo compile-time inequality assertions with formatted error messages.\n\nThis requires the `\"assertcp\"` feature.\n\n```rust, compile_fail\nuse const_format::assertcp_ne;\n\nmacro_rules! check_valid_pizza{\n    ($user:expr, $topping:expr) => {\n        assertcp_ne!(\n            $topping,\n            \"pineapple\",\n            \"You can't put pineapple on pizza, {}\",\n            $user,\n        );\n    }\n}\n\ncheck_valid_pizza!(\"John\", \"salami\");\ncheck_valid_pizza!(\"Dave\", \"sausage\");\ncheck_valid_pizza!(\"Bob\", \"pineapple\");\n\n```\n\nThis is the compiler output:\n\n```text\nerror[E0080]: evaluation of constant value failed\n  --> src/lib.rs:178:27\n   |\n20 | check_valid_pizza!(\"Bob\", \"pineapple\");\n   |                           ^^^^^^^^^^^ the evaluated program panicked at '\nassertion failed: `(left != right)`\n left: `\"pineapple\"`\nright: `\"pineapple\"`\nYou can't put pineapple on pizza, Bob\n', src/lib.rs:20:27\n\n\n```\n\n<div id=\"macro-limitations\"></div>\n\n# Limitations\n\nAll of the macros from `const_format` have these limitations:\n\n- The formatting macros that expand to\n`&'static str`s can only use constants from concrete types,\nso while a `Type::<u8>::FOO` argument would be fine,\n`Type::<T>::FOO` would not be (`T` being a type parameter).\n\n- Integer arguments must have a type inferrable from context,\n[more details in the Integer arguments section](#integer-args).\n\n- They cannot be used places that take string literals.\nSo `#[doc = \"foobar\"]` cannot be replaced with `#[doc = concatcp!(\"foo\", \"bar\") ]`.\n\n<span id=\"integer-args\"></span>\n\n### Integer arguments\n\nInteger arguments must have a type inferrable from context.\nso if you only pass an integer literal it must have a suffix.\n\nExample of what does compile:\n\n```rust\nconst N: u32 = 1;\nassert_eq!(const_format::concatcp!(N + 1, 2 + N), \"23\");\n\nassert_eq!(const_format::concatcp!(2u32, 2 + 1u8, 3u8 + 1), \"234\");\n```\n\nExample of what does not compile:\n```rust,compile_fail\nassert_eq!(const_format::concatcp!(1 + 1, 2 + 1), \"23\");\n```\n# Plans\n\nNone right now.\n\n# Renaming crate\n\nAll function-like macros from `const_format` can be used when the crate is renamed.\n\nThe [`ConstDebug`] derive macro has the `#[cdeb(crate = \"foo::bar\")]` attribute to\ntell it where to find the `const_format` crate.\n\nExample of renaming the `const_format` crate in the Cargo.toml file:\n```toml\n[dependencies]\ncfmt = {version = \"0.*\", package = \"const_format\"}\n```\n\n# Cargo features\n\n- `\"fmt\"`: Enables the [`std::fmt`]-like API and `\"rust_1_83\"` feature,\nrequires Rust 1.83.0 because it uses mutable references in const fn.<br>\nThis feature includes the [`formatc`]/[`writec`] formatting macros.\n\n- `\"derive\"`: requires Rust 1.83.0, implies the `\"fmt\"` feature,\nprovides the [`ConstDebug`] derive macro to format user-defined types at compile-time.<br>\nThis implicitly uses the `syn` crate, so clean compiles take a bit longer than without the feature.\n\n- `\"assertc\"`: requires Rust 1.83.0, implies the `\"fmt\"` feature,\nenables the [`assertc`], [`assertc_eq`], and [`assertc_ne`] assertion macros.<br>\nThis feature was previously named `\"assert\"`,\nbut it was renamed to avoid confusion with the `\"assertcp\"` feature.\n\n- `\"assertcp\"`:\nEnables the [`assertcp`], [`assertcp_eq`], and [`assertcp_ne`] assertion macros.\n\n- `\"rust_1_83\"`: \nMakes macros that evaluate to a value become compatible with [inline const patterns].\n\n# No-std support\n\n`const_format` is unconditionally `#![no_std]`, it can be used anywhere Rust can be used.\n\n# Minimum Supported Rust Version\n\n`const_format` requires Rust 1.71.0.\n\nFeatures that require newer versions of Rust, or the nightly compiler,\nneed to be explicitly enabled with cargo features.\n\n[`assertc`]: https://docs.rs/const_format/0.2.*/const_format/macro.assertc.html\n\n[`assertc_eq`]: https://docs.rs/const_format/0.2.*/const_format/macro.assertc_eq.html\n\n[`assertc_ne`]: https://docs.rs/const_format/0.2.*/const_format/macro.assertc_ne.html\n\n[`assertcp`]: https://docs.rs/const_format/0.2.*/const_format/macro.assertcp.html\n\n[`assertcp_eq`]: https://docs.rs/const_format/0.2.*/const_format/macro.assertcp_eq.html\n\n[`assertcp_ne`]: https://docs.rs/const_format/0.2.*/const_format/macro.assertcp_ne.html\n\n[`concatcp`]: https://docs.rs/const_format/0.2.*/const_format/macro.concatcp.html\n\n[`formatcp`]: https://docs.rs/const_format/0.2.*/const_format/macro.formatcp.html\n\n[`format`]: https://doc.rust-lang.org/std/macro.format.html\n\n[`std::fmt`]: https://doc.rust-lang.org/std/fmt/index.html\n\n[`const_format::fmt`]: https://docs.rs/const_format/0.2.*/const_format/fmt/index.html\n\n[`concatc`]: https://docs.rs/const_format/0.2.*/const_format/macro.concatc.html\n\n[`formatc`]: https://docs.rs/const_format/0.2.*/const_format/macro.formatc.html\n\n[`writec`]: https://docs.rs/const_format/0.2.*/const_format/macro.writec.html\n\n[`write`]: https://doc.rust-lang.org/std/macro.write.html\n\n[`Formatter`]: https://docs.rs/const_format/0.2.*/const_format/fmt/struct.Formatter.html\n\n[`StrWriter`]: https://docs.rs/const_format/0.2.*/const_format/fmt/struct.StrWriter.html\n\n[`ConstDebug`]: https://docs.rs/const_format/0.2.*/const_format/derive.ConstDebug.html\n\n[`FormatMarker`]: https://docs.rs/const_format/0.2.*/const_format/marker_traits/trait.FormatMarker.html\n\n[`WriteMarker`]: https://docs.rs/const_format/0.2.*/const_format/marker_traits/trait.WriteMarker.html\n\n[`map_ascii_case`]: https://docs.rs/const_format/0.2.*/const_format/macro.map_ascii_case.html\n\n[`Case`]: https://docs.rs/const_format/0.2.*/const_format/enum.Case.html\n\n[`str_get`]: https://docs.rs/const_format/0.2.*/const_format/macro.str_get.html\n\n[`str_index`]: https://docs.rs/const_format/0.2.*/const_format/macro.str_index.html\n\n[`str_repeat`]: https://docs.rs/const_format/0.2.*/const_format/macro.str_repeat.html\n\n[`str_splice`]: https://docs.rs/const_format/0.2.*/const_format/macro.str_splice.html\n\n[`str_replace`]: https://docs.rs/const_format/0.2.*/const_format/macro.str_replace.html\n\n[`str_split`]: https://docs.rs/const_format/0.2.*/const_format/macro.str_split.html\n\n[`str::replace`]: https://doc.rust-lang.org/std/primitive.str.html#method.replace\n\n[inline const patterns]: https://doc.rust-lang.org/1.83.0/unstable-book/language-features/inline-const-pat.html\n"
  },
  {
    "path": "commit.sh",
    "content": "#!/bin/sh\n\n#\n# You can use this script to format and commit the code all at once\n#\n#\n\ncargo fmt\n\nif [ $? -eq 0 ]\nthen\n    echo \"ran cargo fmt!!!!\"\nelse\n    exit 1\nfi\n\n\ngit update-index --again\n\ngit commit"
  },
  {
    "path": "const_format/Cargo.toml",
    "content": "[package]\nname = \"const_format\"\nversion = \"0.2.36\"\nauthors = [\"rodrimati1992 <rodrimatt1985@gmail.com>\"]\nrust-version = \"1.71.0\"\nedition = \"2021\"\nlicense = \"Zlib\"\ndescription = \"Compile-time string formatting\"\ndocumentation = \"https://docs.rs/const_format/\"\nreadme=\"../README.md\"\nkeywords = [\"no-std\", \"format\", \"concat\"]\ncategories = [\"no-std\", \"text-processing\"]\nrepository = \"https://github.com/rodrimati1992/const_format_crates/\"\ninclude = [\n    \"Cargo.toml\", \n    \"src/**/*.rs\", \n    \"../README.md\",\n    \"LICENSE-ZLIB.md\", \n]\n\n[features]\ndefault = []\nconst_generics = [\"rust_1_51\"]\nnightly_const_generics = [\"const_generics\"]\nrust_1_51 = []\nrust_1_64 = [\"rust_1_51\"]\nrust_1_83 = [\"rust_1_64\"]\nfmt = [\"rust_1_83\"]\nderive = [\"fmt\", \"const_format_proc_macros/derive\"]\n\n# soft-deprecated, use assertc instead.\nassert = [\"assertc\"]\n\nassertc = [\"fmt\", \"assertcp\"]\nassertcp = [\"rust_1_51\"]\nconstant_time_as_str = [\"fmt\"]\nmore_str_macros = [\"rust_1_64\"]\n\n# enables all the features, requires (potentially) the latest nightly\nall = [\n    \"fmt\",\n    \"derive\",\n    \"rust_1_64\",\n    \"assert\",\n]\n\n##############\n### \"private\" features\n\n# \n__debug = [\"const_format_proc_macros/debug\"]\n__test = []\n__only_new_tests = [\"__test\"]\n__inline_const_pat_tests = [\"__test\", \"fmt\"]\n__docsrs = []\n\n[dependencies.const_format_proc_macros]\nversion = \"=0.2.34\"\npath = \"../const_format_proc_macros\"\n\n[dependencies.konst]\nversion = \"0.2.20\"\ndefault-features = false\nfeatures = [\"rust_1_64\"]\n\n[dev-dependencies]\nfastrand = {version = \"1.3.5\", default-features = false}\narrayvec = {version = \"0.7.0\", default-features = false}\n\n[package.metadata.docs.rs]\nfeatures = [\"all\", \"__docsrs\"]\n\n"
  },
  {
    "path": "const_format/LICENSE-ZLIB.md",
    "content": "Copyright (c) 2020 Matias Rodriguez.\n\nThis software is provided 'as-is', without any express or implied\nwarranty. In no event will the authors be held liable for any damages\narising from the use of this software.\n\nPermission is granted to anyone to use this software for any purpose,\nincluding commercial applications, and to alter it and redistribute it\nfreely, subject to the following restrictions:\n\n1. The origin of this software must not be misrepresented; you must not\n   claim that you wrote the original software. If you use this software\n   in a product, an acknowledgment in the product documentation would be\n   appreciated but is not required.\n2. Altered source versions must be plainly marked as such, and must not be\n   misrepresented as being the original software.\n3. This notice may not be removed or altered from any source distribution."
  },
  {
    "path": "const_format/src/__ascii_case_conv/word_iterator.rs",
    "content": "use core::fmt::{self, Debug};\n\nmacro_rules! for_range_inc {\n    ($current:ident in $start:expr, $end:expr => $($code:tt)*) => {\n        let mut $current = $start;\n        let end = $end;\n\n        while $current <= end {\n            $($code)*\n\n            $current+=1;\n        }\n    };\n}\n\nuse core::ops::Range;\n\n#[derive(Copy, Clone)]\nstruct ByteKind(u8);\n\nimpl Debug for ByteKind {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        f.write_str(match () {\n            _ if self.0 == Self::Other.0 => \"Other\",\n            _ if self.0 == Self::Number.0 => \"Number\",\n            _ if self.0 == Self::LowerCase.0 => \"LowerCase\",\n            _ if self.0 == Self::UpperCase.0 => \"UpperCase\",\n            _ if self.0 == Self::NonAscii.0 => \"NonAscii\",\n            _ => unreachable!(),\n        })\n    }\n}\n\n#[allow(non_upper_case_globals)]\nimpl ByteKind {\n    const Other: Self = Self(0b0001);\n    const Number: Self = Self(0b0010);\n    const LowerCase: Self = Self(0b0100);\n    const UpperCase: Self = Self(0b1000);\n    const Alphabetic: Self = Self(Self::LowerCase.0 | Self::UpperCase.0);\n    // Assumes that non-ascii chars are mostly alphabetic,\n    // this should work out fine most of the time.\n    const NonAscii: Self = Self(0b1100);\n}\n\nimpl ByteKind {\n    #[allow(dead_code)]\n    #[inline(always)]\n    pub const fn eq(self, other: Self) -> bool {\n        (self.0 & other.0) != 0\n    }\n\n    #[inline(always)]\n    pub const fn ne(self, other: Self) -> bool {\n        (self.0 & other.0) == 0\n    }\n\n    #[inline(always)]\n    pub const fn is_alphabetic(self) -> bool {\n        self.0 == Self::LowerCase.0 || self.0 == Self::UpperCase.0\n    }\n\n    pub const fn is_end_of_word(mut self, prev: Self, other: Self) -> bool {\n        if self.0 == Self::NonAscii.0 {\n            self = prev;\n        }\n\n        if self.0 == Self::UpperCase.0 {\n            other.ne(Self::Alphabetic)\n        } else {\n            self.ne(other)\n        }\n    }\n}\n\n#[derive(Debug, Copy, Clone)]\npub(crate) struct WordIterator<'a> {\n    bytes: &'a [u8],\n    start: usize,\n}\n\nconst BYTE_KIND: &[ByteKind; 256] = &{\n    let mut out = [ByteKind::NonAscii; 256];\n\n    // Make sure that this goes first\n    for_range_inc! {i in 0, 127 => out[i as usize] = ByteKind::Other; }\n    for_range_inc! {i in b'A', b'Z' => out[i as usize] = ByteKind::UpperCase; }\n    for_range_inc! {i in b'a', b'z' => out[i as usize] = ByteKind::LowerCase; }\n    for_range_inc! {i in b'0', b'9' => out[i as usize] = ByteKind::Number; }\n\n    out\n};\n\nimpl<'a> WordIterator<'a> {\n    pub(crate) const fn new(bytes: &'a [u8]) -> Self {\n        Self { bytes, start: 0 }\n    }\n\n    const fn skip_same_kind(mut self, mut kind: ByteKind) -> (Self, ByteKind) {\n        let orig_bytes_len = self.bytes.len();\n\n        let mut prev_kind = kind;\n        while let [b, rem @ ..] = self.bytes {\n            let next_kind = BYTE_KIND[*b as usize];\n            let cmp = kind.is_end_of_word(prev_kind, next_kind);\n            if kind.is_alphabetic() {\n                prev_kind = kind;\n            }\n            kind = next_kind;\n            if cmp {\n                break;\n            }\n            self.bytes = rem;\n        }\n\n        // Advance until a char boundary is found\n        while let [b, rem @ ..] = self.bytes {\n            if (*b as i8) >= -0x40 {\n                break;\n            }\n            self.bytes = rem;\n        }\n\n        // Remember not to add return statements to the function\n        self.start += orig_bytes_len - self.bytes.len();\n\n        (self, kind)\n    }\n\n    pub(crate) const fn next(self) -> Option<(Self, Range<usize>)> {\n        let (this, fkind) = self.skip_same_kind(ByteKind::Other);\n        if let [] = this.bytes {\n            None\n        } else {\n            let (next, _) = this.skip_same_kind(fkind);\n            let range = this.start..next.start;\n            Some((next, range))\n        }\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    use arrayvec::ArrayVec;\n\n    fn get_words(text: &str) -> ArrayVec<&str, 20> {\n        let mut list = <ArrayVec<&str, 20>>::new();\n        let mut word_iter = WordIterator::new(text.as_bytes());\n\n        while let Some((niter, word_range)) = word_iter.next() {\n            word_iter = niter;\n            list.push(&text[word_range]);\n        }\n\n        list\n    }\n\n    #[test]\n    fn test_word_iter() {\n        assert_eq!(\n            get_words(\"01934324ñmaniÑNnFooBar\")[..],\n            [\"01934324\", \"ñmaniÑ\", \"Nn\", \"Foo\", \"Bar\"],\n        );\n\n        assert_eq!(\n            get_words(\"01934 324  ñmani-嶲Nn____FOOOBar\")[..],\n            [\"01934\", \"324\", \"ñmani\", \"嶲Nn\", \"FOOOBar\"],\n        );\n\n        assert_eq!(get_words(\"    01934 1111 \")[..], [\"01934\", \"1111\"],);\n\n        assert_eq!(get_words(\"    嶲01934 \")[..], [\"嶲\", \"01934\"],);\n\n        assert_eq!(get_words(\"    嶲A01934 \")[..], [\"嶲A\", \"01934\"],);\n\n        assert_eq!(get_words(\"    嶲a01934 \")[..], [\"嶲a\", \"01934\"],);\n\n        assert_eq!(get_words(\"    ñA01934 \")[..], [\"ñA\", \"01934\"],);\n\n        assert_eq!(get_words(\"    ña01934 \")[..], [\"ña\", \"01934\"],);\n    }\n}\n"
  },
  {
    "path": "const_format/src/__ascii_case_conv.rs",
    "content": "mod word_iterator;\n\nuse word_iterator::WordIterator;\n\n/// The casing style of a string.\n///\n/// You can pass this to [`map_ascii_case`] to determine the casing style of the\n/// returned `&'static str`.\n///\n///\n/// [`map_ascii_case`]: ./macro.map_ascii_case.html\n#[derive(Debug, Copy, Clone, PartialEq)]\npub enum Case {\n    /// Lowercase\n    Lower,\n    /// Uppercase\n    Upper,\n    /// Pascal case, eg: `FooBarBaz`. The first character is always uppercase.\n    Pascal,\n    /// Camel case, eg: `fooBarBaz`. The first character is always lowercase.\n    Camel,\n    /// Snake case, eg: `foo_bar_baz`. Also turns the string lowercase.\n    Snake,\n    /// Snake case, eg: `FOO_BAR_BAZ`. Also turns the string uppercase.\n    UpperSnake,\n    /// Kebab case, eg: `foo-bar-baz`. Also turns the string lowercase.\n    Kebab,\n    /// Kebab case, eg: `FOO-BAR-BAZ`. Also turns the string uppercase.\n    UpperKebab,\n}\n\nmacro_rules! if_next_word {\n    ($word_iterator:ident, $word_range:ident => $then:block $(else $else:block)? ) => {\n        #[allow(unused_mut)]\n        if let Some((niter, mut $word_range)) = $word_iterator.next() {\n            $word_iterator = niter;\n\n            $then\n        } $(else $else)?\n    };\n}\n\nmacro_rules! while_next_word {\n    ($word_iterator:ident, $word_range:ident => $then:block) => {\n        #[allow(unused_mut)]\n        while let Some((niter, mut $word_range)) = $word_iterator.next() {\n            $word_iterator = niter;\n\n            $then\n        }\n    };\n}\n\nstruct WordCountAndLength {\n    /// The amount of words\n    count: usize,\n    /// The length of all words added up\n    length: usize,\n}\n\nconst fn words_count_and_length(bytes: &[u8]) -> WordCountAndLength {\n    let mut count = 0;\n    let mut length = 0;\n    let mut word_iter = WordIterator::new(bytes);\n    while_next_word! {word_iter, word_range => {\n        count += 1;\n        length += word_range.end - word_range.start;\n    }}\n    WordCountAndLength { count, length }\n}\n\npub const fn size_after_conversion(case: Case, s: &str) -> usize {\n    match case {\n        Case::Upper | Case::Lower => s.len(),\n        Case::Pascal | Case::Camel => {\n            let wcl = words_count_and_length(s.as_bytes());\n            wcl.length\n        }\n        Case::Snake | Case::Kebab | Case::UpperSnake | Case::UpperKebab => {\n            let wcl = words_count_and_length(s.as_bytes());\n            wcl.length + wcl.count.saturating_sub(1)\n        }\n    }\n}\n\npub const fn convert_str<const N: usize>(case: Case, s: &str) -> [u8; N] {\n    let mut arr = [0; N];\n    let mut inp = s.as_bytes();\n    let mut o = 0;\n\n    macro_rules! map_bytes {\n        ($byte:ident => $e:expr) => {\n            while let [$byte, rem @ ..] = inp {\n                let $byte = *$byte;\n                inp = rem;\n                arr[o] = $e;\n                o += 1;\n            }\n        };\n    }\n\n    macro_rules! write_byte {\n        ($byte:expr) => {\n            arr[o] = $byte;\n            o += 1;\n        };\n    }\n\n    macro_rules! write_range_from {\n        ($range:expr, $from:expr, $byte:ident => $mapper:expr) => {{\n            let mut range = $range;\n            while range.start < range.end {\n                let $byte = $from[range.start];\n                arr[o] = $mapper;\n\n                range.start += 1;\n                o += 1;\n            }\n        }};\n    }\n\n    macro_rules! write_snake_kebab_case {\n        ($separator:expr, $byte_conversion:expr) => {{\n            let mut word_iter = WordIterator::new(inp);\n\n            if_next_word! {word_iter, word_range => {\n                write_range_from!(word_range, inp, byte => $byte_conversion(byte));\n\n                while_next_word!{word_iter, word_range => {\n                    write_byte!($separator);\n                    write_range_from!(word_range, inp, byte => $byte_conversion(byte));\n                }}\n            }}\n        }};\n    }\n\n    macro_rules! write_pascal_camel_case {\n        ($first_word_conv:expr) => {{\n            let mut word_iter = WordIterator::new(inp);\n\n            if_next_word! {word_iter, word_range => {\n                write_byte!($first_word_conv(inp[word_range.start]));\n                word_range.start += 1;\n                write_range_from!(word_range, inp, byte => lowercase_u8(byte));\n\n                while_next_word!{word_iter, word_range => {\n                    write_byte!(uppercase_u8(inp[word_range.start]));\n                    word_range.start += 1;\n                    write_range_from!(word_range, inp, byte => lowercase_u8(byte));\n                }}\n            }}\n        }};\n    }\n\n    match case {\n        Case::Upper => map_bytes!(b => uppercase_u8(b)),\n        Case::Lower => map_bytes!(b => lowercase_u8(b)),\n        Case::Snake => write_snake_kebab_case!(b'_', lowercase_u8),\n        Case::UpperSnake => write_snake_kebab_case!(b'_', uppercase_u8),\n        Case::Kebab => write_snake_kebab_case!(b'-', lowercase_u8),\n        Case::UpperKebab => write_snake_kebab_case!(b'-', uppercase_u8),\n        Case::Pascal => write_pascal_camel_case!(uppercase_u8),\n        Case::Camel => write_pascal_camel_case!(lowercase_u8),\n    }\n\n    arr\n}\n\nconst CASE_DIFF: u8 = b'a' - b'A';\n\nconst fn uppercase_u8(b: u8) -> u8 {\n    if let b'a'..=b'z' = b {\n        b - CASE_DIFF\n    } else {\n        b\n    }\n}\n\nconst fn lowercase_u8(b: u8) -> u8 {\n    if let b'A'..=b'Z' = b {\n        b + CASE_DIFF\n    } else {\n        b\n    }\n}\n"
  },
  {
    "path": "const_format/src/__hidden_utils.rs",
    "content": "pub(crate) const fn max_usize(l: usize, r: usize) -> usize {\n    if l > r {\n        l\n    } else {\n        r\n    }\n}\npub(crate) const fn saturating_add(l: usize, r: usize) -> usize {\n    let (sum, overflowed) = l.overflowing_add(r);\n    if overflowed {\n        usize::MAX\n    } else {\n        sum\n    }\n}\n\npub(crate) const fn is_char_boundary_no_len_check(str: &[u8], index: usize) -> bool {\n    index == str.len() || (str[index] as i8) >= -0x40\n}\n\n#[repr(C)]\npub union PtrToRef<'a, T: ?Sized> {\n    pub ptr: *const T,\n    pub reff: &'a T,\n}\n"
  },
  {
    "path": "const_format/src/__str_methods/pattern.rs",
    "content": "use super::AsciiByte;\n\npub(crate) struct PatternCtor<T>(pub(crate) T);\n\nimpl PatternCtor<u8> {\n    pub(crate) const fn conv(self) -> Pattern {\n        Pattern::AsciiByte(AsciiByte::new(self.0))\n    }\n}\n\nimpl PatternCtor<&'static str> {\n    pub(crate) const fn conv(self) -> Pattern {\n        if let [b @ 0..=127] = *self.0.as_bytes() {\n            Pattern::AsciiByte(AsciiByte::new(b))\n        } else {\n            Pattern::Str(self.0)\n        }\n    }\n}\n\nimpl PatternCtor<char> {\n    pub(crate) const fn conv(self) -> Pattern {\n        let code = self.0 as u32;\n        if let c @ 0..=127 = code {\n            Pattern::AsciiByte(AsciiByte::new(c as u8))\n        } else {\n            Pattern::Char(crate::char_encoding::char_to_display(self.0))\n        }\n    }\n}\n\n#[derive(Copy, Clone)]\npub(crate) enum Pattern {\n    AsciiByte(AsciiByte),\n    Str(&'static str),\n    Char(crate::char_encoding::FmtChar),\n}\n\npub(crate) enum PatternNorm<'a> {\n    AsciiByte(AsciiByte),\n    Str(&'a [u8]),\n}\n\nimpl Pattern {\n    pub(crate) const fn normalize(&self) -> PatternNorm<'_> {\n        match self {\n            Pattern::AsciiByte(ab) => PatternNorm::AsciiByte(*ab),\n            Pattern::Str(str) => PatternNorm::Str(str.as_bytes()),\n            Pattern::Char(char) => PatternNorm::Str(char.as_bytes()),\n        }\n    }\n}\n"
  },
  {
    "path": "const_format/src/__str_methods/str_indexing.rs",
    "content": "pub struct StrIndexArgsConv<T> {\n    pub str: &'static str,\n    pub arg: T,\n}\n\n#[allow(non_snake_case)]\npub const fn StrIndexArgsConv<T>(str: &'static str, arg: T) -> StrIndexArgsConv<T> {\n    StrIndexArgsConv { str, arg }\n}\n\npub struct StrIndexArgs {\n    pub str: &'static str,\n    pub index_validity: IndexValidity,\n    pub used_rstart: usize,\n    pub used_rlen: usize,\n    pub used_rend: usize,\n}\n\n#[derive(Copy, Clone)]\n#[cfg_attr(test, derive(Debug, PartialEq))]\npub enum IndexValidity {\n    Valid,\n    StartOob(usize),\n    StartInsideChar(usize),\n    EndOob(usize),\n    EndInsideChar(usize),\n}\n\nimpl IndexValidity {\n    pub const fn is_valid(self) -> bool {\n        matches!(self, Self::Valid)\n    }\n\n    pub const fn assert_valid(self) {\n        match self {\n            Self::Valid => (),\n            Self::StartOob(index) => [/*start index is out of bounds*/][index],\n            Self::StartInsideChar(index) => [/*start index is not on a char boundary*/][index],\n            Self::EndOob(index) => [/*end index is out of bounds*/][index],\n            Self::EndInsideChar(index) => [/*end index is not on a char boundary*/][index],\n        }\n    }\n}\n\nmacro_rules! pass_range_types {\n    ($macro:ident) => {\n        const _: () = {\n            use core::ops;\n\n            #[allow(unused_imports)]\n            use crate::__hidden_utils::{is_char_boundary_no_len_check, max_usize, saturating_add};\n\n            $macro! {\n                fn(self, usize) {\n                    let mut end = saturating_add(self.arg, 1);\n                    let bytes = self.str.as_bytes();\n\n                    if end < self.str.len() {\n                        while !is_char_boundary_no_len_check(bytes, end) {\n                            end = saturating_add(end, 1);\n                        }\n                    }\n\n                    self.arg .. end\n                }\n\n                fn(self, ops::Range<usize>) {\n                    let ops::Range{start, end} = self.arg;\n                    start .. max_usize(start, end)\n                }\n\n                fn(self, ops::RangeTo<usize>) {\n                    0..self.arg.end\n                }\n\n                fn(self, ops::RangeFrom<usize>) {\n                    self.arg.start..self.str.len()\n                }\n\n                fn(self, ops::RangeInclusive<usize>) {\n                    let start = *self.arg.start();\n                    start .. max_usize(saturating_add(*self.arg.end(), 1), start)\n                }\n\n                fn(self, ops::RangeToInclusive<usize>) {\n                    0 .. saturating_add(self.arg.end, 1)\n                }\n\n                fn(self, ops::RangeFull) {\n                    0 .. self.str.len()\n                }\n            }\n        };\n    };\n}\npub(super) use pass_range_types;\n\nmacro_rules! define_conversions {\n    (\n        $( fn($self:ident, $ty:ty) $block:block )*\n    ) => {\n\n        $(\n            impl StrIndexArgsConv<$ty> {\n                pub const fn conv($self) -> StrIndexArgs {\n                    use crate::__hidden_utils::is_char_boundary_no_len_check;\n\n                    let range = $block;\n\n                    let str_len = $self.str.len();\n\n                    let mut used_rstart = 0;\n                    let mut used_rend = str_len;\n\n                    let mut index_validity = IndexValidity::Valid;\n                    let bytes = $self.str.as_bytes();\n\n                    if range.end > str_len {\n                        index_validity = IndexValidity::EndOob(range.end);\n                    } else if is_char_boundary_no_len_check(bytes, range.end) {\n                        used_rend = range.end;\n                    } else {\n                        index_validity = IndexValidity::EndInsideChar(range.end);\n                    };\n\n                    if range.start > str_len {\n                        index_validity = IndexValidity::StartOob(range.start);\n                    } else if is_char_boundary_no_len_check(bytes, range.start) {\n                        used_rstart = range.start;\n                    } else {\n                        index_validity = IndexValidity::StartInsideChar(range.start);\n                    };\n\n                    StrIndexArgs {\n                        str: $self.str,\n                        index_validity,\n                        used_rstart,\n                        used_rend,\n                        used_rlen: used_rend - used_rstart,\n                    }\n                }\n            }\n        )*\n    };\n}\n\npass_range_types! {define_conversions}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    #[test]\n    fn index_validity_test() {\n        macro_rules! miv {\n            ($str:expr, $range:expr) => {\n                StrIndexArgsConv($str, $range).conv().index_validity\n            };\n        }\n\n        assert_eq!(miv!(\"効率的\", 3), IndexValidity::Valid);\n        assert_eq!(miv!(\"効率的\", 6), IndexValidity::Valid);\n        assert_eq!(miv!(\"効率的\", 3..6), IndexValidity::Valid);\n\n        assert_eq!(miv!(\"効率的\", 4..6), IndexValidity::StartInsideChar(4));\n        assert_eq!(miv!(\"効率的\", 3..5), IndexValidity::EndInsideChar(5));\n        assert_eq!(miv!(\"効率的\", 7..9), IndexValidity::StartInsideChar(7));\n\n        assert_eq!(miv!(\"効率的\", 100..9), IndexValidity::StartOob(100));\n        assert_eq!(miv!(\"効率的\", 3..10), IndexValidity::EndOob(10));\n        assert_eq!(miv!(\"効率的\", 9), IndexValidity::EndOob(10));\n        assert_eq!(miv!(\"効率的\", 10), IndexValidity::StartOob(10));\n        assert_eq!(miv!(\"効率的\", 100..900), IndexValidity::StartOob(100));\n    }\n}\n"
  },
  {
    "path": "const_format/src/__str_methods/str_repeat.rs",
    "content": "pub struct StrRepeatArgs {\n    pub str: &'static str,\n    pub str_len: usize,\n    pub out_len: usize,\n    pub overflowed_len: Option<usize>,\n    pub repeat: usize,\n}\n\n#[allow(non_snake_case)]\npub const fn StrRepeatArgs(str: &'static str, repeat: usize) -> StrRepeatArgs {\n    let str_len = str.len();\n    let (mul, overflowed) = str_len.overflowing_mul(repeat);\n\n    let (out_len, overflowed_len, repeat) = if overflowed {\n        (str_len, Some(mul), 1)\n    } else {\n        (mul, None, repeat)\n    };\n\n    StrRepeatArgs {\n        str,\n        str_len,\n        out_len,\n        overflowed_len,\n        repeat,\n    }\n}\n\nimpl StrRepeatArgs {\n    pub const fn assert_valid(&self) {\n        if let Some(overflowed_len) = self.overflowed_len {\n            [/* the returned string is too large */][overflowed_len]\n        }\n    }\n}\n"
  },
  {
    "path": "const_format/src/__str_methods/str_replace.rs",
    "content": "use super::{bytes_find, Pattern, PatternCtor, PatternNorm};\n\npub struct ReplaceInputConv<T>(pub &'static str, pub T, pub &'static str);\n\nmacro_rules! ctor {\n    ($ty:ty) => {\n        impl ReplaceInputConv<$ty> {\n            pub const fn conv(self) -> ReplaceInput {\n                ReplaceInput {\n                    str: self.0,\n                    pattern: PatternCtor(self.1).conv(),\n                    replaced_with: self.2,\n                }\n            }\n        }\n    };\n}\n\nctor! {u8}\nctor! {&'static str}\nctor! {char}\n\npub struct ReplaceInput {\n    str: &'static str,\n    pattern: Pattern,\n    replaced_with: &'static str,\n}\n\nimpl ReplaceInput {\n    pub const fn replace_length(&self) -> usize {\n        str_replace_length(self.str, self.pattern, self.replaced_with)\n    }\n    pub const fn replace<const L: usize>(&self) -> [u8; L] {\n        str_replace(self.str, self.pattern, self.replaced_with)\n    }\n}\n\nconst fn str_replace_length(inp: &str, r: Pattern, replaced_with: &str) -> usize {\n    let inp = inp.as_bytes();\n\n    let replaced_len = replaced_with.len();\n    let mut out_len = 0;\n\n    match r.normalize() {\n        PatternNorm::AsciiByte(byte) => {\n            let byte = byte.get();\n            iter_copy_slice! {b in inp =>\n                out_len += if b == byte { replaced_len } else { 1 };\n            }\n        }\n        PatternNorm::Str(str) => {\n            if str.is_empty() {\n                return inp.len();\n            }\n            let str_len = str.len();\n            let mut i = 0;\n            while let Some(next_match) = bytes_find(inp, str, i) {\n                out_len += (next_match - i) + replaced_len;\n                i = next_match + str_len;\n            }\n            out_len += inp.len() - i;\n        }\n    }\n\n    out_len\n}\n\nconst fn str_replace<const L: usize>(inp: &str, r: Pattern, replaced_with: &str) -> [u8; L] {\n    let inp = inp.as_bytes();\n\n    let replaced_with_bytes = replaced_with.as_bytes();\n    let mut out = [0u8; L];\n    let mut out_i = 0;\n\n    macro_rules! write_replaced {\n        () => {\n            iter_copy_slice! {b in replaced_with_bytes =>\n                out[out_i] = b;\n                out_i += 1;\n            }\n        };\n    }\n    macro_rules! write_byte {\n        ($byte:expr) => {\n            out[out_i] = $byte;\n            out_i += 1;\n        };\n    }\n\n    match r.normalize() {\n        PatternNorm::AsciiByte(byte) => {\n            let byte = byte.get();\n            iter_copy_slice! {b in inp =>\n                if b == byte {\n                    write_replaced!{}\n                } else {\n                    write_byte!{b}\n                }\n            }\n        }\n        PatternNorm::Str(str) => {\n            if str.is_empty() {\n                iter_copy_slice! {b in inp =>\n                    write_byte!(b);\n                }\n                return out;\n            }\n            let str_len = str.len();\n            let mut i = 0;\n            while let Some(next_match) = bytes_find(inp, str, i) {\n                __for_range! {j in i..next_match =>\n                    write_byte!(inp[j]);\n                }\n                write_replaced! {}\n\n                i = next_match + str_len;\n            }\n            __for_range! {j in i..inp.len() =>\n                write_byte!(inp[j]);\n            }\n        }\n    }\n    out\n}\n"
  },
  {
    "path": "const_format/src/__str_methods/str_splice.rs",
    "content": "use super::str_indexing::{pass_range_types, IndexValidity, StrIndexArgs, StrIndexArgsConv};\n\npub struct StrSplceArgsConv<T> {\n    pub arg: T,\n    pub str: &'static str,\n    pub insert: &'static str,\n}\n\n#[allow(non_snake_case)]\npub const fn StrSplceArgsConv<T>(\n    str: &'static str,\n    arg: T,\n    insert: &'static str,\n) -> StrSplceArgsConv<T> {\n    StrSplceArgsConv { str, arg, insert }\n}\n\npub struct StrSpliceArgs {\n    pub str: &'static str,\n    pub insert: &'static str,\n    pub index_validity: IndexValidity,\n    pub used_rstart: usize,\n    pub used_rlen: usize,\n    pub insert_len: usize,\n    pub suffix_len: usize,\n    pub out_len: usize,\n}\n\n/// The return value of [`str_splice`](./macro.str_splice.html)\n#[derive(Debug, Copy, Clone, PartialEq, Eq)]\npub struct SplicedStr {\n    /// A string that had `removed` replaced with some other string.\n    pub output: &'static str,\n    /// The part of the string that was removed.\n    pub removed: &'static str,\n}\n\n#[repr(C, packed)]\npub struct DecomposedString<P, M, S> {\n    pub prefix: P,\n    pub middle: M,\n    pub suffix: S,\n}\n\nmacro_rules! define_conversions {\n    (\n        $( fn($self:ident, $ty:ty) $block:block )*\n    ) => {\n        $(\n            impl StrSplceArgsConv<$ty> {\n                pub const fn conv(self) -> StrSpliceArgs {\n                    let StrIndexArgs{\n                        str,\n                        index_validity,\n                        used_rstart,\n                        used_rend,\n                        used_rlen,\n                    } = StrIndexArgsConv{\n                        arg: self.arg,\n                        str: self.str,\n                    }.conv();\n\n                    StrSpliceArgs{\n                        str,\n                        index_validity,\n                        used_rstart,\n                        used_rlen,\n                        insert: self.insert,\n                        insert_len: self.insert.len(),\n                        suffix_len: str.len() - used_rend,\n                        out_len: str.len() - used_rlen + self.insert.len(),\n                    }\n                }\n            }\n        )*\n    };\n}\n\npass_range_types! {define_conversions}\n"
  },
  {
    "path": "const_format/src/__str_methods/str_split.rs",
    "content": "use super::{Pattern, PatternCtor, PatternNorm};\n\nuse konst::slice::{bytes_find, bytes_find_skip};\n\npub struct SplitInputConv<T>(pub &'static str, pub T);\n\nmacro_rules! ctor {\n    ($ty:ty) => {\n        impl SplitInputConv<$ty> {\n            pub const fn conv(self) -> SplitInput {\n                SplitInput {\n                    str: self.0,\n                    pattern: PatternCtor(self.1).conv(),\n                    length: usize::MAX,\n                }\n                .compute_length()\n            }\n        }\n    };\n}\n\nctor! {u8}\nctor! {&'static str}\nctor! {char}\n\n#[derive(Copy, Clone)]\npub struct SplitInput {\n    str: &'static str,\n    pattern: Pattern,\n    length: usize,\n}\n\nimpl SplitInput {\n    const fn compute_length(mut self) -> Self {\n        self.length = count_splits(self);\n        self\n    }\n\n    pub const fn split_it<const LEN: usize>(self) -> [&'static str; LEN] {\n        split_it(self)\n    }\n\n    pub const fn length(&self) -> usize {\n        self.length\n    }\n}\n\npub const fn count_splits(SplitInput { str, pattern, .. }: SplitInput) -> usize {\n    let mut count = 1;\n\n    match pattern.normalize() {\n        PatternNorm::AsciiByte(ascii_c) => {\n            let mut bytes = str.as_bytes();\n            let ascii_c = ascii_c.get();\n\n            while let [byte, rem @ ..] = bytes {\n                bytes = rem;\n\n                if *byte == ascii_c {\n                    count += 1;\n                }\n            }\n        }\n        PatternNorm::Str(str_pat) => {\n            if str_pat.is_empty() {\n                let mut char_i = 0;\n                count += 1;\n                while let Some(next) = find_next_char_boundary(str, char_i) {\n                    char_i = next;\n                    count += 1;\n                }\n            } else {\n                let mut str = str.as_bytes();\n                while let Some(next) = bytes_find_skip(str, str_pat) {\n                    str = next;\n                    count += 1;\n                }\n            }\n        }\n    }\n\n    count\n}\n\nconst fn find_u8(mut slice: &[u8], byte: u8) -> Option<usize> {\n    let mut i = 0;\n\n    while let [b, ref rem @ ..] = *slice {\n        if byte == b {\n            return Some(i);\n        }\n        slice = rem;\n        i += 1;\n    }\n    None\n}\n\nconst fn find_next_char_boundary(str: &str, mut index: usize) -> Option<usize> {\n    if index == str.len() {\n        None\n    } else {\n        loop {\n            index += 1;\n            if index == str.len() || (str.as_bytes()[index] as i8) >= -0x40 {\n                break Some(index);\n            }\n        }\n    }\n}\n\npub const fn split_it<const LEN: usize>(args: SplitInput) -> [&'static str; LEN] {\n    let SplitInput {\n        mut str,\n        pattern,\n        length: _,\n    } = args;\n\n    let mut out = [\"\"; LEN];\n    let mut out_i = 0;\n\n    macro_rules! write_out {\n        ($string:expr) => {\n            out[out_i] = $string;\n            out_i += 1;\n        };\n    }\n\n    match pattern.normalize() {\n        PatternNorm::AsciiByte(ascii_c) => {\n            let ascii_c = ascii_c.get();\n\n            while let Some(found_at) = find_u8(str.as_bytes(), ascii_c) {\n                write_out! {konst::string::str_up_to(str, found_at)}\n                str = konst::string::str_from(str, found_at + 1);\n            }\n        }\n        PatternNorm::Str(str_pat) => {\n            if str_pat.is_empty() {\n                out_i += 1;\n                while let Some(next) = find_next_char_boundary(str, 0) {\n                    write_out! {konst::string::str_up_to(str, next)}\n                    str = konst::string::str_from(str, next);\n                }\n            } else {\n                while let Some(found_at) = bytes_find(str.as_bytes(), str_pat, 0) {\n                    write_out! {konst::string::str_up_to(str, found_at)}\n                    str = konst::string::str_from(str, found_at + str_pat.len());\n                }\n            }\n        }\n    }\n\n    write_out! {str}\n\n    assert!(out_i == LEN);\n    out\n}\n"
  },
  {
    "path": "const_format/src/__str_methods.rs",
    "content": "mod str_replace;\n\npub use self::str_replace::{ReplaceInput, ReplaceInputConv};\n\nmod str_repeat;\npub use str_repeat::StrRepeatArgs;\n\nmod str_splice;\npub use str_splice::{DecomposedString, SplicedStr, StrSplceArgsConv, StrSpliceArgs};\n\nmod str_indexing;\npub use str_indexing::{IndexValidity, StrIndexArgs, StrIndexArgsConv};\n\nmod str_split;\n\npub use str_split::{SplitInput, SplitInputConv};\n\nmod pattern;\n\nuse pattern::{Pattern, PatternCtor, PatternNorm};\n\nmod ascii_byte {\n    #[derive(Copy, Clone)]\n    pub struct AsciiByte(u8);\n\n    impl AsciiByte {\n        #[inline(always)]\n        pub const fn new(byte: u8) -> Self {\n            if byte > 127 {\n                let byte = byte as usize;\n                let _: () = [/* byte isn't valid ascii */][byte];\n                loop {}\n            }\n            Self(byte)\n        }\n        #[inline(always)]\n        pub const fn get(self) -> u8 {\n            self.0\n        }\n    }\n}\npub use ascii_byte::AsciiByte;\n\n// copied from the konst crate, if that implementation is wrong, this needs to be fixed\nconst fn bytes_find(left: &[u8], right: &[u8], from: usize) -> Option<usize> {\n    let mut matching = right;\n\n    __for_range! {i in from..left.len() =>\n        match matching {\n            [mb, m_rem @ ..] => {\n                let b = left[i];\n\n                matching = if b == *mb {\n                    m_rem\n                } else {\n                    match right {\n                        // For when the string is \"lawlawn\" and we are trying to find \"lawn\"\n                        [mb2, m_rem2 @ ..] if b == *mb2 => m_rem2,\n                        _ => right,\n                    }\n                };\n            }\n            [] => {\n                return Some(i - right.len())\n            }\n        }\n    }\n\n    if matching.is_empty() {\n        Some(left.len() - right.len())\n    } else {\n        None\n    }\n}\n"
  },
  {
    "path": "const_format/src/char_encoding/tests.rs",
    "content": "use super::{char_debug_len, char_display_len, char_to_debug, char_to_display};\n\n#[test]\nfn char_to_utf8_encoding_test() {\n    for c in '\\0'..=core::char::MAX {\n        let mut utf8_std = [0u8; 4];\n        let utf8_std = c.encode_utf8(&mut utf8_std);\n\n        let utf8_here = char_to_display(c);\n        assert_eq!(utf8_here.len(), char_display_len(c));\n\n        assert_eq!(utf8_std.as_bytes(), utf8_here.as_bytes());\n    }\n}\n\n#[test]\nfn char_to_utf8_display_test() {\n    for c in '\\0'..=core::char::MAX {\n        let mut utf8_std = [0u8; 4];\n        let utf8_std = c.encode_utf8(&mut utf8_std);\n\n        let utf8_here = char_to_display(c);\n        assert_eq!(utf8_here.len(), char_display_len(c));\n\n        assert_eq!(utf8_std.as_bytes(), utf8_here.as_bytes());\n    }\n}\n\n#[test]\nfn char_to_utf8_debug_test() {\n    let first_escapes = [\n        ('\\x00', r#\"'\\x00'\"#),\n        ('\\x01', r#\"'\\x01'\"#),\n        ('\\x02', r#\"'\\x02'\"#),\n        ('\\x03', r#\"'\\x03'\"#),\n        ('\\x04', r#\"'\\x04'\"#),\n        ('\\x05', r#\"'\\x05'\"#),\n        ('\\x06', r#\"'\\x06'\"#),\n        ('\\x07', r#\"'\\x07'\"#),\n        ('\\x08', r#\"'\\x08'\"#),\n        ('\\t', r#\"'\\t'\"#),\n        ('\\n', r#\"'\\n'\"#),\n        ('\\x0B', r#\"'\\x0B'\"#),\n        ('\\x0C', r#\"'\\x0C'\"#),\n        ('\\r', r#\"'\\r'\"#),\n        ('\\x0E', r#\"'\\x0E'\"#),\n        ('\\x0F', r#\"'\\x0F'\"#),\n        ('\\x10', r#\"'\\x10'\"#),\n        ('\\x11', r#\"'\\x11'\"#),\n        ('\\x12', r#\"'\\x12'\"#),\n        ('\\x13', r#\"'\\x13'\"#),\n        ('\\x14', r#\"'\\x14'\"#),\n        ('\\x15', r#\"'\\x15'\"#),\n        ('\\x16', r#\"'\\x16'\"#),\n        ('\\x17', r#\"'\\x17'\"#),\n        ('\\x18', r#\"'\\x18'\"#),\n        ('\\x19', r#\"'\\x19'\"#),\n        ('\\x1A', r#\"'\\x1A'\"#),\n        ('\\x1B', r#\"'\\x1B'\"#),\n        ('\\x1C', r#\"'\\x1C'\"#),\n        ('\\x1D', r#\"'\\x1D'\"#),\n        ('\\x1E', r#\"'\\x1E'\"#),\n        ('\\x1F', r#\"'\\x1F'\"#),\n    ];\n\n    for (c, expected) in first_escapes.iter().copied() {\n        let utf8_here = char_to_debug(c);\n        assert_eq!(expected.as_bytes(), utf8_here.as_bytes(), \"{:?}\", c);\n        assert_eq!(expected.len(), char_debug_len(c), \"{:?}\", c);\n    }\n\n    let other_escapes = [('\\'', r#\"'\\''\"#), ('\\\"', r#\"'\\\"'\"#), ('\\\\', r#\"'\\\\'\"#)];\n\n    let mut buffer = arrayvec::ArrayString::<12>::new();\n    for c in '\\x20'..=core::char::MAX {\n        let utf8_here = char_to_debug(c);\n\n        if let Some((_, expected)) = Some(c)\n            .filter(|c| *c <= '\\x7F')\n            .and_then(|c| other_escapes.iter().copied().find(|x| x.0 == c))\n        {\n            assert_eq!(expected.as_bytes(), utf8_here.as_bytes(), \"{:?}\", c);\n            assert_eq!(expected.len(), char_debug_len(c), \"{:?}\", c);\n        } else {\n            buffer.clear();\n            buffer.push('\\'');\n            buffer.push(c);\n            buffer.push('\\'');\n            assert_eq!(buffer.as_bytes(), utf8_here.as_bytes(), \"{:?}\", c);\n            assert_eq!(buffer.len(), char_debug_len(c), \"{:?}\", c);\n        }\n    }\n}\n"
  },
  {
    "path": "const_format/src/char_encoding.rs",
    "content": "use crate::formatting::{hex_as_ascii, HexFormatting};\n\n#[cfg(any(test, feature = \"fmt\"))]\npub(crate) const fn char_display_len(c: char) -> usize {\n    match c as u32 {\n        0..=127 => 1,\n        0x80..=0x7FF => 2,\n        0x800..=0xFFFF => 3,\n        0x10000..=u32::MAX => 4,\n    }\n}\n\n#[cfg(any(test, feature = \"fmt\"))]\npub(crate) const fn char_debug_len(c: char) -> usize {\n    let inner = match c {\n        '\\t' | '\\r' | '\\n' | '\\\\' | '\\'' | '\\\"' => 2,\n        '\\x00'..='\\x1F' => 4,\n        _ => char_display_len(c),\n    };\n    inner + 2\n}\n\nconst fn char_to_utf8(char: char) -> ([u8; 4], usize) {\n    let u32 = char as u32;\n    match u32 {\n        0..=127 => ([u32 as u8, 0, 0, 0], 1),\n        0x80..=0x7FF => {\n            let b0 = 0b1100_0000 | (u32 >> 6) as u8;\n            let b1 = 0b1000_0000 | (u32 & 0b0011_1111) as u8;\n            ([b0, b1, 0, 0], 2)\n        }\n        0x800..=0xFFFF => {\n            let b0 = 0b1110_0000 | (u32 >> 12) as u8;\n            let b1 = 0b1000_0000 | ((u32 >> 6) & 0b0011_1111) as u8;\n            let b2 = 0b1000_0000 | (u32 & 0b0011_1111) as u8;\n            ([b0, b1, b2, 0], 3)\n        }\n        0x10000..=u32::MAX => {\n            let b0 = 0b1111_0000 | (u32 >> 18) as u8;\n            let b1 = 0b1000_0000 | ((u32 >> 12) & 0b0011_1111) as u8;\n            let b2 = 0b1000_0000 | ((u32 >> 6) & 0b0011_1111) as u8;\n            let b3 = 0b1000_0000 | (u32 & 0b0011_1111) as u8;\n            ([b0, b1, b2, b3], 4)\n        }\n    }\n}\n\npub(crate) const fn char_to_display(char: char) -> FmtChar {\n    let ([b0, b1, b2, b3], len) = char_to_utf8(char);\n    FmtChar {\n        encoded: [b0, b1, b2, b3, 0, 0],\n        len: len as u8,\n    }\n}\n\npub(crate) const fn char_to_debug(c: char) -> FmtChar {\n    let ([b0, b1, b2, b3], len) = match c {\n        '\\t' => (*br#\"\\t  \"#, 2),\n        '\\r' => (*br#\"\\r  \"#, 2),\n        '\\n' => (*br#\"\\n  \"#, 2),\n        '\\\\' => (*br#\"\\\\  \"#, 2),\n        '\\'' => (*br#\"\\'  \"#, 2),\n        '\\\"' => (*br#\"\\\"  \"#, 2),\n        '\\x00'..='\\x1F' => {\n            let n = c as u8;\n            (\n                [\n                    b'\\\\',\n                    b'x',\n                    hex_as_ascii(n >> 4, HexFormatting::Upper),\n                    hex_as_ascii(n & 0b1111, HexFormatting::Upper),\n                ],\n                4,\n            )\n        }\n        _ => char_to_utf8(c),\n    };\n\n    let mut encoded = [b'\\'', b0, b1, b2, b3, 0];\n    encoded[len + 1] = b'\\'';\n\n    FmtChar {\n        encoded,\n        len: (len as u8) + 2,\n    }\n}\n\n#[derive(Copy, Clone)]\npub struct FmtChar {\n    encoded: [u8; 6],\n    len: u8,\n}\n\nimpl FmtChar {\n    /// Array which contains the pre-len display/debug-formatted  `char`,\n    /// only `&self.encoded[][..self.len()]` should be copied.\n    pub const fn encoded(&self) -> &[u8; 6] {\n        &self.encoded\n    }\n\n    pub const fn len(&self) -> usize {\n        self.len as usize\n    }\n\n    pub(crate) const fn as_bytes(&self) -> &[u8] {\n        self.encoded.split_at(self.len()).0\n    }\n}\n\n#[cfg(all(test, not(miri)))]\nmod tests;\n"
  },
  {
    "path": "const_format/src/const_debug_derive.rs",
    "content": "/// Derives const debug formatting for a type.\n///\n/// Derives the [`FormatMarker`] trait, and defines an `const_debug_fmt` inherent\n/// method to format a type at compile-time.\n/// \n/// # Features \n/// \n/// This derive macro is only available with the \"derive\" feature,\n/// and Rust 1.83.0, because is uses mutable references in const.\n///\n/// # Limitations\n///\n/// Compile-time formatting currently imposes these limitations on users,\n/// this derive macro has some mitigations for some of them.\n///\n/// ### Generic impls\n///\n/// Because the formatting of custom types is implemented with duck typing,\n/// it's not possible to format generic types, instead you must do either of these:\n///\n/// - Provide all the implementations ahead of time, what the [`impls attribute`] is for.\n///\n/// - Provide a macro that formats the type.\n/// The `call_debug_fmt` macro is a version of this that formats generic std types,\n/// then it can be used to format fields of the type with the \n/// [`#[cdeb(with_macro = \"....\")]`](#cdeb_with_macro) attribute.\n///\n/// These are the things that this macro does to mitigate the limitations:\n///\n/// - Allows users to provide a function/macro/wrapper to format a field.\n///\n/// - Automatically detect some builtin/standard library types that are generic.\n///\n/// - Allow users to ignore a field.\n///\n/// # Container Attributes \n///\n/// These attributes go on the type itself, rather than the fields.\n///\n/// ### `#[cdeb(debug_print)]`\n///\n/// Panics with the output of the expanded derive.\n///\n/// ### `#[cdeb(impls(....))]`\n///\n/// Allows users to implement const debug formatting for multiple different\n/// concrete instances of the type.\n/// \n/// When this attribute is used it disables the default implementation\n/// that uses the type parameters generically.\n///\n/// Example:\n/// \n/// ```rust\n/// #[derive(const_format::ConstDebug)]\n/// #[cdeb(impls(\n///     \"Foo<u8, u64>\",\n///     \"<T> Foo<u16, T>\",\n///     \"<T> Foo<u32, T> where T: 'static\",\n/// ))]\n/// struct Foo<A, B>(A, *const B);\n/// ```\n///\n/// In this example, there's exactly three impls of \n/// the `const_debug_fmt` method and [`FormatMarker`] trait.\n///\n/// ### `#[cdeb(crate = \"foo::bar\")]`\n///\n/// The path to the `const_format` crate, useful if you want to reexport the ConstDebug macro,\n/// or rename the `const_format` crate in the Cargo.toml .\n///\n/// Example of renaming the `const_format` crate in the Cargo.toml file:\n/// ```toml\n/// cfmt = {version = \"0.*\", package = \"const_format\"}\n/// ```\n///\n/// # Field attributes\n///\n/// ### `#[cdeb(ignore)]`\n///\n/// Ignores the field, pretending that it doesn't exist.\n///\n/// ### `#[cdeb(with = \"module::function\")]`\n///\n/// Uses the function at the passed-in path to format the field.\n///\n/// The function is expected to have this signature:\n/// ```ignored\n/// const fn(&FieldType, &mut const_format::Formatter<'_>) -> Result<(), const_format::Error>\n/// ```\n///\n/// <span id = \"cdeb_with_macro\"> </span>\n///\n/// ### `#[cdeb(with_macro = \"module::the_macro\")]`\n///\n/// Uses the macro at the passed-in path to format the field.\n///\n/// The macro is expected to be callable like a function with this signature: \n/// ```ignored\n/// const fn(&FieldType, &mut const_format::Formatter<'_>) -> Result<(), const_format::Error>\n/// ```\n/// \n/// ### `#[cdeb(with_wrapper = \"module::Wrapper\")]`\n/// \n/// Uses the wrapper type to print the field.\n///\n/// The wrapper is expected to wrap a reference to the field type,\n/// to have an implementation of the [`FormatMarker`] trait,\n/// and have a method with this signature:\n/// ```ignored\n/// const fn const_debug_fmt(\n///     self,\n///     &mut const_format::Formatter<'_>,\n/// ) -> Result<(), const_format::Error>\n/// ```\n/// (`self` can be taken by reference or by value)\n///\n/// ### `#[cdeb(is_a(....))]`\n/// \n/// Gives the derive macro a hint of what the type is.\n///\n/// For standard library types,\n/// this is necessary if you're using a type alias, since the derive macro detects \n/// those types syntactically.\n///\n/// These are the valid ways to use this attribute:\n///\n/// - `#[cdeb(is_a(array))]`/`#[cdeb(is_a(slice))]`:\n/// Treats the field as being a slice/array,\n/// printing the elements of std or user-defined type with const debug formatting.\n///\n/// - `#[cdeb(is_a(Option))]`/`#[cdeb(is_a(option))]`:\n/// Treats the field as being an Option, \n/// printing the contents of std or user-defined type with const debug formatting.\n///\n/// - `#[cdeb(is_a(newtype))]`:\n/// Treats the field as being being a single field tuple struct, \n/// using the identifier of the field type as the name of the struct,\n/// then printing the single field of std or user-defined type with const debug formatting.\n///\n/// - `#[cdeb(is_a(non_std))]`/`#[cdeb(is_a(not_std))]`:\n/// This acts as an opt-out for the automatic detection of std types,\n/// most likely needed for types named `Option`.\n/// \n/// # Examples\n/// \n/// ### Basic\n/// \n/// This example demonstrates using the derive without using any helper attributes.\n/// \n/// ```rust\n/// \n/// use const_format::{ConstDebug, formatc};\n/// \n/// use std::cmp::Ordering;\n/// \n/// const E_FOO: &str = formatc!(\"{:?}\", Enum::Foo);\n/// const E_BAR: &str = formatc!(\"{:?}\", Enum::Bar(10));\n/// const E_BAZ: &str = formatc!(\"{:?}\", Enum::Baz{order: Ordering::Less});\n/// \n/// const S_UNIT: &str = formatc!(\"{:?}\", Unit);\n/// const S_BRACED: &str = formatc!(\"{:?}\", Braced{is_true: false, optional: Some(Unit)});\n/// \n/// assert_eq!(E_FOO, \"Foo\");\n/// assert_eq!(E_BAR, \"Bar(10)\");\n/// assert_eq!(E_BAZ, \"Baz { order: Less }\");\n/// \n/// assert_eq!(S_UNIT, \"Unit\");\n/// assert_eq!(S_BRACED, \"Braced { is_true: false, optional: Some(Unit) }\");\n/// \n/// \n/// #[derive(ConstDebug)]\n/// enum Enum {\n///     Foo,\n///     Bar(u32),\n///     Baz{\n///         order: Ordering,\n///     },\n/// }\n/// \n/// #[derive(ConstDebug)]\n/// struct Unit;\n/// \n/// #[derive(ConstDebug)]\n/// struct Braced {\n///     is_true: bool,\n///     optional: Option<Unit>,\n/// }\n/// \n/// ```\n/// \n/// ### Generic type\n/// \n/// This example demonstrates the `#[cdeb(impls)]` attribute,\n/// a workaround for deriving this trait for generic types,\n/// specifying a list of impls of types that unconditionally implement const debug formatting\n/// \n/// ```rust\n/// \n/// use const_format::{ConstDebug, formatc};\n/// \n/// use std::marker::PhantomData;\n/// \n/// \n/// const S_U32: &str = formatc!(\"{:?}\", Foo(10));\n///\n/// const S_STR: &str = formatc!(\"{:?}\", Foo(\"hello\"));\n/// \n/// const S_PHANTOM: &str = formatc!(\"{:?}\", Foo(PhantomData::<()>));\n/// \n/// assert_eq!(S_U32, r#\"Foo(10)\"#);\n/// assert_eq!(S_STR, r#\"Foo(\"hello\")\"#);\n/// assert_eq!(S_PHANTOM, r#\"Foo(PhantomData)\"#);\n/// \n/// \n/// // This type implements const debug formatting three times:\n/// // - `Foo<u32>`\n/// // - `Foo<&str>`\n/// // - `Foo<PhantomData<T>>`: with a generic `T`\n/// #[derive(ConstDebug)]\n/// #[cdeb(impls(\n///     \"Foo<u32>\",\n///     \"Foo<&str>\",\n///     \"<T> Foo<PhantomData<T>>\",\n/// ))]\n/// struct Foo<T>(T);\n/// \n/// ```\n/// \n/// ### `is_a` attributes\n/// \n/// This example demonstrates when you would use the `is_a` attributes.\n/// \n/// ```rust\n/// \n/// use const_format::{ConstDebug, formatc};\n/// \n/// use std::{\n///     cmp::Ordering,\n///     marker::PhantomData,\n///     num::Wrapping,\n/// };\n/// \n/// const STRUCT: &Struct = &Struct {\n///     arr: [Ordering::Less, Ordering::Equal, Ordering::Greater, Ordering::Less],\n///     opt: Some(Unit),\n///     wrap: Wrapping(21),\n///     not_option: Option(PhantomData), // This is not the standard library `Option`\n/// };\n/// \n/// const S_STRUCT: &str = formatc!(\"{STRUCT:#?}\");\n/// \n/// const EXPECTED: &str = \"\\\n/// Struct {\n///     arr: [\n///         Less,\n///         Equal,\n///         Greater,\n///         Less,\n///     ],\n///     opt: Some(\n///         Unit,\n///     ),\n///     wrap: Wrapping(\n///         21,\n///     ),\n///     not_option: Option(\n///         PhantomData,\n///     ),\n/// }\";\n/// \n/// fn main(){\n///     assert_eq!(S_STRUCT, EXPECTED);\n/// }\n/// \n/// #[derive(ConstDebug)]\n/// struct Struct {\n///     // `Ordering` implements const debug formatting,\n///     // but `[Ordering; 4]` does not, so this attribute is required for the \n///     // derive macro to generate code to format this array field.\n///     #[cdeb(is_a(array))]\n///     arr: Array,\n///     \n///     // Attribute is required to tell the derive macro that this is an\n///     // `Option` wrapping a user-defined type,\n///     // since `Option<Unit>` doesn't implement const debug formatting.\n///     #[cdeb(is_a(option))]\n///     opt: Opt,\n///     \n///     // Attribute is required because `Wrapping<usize>` is a newtype struct\n///     // that doesn't implement const debug formatting,\n///     // so the derive generates code to format it.\n///     #[cdeb(is_a(newtype))]\n///     wrap: Wrapping<usize>,\n///\n///     // Attribute is required for the field to be treated as a user-defined type,\n///     // otherwise it'd be assumed to be `Option` from the standard library.\n///     #[cdeb(is_a(not_std))]\n///     not_option: Option<u32>, \n///     \n/// }\n/// \n/// type Array = [Ordering; 4];\n/// \n/// type Opt = std::option::Option<Unit>;\n/// \n/// #[derive(ConstDebug)]\n/// struct Unit;\n/// \n/// #[derive(ConstDebug)]\n/// struct Option<T>(PhantomData<T>);\n/// \n/// ```\n///\n/// [`FormatMarker`]: ./marker_traits/trait.FormatMarker.html\n/// [`impls attribute`]: #cdebimpls\n///\n///\n///\n/// \n/// ### Renamed import\n/// \n/// This example demonstrates that you can use all the macros when the `const_format`\n/// crate is renamed.\n/// \n/// ```rust\n/// # extern crate self as const_format;\n/// # extern crate const_format as cfmt;\n/// # fn main() {\n/// use cfmt::{\n///     for_examples::Unit,\n///     ConstDebug, formatc,\n/// };\n/// \n/// #[derive(ConstDebug)]\n/// #[cdeb(crate = \"cfmt\")]\n/// struct Foo {\n///     bar: &'static str,\n///     baz: Unit\n/// }\n/// \n/// const TEXT: &str = formatc!(\"{:?}\", Foo{ bar: \"hello\", baz: Unit });\n/// \n/// assert_eq!(TEXT, r#\"Foo { bar: \"hello\", baz: Unit }\"#);\n/// \n/// # }\n/// ```\n///\n#[cfg_attr(feature = \"__docsrs\", doc(cfg(feature = \"derive\")))]\n#[cfg(feature = \"derive\")]\npub use const_format_proc_macros::ConstDebug;\n"
  },
  {
    "path": "const_format/src/const_generic_concatcp.rs",
    "content": "//! Reimplements some stuff from concatcp to be const generic instead of macro generated\n\nuse crate::pmr::{LenAndArray, PArgument, PVariant};\n\n#[doc(hidden)]\npub const fn __priv_concatenate<const LEN: usize>(input: &[PArgument]) -> LenAndArray<[u8; LEN]> {\n    let mut out = LenAndArray {\n        len: 0,\n        array: [0u8; LEN],\n    };\n\n    crate::__for_range! { outer_i in 0..input.len() =>\n        let current = &input[outer_i];\n\n        match current.elem {\n            PVariant::Str(s) => crate::__write_pvariant!(str, current, s => out),\n            PVariant::Int(int) => crate::__write_pvariant!(int, current, int => out),\n            PVariant::Char(c) => crate::__write_pvariant!(char, current, c => out),\n        }\n    }\n\n    out\n}\n"
  },
  {
    "path": "const_format/src/doctests.rs",
    "content": "//! This module tests for errors that happen in the expanded code,\n//! errors detectable by the macro itself are tested in the proc macro crate.\n\n#![allow(non_camel_case_types)]\n\n///\n/// ```rust\n///\n/// struct Foo<T>(T);\n///\n/// const_format::impl_fmt!{\n///     impl[T,] Foo<T>\n///     where[T: 'static,];\n///\n///     fn foo(){}\n///\n/// }\n/// ```\n///\n/// ```compile_fail\n///\n/// struct Foo<T>(T);\n///\n/// const_format::impl_fmt!{\n///     impl[T,] Foo<T>\n///     where[asodkaspodaoskd,];\n///\n///     fn foo(){}\n/// }\n/// ```\n///\n/// ```compile_fail\n///\n/// struct Foo<T>(T);\n///\n/// const_format::impl_fmt!{\n///     impl[T,] Foo<T>\n///     where[T: T];\n///\n///     fn foo(){}\n/// }\n/// ```\n///\n#[cfg(feature = \"fmt\")]\npub struct ImplFmtWhereClause;\n\n///\n/// ```rust\n///\n/// #[derive(const_format::ConstDebug)]\n/// struct Foo<T>(*const T)\n/// where T: 'static;\n///\n/// fn main(){}\n/// ```\n///\n/// ```compile_fail\n///\n/// #[derive(const_format::ConstDebug)]\n/// struct Foo<T>(*const T)\n/// where AAAA: AAAA;\n///\n/// fn main(){}\n/// ```\n///\n#[cfg(feature = \"derive\")]\npub struct ConstDebugWhereClause;\n\n/// ```rust\n///\n/// use const_format::StrWriterMut;\n///\n/// let mut len = 0;\n/// let mut buffer = [0; 128];\n///\n/// let mut writer = StrWriterMut::from_custom(&mut buffer, &mut len);\n///\n/// writer.write_str(\"hello\").unwrap();\n///\n/// assert_eq!(writer.as_bytes(), b\"hello\")\n///\n/// ```\n///\n/// ```compile_fail\n///\n/// use const_format::StrWriterMut;\n///\n/// let mut len = 0;\n/// let mut buffer = [0; 128];\n///\n/// let mut writer = StrWriterMut::from_custom(&mut buffer, &mut len);\n///\n/// writer.write_str(\"hello\").unwrap();\n///\n/// assert_eq!(writer.as_str(), \"hello\")\n///\n/// ```\n///\n#[cfg(feature = \"fmt\")]\npub struct AsStr_For_StrWriterMut_NoEncoding;\n\n/// ```rust\n///\n/// const_format::assertc!(true, \"foo\");\n///\n/// ```\n///\n/// ```compile_fail\n///\n/// const_format::assertc!(false, \"foo\");\n///\n/// ```\n///\n/// # With a Formatting argument\n///\n/// ```rust\n///\n/// const_format::assertc!(\n///     true,\n///     \"{foo}\\n{foo:#?}\\n{}\",\n///     |fmt| { const_format::call_debug_fmt!(array, [100u8], fmt ) },\n///     foo = |fmt| { const_format::call_debug_fmt!(array, [(), ()], fmt ) },\n/// );\n///\n/// const_format::assertc!(\n///     true,\n///     \"{foo}\\n{foo:#?}\\n{}\",\n///     |fmt| const_format::call_debug_fmt!(array, [100u8], fmt ),\n///     foo = |fmt| const_format::call_debug_fmt!(array, [(), ()], fmt ),\n/// );\n///\n/// ```\n///\n/// ```compile_fail\n///\n/// const_format::assertc!(\n///     false,\n///     \"{foo}\\n{foo:#?}\\n{}\",\n///     |fmt| { const_format::call_debug_fmt!(array, [100u8], fmt ) },\n///     foo = |fmt| { const_format::call_debug_fmt!(array, [(), ()], fmt ) },\n/// );\n///\n/// const_format::assertc!(\n///     false,\n///     \"{foo}\\n{foo:#?}\\n{}\",\n///     |fmt| const_format::call_debug_fmt!(array, [100u8], fmt ),\n///     foo = |fmt| const_format::call_debug_fmt!(array, [(), ()], fmt ),\n/// );\n///\n/// ```\n///\n#[cfg(feature = \"assertc\")]\npub struct Assert;\n\n/// # assert_eq\n///\n/// ```rust\n///\n/// const_format::assertc_eq!(0u8, 0u8, \"foo\");\n///\n/// ```\n///\n/// ```compile_fail\n///\n/// const_format::assertc_eq!(0u8, 10u8, \"foo\");\n///\n/// ```\n///\n/// # assert_ne\n///\n/// ```rust\n///\n/// const_format::assertc_ne!(0u8, 10u8, \"foo\");\n///\n/// ```\n///\n/// ```compile_fail\n///\n/// const_format::assertc_ne!(0u8, 0u8, \"foo\");\n///\n/// ```\n///\n#[cfg(feature = \"assertc\")]\npub struct AssertCmp;\n\n/// ```rust\n/// const_format::assertcp!(true, \"foo\");\n/// ```\n///\n/// ```compile_fail\n/// const_format::assertcp!(false, \"foo\");\n/// ```\n///\n#[cfg(feature = \"assertcp\")]\npub struct AssertCP;\n\n/// # assert_eq\n///\n/// ```rust\n/// const_format::assertcp_eq!(0u8, 0u8, \"foo\");\n/// ```\n///\n/// ```compile_fail\n/// const_format::assertcp_eq!(0u8, 10u8, \"foo\");\n/// ```\n///\n/// # assert_ne\n///\n/// ```rust\n/// const_format::assertcp_ne!(0u8, 10u8, \"foo\");\n/// ```\n///\n/// ```compile_fail\n/// const_format::assertcp_ne!(0u8, 0u8, \"foo\");\n/// ```\n///\n#[cfg(feature = \"assertcp\")]\npub struct AssertCPCmp;\n"
  },
  {
    "path": "const_format/src/equality.rs",
    "content": "#![allow(missing_docs, unused_variables)]\n\nuse crate::wrapper_types::PWrapper;\n\nuse core::{\n    cmp::Ordering,\n    marker::{PhantomData, PhantomPinned},\n    num::{\n        NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize, NonZeroU128,\n        NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize,\n    },\n    ops::{Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive},\n    sync::atomic::Ordering as AtomicOrdering,\n};\n\n////////////////////////////////////////////////////////////////////////////////\n\nmacro_rules! slice_of_const_eq {($($elem:ty),* $(,)?) => (\n    $(\n        impl PWrapper<&[$elem]> {\n            /// This method is only available with the \"assert\" feature.\n            pub const fn const_eq(&self, other: &[$elem]) -> bool {\n                if self.0.len() != other.len() {\n                    return false;\n                }\n\n                __for_range!{i in 0..self.0.len() =>\n                    if !PWrapper(self.0[i]).const_eq(&other[i]) {\n                        return false\n                    }\n                }\n                true\n            }\n        }\n    )*\n)}\n\nslice_of_const_eq! {\n    &str,\n}\n\nmacro_rules! slice_of_equal_op_impl {($($elem:ty),* $(,)?) => (\n    $(\n        impl PWrapper<&[$elem]> {\n            /// This method is only available with the \"assert\" feature.\n            pub const fn const_eq(&self, other: &[$elem]) -> bool {\n                if self.0.len() != other.len() {\n                    return false;\n                }\n\n                __for_range!{i in 0..self.0.len() =>\n                    if self.0[i] != other[i] {\n                        return false\n                    }\n                }\n                true\n            }\n        }\n    )*\n)}\n\nslice_of_equal_op_impl! {\n    bool,\n    char,\n    u8, i8,\n    u16, i16,\n    u32, i32,\n    u64, i64,\n    u128, i128,\n    usize, isize,\n}\n\n////////////////////////////////////////////////////////////////////////////////\n\nmacro_rules! impl_eq_for_option_prim {\n    (\n        (l=$l:ident, r=$r:ident)\n        $( impl[$($impl_:tt)*] $type:ty = $comparison:expr; )*\n    ) => (\n        $(\n            impl<$($impl_)*> PWrapper<Option<$type>> {\n                /// This method is only available with the \"assert\" feature.\n                pub const fn const_eq(&self, other:&Option<$type>) -> bool {\n                    match (self.0, other) {\n                        (Some($l), Some($r)) => $comparison,\n                        (None, None) => true,\n                        _ => false,\n                    }\n                }\n            }\n        )*\n    )\n}\n\nimpl_eq_for_option_prim! {\n    (l=l, r=r)\n    impl[] u8 = l == *r;\n    impl[] i8 = l == *r;\n    impl[] u16 = l == *r;\n    impl[] i16 = l == *r;\n    impl[] u32 = l == *r;\n    impl[] i32 = l == *r;\n    impl[] u64 = l == *r;\n    impl[] i64 = l == *r;\n    impl[] u128 = l == *r;\n    impl[] i128 = l == *r;\n    impl[] usize = l == *r;\n    impl[] isize = l == *r;\n    impl[] bool = l == *r;\n    impl[] char = l == *r;\n    impl[] &str = crate::slice_cmp::str_eq(l, r);\n}\n\nmacro_rules! impl_eq_for_option {\n    (\n        (l=$l:ident, r=$r:ident)\n        $( impl[$($impl_:tt)*] $type:ty = $comparison:expr; )*\n    ) => (\n        $(\n            impl<$($impl_)*> PWrapper<$type> {\n                /// This method is only available with the \"assert\" feature.\n                pub const fn const_eq(&self, $r:&$type) -> bool {\n                    let $l = self.0;\n                    $comparison\n                }\n            }\n        )*\n\n        impl_eq_for_option_prim! {\n            (l=$l, r=$r)\n            $( impl[$($impl_)*] $type = $comparison; )*\n        }\n    )\n}\n\nimpl_eq_for_option! {\n    (l=l, r=r)\n\n    impl[] NonZeroU8 = l.get() == r.get();\n    impl[] NonZeroI8 = l.get() == r.get();\n    impl[] NonZeroU16 = l.get() == r.get();\n    impl[] NonZeroI16 = l.get() == r.get();\n    impl[] NonZeroU32 = l.get() == r.get();\n    impl[] NonZeroI32 = l.get() == r.get();\n    impl[] NonZeroU64 = l.get() == r.get();\n    impl[] NonZeroI64 = l.get() == r.get();\n    impl[] NonZeroU128 = l.get() == r.get();\n    impl[] NonZeroI128 = l.get() == r.get();\n    impl[] NonZeroUsize = l.get() == r.get();\n    impl[] NonZeroIsize = l.get() == r.get();\n}\n\nmacro_rules! impl_equality {\n    (\n        (l=$l:ident, r=$r:ident)\n\n        $( impl[$($impl_:tt)*] $type:ty = $comparison:expr ;)*\n    ) => (\n        $(\n            impl<$($impl_)*> PWrapper<$type> {\n                /// This method is only available with the \"assert\" feature.\n                #[inline(always)]\n                pub const fn const_eq(&self, $r: &$type) -> bool {\n                    let $l = &self.0;\n                    $comparison\n                }\n            }\n        )*\n    )\n}\n\nimpl_equality! {\n    (l=l, r=r)\n\n    impl[T: ?Sized,] PhantomData<T> = true;\n    impl[] PhantomPinned = true;\n    impl[] () = true;\n\n    impl[] Ordering = *l as u8 == *r as u8;\n    impl[] AtomicOrdering = *l as u8 == *r as u8;\n\n    impl[] Range<usize>            = l.start == r.start && l.end == r.end;\n    impl[] RangeInclusive<usize>   = *l.start() == *r.start() && *l.end() == *r.end();\n    impl[] RangeFrom<usize>        = l.start == r.start;\n    impl[] RangeFull               = true;\n    impl[] RangeTo<usize>          = l.end == r.end;\n    impl[] RangeToInclusive<usize> = l.end == r.end;\n}\n"
  },
  {
    "path": "const_format/src/fmt/error.rs",
    "content": "// <_< clippy you silly\n#![allow(clippy::enum_variant_names)]\n\nuse core::fmt::{self, Display};\n\n/// An error while trying to write into a StrWriter.\n#[non_exhaustive]\n#[derive(Debug, Copy, Clone, PartialEq, Eq)]\npub enum Error {\n    /// Attempted to write something into the buffer when there isn't enough space to write it.\n    NotEnoughSpace,\n    /// For compatibility with [`NotAsciiError`](../wrapper_types/struct.NotAsciiError.html)\n    NotAscii,\n    /// Attempted to index a string arguent by an range where one of the bounds\n    /// was not on a char boundary.\n    NotOnCharBoundary,\n}\n\nimpl Display for Error {\n    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {\n        match self {\n            Self::NotEnoughSpace => {\n                fmt.write_str(\"The was not enough space to write the formatted output\")\n            }\n            Self::NotAscii => fmt.write_str(\"Attempted to write non-ascii text\"),\n            Self::NotOnCharBoundary => {\n                fmt.write_str(\"Attempted to index a byte that's not on a char boundary.\")\n            }\n        }\n    }\n}\n\nmacro_rules! index_vars{\n    ($self:ident, $index:ident; $($variant:ident),* $(,)? ) => (\n        enum Index{\n            $($variant,)*\n        }\n\n        let $index = match &$self {\n            $(Error::$variant{..} => 3300 + Index::$variant as usize,)*\n        };\n    )\n}\n\nimpl Error {\n    /// For panicking at compile-time, with a compile-time error that says what the error is.\n    #[track_caller]\n    pub const fn unwrap<T>(&self) -> T {\n        index_vars! {\n            self,i;\n            NotEnoughSpace,\n            NotAscii,\n            NotOnCharBoundary,\n        };\n\n        match self {\n            Error::NotEnoughSpace => [\"The was not enough space to write the formatted output\"][i],\n            Error::NotAscii => [\"Attempted to write non-ascii text\"][i],\n            Error::NotOnCharBoundary => {\n                [\"Attempted to index a byte that's not on a char boundary.\"][i]\n            }\n        };\n        loop {}\n    }\n}\n\n////////////////////////////////////////////////////////////////////////////////\n\n/// The return type of most formatting functions\npub type Result<T = (), E = Error> = core::result::Result<T, E>;\n\n////////////////////////////////////////////////////////////////////////////////\n\n/// For converting types to [`const_format::Result`]\n///\n/// [`const_format::Result`]: ./type.Result.html\npub struct ToResult<T>(pub T);\n\nimpl ToResult<()> {\n    ///\n    #[inline(always)]\n    pub const fn to_result(self) -> Result {\n        Ok(())\n    }\n}\n\nimpl ToResult<Result> {\n    ///\n    #[inline(always)]\n    pub const fn to_result(self) -> Result {\n        self.0\n    }\n}\n"
  },
  {
    "path": "const_format/src/fmt/formatter.rs",
    "content": "use crate::{\n    fmt::{Error, FormattingFlags, NoEncoding, StrWriter, StrWriterMut},\n    utils::saturate_range,\n    wrapper_types::{AsciiStr, PWrapper},\n};\n\nuse core::ops::Range;\n\n////////////////////////////////////////////////////////////////////////////////\n\n/// For computing how long a formatted string would be.\n///\n/// This is what the [`formatc`] macro uses to precalculate the length of its returned `&str`.\n///\n/// # Example\n///\n/// ```rust\n///\n/// use const_format::fmt::{ComputeStrLength, Error, Formatter, FormattingFlags, StrWriter};\n/// use const_format::{try_, writec, unwrap};\n///\n/// const fn write_sum(mut f: Formatter<'_>) -> Result<(), Error> {\n///     let l = 7u8;\n///     let r = 8u8;\n///     writec!(f, \"{} + {} = {}\", l, r, l + r)\n/// }\n///\n/// const LEN: usize = {\n///     let mut computer = ComputeStrLength::new();\n///     unwrap!(write_sum(computer.make_formatter(FormattingFlags::NEW)));\n///     computer.len()\n/// };\n///\n/// // The type annotation coerces a `&mut StrWriter<[u8; LEN]>`\n/// // to a `&mut StrWriter<[u8]>` (the type parameter defaults to `[u8]`)\n/// let writer: &mut StrWriter = &mut StrWriter::new([0; LEN]);\n///\n/// write_sum(writer.make_formatter(FormattingFlags::NEW)).unwrap();\n///\n/// assert_eq!(writer.as_str(), \"7 + 8 = 15\");\n/// assert_eq!(writer.len(), LEN);\n/// assert_eq!(writer.capacity(), LEN);\n///\n/// ```\n///\n/// [`formatc`]: ../macro.formatc.html\n///\n///\npub struct ComputeStrLength {\n    len: usize,\n}\n\nimpl ComputeStrLength {\n    /// Constructs a ComputeStrLength of length 0.\n    pub const fn new() -> Self {\n        Self { len: 0 }\n    }\n\n    /// Constructs a `Formatter`,\n    /// which instead of writing to a buffer it adds the computed length into this.\n    pub const fn make_formatter(&mut self, flags: FormattingFlags) -> Formatter<'_> {\n        Formatter {\n            margin: 0,\n            flags,\n            writer: WriterBackend::Length(self),\n        }\n    }\n\n    /// Adds `len` to the calculated length.\n    pub const fn add_len(&mut self, len: usize) {\n        self.len += len;\n    }\n\n    /// The length of the string when formatted.\n    pub const fn len(&self) -> usize {\n        self.len\n    }\n\n    /// Whether the length of the computed string is zero.\n    pub const fn is_empty(&self) -> bool {\n        self.len == 0\n    }\n\n    /// For borrowing this mutably in macros,just takes and returns a `&mut Self`.\n    #[inline(always)]\n    pub const fn borrow_mutably(&mut self) -> &mut Self {\n        self\n    }\n}\n\n////////////////////////////////////////////////////////////////////////////////\n\nenum WriterBackend<'w> {\n    Str(StrWriterMut<'w, NoEncoding>),\n    Length(&'w mut ComputeStrLength),\n}\n\n////////////////////////////////////////////////////////////////////////////////\n\n/// A handle for writing formatted output.\n///\n/// `Formatter` writes utf8 encoded text, it can't be used to write arbitrary bytes.\n///\n/// # FormattingFlags\n///\n/// Types can change how they're formatted based on the value returned by `.flags()`,\n/// for more details on that you can read the documentation for [`FormattingFlags`].\n///\n/// # Construction\n///\n/// This type can be constructed in these ways:\n///\n/// - From a pair of mutable reference to a [`StrWriter`] and a [`FormattingFlags`],\n/// with the [`from_sw`] constructor.\n///\n/// - From a pair of [`StrWriterMut`] and [`FormattingFlags`],\n/// with the [`from_sw_mut`] constructor.\n///\n/// - From a [`ComputeStrLength`], by calling its\n/// [`make_formatter`](./struct.ComputeStrLength.html#method.make_formatter) method.\n/// This allows computing the length of formatted output without writing to anything.\n///\n/// - From a triple of `[u8]` and `usize` mutable references, and a [`FormattingFlags`],\n/// with the [`from_custom_cleared`] constructor,\n/// or the [`from_custom`] constructor.\n///\n/// # Errors\n///\n/// The `write_*` methods can only return an `Error::NotEnoughSpace`,\n/// when they do, the formatter was not written to, so you can try again with a shorter input.\n///\n/// In the case of the `debug_*` methods / the `Debug*` structs,\n/// they can return a `Error::NotEnoughSpace` when their `finish` method is called,\n/// not as soon as it happens.\n///\n/// # Examples\n///\n/// ### Display formatting\n///\n/// This example demonstrates how you can do display formatting with a Formatter.\n///\n/// If you want to write a braced struct/variant you can use [`DebugStruct`],\n/// or [`DebugTuple`] for tuple structs/variants.\n///\n/// ```rust\n///\n/// use const_format::{Error, Formatter, FormattingFlags, StrWriter};\n/// use const_format::{impl_fmt, try_};\n///\n/// struct Foo;\n///\n/// impl_fmt!{\n///     impl[] Foo;\n///     \n///     const fn const_display_fmt(&self, mut f: Formatter<'_>) -> Result<(), Error> {\n///         let string = \"foo bar baz\";\n///         try_!(f.write_u8_display(100));\n///         try_!(f.write_str(\" \"));\n///         try_!(f.write_str_range(string, 4..7));\n///         try_!(f.write_str(\"\\n\\n\\n...figters\"));\n///         Ok(())\n///     }\n/// }\n///\n/// // We have to coerce `&mut StrWriter<[u8; 256]>` to `&mut StrWriter` to call the\n/// // `make_formatter` method.\n/// let writer: &mut StrWriter = &mut StrWriter::new([0; 256]);\n///\n/// let flags = FormattingFlags::NEW.set_binary();\n///\n/// // The Display formatters from this crate don't care which NumberFormatting you pass,\n/// // they'll just write integers as decimal.\n/// Foo.const_display_fmt(writer.make_formatter(flags));\n///\n/// assert_eq!(writer.as_str(), \"100 bar\\n\\n\\n...figters\");\n/// ```\n///\n/// <span id = \"write_array_example\"></span>\n/// ### Writing to an array\n///\n/// This example demonstrates how you can use a Formatter to write to a byte slice.\n///\n/// You can use the [`from_custom`] constructor if you need to start writing from\n/// anywhere other than 0.\n///\n/// ```rust\n///\n/// use const_format::{Error, Formatter, FormattingFlags, StrWriter};\n/// use const_format::{impl_fmt, try_, writec};\n///\n/// const fn write_int(int: u32, buffer: &mut [u8]) -> Result<usize, Error> {\n///     let mut len = 0;\n///     let mut f = Formatter::from_custom_cleared(buffer, &mut len, FormattingFlags::NEW);\n///     try_!(writec!(f, \"{0},{0:x},{0:b}\", int));\n///     Ok(len)\n/// }\n///\n/// let mut buffer = [0;64];\n///\n/// let written = write_int(17, &mut buffer).unwrap();\n///\n/// let string = std::str::from_utf8(&buffer[..written])\n///     .expect(\"Formatter only writes valid UTF8\");\n///\n/// assert_eq!(string, \"17,11,10001\");\n///\n/// ```\n///\n///\n/// [`DebugStruct`]: crate::fmt::DebugStruct\n/// [`DebugTuple`]: crate::fmt::DebugTuple\n/// [`StrWriter`]: crate::fmt::StrWriter\n/// [`StrWriterMut`]: crate::fmt::StrWriterMut\n/// [`ComputeStrLength`]: crate::fmt::ComputeStrLength\n/// [`from_sw`]: #method.from_sw\n/// [`from_sw_mut`]: #method.from_sw_mut\n/// [`from_custom_cleared`]: #method.from_custom_cleared\n/// [`from_custom`]:  #method.from_custom\n/// [`NumberFormatting`]: crate::fmt::NumberFormatting\n/// [`FormattingFlags`]: crate::fmt::FormattingFlags\n///\npub struct Formatter<'w> {\n    margin: u16,\n    flags: FormattingFlags,\n    writer: WriterBackend<'w>,\n}\n\nconst MARGIN_STEP: u16 = 4;\n\nimpl<'w> Formatter<'w> {\n    /// Constructs a `Formatter`.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    ///\n    /// use const_format::{Error, Formatter, FormattingFlags, StrWriter};\n    /// use const_format::try_;\n    ///\n    /// const fn inner(mut f: Formatter<'_>) -> Result<(), Error> {\n    ///     try_!(f.write_str_range(\"ABCDEF\", 2..4));\n    ///     try_!(f.write_str(\" N\"));\n    ///     try_!(f.write_ascii_repeated(b'o', 10));\n    ///     Ok(())\n    /// }\n    ///\n    /// // We have to coerce `&mut StrWriter<[u8; 128]>` to `&mut StrWriter` to call the\n    /// // `as_str` method.\n    /// let writer: &mut StrWriter = &mut StrWriter::new([0; 128]);\n    /// inner(Formatter::from_sw(writer, FormattingFlags::NEW)).unwrap();\n    ///\n    /// assert_eq!(writer.as_str(), \"CD Noooooooooo\");\n    ///\n    /// ```\n    #[inline]\n    pub const fn from_sw(writer: &'w mut StrWriter, flags: FormattingFlags) -> Self {\n        Self {\n            margin: 0,\n            flags,\n            // safety:\n            // Formatter only writes valid utf8, which is valid for both\n            // encoding type parameters that StrWriterMut can have(Utf8Encoding / NoEncoding).\n            writer: WriterBackend::Str(unsafe { writer.as_mut().into_byte_encoding() }),\n        }\n    }\n\n    /// Constructs a `Formatter`.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    ///\n    /// use const_format::{Error, Formatter, FormattingFlags, StrWriterMut};\n    /// use const_format::try_;\n    ///\n    /// const fn inner(mut f: Formatter<'_>) -> Result<(), Error> {\n    ///     try_!(f.write_str_range(\"DVDVDVD\", 2..5));\n    ///     try_!(f.write_str(\" N\"));\n    ///     try_!(f.write_ascii_repeated(b'o', 10));\n    ///     Ok(())\n    /// }\n    ///\n    /// let mut len = 0;\n    /// let mut buffer = [0; 128];\n    ///\n    /// let mut writer = StrWriterMut::from_custom_cleared(&mut buffer, &mut len);\n    ///\n    /// // We need to call `.reborrow()`, because otherwise the `StrWriterMut` is moved.\n    /// inner(Formatter::from_sw_mut(writer.reborrow(), FormattingFlags::NEW)).unwrap();\n    ///\n    /// assert_eq!(writer.as_str(), \"DVD Noooooooooo\");\n    ///\n    /// ```\n    #[inline]\n    pub const fn from_sw_mut<E: 'static>(\n        writer: StrWriterMut<'w, E>,\n        flags: FormattingFlags,\n    ) -> Self {\n        Self {\n            margin: 0,\n            flags,\n            // safety:\n            // Formatter only writes valid utf8, which is valid for both\n            // encoding type parameters that StrWriterMut can have(Utf8Encoding / NoEncoding).\n            writer: WriterBackend::Str(unsafe { writer.into_byte_encoding() }),\n        }\n    }\n\n    /// Construct a `Formatter` from a byte slice.\n    ///\n    /// `Formatter` only writes utf8, which means that if `&buffer[..length]` is valid utf8,\n    /// then `buffer` will continue to be `utf8` after being written by the `Formatter`.\n    ///\n    /// # Example\n    ///\n    /// This example demonstrates how you can use a Formatter to write to a byte slice\n    /// that had some text written to it already.\n    ///\n    /// ```rust\n    ///\n    /// use const_format::{Error, Formatter, FormattingFlags, StrWriter};\n    /// use const_format::{impl_fmt, try_, writec};\n    ///\n    /// ///\n    /// /// # Safety\n    /// ///\n    /// /// `&buffer[..start]` must be valid utf8.\n    /// const fn write_int(\n    ///     int: u32,\n    ///     buffer: &mut [u8],\n    ///     start: usize,\n    /// ) -> Result<usize, Error> {\n    ///     let mut len = start;\n    ///     let mut f = Formatter::from_custom(buffer, &mut len, FormattingFlags::NEW);\n    ///     try_!(writec!(f, \"{0},{0:x},{0:b}\", int));\n    ///     Ok(len)\n    /// }\n    ///\n    /// let start_str = \"The number is \";\n    /// let mut buffer = [0;64];\n    /// buffer[..start_str.len()].copy_from_slice(start_str.as_bytes());\n    ///\n    /// let new_len = write_int(20, &mut buffer, start_str.len()).unwrap();\n    ///\n    /// let string = std::str::from_utf8(&buffer[..new_len])\n    ///     .expect(\"Formatter only writes valid UTF8\");\n    ///\n    /// assert_eq!(string, \"The number is 20,14,10100\");\n    ///\n    /// ```\n    #[inline]\n    pub const fn from_custom(\n        buffer: &'w mut [u8],\n        length: &'w mut usize,\n        flags: FormattingFlags,\n    ) -> Self {\n        Self {\n            margin: 0,\n            flags,\n            writer: WriterBackend::Str(StrWriterMut::from_custom(buffer, length)),\n        }\n    }\n\n    /// Construct a `Formatter`from a byte slice.\n    ///\n    /// # Example\n    ///\n    /// For an example of using this method you can look at\n    /// [the type level docs](#write_array_example)\n    ///\n    #[inline]\n    pub const fn from_custom_cleared(\n        buffer: &'w mut [u8],\n        length: &'w mut usize,\n        flags: FormattingFlags,\n    ) -> Self {\n        *length = 0;\n        Self {\n            margin: 0,\n            flags,\n            writer: WriterBackend::Str(StrWriterMut::from_custom(buffer, length)),\n        }\n    }\n\n    /// Gets the formatting flags associated with this `Formatter`.\n    #[inline(always)]\n    pub const fn flags(&self) -> FormattingFlags {\n        self.flags\n    }\n\n    /// Gets how much indentation a data structure is printed with.\n    pub const fn margin(&self) -> usize {\n        self.margin as usize\n    }\n\n    #[inline(always)]\n    const fn increment_margin(&mut self) -> &mut Self {\n        self.margin += 4;\n        self\n    }\n\n    #[inline(always)]\n    const fn decrement_margin(&mut self) {\n        self.margin -= 4;\n    }\n}\n\nimpl<'w> Formatter<'w> {\n    /// For borrowing this mutably in macros,just takes and returns a `&mut Self`.\n    #[inline(always)]\n    pub const fn borrow_mutably(&mut self) -> &mut Self {\n        self\n    }\n\n    /// Constructs a reborrow of this formatter, using `flags` as the formatting flags.\n    ///\n    /// The return value inherits the margin from this Formatter.\n    ///\n    /// This method exists because the [`writec`] macro gets a formatter from any writer\n    /// by calling a `make_formatter` method.\n    ///\n    /// # Example\n    ///\n    /// This example demonstrates how you can change the flags when writing a field.\n    ///\n    /// ```rust\n    ///\n    /// use const_format::{Error, Formatter, PWrapper};\n    /// use const_format::{coerce_to_fmt, formatc, impl_fmt, try_};\n    ///\n    /// use std::ops::RangeInclusive;\n    ///\n    /// struct Foo{\n    ///     x: u32,\n    ///     y: RangeInclusive<usize>,\n    ///     z: u32,\n    /// }\n    ///\n    /// impl_fmt!{\n    ///     impl Foo;\n    ///\n    ///     pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {\n    ///         let mut f = f.debug_struct(\"Foo\");\n    ///         try_!(PWrapper(self.x).const_debug_fmt(f.field(\"x\")));\n    ///         \n    ///         let mut fmt_y = f.field(\"y\");\n    ///         let flags = fmt_y.flags().set_binary();\n    ///         try_!(coerce_to_fmt!(&self.y).const_debug_fmt(&mut fmt_y.make_formatter(flags)));\n    ///\n    ///         try_!(PWrapper(self.z).const_debug_fmt(f.field(\"z\")));\n    ///         f.finish()\n    ///     }\n    /// }\n    ///\n    /// const FOO: Foo = Foo {\n    ///     x: 15,\n    ///     y: 16..=31,\n    ///     z: 32,\n    /// };\n    /// const S: &str = formatc!(\"{FOO:#?}\");\n    ///\n    /// const EXPECTED: &str = \"\\\n    /// Foo {\n    ///     x: 15,\n    ///     y: 0b10000..=0b11111,\n    ///     z: 32,\n    /// }\\\n    /// \";\n    ///\n    /// assert_eq!(S, EXPECTED);\n    /// ```\n    ///\n    /// [`writec`]: ../macro.writec.html\n    ///\n    pub const fn make_formatter(&mut self, flags: FormattingFlags) -> Formatter<'_> {\n        Formatter {\n            margin: self.margin,\n            flags,\n            writer: match &mut self.writer {\n                WriterBackend::Str(x) => WriterBackend::Str(x.reborrow()),\n                WriterBackend::Length(x) => WriterBackend::Length(x),\n            },\n        }\n    }\n\n    /// For debug writing a braced struct, or braced variant,\n    /// taking its name as a parameter\n    ///\n    /// # Examples\n    ///\n    /// For examples of using this method, you can look at the docs for [`DebugStruct`]\n    ///\n    /// [`DebugStruct`]: ./struct.DebugStruct.html\n    ///\n    #[inline]\n    pub const fn debug_struct(&mut self, name: &str) -> DebugStruct<'_, 'w> {\n        let err = self.write_str(name);\n        DebugStruct {\n            fmt: self.increment_margin(),\n            wrote_field: false,\n            err,\n        }\n    }\n\n    /// For debug writing a tuple struct, or tuple variant,taking its name as a parameter\n    ///\n    /// # Examples\n    ///\n    /// For examples of using this method, you can look at the docs for [`DebugTuple`]\n    ///\n    /// [`DebugTuple`]: ./struct.DebugTuple.html\n    ///\n    #[inline]\n    pub const fn debug_tuple(&mut self, name: &str) -> DebugTuple<'_, 'w> {\n        let err = self.write_str(name);\n        DebugTuple {\n            fmt: self.increment_margin(),\n            wrote_field: false,\n            err,\n        }\n    }\n\n    /// For debug writing a list/array.\n    ///\n    /// # Examples\n    ///\n    /// For examples of using this method, you can look at the docs for [`DebugList`]\n    ///\n    /// [`DebugList`]: ./struct.DebugList.html\n    ///\n    #[inline]\n    pub const fn debug_list(&mut self) -> DebugList<'_, 'w> {\n        DebugList {\n            fmt: self.increment_margin(),\n            wrote_field: false,\n            err: Ok(()),\n        }\n    }\n\n    /// For debug writing a set.\n    ///\n    /// # Examples\n    ///\n    /// For examples of using this method, you can look at the docs for [`DebugSet`]\n    ///\n    /// [`DebugSet`]: ./struct.DebugSet.html\n    ///\n    #[inline]\n    pub const fn debug_set(&mut self) -> DebugSet<'_, 'w> {\n        DebugSet {\n            fmt: self.increment_margin(),\n            wrote_field: false,\n            err: Ok(()),\n        }\n    }\n}\n\n////////////////////////////////////////////////////////////////////////////////\n\nmacro_rules! trys {\n    ($e:expr,$self:ident) => {\n        if let result @ Err(_) = $e {\n            $self.err = result;\n        }\n    };\n}\n\nconst COLON_SPACE_LEN: usize = \": \".len();\nconst COMMA_SPACE_LEN: usize = \", \".len();\nconst COMMA_NL_LEN: usize = \",\\n\".len();\n\nmacro_rules! field_method_impl {\n    ($\n        self: ident, $open_space:expr, $open_newline:expr;\n        len(|$fmt_len:ident| $($write_name_len:tt)*)\n        fmt(|$writer:ident| $($write_name_fmt:tt)*)\n    ) => ({\n        match &mut $self.fmt.writer {\n            WriterBackend::Length($fmt_len)=>{\n                let $fmt_len = &mut **$fmt_len;\n\n                const OPEN_SPACE: usize = $open_space.len();\n                const OPEN_NEWLINE: usize = $open_newline.len();\n\n                let is_alternate = $self.fmt.flags.is_alternate();\n                $fmt_len.add_len(match ($self.wrote_field, is_alternate) {\n                    (false, false) => OPEN_SPACE,\n                    (false, true) => OPEN_NEWLINE + $self.fmt.margin as usize,\n                    (true , false) => COMMA_SPACE_LEN,\n                    (true , true) => COMMA_NL_LEN + $self.fmt.margin as usize,\n                });\n                $($write_name_len)*\n            }\n            WriterBackend::Str($writer)=>{\n                let $writer = &mut *$writer;\n\n                let is_alternate = $self.fmt.flags.is_alternate();\n                let sep = match ($self.wrote_field, is_alternate) {\n                    (false, false)=>$open_space,\n                    (false, true)=>$open_newline,\n                    (true, false)=>\", \",\n                    (true, true)=>\",\\n\",\n                };\n                trys!($writer.write_str(sep), $self);\n                if is_alternate {\n                    trys!($writer.write_ascii_repeated(b' ', $self.fmt.margin as usize), $self);\n                }\n                $($write_name_fmt)*\n            }\n        }\n        $self.wrote_field = true;\n\n        $self.fmt\n    })\n}\n\nmacro_rules! finish_method_impl {\n    ($self: ident, $close_token:expr, $space_close:expr) => {{\n        if let result @ Err(_) = $self.err {\n            return result;\n        }\n\n        $self.fmt.decrement_margin();\n        if $self.wrote_field {\n            match &mut $self.fmt.writer {\n                WriterBackend::Length(fmt_len) => {\n                    let fmt_len = &mut **fmt_len;\n\n                    const CLOSE_TOKEN: usize = $close_token.len();\n                    const SPACE_CLOSE: usize = $space_close.len();\n\n                    if $self.fmt.flags.is_alternate() {\n                        fmt_len.add_len(COMMA_NL_LEN + $self.fmt.margin as usize + CLOSE_TOKEN);\n                    } else {\n                        fmt_len.add_len(SPACE_CLOSE);\n                    }\n                    Ok(())\n                }\n                WriterBackend::Str(writer) => {\n                    let writer = &mut *writer;\n\n                    if $self.fmt.flags.is_alternate() {\n                        try_!(writer.write_str(\",\\n\"));\n                        try_!(writer.write_ascii_repeated(b' ', $self.fmt.margin as usize));\n                        writer.write_str($close_token)\n                    } else {\n                        writer.write_str($space_close)\n                    }\n                }\n            }\n        } else {\n            Ok(())\n        }\n    }};\n}\n\n////////////////////////////////////////////////////////////////////////////////\n\n/// A helper struct for debug formatting a braced struct, or braced variant.\n///\n/// # Example\n///\n/// This example demonstrates how you can debug format a struct,\n/// and a braced variant.\n///\n/// ```rust\n///\n/// use const_format::{Error, Formatter};\n/// use const_format::{call_debug_fmt, coerce_to_fmt, formatc, impl_fmt, try_};\n///\n/// fn main() {\n///     const STRUC: &str = formatc!(\"{:?}\", Foo { a: 5, b: [8, 13, 21], c: \"34\" });\n///     const ENUM_: &str = formatc!(\"{:?}\", Bar::Baz { d: false, e: None });\n///     \n///     assert_eq!(STRUC, \"Foo { a: 5, b: [8, 13, 21], c: \\\"34\\\" }\");\n///     assert_eq!(ENUM_, \"Baz { d: false, e: None }\");\n/// }\n///\n/// struct Foo{\n///     a: u32,\n///     b: [u32; 3],\n///     c: &'static str,\n/// }\n///\n/// enum Bar {\n///     Baz{\n///         d: bool,\n///         e: Option<bool>,\n///     }\n/// }\n///\n/// impl_fmt!{\n///     impl Foo;\n///     \n///     const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {\n///         let mut f = f.debug_struct(\"Foo\");\n///         try_!(coerce_to_fmt!(&self.a).const_debug_fmt(f.field(\"a\")));\n///         try_!(coerce_to_fmt!(&self.b).const_debug_fmt(f.field(\"b\")));\n///         try_!(coerce_to_fmt!(&self.c).const_debug_fmt(f.field(\"c\")));\n///         f.finish()\n///     }\n/// }\n///\n/// impl_fmt!{\n///     impl Bar;\n///     \n///     const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {\n///         match self {\n///             Bar::Baz{d, e} => {\n///                 let mut f = f.debug_struct(\"Baz\");\n///                 \n///                 // This macro allows debug formatting some generic types that\n///                 // don't have a const_debug_fmt fn, like Options which wrap non-std types.\n///                 call_debug_fmt!(std, d, f.field(\"d\"));\n///                 call_debug_fmt!(Option, e, f.field(\"e\"));\n///                 \n///                 f.finish()\n///             }\n///         }\n///     }\n/// }\n///\n///\n///\n/// ```\npub struct DebugStruct<'f, 'w> {\n    fmt: &'f mut Formatter<'w>,\n    wrote_field: bool,\n    err: Result<(), Error>,\n}\n\nimpl<'f, 'w> DebugStruct<'f, 'w> {\n    /// Adds a field to the formatted output.\n    pub const fn field(&mut self, name: &str) -> &mut Formatter<'w> {\n        field_method_impl!(\n            self, \" { \", \" {\\n\";\n            len(|fmt_len|\n                fmt_len.add_len(name.len() + COLON_SPACE_LEN);\n            )\n            fmt(|writer|\n                trys!(writer.write_str(name), self);\n                trys!(writer.write_str(\": \"), self);\n            )\n        )\n    }\n\n    /// Finishes writing the struct/variant,\n    /// and if anything went wrong in the `field` method,returns an error.\n    pub const fn finish(self) -> Result<(), Error> {\n        finish_method_impl!(self, \"}\", \" }\")\n    }\n}\n\n////////////////////////////////////////////////////////////////////////////////\n\n/// For debug formatting a tuple struct, or tuple variant.\n///\n/// # Example\n///\n/// This example demonstrates how you can debug format a tuple struct,\n/// and an enum of tuple variants.\n///\n/// ```rust\n///\n/// use const_format::{Error, Formatter};\n/// use const_format::{call_debug_fmt, coerce_to_fmt, formatc, impl_fmt, try_};\n///\n/// fn main() {\n///     const STRUC: &str = formatc!(\"{:?}\", Foo(5, [8, 13, 21], \"34\"));\n///     const ENUM_: &str = formatc!(\"{:?}\", Bar::Baz(false, None));\n///     \n///     assert_eq!(STRUC, \"Foo(5, [8, 13, 21], \\\"34\\\")\");\n///     assert_eq!(ENUM_, \"Baz(false, None)\");\n/// }\n///\n/// struct Foo(u32, [u32; 3], &'static str);\n///\n/// enum Bar {\n///     Baz(bool, Option<bool>),\n/// }\n///\n/// impl_fmt!{\n///     impl Foo;\n///     \n///     const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {\n///         let mut f = f.debug_tuple(\"Foo\");\n///         try_!(coerce_to_fmt!(&self.0).const_debug_fmt(f.field()));\n///         try_!(coerce_to_fmt!(&self.1).const_debug_fmt(f.field()));\n///         try_!(coerce_to_fmt!(&self.2).const_debug_fmt(f.field()));\n///         f.finish()\n///     }\n/// }\n///\n/// impl_fmt!{\n///     impl Bar;\n///     \n///     const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {\n///         match self {\n///             Bar::Baz(f0, f1) => {\n///                 let mut f = f.debug_tuple(\"Baz\");\n///                 \n///                 // This macro allows debug formatting some generic types that\n///                 // don't have a const_debug_fmt fn, like Options which wrap non-std types.\n///                 call_debug_fmt!(std, f0, f.field());\n///                 call_debug_fmt!(Option, f1, f.field());\n///                 \n///                 f.finish()\n///             }\n///         }\n///     }\n/// }\n///\n///\n///\n/// ```\npub struct DebugTuple<'f, 'w> {\n    fmt: &'f mut Formatter<'w>,\n    wrote_field: bool,\n    err: Result<(), Error>,\n}\n\nimpl<'f, 'w> DebugTuple<'f, 'w> {\n    /// Adds a field to the formatted output.\n    pub const fn field(&mut self) -> &mut Formatter<'w> {\n        field_method_impl!(self, \"(\", \"(\\n\"; len(|fmt_len|) fmt(|writer|) )\n    }\n\n    /// Finishes writing the tuple struct/variant,\n    /// and if anything went wrong in the `field` method,returns an error.\n    pub const fn finish(self) -> Result<(), Error> {\n        finish_method_impl!(self, \")\", \")\")\n    }\n}\n\n////////////////////////////////////////////////////////////////////////////////\n\nmacro_rules! finish_listset_method_impl {\n    ($self: ident, $close_token:expr, $open_close:expr) => {{\n        if let result @ Err(_) = $self.err {\n            return result;\n        }\n\n        match &mut $self.fmt.writer {\n            WriterBackend::Length(fmt_len) => {\n                let fmt_len = &mut **fmt_len;\n                const CLOSE_TOKEN: usize = $close_token.len();\n                const OPEN_CLOSE: usize = $open_close.len();\n\n                $self.fmt.margin -= MARGIN_STEP;\n                if $self.wrote_field {\n                    if $self.fmt.flags.is_alternate() {\n                        fmt_len.add_len(COMMA_NL_LEN + $self.fmt.margin as usize);\n                    }\n                    fmt_len.add_len(CLOSE_TOKEN);\n                } else {\n                    fmt_len.add_len(OPEN_CLOSE);\n                }\n                Ok(())\n            }\n            WriterBackend::Str(writer) => {\n                let writer = &mut *writer;\n\n                $self.fmt.margin -= MARGIN_STEP;\n                let margin = $self.fmt.margin as usize;\n                if $self.wrote_field {\n                    if $self.fmt.flags.is_alternate() {\n                        try_!(writer.write_str(\",\\n\"));\n                        try_!(writer.write_ascii_repeated(b' ', margin));\n                    }\n                    writer.write_str($close_token)\n                } else {\n                    writer.write_str($open_close)\n                }\n            }\n        }\n    }};\n}\n\n////////////////////////////////////////////////////////////////////////////////\n\n/// For debug formatting a list/array.\n///\n/// # Example\n///\n/// This example demonstrates how you can debug format a custom type as a list.\n///\n/// ```rust\n///\n/// use const_format::{Error, Formatter};\n/// use const_format::{formatc, impl_fmt, try_};\n///\n/// use std::ops::Range;\n///\n/// fn main() {\n///     const LIST: &str = formatc!(\"{:?}\", RangeList(0..5));\n///     \n///     assert_eq!(LIST, \"[0, 1, 2, 3, 4]\");\n/// }\n///\n/// struct RangeList(Range<usize>);\n///\n/// impl_fmt!{\n///     impl RangeList;\n///     \n///     const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {\n///         let mut f = f.debug_list();\n///         let mut i = self.0.start;\n///         while i < self.0.end {\n///             try_!(f.entry().write_usize_display(i));\n///             i+=1;\n///         }\n///         f.finish()\n///     }\n/// }\n///\n/// ```\n///\npub struct DebugList<'f, 'w> {\n    fmt: &'f mut Formatter<'w>,\n    wrote_field: bool,\n    err: Result<(), Error>,\n}\n\nimpl<'f, 'w> DebugList<'f, 'w> {\n    /// Adds a list entry to the formatted output\n    pub const fn entry(&mut self) -> &mut Formatter<'w> {\n        field_method_impl!(self, \"[\", \"[\\n\"; len(|fmt_len|) fmt(|writer|) )\n    }\n\n    /// Finishes writing the list,\n    /// and if anything went wrong in the `entry` method,returns an error.\n    pub const fn finish(self) -> Result<(), Error> {\n        finish_listset_method_impl!(self, \"]\", \"[]\")\n    }\n}\n\n////////////////////////////////////////////////////////////////////////////////\n\n/// For debug formatting a set.\n///\n/// # Example\n///\n/// This example demonstrates how you can debug format a custom type as a set.\n///\n/// ```rust\n///\n/// use const_format::{Error, Formatter};\n/// use const_format::{formatc, impl_fmt, try_};\n///\n/// use std::ops::Range;\n///\n/// fn main() {\n///     const SET: &str = formatc!(\"{:?}\", StrSet(&[\"foo\", \"bar\", \"baz\"]));\n///     \n///     assert_eq!(SET, r#\"{\"foo\", \"bar\", \"baz\"}\"#);\n/// }\n///\n/// struct StrSet(&'static [&'static str]);\n///\n/// impl_fmt!{\n///     impl StrSet;\n///     \n///     const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {\n///         let mut f = f.debug_set();\n///         let mut i = 0;\n///         while i < self.0.len() {\n///             try_!(f.entry().write_str_debug(self.0[i]));\n///             i+=1;\n///         }\n///         f.finish()\n///     }\n/// }\n///\n/// ```\n///\npub struct DebugSet<'f, 'w> {\n    fmt: &'f mut Formatter<'w>,\n    wrote_field: bool,\n    err: Result<(), Error>,\n}\n\nimpl<'f, 'w> DebugSet<'f, 'w> {\n    /// Adds a set entry to the formatted output\n    pub const fn entry(&mut self) -> &mut Formatter<'w> {\n        field_method_impl!(self, \"{\", \"{\\n\"; len(|fmt_len|) fmt(|writer|) )\n    }\n\n    /// Finishes writing the set,\n    /// and if anything went wrong in the `entry` method,returns an error.\n    pub const fn finish(self) -> Result<(), Error> {\n        finish_listset_method_impl!(self, \"}\", \"{}\")\n    }\n}\n\n////////////////////////////////////////////////////////////////////////////////\n\nmacro_rules! delegate_write_methods {\n    (\n        shared_attrs $shared_attrs:tt\n        $(\n            $(#[$attrs:meta])*\n            fn $method:ident($($arg:ident: $arg_ty:ty ),* $(,)* )\n            length = $len:expr;\n        )*\n    ) => (\n        impl Formatter<'_>{\n            $(\n                delegate_write_methods!{\n                    @inner\n                    shared_attrs $shared_attrs\n                    $(#[$attrs])*\n                    fn $method($($arg: $arg_ty ),* )\n                    length = $len;\n                }\n            )*\n        }\n    );\n    (\n        @inner\n        shared_attrs (\n            $( #[$shared_attrs:meta] )*\n        )\n        $(#[$attrs:meta])*\n        fn $method:ident($($arg:ident: $arg_ty:ty ),* $(,)* )\n        length = $len:expr;\n    ) => (\n        $( #[$shared_attrs] )*\n        $(#[$attrs])*\n        pub const fn $method(&mut self, $($arg: $arg_ty ),*  ) -> Result<(), Error> {\n            match &mut self.writer {\n                WriterBackend::Length(fmt_len)=>{\n                    fmt_len.add_len($len);\n                    Ok(())\n                }\n                WriterBackend::Str(writer)=>{\n                    writer.$method($($arg,)*)\n                }\n            }\n        }\n    )\n}\n\ndelegate_write_methods! {\n    shared_attrs()\n\n    /// Writes `&string[range]` into this Formatter.\n    ///\n    /// This is a workaround for being unable to do `&foo[start..end]` at compile time.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    ///\n    /// use const_format::{Formatter, FormattingFlags, StrWriter};\n    ///\n    /// let writer: &mut StrWriter = &mut StrWriter::new([0; 16]);\n    /// let mut fmt = writer.make_formatter(FormattingFlags::NEW);\n    ///\n    /// let _ = fmt.write_str_range(\"FOO BAR BAZ\", 4..7);\n    ///\n    /// assert_eq!(writer.as_str(), \"BAR\");\n    ///\n    /// ```\n    ///\n    fn write_str_range(string: &str, range: Range<usize>)\n    length = calculate_display_len(string.as_bytes(), &range);\n\n    /// Writes `string` into this Formatter.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    ///\n    /// use const_format::{Formatter, FormattingFlags, StrWriter};\n    ///\n    /// let writer: &mut StrWriter = &mut StrWriter::new([0; 16]);\n    /// let mut fmt = writer.make_formatter(FormattingFlags::NEW);\n    ///\n    /// let _ = fmt.write_str(\"FOO BAR BAZ\");\n    ///\n    /// assert_eq!(writer.as_str(), \"FOO BAR BAZ\");\n    ///\n    /// ```\n    ///\n    fn write_str(string: &str)\n    length = string.len();\n\n    /// Writes `character` into this Formatter.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    ///\n    /// use const_format::{Formatter, FormattingFlags, StrWriter};\n    ///\n    /// let writer: &mut StrWriter = &mut StrWriter::new([0; 4]);\n    /// let mut fmt = writer.make_formatter(FormattingFlags::NEW);\n    ///\n    /// let _ = fmt.write_char('a');\n    /// let _ = fmt.write_char('b');\n    /// let _ = fmt.write_char('c');\n    ///\n    /// assert_eq!(writer.as_str(), \"abc\");\n    ///\n    /// ```\n    ///\n    fn write_char(character: char)\n    length = crate::char_encoding::char_display_len(character);\n\n    /// Writes `&ascii[range]` into this formatter.\n    ///\n    /// This is a workaround for being unable to do `&foo[start..end]` at compile time.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    ///\n    /// use const_format::{Formatter, FormattingFlags, StrWriter, ascii_str};\n    ///\n    /// let writer: &mut StrWriter = &mut StrWriter::new([0; 16]);\n    /// let mut fmt = writer.make_formatter(FormattingFlags::NEW);\n    ///\n    /// let _ = fmt.write_ascii_range(ascii_str!(\"FOO BAR BAZ\"), 4..7);\n    ///\n    /// assert_eq!(writer.as_str(), \"BAR\");\n    ///\n    /// ```\n    ///\n    fn write_ascii_range(ascii: AsciiStr<'_>, range: Range<usize>)\n    length = calculate_display_len(ascii.as_bytes(), &range);\n\n    /// Writes `ascii` into this formatter.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    ///\n    /// use const_format::{Formatter, FormattingFlags, StrWriter, ascii_str};\n    ///\n    /// let writer: &mut StrWriter = &mut StrWriter::new([0; 16]);\n    /// let mut fmt = writer.make_formatter(FormattingFlags::NEW);\n    ///\n    /// let _ = fmt.write_ascii(ascii_str!(\"FOO BAR BAZ\"));\n    ///\n    /// assert_eq!(writer.as_str(), \"FOO BAR BAZ\");\n    ///\n    /// ```\n    ///\n    fn write_ascii(ascii: AsciiStr<'_>)\n    length = ascii.len();\n\n    /// Writes the ascii `character` into this formatter `repeated` times.\n    ///\n    /// If `character` is greater than 127,\n    /// this writes `character - 128` as an ascii character.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    ///\n    /// use const_format::{Formatter, FormattingFlags, StrWriter};\n    ///\n    /// let writer: &mut StrWriter = &mut StrWriter::new([0; 16]);\n    /// let mut fmt = writer.make_formatter(FormattingFlags::NEW);\n    ///\n    /// let _ = fmt.write_ascii_repeated(b'A', 10);\n    ///\n    /// assert_eq!(writer.as_str(), \"AAAAAAAAAA\");\n    ///\n    /// ```\n    ///\n    fn write_ascii_repeated(character: u8,repeated: usize)\n    length = repeated;\n\n    /// Writes `string` into this formatter, with debug formatting.\n    ///\n    /// This is a workaround for being unable to do `&foo[start..end]` at compile time.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    ///\n    /// use const_format::{Formatter, FormattingFlags, StrWriter};\n    ///\n    /// let writer: &mut StrWriter = &mut StrWriter::new([0; 16]);\n    /// let mut fmt = writer.make_formatter(FormattingFlags::NEW);\n    ///\n    /// let _ = fmt.write_str_range_debug(\"FOO\\nBAR\\tBAZ\", 3..8);\n    ///\n    /// assert_eq!(writer.as_str(), r#\"\"\\nBAR\\t\"\"#);\n    ///\n    /// ```\n    ///\n    fn write_str_range_debug(string: &str, range: Range<usize>)\n    length = calculate_display_len_debug_range(string.as_bytes(), &range);\n\n    /// Writes `string` into this formatter, with debug formatting.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    ///\n    /// use const_format::{Formatter, FormattingFlags, StrWriter};\n    ///\n    /// let writer: &mut StrWriter = &mut StrWriter::new([0; 16]);\n    /// let mut fmt = writer.make_formatter(FormattingFlags::NEW);\n    ///\n    /// let _ = fmt.write_str_debug(\"FOO\\nBAR\\tBAZ\");\n    ///\n    /// assert_eq!(writer.as_str(), r#\"\"FOO\\nBAR\\tBAZ\"\"#);\n    ///\n    /// ```\n    ///\n    fn write_str_debug(string: &str)\n    length = PWrapper(string.as_bytes()).compute_utf8_debug_len();\n\n    /// Writes `character` into this Formatter, with debug formatting.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    ///\n    /// use const_format::{Formatter, FormattingFlags, StrWriter};\n    ///\n    /// let writer: &mut StrWriter = &mut StrWriter::new([0; 64]);\n    /// let mut fmt = writer.make_formatter(FormattingFlags::NEW);\n    ///\n    /// let _ = fmt.write_str(\" \");\n    /// let _ = fmt.write_char_debug('\\\\');\n    /// let _ = fmt.write_str(\" \");\n    /// let _ = fmt.write_char_debug('A');\n    /// let _ = fmt.write_str(\" \");\n    /// let _ = fmt.write_char_debug('0');\n    /// let _ = fmt.write_str(\" \");\n    /// let _ = fmt.write_char_debug('\\'');\n    /// let _ = fmt.write_str(\" \");\n    ///\n    /// assert_eq!(writer.as_str(), r#\" '\\\\' 'A' '0' '\\'' \"#);\n    ///\n    /// ```\n    ///\n    fn write_char_debug(character: char)\n    length = crate::char_encoding::char_debug_len(character);\n\n    /// Writes `&ascii[range]` into this formatter, with debug formatting.\n    ///\n    /// This is a workaround for being unable to do `&foo[start..end]` at compile time.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    ///\n    /// use const_format::{Formatter, FormattingFlags, StrWriter, ascii_str};\n    ///\n    /// let writer: &mut StrWriter = &mut StrWriter::new([0; 16]);\n    /// let mut fmt = writer.make_formatter(FormattingFlags::NEW);\n    ///\n    /// let _ = fmt.write_ascii_range_debug(ascii_str!(\"FOO\\nBAR\\tBAZ\"), 3..8);\n    ///\n    /// assert_eq!(writer.as_str(), r#\"\"\\nBAR\\t\"\"#);\n    ///\n    /// ```\n    ///\n    fn write_ascii_range_debug(ascii: AsciiStr<'_>,range: Range<usize>)\n    length = calculate_display_len_debug_range(ascii.as_bytes(), &range);\n\n    /// Writes `ascii` into this formatter, with debug formatting.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    ///\n    /// use const_format::{Formatter, FormattingFlags, StrWriter, ascii_str};\n    ///\n    /// let writer: &mut StrWriter = &mut StrWriter::new([0; 16]);\n    /// let mut fmt = writer.make_formatter(FormattingFlags::NEW);\n    ///\n    /// let _ = fmt.write_ascii_debug(ascii_str!(\"FOO\\nBAR\\tBAZ\"));\n    ///\n    /// assert_eq!(writer.as_str(), r#\"\"FOO\\nBAR\\tBAZ\"\"#);\n    ///\n    /// ```\n    ///\n    fn write_ascii_debug(ascii: AsciiStr<'_>)\n    length = PWrapper(ascii.as_bytes()).compute_utf8_debug_len();\n\n\n    /// Write `n` with display formatting.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    ///\n    /// use const_format::{Formatter, FormattingFlags, StrWriter, ascii_str};\n    ///\n    /// let writer: &mut StrWriter = &mut StrWriter::new([0; 16]);\n    /// let mut fmt = writer.make_formatter(FormattingFlags::NEW);\n    ///\n    /// let _ = fmt.write_u8_display(13);\n    /// let _ = fmt.write_u8_display(21);\n    /// let _ = fmt.write_u8_display(34);\n    ///\n    /// assert_eq!(writer.as_str(), \"132134\");\n    ///\n    /// ```\n    ///\n    fn write_u8_display(n: u8)\n    length = PWrapper(n).compute_display_len(FormattingFlags::NEW);\n}\n\ndelegate_write_methods! {\n    shared_attrs(\n        /// Writes `n` with display formatting\n        ///\n        /// For an example,\n        /// you can look at the one for the [`write_u8_display`] method.\n        ///\n        /// [`write_u8_display`]: #method.write_u8_display\n    )\n\n    fn write_u16_display(n: u16)\n    length = PWrapper(n).compute_display_len(FormattingFlags::NEW);\n\n    fn write_u32_display(n: u32)\n    length = PWrapper(n).compute_display_len(FormattingFlags::NEW);\n\n    fn write_u64_display(n: u64)\n    length = PWrapper(n).compute_display_len(FormattingFlags::NEW);\n\n    fn write_u128_display(n: u128)\n    length = PWrapper(n).compute_display_len(FormattingFlags::NEW);\n\n    fn write_usize_display(n: usize)\n    length = PWrapper(n).compute_display_len(FormattingFlags::NEW);\n\n    fn write_i8_display(n: i8)\n    length = PWrapper(n).compute_display_len(FormattingFlags::NEW);\n\n    fn write_i16_display(n: i16)\n    length = PWrapper(n).compute_display_len(FormattingFlags::NEW);\n\n    fn write_i32_display(n: i32)\n    length = PWrapper(n).compute_display_len(FormattingFlags::NEW);\n\n    fn write_i64_display(n: i64)\n    length = PWrapper(n).compute_display_len(FormattingFlags::NEW);\n\n    fn write_i128_display(n: i128)\n    length = PWrapper(n).compute_display_len(FormattingFlags::NEW);\n\n    fn write_isize_display(n: isize)\n    length = PWrapper(n).compute_display_len(FormattingFlags::NEW);\n}\n\nmacro_rules! delegate_integer_debug_methods {\n    (\n        shared_attrs $shared_attrs:tt\n        $(\n            $(#[$attrs:meta])*\n            fn $method:ident($($arg:ident: $arg_ty:ty ),* $(,)* )\n            length = |$flags:ident| $len:expr;\n        )*\n    ) => (\n        impl Formatter<'_>{\n            $(\n                delegate_integer_debug_methods!{\n                    @inner\n                    shared_attrs $shared_attrs\n                    $(#[$attrs])*\n                    fn $method($($arg: $arg_ty ),*)\n                    length = |$flags| $len;\n                }\n            )*\n        }\n    );\n    (\n        @inner\n        shared_attrs (\n            $( #[$shared_attrs:meta] )*\n        )\n        $(#[$attrs:meta])*\n        fn $method:ident($($arg:ident: $arg_ty:ty ),* $(,)* )\n        length = |$flags:ident| $len:expr;\n    ) => (\n        $( #[$shared_attrs] )*\n        $(#[$attrs])*\n        pub const fn $method(&mut self, $($arg: $arg_ty ),*  ) -> Result<(), Error> {\n            let $flags = self.flags;\n\n            match &mut self.writer {\n                WriterBackend::Length(fmt_len)=>{\n                    fmt_len.add_len($len);\n                    Ok(())\n                }\n                WriterBackend::Str(writer)=>{\n                    writer.$method($($arg,)* $flags)\n                }\n            }\n        }\n    )\n}\n\ndelegate_integer_debug_methods! {\n    shared_attrs()\n\n    /// Writes `n` with debug formatting.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    ///\n    /// use const_format::{Formatter, FormattingFlags, StrWriter};\n    ///\n    /// fn debug_fmt(writer: &mut StrWriter, flag: FormattingFlags) -> &str {\n    ///     writer.clear();\n    ///     let mut fmt = Formatter::from_sw(writer, flag);\n    ///     let _ = fmt.write_u8_debug(63);\n    ///     writer.as_str()\n    /// }\n    ///\n    /// let reg_flag = FormattingFlags::NEW.set_alternate(false);\n    /// let alt_flag = FormattingFlags::NEW.set_alternate(true);\n    ///\n    /// let writer: &mut StrWriter = &mut StrWriter::new([0; 64]);\n    ///\n    /// assert_eq!(debug_fmt(writer, reg_flag),                   \"63\"     );\n    /// assert_eq!(debug_fmt(writer, reg_flag.set_hexadecimal()), \"3F\"     );\n    /// assert_eq!(debug_fmt(writer, reg_flag.set_lower_hexadecimal()), \"3f\"     );\n    /// assert_eq!(debug_fmt(writer, reg_flag.set_binary()),      \"111111\" );\n    /// assert_eq!(debug_fmt(writer, alt_flag),                   \"63\"     );\n    /// assert_eq!(debug_fmt(writer, alt_flag.set_hexadecimal()), \"0x3F\"   );\n    /// assert_eq!(debug_fmt(writer, alt_flag.set_lower_hexadecimal()), \"0x3f\"   );\n    /// assert_eq!(debug_fmt(writer, alt_flag.set_binary()),      \"0b111111\");\n    ///\n    /// ```\n    ///\n    fn write_u8_debug(n: u8)\n    length = |flags| PWrapper(n).compute_debug_len(flags);\n}\n\ndelegate_integer_debug_methods! {\n    shared_attrs(\n        /// Writes `n` with debug formatting.\n        ///\n        /// For an example,\n        /// you can look at the one for the [`write_u8_debug`] method.\n        ///\n        /// [`write_u8_debug`]: #method.write_u8_debug\n    )\n\n    fn write_u16_debug(n: u16)\n    length = |flags| PWrapper(n).compute_debug_len(flags);\n\n    fn write_u32_debug(n: u32)\n    length = |flags| PWrapper(n).compute_debug_len(flags);\n\n    fn write_u64_debug(n: u64)\n    length = |flags| PWrapper(n).compute_debug_len(flags);\n\n    fn write_u128_debug(n: u128)\n    length = |flags| PWrapper(n).compute_debug_len(flags);\n\n    fn write_usize_debug(n: usize)\n    length = |flags| PWrapper(n).compute_debug_len(flags);\n\n    fn write_i8_debug(n: i8)\n    length = |flags| PWrapper(n).compute_debug_len(flags);\n\n    fn write_i16_debug(n: i16)\n    length = |flags| PWrapper(n).compute_debug_len(flags);\n\n    fn write_i32_debug(n: i32)\n    length = |flags| PWrapper(n).compute_debug_len(flags);\n\n    fn write_i64_debug(n: i64)\n    length = |flags| PWrapper(n).compute_debug_len(flags);\n\n    fn write_i128_debug(n: i128)\n    length = |flags| PWrapper(n).compute_debug_len(flags);\n\n    fn write_isize_debug(n: isize)\n    length = |flags| PWrapper(n).compute_debug_len(flags);\n}\n\n#[inline(always)]\nconst fn calculate_display_len(b: &[u8], range: &Range<usize>) -> usize {\n    let Range { start, end } = saturate_range(b, range);\n    end - start\n}\n\n#[inline(always)]\nconst fn calculate_display_len_debug_range(b: &[u8], range: &Range<usize>) -> usize {\n    let Range { start, end } = saturate_range(b, range);\n    PWrapper(b).compute_utf8_debug_len_in_range(start..end)\n}\n"
  },
  {
    "path": "const_format/src/fmt/std_type_impls/ranges.rs",
    "content": "use crate::{\n    fmt::{Error, Formatter},\n    marker_traits::{FormatMarker, IsAFormatMarker, IsStdKind},\n    wrapper_types::PWrapper,\n};\n\nuse core::ops::{Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive};\n\n////////////////////////////////////////////////////////////////////////////////\n\nimpl FormatMarker for Range<usize> {\n    type Kind = IsStdKind;\n    type This = Self;\n}\n\nimpl<T> IsAFormatMarker<IsStdKind, Range<usize>, T> {\n    #[inline(always)]\n    pub const fn coerce(self, range: &Range<usize>) -> PWrapper<Range<usize>> {\n        PWrapper(Range {\n            start: range.start,\n            end: range.end,\n        })\n    }\n}\n\nimpl PWrapper<Range<usize>> {\n    const RANGE: &'static str = \"..\";\n\n    #[inline(always)]\n    pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {\n        try_!(PWrapper(self.0.start).const_debug_fmt(f));\n        try_!(PWrapper(Self::RANGE).const_display_fmt(f));\n        try_!(PWrapper(self.0.end).const_debug_fmt(f));\n        Ok(())\n    }\n}\n\n///////////////////////////////////////////////////////////////////////////////\n\nimpl FormatMarker for RangeFrom<usize> {\n    type Kind = IsStdKind;\n    type This = Self;\n}\n\nimpl<T> IsAFormatMarker<IsStdKind, RangeFrom<usize>, T> {\n    #[inline(always)]\n    pub const fn coerce(self, range: &RangeFrom<usize>) -> PWrapper<RangeFrom<usize>> {\n        PWrapper(RangeFrom { start: range.start })\n    }\n}\n\nimpl PWrapper<RangeFrom<usize>> {\n    const RANGE: &'static str = \"..\";\n\n    #[inline(always)]\n    pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {\n        try_!(PWrapper(self.0.start).const_debug_fmt(f));\n        try_!(PWrapper(Self::RANGE).const_display_fmt(f));\n        Ok(())\n    }\n}\n\n///////////////////////////////////////////////////////////////////////////////\n\nimpl FormatMarker for RangeTo<usize> {\n    type Kind = IsStdKind;\n    type This = Self;\n}\n\nimpl<T> IsAFormatMarker<IsStdKind, RangeTo<usize>, T> {\n    #[inline(always)]\n    pub const fn coerce(self, range: &RangeTo<usize>) -> PWrapper<RangeTo<usize>> {\n        PWrapper(RangeTo { end: range.end })\n    }\n}\n\nimpl PWrapper<RangeTo<usize>> {\n    const RANGE: &'static str = \"..\";\n\n    #[inline(always)]\n    pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {\n        try_!(PWrapper(Self::RANGE).const_display_fmt(f));\n        try_!(PWrapper(self.0.end).const_debug_fmt(f));\n        Ok(())\n    }\n}\n\n///////////////////////////////////////////////////////////////////////////////\n\nimpl FormatMarker for RangeToInclusive<usize> {\n    type Kind = IsStdKind;\n    type This = Self;\n}\n\nimpl<T> IsAFormatMarker<IsStdKind, RangeToInclusive<usize>, T> {\n    #[inline(always)]\n    pub const fn coerce(\n        self,\n        range: &RangeToInclusive<usize>,\n    ) -> PWrapper<RangeToInclusive<usize>> {\n        PWrapper(RangeToInclusive { end: range.end })\n    }\n}\n\nimpl PWrapper<RangeToInclusive<usize>> {\n    const RANGE: &'static str = \"..=\";\n\n    #[inline(always)]\n    pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {\n        try_!(PWrapper(Self::RANGE).const_display_fmt(f));\n        try_!(PWrapper(self.0.end).const_debug_fmt(f));\n        Ok(())\n    }\n}\n\n///////////////////////////////////////////////////////////////////////////////\n\nimpl FormatMarker for RangeInclusive<usize> {\n    type Kind = IsStdKind;\n    type This = Self;\n}\n\nimpl<T> IsAFormatMarker<IsStdKind, RangeInclusive<usize>, T> {\n    #[inline(always)]\n    pub const fn coerce(self, range: &RangeInclusive<usize>) -> PWrapper<RangeInclusive<usize>> {\n        PWrapper(RangeInclusive::new(*range.start(), *range.end()))\n    }\n}\n\nimpl PWrapper<RangeInclusive<usize>> {\n    const RANGE: &'static str = \"..=\";\n\n    #[inline(always)]\n    pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {\n        try_!(PWrapper(*self.0.start()).const_debug_fmt(f));\n        try_!(PWrapper(Self::RANGE).const_display_fmt(f));\n        try_!(PWrapper(*self.0.end()).const_debug_fmt(f));\n        Ok(())\n    }\n}\n\n///////////////////////////////////////////////////////////////////////////////\n\nimpl FormatMarker for RangeFull {\n    type Kind = IsStdKind;\n    type This = Self;\n}\n\nimpl<T> IsAFormatMarker<IsStdKind, RangeFull, T> {\n    #[inline(always)]\n    pub const fn coerce(self, _: &RangeFull) -> PWrapper<RangeFull> {\n        PWrapper(..)\n    }\n}\n\nimpl PWrapper<RangeFull> {\n    const RANGE: &'static str = \"..\";\n\n    #[inline(always)]\n    pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {\n        PWrapper(Self::RANGE).const_display_fmt(f)\n    }\n}\n"
  },
  {
    "path": "const_format/src/fmt/std_type_impls.rs",
    "content": "#![allow(missing_docs)]\n\nuse crate::{\n    fmt::{Error, Formatter},\n    marker_traits::IsStdKind,\n    wrapper_types::PWrapper,\n};\n\nmod ranges;\n\n////////////////////////////////////////////////////////////////////////////////\n\nimpl PWrapper<&str> {\n    pub const fn const_display_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {\n        f.write_str(self.0)\n    }\n\n    pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {\n        f.write_str_debug(self.0)\n    }\n}\n\nimpl PWrapper<bool> {\n    pub const fn const_display_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {\n        f.write_str(if self.0 { \"true\" } else { \"false\" })\n    }\n\n    #[inline(always)]\n    pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {\n        self.const_display_fmt(f)\n    }\n}\n\nimpl PWrapper<char> {\n    pub const fn const_display_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {\n        f.write_char(self.0)\n    }\n\n    #[inline(always)]\n    pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {\n        f.write_char_debug(self.0)\n    }\n}\n\nmacro_rules! slice_of_std_impl {($($elem:ty),* $(,)?) => (\n    $(\n\n        impl PWrapper<&[$elem]> {\n            pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {\n                let mut f = f.debug_list();\n                __for_range!{i in 0..self.0.len() =>\n                    try_!(PWrapper(self.0[i]).const_debug_fmt(f.entry()));\n                }\n                f.finish()\n            }\n        }\n    )*\n)}\n\nslice_of_std_impl! {\n    &str,\n    bool,\n    char,\n    u8, i8,\n    u16, i16,\n    u32, i32,\n    u64, i64,\n    u128, i128,\n    usize, isize,\n}\n\n////////////////////////////////////////////////////////////////////////////////\n\nuse core::{\n    marker::{PhantomData, PhantomPinned},\n    num::{\n        NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize, NonZeroU128,\n        NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize,\n    },\n    ptr::NonNull,\n};\n\nimpl_fmt! {\n    is_std_type;\n\n    impl[T,] Option<NonNull<T>>;\n    impl[] Option<NonZeroU8>;\n    impl[] Option<NonZeroI8>;\n    impl[] Option<NonZeroU16>;\n    impl[] Option<NonZeroI16>;\n    impl[] Option<NonZeroU32>;\n    impl[] Option<NonZeroI32>;\n    impl[] Option<NonZeroU64>;\n    impl[] Option<NonZeroI64>;\n    impl[] Option<NonZeroU128>;\n    impl[] Option<NonZeroI128>;\n    impl[] Option<NonZeroUsize>;\n    impl[] Option<NonZeroIsize>;\n    impl[] Option<u8>;\n    impl[] Option<i8>;\n    impl[] Option<u16>;\n    impl[] Option<i16>;\n    impl[] Option<u32>;\n    impl[] Option<i32>;\n    impl[] Option<u64>;\n    impl[] Option<i64>;\n    impl[] Option<u128>;\n    impl[] Option<i128>;\n    impl[] Option<usize>;\n    impl[] Option<isize>;\n    impl[] Option<bool>;\n    impl[] Option<char>;\n    impl['a,] Option<&'a str>;\n\n    pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {\n        match self.0 {\n            Some(x) => {\n                let mut f = f.debug_tuple(\"Some\");\n                try_!(PWrapper(x).const_debug_fmt(f.field()));\n                f.finish()\n            },\n            None => f.write_str(\"None\"),\n        }\n    }\n}\n\nmacro_rules! non_zero_impls {\n    ($($ty:ident,)*) => (\n        $(\n            std_kind_impl!{ impl[] $ty }\n\n            impl PWrapper<$ty> {\n                #[inline(always)]\n                pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {\n                    PWrapper(self.0.get()).const_debug_fmt(f)\n                }\n\n                #[inline(always)]\n                pub const fn const_display_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {\n                    PWrapper(self.0.get()).const_display_fmt(f)\n                }\n            }\n        )*\n    )\n}\n\nnon_zero_impls! {\n    NonZeroU8, NonZeroI8, NonZeroU16, NonZeroI16,\n    NonZeroU32, NonZeroI32, NonZeroU64, NonZeroI64,\n    NonZeroU128, NonZeroI128, NonZeroUsize, NonZeroIsize,\n}\n\nstd_kind_impl! { impl[T,] *mut T }\n// Unfortunately, can't print pointer addresses at compile-time.\nimpl<T> PWrapper<*mut T> {\n    const PTR: &'static str = \"<pointer>\";\n\n    #[inline(always)]\n    pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {\n        f.write_str(Self::PTR)\n    }\n}\n\nstd_kind_impl! { impl[T,] *const T }\nimpl<T> PWrapper<*const T> {\n    #[inline(always)]\n    pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {\n        PWrapper(self.0 as *mut T).const_debug_fmt(f)\n    }\n}\n\nstd_kind_impl! { impl[T,] NonNull<T> }\nimpl<T> PWrapper<NonNull<T>> {\n    #[inline(always)]\n    pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {\n        PWrapper(self.0.as_ptr()).const_debug_fmt(f)\n    }\n}\n\nmacro_rules! impl_std_marker_type {\n    (\n        $( impl[$($impl_:tt)*] $type:ty = $tyname:expr ;)*\n    ) => (\n        $(\n            std_kind_impl!{ impl[$($impl_)*] $type }\n\n            impl<$($impl_)*> PWrapper<$type> {\n                const NAME: &'static str = $tyname;\n\n                #[inline(always)]\n                pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {\n                    PWrapper(Self::NAME).const_display_fmt(f)\n                }\n            }\n        )*\n    )\n}\n\nimpl_std_marker_type! {\n    impl[T: ?Sized,] PhantomData<T> = \"PhantomData\";\n    impl[] PhantomPinned = \"PhantomPinned\";\n    impl[] () = \"()\";\n}\n\n////////////////////////////////////////////////////////////////////////////////\n\nuse core::{cmp::Ordering, sync::atomic::Ordering as AtomicOrdering};\n\nimpl_fmt! {\n    is_std_type;\n\n    impl AtomicOrdering;\n\n    pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {\n        match self.0 {\n            AtomicOrdering::Relaxed => f.write_str(\"Relaxed\"),\n            AtomicOrdering::Release => f.write_str(\"Release\"),\n            AtomicOrdering::Acquire => f.write_str(\"Acquire\"),\n            AtomicOrdering::AcqRel => f.write_str(\"AcqRel\"),\n            AtomicOrdering::SeqCst => f.write_str(\"SeqCst\"),\n            _ => f.write_str(\"<core::atomic::Ordering>\"),\n        }\n    }\n}\n\nimpl_fmt! {\n    is_std_type;\n\n    impl Ordering;\n\n    pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {\n        match self.0 {\n            Ordering::Less => f.write_str(\"Less\"),\n            Ordering::Equal => f.write_str(\"Equal\"),\n            Ordering::Greater => f.write_str(\"Greater\"),\n        }\n    }\n}\n"
  },
  {
    "path": "const_format/src/fmt/str_writer.rs",
    "content": "use super::{Error, Formatter, FormattingFlags, StrWriterMut, Utf8Encoding};\n\nuse core::marker::PhantomData;\n\n////////////////////////////////////////////////////////////////////////////////\n\n/// A wrapper over an array usable to build up a `&str` at compile-time.\n///\n/// # Calling methods\n///\n/// [Certain `StrWriter` methods](#certain-methods) require\n/// a `StrWriter<[u8]>` to be called,\n/// and since constructing `StrWriter` from an array produces a `StrWriter<[u8; N]>`,\n/// it must be cast to call them.\n///\n/// `StrWriter`'s type parameter defaults to `[u8]`,\n/// so every instance of a `StrWriter` as a *type* is a `StrWriter<[u8]>`.\n///\n/// Example of casting it:\n///\n/// ```rust\n/// # use const_format::StrWriter;\n/// let writer: &mut StrWriter<[u8; 8]> = &mut StrWriter::new([0; 8]);\n///\n/// // Casts `&StrWriter<[u8; 8]>` to `&StrWriter`\n/// writer.unsize();\n///\n/// // Casts `&StrWriter<[u8; 8]>` to `&StrWriter`\n/// writer.r();\n///\n/// // Coerces the `&mut StrWriter<[u8; 8]>` to `&mut StrWriter`\n/// let _writer: &mut StrWriter = writer;\n///\n/// // Casts `&mut StrWriter<[u8; 8]>` to `StrWriterMut<'_>`,\n/// // which defines methods for mutating `StrWriter`\n/// let _writer = writer.as_mut();\n///\n/// # drop(writer);\n/// ```\n///\n/// # StrWriterMut\n///\n/// `StrWriter` can be borrowed into a [`StrWriterMut`],\n/// which provides methods for writing a formatted string.\n///\n/// Example:\n///\n/// ```rust\n/// use const_format::StrWriter;\n///\n/// let mut buffer: &mut StrWriter = &mut StrWriter::new([0; 100]);\n///\n/// let mut writer = buffer.as_mut();\n/// writer.write_str(\"Your password is: \");\n/// writer.write_str_debug(\"PASSWORD\");\n///\n/// assert_eq!(writer.as_str(), r#\"Your password is: \"PASSWORD\"\"#);\n///\n/// ```\n///\n/// # Examples\n///\n/// ### Formatting into associated constant\n///\n/// This example shows how you can construct a formatted `&'static str` from associated constants.\n///\n/// ```rust\n///\n/// use const_format::{StrWriter, writec, unwrap};\n///\n/// trait Num {\n///     const V: u32;\n/// }\n///\n/// struct Two;\n///\n/// impl Num for Two {\n///     const V: u32 = 2;\n/// }\n///\n/// struct Three;\n///\n/// impl Num for Three {\n///     const V: u32 = 3;\n/// }\n///\n/// struct Mul<L, R>(L, R);\n///\n/// const fn compute_str(l: u32, r: u32) -> StrWriter<[u8; 128]> {\n///     let mut writer = StrWriter::new([0; 128]);\n///     unwrap!(writec!(writer, \"{} * {} == {}\", l, r, l * r ));\n///     writer\n/// }\n///\n/// impl<L: Num, R: Num> Mul<L, R> {\n///     const __STR: &'static StrWriter<[u8]> = &compute_str(L::V, R::V);\n///     const STR: &'static str = Self::__STR.as_str();\n/// }\n///\n/// assert_eq!(Mul::<Two,Three>::STR, \"2 * 3 == 6\");\n/// assert_eq!(Mul::<Three,Three>::STR, \"3 * 3 == 9\");\n///\n/// ```\n///\n/// [`StrWriterMut`]: ./struct.StrWriterMut.html\n///\n#[derive(Debug, Copy, Clone)]\npub struct StrWriter<A: ?Sized = [u8]> {\n    pub(super) len: usize,\n    pub(super) buffer: A,\n}\n\nimpl<A> StrWriter<A> {\n    /// Constructs a `StrWriter` from a `u8` array\n    pub const fn new(array: A) -> Self {\n        Self {\n            len: 0,\n            buffer: array,\n        }\n    }\n}\n\nimpl<A: ?Sized> StrWriter<A> {\n    /// Accesses the underlying buffer immutably.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    /// use const_format::StrWriter;\n    ///\n    /// let buffer: &mut StrWriter = &mut StrWriter::new([0; 7]);\n    /// assert_eq!(buffer.buffer(), &[0; 7]);\n    ///\n    /// buffer.as_mut().write_str(\"foo\")?;\n    /// assert_eq!(buffer.buffer(), b\"foo\\0\\0\\0\\0\");\n    ///\n    /// buffer.as_mut().write_str(\"bar\")?;\n    /// assert_eq!(buffer.buffer(), b\"foobar\\0\");\n    ///\n    /// # Ok::<(), const_format::Error>(())\n    /// ```\n    #[inline(always)]\n    pub const fn buffer(&self) -> &A {\n        &self.buffer\n    }\n\n    /// How long the string this wrote is.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    /// use const_format::StrWriter;\n    ///\n    /// let buffer: &mut StrWriter = &mut StrWriter::new([0; 64]);\n    /// assert_eq!(buffer.len(), 0);\n    ///\n    /// buffer.as_mut().write_str(\"foo\")?;\n    /// assert_eq!(buffer.len(), 3);\n    ///\n    /// buffer.as_mut().write_str(\"bar\")?;\n    /// assert_eq!(buffer.len(), 6);\n    ///\n    /// # Ok::<(), const_format::Error>(())\n    /// ```\n    #[inline(always)]\n    pub const fn len(&self) -> usize {\n        self.len\n    }\n\n    /// Checks whether the string this wrote is empty.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    /// use const_format::StrWriter;\n    ///\n    /// let buffer: &mut StrWriter = &mut StrWriter::new([0; 64]);\n    /// assert!( buffer.is_empty() );\n    ///\n    /// buffer.as_mut().write_str(\"foo\")?;\n    /// assert!( !buffer.is_empty() );\n    ///\n    /// # Ok::<(), const_format::Error>(())\n    /// ```\n    #[inline]\n    pub const fn is_empty(&self) -> bool {\n        self.len == 0\n    }\n}\n\n/// <span id=\"certain-methods\"></span>\nimpl StrWriter {\n    /// Gets the maximum length for a string written into this.\n    ///\n    /// Trying to write more that the capacity causes an error,\n    /// returning back an `Err(Error::NotEnoughSpace)`\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    /// use const_format::{Error, StrWriter};\n    ///\n    /// let buffer: &mut StrWriter = &mut StrWriter::new([0; 64]);\n    /// assert_eq!(buffer.capacity(), 64);\n    ///\n    /// buffer.as_mut().write_ascii_repeated(b'A', 64)?;\n    /// assert_eq!(buffer.capacity(), 64);\n    ///\n    /// assert_eq!(buffer.as_mut().write_str(\"-\").unwrap_err(), Error::NotEnoughSpace);\n    /// assert_eq!(buffer.capacity(), 64);\n    ///\n    /// # Ok::<(), const_format::Error>(())\n    /// ```\n    #[inline(always)]\n    pub const fn capacity(&self) -> usize {\n        self.buffer.len()\n    }\n\n    /// Checks how many more bytes can be written.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    /// use const_format::{Error, StrWriter};\n    ///\n    /// let buffer: &mut StrWriter = &mut StrWriter::new([0; 64]);\n    /// assert_eq!(buffer.remaining_capacity(), 64);\n    ///\n    /// buffer.as_mut().write_str(\"foo\")?;\n    /// assert_eq!(buffer.remaining_capacity(), 61);\n    ///\n    /// buffer.as_mut().write_ascii_repeated(b'a', 61)?;\n    /// assert_eq!(buffer.remaining_capacity(), 0);\n    ///\n    /// assert_eq!(buffer.as_mut().write_str(\" \").unwrap_err(), Error::NotEnoughSpace);\n    ///\n    /// # Ok::<(), const_format::Error>(())\n    /// ```\n    #[inline]\n    pub const fn remaining_capacity(&self) -> usize {\n        self.buffer.len() - self.len\n    }\n\n    /// Truncates this `StrWriter` to `length`.\n    ///\n    /// If `length` is greater than the current length, this does nothing.\n    ///\n    /// # Errors\n    ///\n    /// Returns an `Error::NotOnCharBoundary` if `length` is not on a char boundary.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    /// use const_format::{Error, StrWriter};\n    ///\n    /// let buffer: &mut StrWriter = &mut StrWriter::new([0; 64]);\n    ///\n    /// buffer.as_mut().write_str(\"foo bâr baz\");\n    /// assert_eq!(buffer.as_str(), \"foo bâr baz\");\n    ///\n    /// assert_eq!(buffer.truncate(6).unwrap_err(), Error::NotOnCharBoundary);\n    ///\n    /// buffer.truncate(3)?;\n    /// assert_eq!(buffer.as_str(), \"foo\");\n    ///\n    /// buffer.as_mut().write_str(\"ooooooo\");\n    /// assert_eq!(buffer.as_str(), \"fooooooooo\");\n    ///\n    /// # Ok::<(), const_format::Error>(())\n    /// ```\n    #[inline]\n    pub const fn truncate(&mut self, length: usize) -> Result<(), Error> {\n        self.as_mut().truncate(length)\n    }\n\n    /// Truncates this `StrWriter` to length 0.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    /// use const_format::{Error, StrWriter};\n    ///\n    /// let buffer: &mut StrWriter = &mut StrWriter::new([0; 64]);\n    ///\n    /// buffer.as_mut().write_str(\"foo\")?;\n    /// assert_eq!(buffer.as_str(), \"foo\");\n    ///\n    /// buffer.clear();\n    /// assert_eq!(buffer.as_str(), \"\");\n    /// assert!(buffer.is_empty());\n    ///\n    /// buffer.as_mut().write_str(\"bar\");\n    /// assert_eq!(buffer.as_str(), \"bar\");\n    ///\n    /// # Ok::<(), const_format::Error>(())\n    /// ```\n    #[inline]\n    pub const fn clear(&mut self) {\n        self.len = 0;\n    }\n\n    /// This is the same as `as_bytes`\n    ///\n    /// (this method only exists for backwards compatibility)\n    #[inline(always)]\n    #[deprecated(since = \"0.2.36\", note = \"redundant, same as `as_bytes`\")]\n    pub const fn as_bytes_alt(&self) -> &[u8] {\n        crate::utils::slice_up_to_len(&self.buffer, self.len)\n    }\n\n    /// This is the same as `as_str`\n    ///\n    /// (this method only exists for backwards compatibility)\n    #[inline(always)]\n    #[deprecated(since = \"0.2.36\", note = \"redundant, same as `as_str`\")]\n    pub const fn as_str_alt(&self) -> &str {\n        self.as_str()\n    }\n\n    /// Gets the written part of this `StrWriter` as a `&str`\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    ///\n    /// use const_format::StrWriter;\n    /// use const_format::{unwrap, writec};\n    ///\n    ///\n    /// const CAP: usize = 128;\n    ///\n    /// const __STR: &StrWriter = &{\n    ///     let mut writer =  StrWriter::new([0; CAP]);\n    ///\n    ///     // Writing the array with debug formatting, and the integers with hexadecimal formatting.\n    ///     unwrap!(writec!(writer, \"{:X}\", [3u32, 5, 8, 13, 21, 34]));\n    ///\n    ///     writer\n    /// };\n    ///\n    /// const STR: &str = __STR.as_str();\n    ///\n    /// fn main() {\n    ///     assert_eq!(STR, \"[3, 5, 8, D, 15, 22]\");\n    /// }\n    /// ```\n    #[inline(always)]\n    pub const fn as_str(&self) -> &str {\n        // All the methods that modify the buffer must ensure utf8 validity,\n        // only methods from this module need to ensure this.\n        unsafe { core::str::from_utf8_unchecked(self.as_bytes()) }\n    }\n\n    /// Gets the written part of this `StrWriter` as a `&[u8]`\n    ///\n    /// The slice is guaranteed to be valid utf8, so this is mostly for convenience.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    /// use const_format::StrWriter;\n    ///\n    /// let buffer: &mut StrWriter = &mut StrWriter::new([0; 64]);\n    ///\n    /// buffer.as_mut().write_str(\"Hello, World!\");\n    ///\n    /// assert_eq!(buffer.as_bytes(), \"Hello, World!\".as_bytes());\n    ///\n    /// ```\n    #[inline(always)]\n    pub const fn as_bytes(&self) -> &[u8] {\n        crate::utils::slice_up_to_len(&self.buffer, self.len)\n    }\n\n    /// Borrows this `StrWriter<[u8]>` into a `StrWriterMut`,\n    /// most useful for calling the `write_*` methods.\n    ///\n    /// ```rust\n    /// use const_format::StrWriter;\n    ///\n    /// let buffer: &mut StrWriter = &mut StrWriter::new([0; 64]);\n    ///\n    /// buffer.as_mut().write_str_range(\"trust\", 1..usize::MAX);\n    ///\n    /// assert_eq!(buffer.as_str(), \"rust\");\n    ///\n    /// ```\n    #[inline(always)]\n    pub const fn as_mut(&mut self) -> StrWriterMut<'_> {\n        StrWriterMut {\n            len: &mut self.len,\n            buffer: &mut self.buffer,\n            _encoding: PhantomData,\n        }\n    }\n\n    /// Constructs a [`Formatter`] that writes into this `StrWriter`,\n    /// which can be passed to debug and display formatting methods.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    ///\n    /// use const_format::{Error, Formatter, FormattingFlags, StrWriter, call_debug_fmt};\n    ///\n    /// use std::ops::Range;\n    ///\n    /// const fn range_debug_fmt(\n    ///     slice: &[Range<usize>],\n    ///     f: &mut Formatter<'_>\n    /// ) -> Result<(), Error> {\n    ///     // We need this macro to debug format arrays of non-primitive types\n    ///     // Also, it implicitly returns a `const_format::Error` on error.\n    ///     call_debug_fmt!(array, slice, f);\n    ///     Ok(())\n    /// }\n    ///\n    /// fn main() -> Result<(), Error> {\n    ///     let buffer: &mut StrWriter = &mut StrWriter::new([0; 64]);\n    ///\n    ///     range_debug_fmt(\n    ///         &[0..14, 14..31, 31..48],\n    ///         &mut buffer.make_formatter(FormattingFlags::new().set_binary())\n    ///     )?;\n    ///    \n    ///     assert_eq!(buffer.as_str(), \"[0..1110, 1110..11111, 11111..110000]\");\n    ///\n    ///     Ok(())\n    /// }\n    /// ```\n    ///\n    /// [`Formatter`]: ./struct.Formatter.html\n    #[inline(always)]\n    pub const fn make_formatter(&mut self, flags: FormattingFlags) -> Formatter<'_> {\n        Formatter::from_sw_mut(\n            StrWriterMut::<Utf8Encoding> {\n                len: &mut self.len,\n                buffer: &mut self.buffer,\n                _encoding: PhantomData,\n            },\n            flags,\n        )\n    }\n}\n\nimpl<const N: usize> StrWriter<[u8; N]> {\n    /// Casts a `&StrWriter<[u8; N]>` to a `&StrWriter<[u8]>`,\n    /// for calling methods defined on `StrWriter<[u8]>` (most of them).\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    /// use const_format::StrWriter;\n    ///\n    /// let mut buffer = StrWriter::new([0; 64]);\n    ///\n    /// buffer.as_mut().write_str(\"Hello,\");\n    /// buffer.as_mut().write_str(\" world!\");\n    ///\n    /// assert_eq!(buffer.r().as_str(), \"Hello, world!\");\n    ///\n    /// ```\n    ///\n    #[inline(always)]\n    pub const fn r(&self) -> &StrWriter<[u8]> {\n        self\n    }\n    /// Casts a `&StrWriter<[u8; N]>` to a `&StrWriter<[u8]>`,\n    /// for calling methods defined on `StrWriter<[u8]>` (most of them).\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    /// use const_format::StrWriter;\n    ///\n    /// let mut buffer = StrWriter::new([0; 64]);\n    ///\n    /// buffer.as_mut().write_str(\"Hello,\");\n    /// buffer.as_mut().write_str(\" world!\");\n    ///\n    /// assert_eq!(buffer.unsize().as_str(), \"Hello, world!\");\n    ///\n    /// ```\n    ///\n    #[inline(always)]\n    pub const fn unsize(&self) -> &StrWriter<[u8]> {\n        self\n    }\n\n    /// Borrows this `StrWriter<[u8; N]>` into a `StrWriterMut`.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    /// use const_format::StrWriter;\n    ///\n    /// let mut buffer = StrWriter::new([0; 64]);\n    ///\n    /// buffer.as_mut().write_str_range(\"trust\", 1..usize::MAX);\n    ///\n    /// assert_eq!(buffer.r().as_str(), \"rust\");\n    ///\n    /// ```\n    #[inline(always)]\n    pub const fn as_mut(&mut self) -> StrWriterMut<'_> {\n        StrWriterMut {\n            len: &mut self.len,\n            buffer: &mut self.buffer,\n            _encoding: PhantomData,\n        }\n    }\n}\n\nimpl<A: ?Sized> StrWriter<A> {\n    /// For borrowing this mutably in macros, without getting nested mutable references.\n    #[inline(always)]\n    pub const fn borrow_mutably(&mut self) -> &mut Self {\n        self\n    }\n}\n"
  },
  {
    "path": "const_format/src/fmt/str_writer_mut.rs",
    "content": "use crate::{\n    formatting::{\n        hex_as_ascii, ForEscaping, FormattingFlags, HexFormatting, NumberFormatting, FOR_ESCAPING,\n    },\n    utils::{min_usize, saturate_range, Constructor},\n    wrapper_types::{AsciiStr, PWrapper},\n};\n\nuse super::{Error, Formatter, StrWriter};\n\nuse core::{marker::PhantomData, ops::Range};\n\n/// For writing a formatted string into a `[u8]`.\n///\n/// # Construction\n///\n/// This type can be constructed in these ways:\n///\n/// - From a `&mut StrWriter`, with the [`StrWriter::as_mut`] method.\n///\n/// - From a `&mut StrWriter<_>`, with the [`StrWriterMut::new`] constructor.\n///\n/// - From a pair of `usize` and `[u8]` mutable references,\n/// with the [`from_custom_cleared`] constructor,\n/// or the [`from_custom`] constructor.\n///\n/// # Relation to `Formatter`\n///\n/// This is the type that [`Formatter`] uses to write formatted text to a slice,\n/// sharing all the `write_*` methods,\n/// the difference is that this doesn't store `FormattingFlags`,\n/// so you must pass them to the `write_*_debug` methods.\n///\n/// # Errors\n///\n/// Every single `write_*` method returns an [`Error::NotEnoughSpace`] if\n/// there is not enough space to write the argument, leaving the string itself unmodified.\n///\n/// # Encoding type parameter\n///\n/// The `E` type parameter represents the encoding of the buffer that this\n/// StrWriterMut writes into,\n/// currently only [`Utf8Encoding`] and [`NoEncoding`] are supported.\n///\n/// # Example\n///\n/// This example demonstrates how you can write a formatted string to a `&mut [u8]`,\n/// using a `StrWriterMut`.\n///\n/// ```rust\n///\n/// use const_format::{Error, StrWriterMut, try_, writec};\n///\n/// const fn format_number(number: u32,slice: &mut [u8]) -> Result<usize, Error> {\n///     let mut len = 0;\n///     let mut writer = StrWriterMut::from_custom_cleared(slice, &mut len);\n///     \n///     try_!(writec!(writer, \"{0} in binary is {0:#b}\", number));\n///\n///     Ok(len)\n/// }\n///\n/// let mut slice = [0; 32];\n///\n/// let len = format_number(100, &mut slice)?;\n///\n/// assert_eq!(&slice[..len], \"100 in binary is 0b1100100\".as_bytes());\n///\n/// # Ok::<(), const_format::Error>(())\n/// ```\n///\n/// [`from_custom_cleared`]: #method.from_custom_cleared\n/// [`from_custom`]: #method.from_custom\n///\n/// [`Utf8Encoding`]: crate::fmt::Utf8Encoding\n/// [`NoEncoding`]: crate::fmt::NoEncoding\n/// [`Formatter`]: crate::fmt::Formatter\n/// [`Error::NotEnoughSpace`]: crate::fmt::Error::NotEnoughSpace\n///\npub struct StrWriterMut<'w, E = Utf8Encoding> {\n    pub(super) len: &'w mut usize,\n    pub(super) buffer: &'w mut [u8],\n    pub(super) _encoding: PhantomData<Constructor<E>>,\n}\n\nmacro_rules! borrow_fields {\n    ($self:ident, $len:ident, $buffer:ident) => {\n        let $len = &mut *$self.len;\n        let $buffer = &mut *$self.buffer;\n    };\n}\n\n/// Marker type indicating that the [`StrWriterMut`] is valid utf8,\n/// enabling the `as_str` method.\n///\n/// [`StrWriterMut`]: ./struct.StrWriterMut.html\npub enum Utf8Encoding {}\n\n/// Marker type indicating that the [`StrWriterMut`] is arbitrary bytes,\n/// disabling the `as_str` method.\n///\n/// [`StrWriterMut`]: ./struct.StrWriterMut.html\npub enum NoEncoding {}\n\nimpl<'w> StrWriterMut<'w, Utf8Encoding> {\n    /// Constructs a `StrWriterMut` from a mutable reference to a `StrWriter`\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    /// use const_format::{StrWriter, StrWriterMut};\n    ///\n    /// let buffer: &mut StrWriter = &mut StrWriter::new([0; 128]);\n    /// {\n    ///     let mut writer = StrWriterMut::new(buffer);\n    ///\n    ///     let _ = writer.write_str(\"Number: \");\n    ///     let _ = writer.write_u8_display(1);\n    /// }\n    /// assert_eq!(buffer.as_str(), \"Number: 1\");\n    ///\n    /// ```\n    pub const fn new(writer: &'w mut StrWriter) -> Self {\n        Self {\n            len: &mut writer.len,\n            buffer: &mut writer.buffer,\n            _encoding: PhantomData,\n        }\n    }\n}\n\nimpl<'w> StrWriterMut<'w, NoEncoding> {\n    /// Construct a `StrWriterMut` from length and byte slice mutable references.\n    ///\n    /// If `length > buffer.len()` is passed, it's simply assigned the length of the buffer.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    /// use const_format::StrWriterMut;\n    ///\n    /// let mut len = 6;\n    /// let mut buffer = *b\"Hello,       \";\n    ///\n    /// let mut writer = StrWriterMut::from_custom(&mut buffer, &mut len);\n    ///\n    /// writer.write_str(\" world!\")?;\n    ///\n    /// assert_eq!(writer.as_bytes(), b\"Hello, world!\");\n    /// assert_eq!(buffer, \"Hello, world!\".as_bytes());\n    /// assert_eq!(len, \"Hello, world!\".len());\n    ///\n    /// # Ok::<(), const_format::Error>(())\n    /// ```\n    pub const fn from_custom(buffer: &'w mut [u8], length: &'w mut usize) -> Self {\n        *length = min_usize(*length, buffer.len());\n\n        Self {\n            len: length,\n            buffer,\n            _encoding: PhantomData,\n        }\n    }\n}\n\nimpl<'w> StrWriterMut<'w, Utf8Encoding> {\n    /// Construct a `StrWriterMut` from length and byte slice mutable references,\n    /// truncating the length to `0`.\n    ///\n    /// Using this instead of [`from_custom`](StrWriterMut::from_custom) allows\n    /// safely casting this to a `&str` with [`as_str`]\n    ///\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    /// use const_format::StrWriterMut;\n    ///\n    /// let mut len = 0;\n    /// let mut buffer = [0; 13];\n    ///\n    /// let mut writer = StrWriterMut::from_custom_cleared(&mut buffer, &mut len);\n    ///\n    /// writer.write_str(\"Hello, world!\")?;\n    ///\n    /// assert_eq!(writer.as_str(), \"Hello, world!\");\n    /// assert_eq!(buffer, \"Hello, world!\".as_bytes());\n    /// assert_eq!(len, \"Hello, world!\".len());\n    ///\n    /// # Ok::<(), const_format::Error>(())\n    /// ```\n    ///\n    /// [`as_str`]: Self::as_str\n    ///\n    pub const fn from_custom_cleared(buffer: &'w mut [u8], length: &'w mut usize) -> Self {\n        *length = 0;\n\n        Self {\n            len: length,\n            buffer,\n            _encoding: PhantomData,\n        }\n    }\n}\n\nimpl<'w, E> StrWriterMut<'w, E> {\n    /// Accesses the underlying buffer immutably.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    /// use const_format::{StrWriter, StrWriterMut};\n    ///\n    /// let mut buffer = StrWriter::new([0; 7]);\n    /// let mut writer = StrWriterMut::new(&mut buffer);\n    /// assert_eq!(writer.buffer(), &[0; 7]);\n    ///\n    /// writer.write_str(\"foo\")?;\n    /// assert_eq!(writer.buffer(), b\"foo\\0\\0\\0\\0\");\n    ///\n    /// writer.write_str(\"bar\")?;\n    /// assert_eq!(writer.buffer(), b\"foobar\\0\");\n    ///\n    /// # Ok::<(), const_format::Error>(())\n    /// ```\n    #[inline(always)]\n    pub const fn buffer(&self) -> &[u8] {\n        self.buffer\n    }\n\n    /// The byte length of the string this is writing.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    /// use const_format::{StrWriter, StrWriterMut};\n    ///\n    /// let mut buffer = StrWriter::new([0; 64]);\n    /// let mut writer = StrWriterMut::new(&mut buffer);\n    ///\n    /// assert_eq!(writer.len(), 0);\n    ///\n    /// writer.write_str(\"foo\")?;\n    /// assert_eq!(writer.len(), 3);\n    ///\n    /// writer.write_str(\"bar\")?;\n    /// assert_eq!(writer.len(), 6);\n    ///\n    /// # Ok::<(), const_format::Error>(())\n    /// ```\n    #[inline(always)]\n    pub const fn len(&self) -> usize {\n        *self.len\n    }\n\n    /// Whether the string this is writing is empty.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    /// use const_format::{StrWriter, StrWriterMut};\n    ///\n    /// let mut buffer = StrWriter::new([0; 64]);\n    /// let mut writer = StrWriterMut::new(&mut buffer);\n    ///\n    /// assert!( writer.is_empty() );\n    ///\n    /// writer.write_str(\"foo\")?;\n    /// assert!( !writer.is_empty() );\n    ///\n    /// # Ok::<(), const_format::Error>(())\n    /// ```\n    #[inline(always)]\n    pub const fn is_empty(&self) -> bool {\n        *self.len == 0\n    }\n\n    /// The maximum byte length of the formatted text for this `StrWriterMut`.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    /// use const_format::{Error, StrWriter, StrWriterMut};\n    ///\n    /// let mut buffer = StrWriter::new([0; 64]);\n    /// let mut writer = StrWriterMut::new(&mut buffer);\n    ///\n    /// assert_eq!(writer.capacity(), 64);\n    ///\n    /// writer.write_ascii_repeated(b'A', 64)?;\n    /// assert_eq!(writer.capacity(), 64);\n    ///\n    /// assert_eq!(writer.write_str(\"-\").unwrap_err(), Error::NotEnoughSpace);\n    /// assert_eq!(writer.capacity(), 64);\n    ///\n    /// # Ok::<(), const_format::Error>(())\n    /// ```\n    #[inline(always)]\n    pub const fn capacity(&self) -> usize {\n        self.buffer.len()\n    }\n\n    /// Checks how many more bytes can be written.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    /// use const_format::{Error, StrWriter, StrWriterMut};\n    ///\n    /// let mut buffer = StrWriter::new([0; 64]);\n    /// let mut writer = StrWriterMut::new(&mut buffer);\n    ///\n    /// assert_eq!(writer.remaining_capacity(), 64);\n    ///\n    /// writer.write_str(\"foo\")?;\n    /// assert_eq!(writer.remaining_capacity(), 61);\n    ///\n    /// writer.write_ascii_repeated(b'a', 61)?;\n    /// assert_eq!(writer.remaining_capacity(), 0);\n    ///\n    /// assert_eq!(writer.write_str(\" \").unwrap_err(), Error::NotEnoughSpace);\n    ///\n    /// # Ok::<(), const_format::Error>(())\n    /// ```\n    #[inline]\n    pub const fn remaining_capacity(&self) -> usize {\n        self.buffer.len() - *self.len\n    }\n}\n\nimpl<'w> StrWriterMut<'w, Utf8Encoding> {\n    /// Truncates this `StrWriterMut` to `length`.\n    ///\n    /// If `length` is greater than the current length, this does nothing.\n    ///\n    /// # Errors\n    ///\n    /// Returns an `Error::NotOnCharBoundary` if `length` is not on a char boundary.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    /// use const_format::{Error, StrWriter, StrWriterMut};\n    ///\n    /// let mut buffer = StrWriter::new([0; 64]);\n    /// let mut writer = StrWriterMut::new(&mut buffer);\n    ///\n    /// writer.write_str(\"foo bâr baz\");\n    /// assert_eq!(writer.as_str(), \"foo bâr baz\");\n    ///\n    /// assert_eq!(writer.truncate(6).unwrap_err(), Error::NotOnCharBoundary);\n    ///\n    /// writer.truncate(3)?;\n    /// assert_eq!(writer.as_str(), \"foo\");\n    ///\n    /// writer.write_str(\"ooooooo\");\n    /// assert_eq!(writer.as_str(), \"fooooooooo\");\n    ///\n    /// # Ok::<(), const_format::Error>(())\n    /// ```\n    #[inline]\n    pub const fn truncate(&mut self, length: usize) -> Result<(), Error> {\n        if length <= *self.len {\n            if !is_valid_str_index(self.buffer, length) {\n                return Err(Error::NotOnCharBoundary);\n            }\n\n            *self.len = length;\n        }\n        Ok(())\n    }\n}\n\nimpl<'w> StrWriterMut<'w, NoEncoding> {\n    /// Truncates this `StrWriterMut<'w, NoEncoding>` to `length`.\n    ///\n    /// If `length` is greater than the current length, this does nothing.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    /// use const_format::{Error, StrWriter, StrWriterMut};\n    ///\n    /// let mut buffer = [0; 32];\n    /// let mut len = 0;\n    /// let mut writer = StrWriterMut::from_custom(&mut buffer, &mut len);\n    ///\n    /// writer.write_str(\"foo bar baz\");\n    /// assert_eq!(writer.as_bytes(), b\"foo bar baz\");\n    ///\n    /// // Truncating to anything larger than the length is a no-op.\n    /// writer.truncate(usize::MAX / 2);\n    /// assert_eq!(writer.as_bytes(), b\"foo bar baz\");\n    ///\n    /// writer.truncate(3);\n    /// assert_eq!(writer.as_bytes(), b\"foo\");\n    ///\n    /// writer.write_str(\"ooooooo\");\n    /// assert_eq!(writer.as_bytes(), b\"fooooooooo\");\n    ///\n    /// ```\n    #[inline]\n    pub const fn truncate(&mut self, length: usize) {\n        if length < *self.len {\n            *self.len = length;\n        }\n    }\n}\n\nimpl<'w, E> StrWriterMut<'w, E> {\n    /// Truncates this `StrWriterMut` to length 0.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    /// use const_format::{Error, StrWriter, StrWriterMut};\n    ///\n    /// let mut buffer = StrWriter::new([0; 64]);\n    /// let mut writer = StrWriterMut::new(&mut buffer);\n    ///\n    /// writer.write_str(\"foo\")?;\n    /// assert_eq!(writer.as_str(), \"foo\");\n    ///\n    /// writer.clear();\n    /// assert_eq!(writer.as_str(), \"\");\n    /// assert!(writer.is_empty());\n    ///\n    /// writer.write_str(\"bar\");\n    /// assert_eq!(writer.as_str(), \"bar\");\n    ///\n    /// # Ok::<(), const_format::Error>(())\n    /// ```\n    #[inline]\n    pub const fn clear(&mut self) {\n        *self.len = 0;\n    }\n\n    /// This is the same as `as_bytes`\n    ///\n    /// (this method only exists for backwards compatibility)\n    #[deprecated(since = \"0.2.36\", note = \"redundant, same as `as_bytes`\")]\n    #[inline(always)]\n    pub const fn as_bytes_alt(&self) -> &[u8] {\n        crate::utils::slice_up_to_len(self.buffer, *self.len)\n    }\n}\n\nimpl<'w> StrWriterMut<'w, Utf8Encoding> {\n    /// This is the same as `as_str`\n    ///\n    /// (this method only exists for backwards compatibility)\n    #[deprecated(since = \"0.2.36\", note = \"redundant, same as `as_str`\")]\n    #[inline(always)]\n    pub const fn as_str_alt(&self) -> &str {\n        // All the methods that modify the buffer must ensure utf8 validity,\n        // only methods from this module need to ensure this.\n        unsafe { core::str::from_utf8_unchecked(self.as_bytes_alt()) }\n    }\n\n    /// Gets the written part of this StrWriterMut as a `&str`\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    ///\n    /// use const_format::{StrWriter, StrWriterMut};\n    ///\n    /// let mut buffer = StrWriter::new([0; 64]);\n    /// let mut writer = StrWriterMut::new(&mut buffer);\n    ///\n    /// writer.write_str(\"Hello, how are you?\");\n    ///\n    /// assert_eq!(writer.as_str(), \"Hello, how are you?\");\n    ///\n    /// ```\n    #[inline(always)]\n    pub const fn as_str(&self) -> &str {\n        // All the methods that modify the buffer must ensure utf8 validity,\n        // only methods from this module need to ensure this.\n        unsafe { core::str::from_utf8_unchecked(self.as_bytes()) }\n    }\n}\n\nimpl<'w, E> StrWriterMut<'w, E> {\n    /// Gets the written part of this `StrWriterMut` as a `&[u8]`\n    ///\n    /// The slice is guaranteed to be valid utf8, so this is mostly for convenience.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    ///\n    /// use const_format::{StrWriter, StrWriterMut};\n    ///\n    /// let mut buffer = StrWriter::new([0; 64]);\n    /// let mut writer = StrWriterMut::new(&mut buffer);\n    ///\n    /// writer.write_str(\"Hello, World!\");\n    ///\n    /// assert_eq!(writer.as_bytes(), \"Hello, World!\".as_bytes());\n    ///\n    /// ```\n    #[inline(always)]\n    pub const fn as_bytes(&self) -> &[u8] {\n        crate::utils::slice_up_to_len(self.buffer, *self.len)\n    }\n}\n\nimpl<'w, E> StrWriterMut<'w, E> {\n    /// Constructs a [`Formatter`] that writes into this `StrWriterMut`,\n    /// which can be passed to debug and display formatting methods.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    ///\n    /// use const_format::{Error, Formatter, FormattingFlags, StrWriter, StrWriterMut};\n    /// use const_format::call_debug_fmt;\n    ///\n    /// use std::ops::Range;\n    ///\n    /// const fn range_debug_fmt(\n    ///     slice: &[Range<usize>],\n    ///     f: &mut Formatter<'_>\n    /// ) -> Result<(), Error> {\n    ///     // We need this macro to debug format arrays of non-primitive types\n    ///     // Also, it implicitly returns a `const_format::Error` on error.\n    ///     call_debug_fmt!(array, slice, f);\n    ///     Ok(())\n    /// }\n    ///\n    /// let mut buffer = StrWriter::new([0; 64]);\n    /// let mut writer = StrWriterMut::new(&mut buffer);\n    ///\n    /// range_debug_fmt(\n    ///     &[0..14, 14..31, 31..48],\n    ///     &mut writer.make_formatter(FormattingFlags::new().set_binary())\n    /// )?;\n    ///    \n    /// assert_eq!(writer.as_str(), \"[0..1110, 1110..11111, 11111..110000]\");\n    ///\n    /// # Ok::<(), Error>(())\n    ///\n    /// ```\n    ///\n    /// [`Formatter`]: ./struct.Formatter.html\n    #[inline(always)]\n    pub const fn make_formatter(&mut self, flags: FormattingFlags) -> Formatter<'_> {\n        Formatter::from_sw_mut(\n            StrWriterMut::<NoEncoding> {\n                len: self.len,\n                buffer: self.buffer,\n                _encoding: PhantomData,\n            },\n            flags,\n        )\n    }\n\n    /// For borrowing this mutably in macros, without getting nested mutable references.\n    #[inline(always)]\n    pub const fn borrow_mutably(&mut self) -> &mut StrWriterMut<'w, E> {\n        self\n    }\n\n    /// For passing a reborrow of this `StrWriterMut` into functions,\n    /// without this you'd need to pass a mutable reference instead.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    ///\n    /// use const_format::{Error, FormattingFlags, StrWriter, StrWriterMut, call_debug_fmt};\n    ///\n    /// use std::ops::Range;\n    ///\n    /// const fn range_debug_fmt(\n    ///     slice: &[[u32; 2]],\n    ///     mut writer: StrWriterMut<'_>\n    /// ) -> Result<(), Error> {\n    ///     let mut formatter = writer.make_formatter(FormattingFlags::new().set_binary());\n    ///\n    ///     // We need this macro to debug format arrays of non-primitive types\n    ///     // Also, it implicitly returns a `const_format::Error` on error.\n    ///     call_debug_fmt!(array, slice, formatter);\n    ///     Ok(())\n    /// }\n    ///\n    /// let mut buffer = StrWriter::new([0; 64]);\n    /// let mut writer = StrWriterMut::new(&mut buffer);\n    ///\n    /// range_debug_fmt(&[[3, 5], [8, 13]], writer.reborrow())?;\n    ///    \n    /// assert_eq!(writer.as_str(), \"[[11, 101], [1000, 1101]]\");\n    ///\n    /// # Ok::<(), Error>(())\n    ///\n    /// ```\n    #[inline(always)]\n    pub const fn reborrow(&mut self) -> StrWriterMut<'_, E> {\n        StrWriterMut {\n            len: self.len,\n            buffer: self.buffer,\n            _encoding: PhantomData,\n        }\n    }\n\n    // Safety: You must not write invalid utf8 bytes with the returned StrWriterMut.\n    pub(crate) const unsafe fn into_byte_encoding(self) -> StrWriterMut<'w, NoEncoding> {\n        StrWriterMut {\n            len: self.len,\n            buffer: self.buffer,\n            _encoding: PhantomData,\n        }\n    }\n}\n\n/////////////////////////////////////////////////////////////////////////////////\n\nmacro_rules! write_integer_fn {\n    (\n        display_attrs $display_attrs:tt\n        debug_attrs $debug_attrs:tt\n        $(($display_fn:ident, $debug_fn:ident, $sign:ident, $ty:ident, $Unsigned:ident))*\n    )=>{\n        impl<'w,E> StrWriterMut<'w,E>{\n            $(\n                write_integer_fn!{\n                    @methods\n                    display_attrs $display_attrs\n                    debug_attrs $debug_attrs\n                    $display_fn, $debug_fn, $sign, ($ty, $Unsigned), stringify!($ty)\n                }\n            )*\n        }\n\n        $(\n            write_integer_fn!{\n                @pwrapper\n                $display_fn, $debug_fn, $sign, ($ty, $Unsigned), stringify!($ty)\n            }\n        )*\n    };\n    (@pwrapper\n        $display_fn:ident,\n        $debug_fn:ident,\n        $sign:ident,\n        ($ty:ident, $Unsigned:ident),\n        $ty_name:expr\n    )=>{\n        impl PWrapper<$ty> {\n            /// Writes a\n            #[doc = $ty_name]\n            /// with Display formatting.\n            pub const fn const_display_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {\n                f.$display_fn(self.0)\n            }\n\n            /// Writes a\n            #[doc = $ty_name]\n            /// with Debug formatting.\n            pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {\n                f.$debug_fn(self.0)\n            }\n        }\n    };\n    (@methods\n        display_attrs( $(#[$display_attrs:meta])* )\n        debug_attrs( $(#[$debug_attrs:meta])* )\n        $display_fn:ident,\n        $debug_fn:ident,\n        $sign:ident,\n        ($ty:ident, $Unsigned:ident),\n        $ty_name:expr\n    )=>{\n        $(#[$display_attrs])*\n        pub const fn $display_fn(&mut self, number: $ty) -> Result<(), Error> {\n            borrow_fields!(self, this_len, this_buffer);\n\n            let n = PWrapper(number);\n            let len = n.compute_display_len(FormattingFlags::DEFAULT);\n\n            let mut cursor = *this_len + len;\n\n            if cursor > this_buffer.len() {\n                return Err(Error::NotEnoughSpace);\n            }\n\n            write_integer_fn!(@unsigned_abs $sign, n);\n\n            loop {\n                cursor-=1;\n                let digit = (n % 10) as u8;\n                this_buffer[cursor] = b'0' + digit;\n                n/=10;\n                if n == 0 { break }\n            }\n\n            write_integer_fn!(@write_sign $sign, this_len, this_buffer, number);\n\n            *this_len+=len;\n            Ok(())\n        }\n\n        $(#[$debug_attrs])*\n        pub const fn $debug_fn(\n            &mut self,\n            number: $ty,\n            flags: FormattingFlags,\n        ) -> Result<(), Error> {\n            const fn hex<E>(\n                this: &mut StrWriterMut<'_, E>,\n                n: $ty,\n                f: FormattingFlags,\n            ) -> Result<(), Error> {\n                borrow_fields!(this, this_len, this_buffer);\n\n                let is_alternate = f.is_alternate();\n                let len = PWrapper(n).hexadecimal_len(f);\n\n                let mut cursor = *this_len + len;\n\n                if cursor > this_buffer.len() {\n                    return Err(Error::NotEnoughSpace);\n                }\n\n                if is_alternate {\n                    this_buffer[*this_len] = b'0';\n                    this_buffer[*this_len + 1] = b'x';\n                }\n\n                write_integer_fn!(@as_unsigned $sign, n, $Unsigned);\n\n                loop {\n                    cursor-=1;\n                    let digit = (n & 0b1111) as u8;\n                    this_buffer[cursor] = hex_as_ascii(digit, f.hex_fmt());\n                    n >>= 4;\n                    if n == 0 { break }\n                }\n\n                *this_len+=len;\n                Ok(())\n            }\n\n            const fn binary<E>(\n                this: &mut StrWriterMut<'_, E>,\n                n: $ty,\n                f: FormattingFlags,\n            ) -> Result<(), Error> {\n                borrow_fields!(this, this_len, this_buffer);\n\n                let is_alternate = f.is_alternate();\n                let len = PWrapper(n).binary_len(f);\n\n                let mut cursor = *this_len + len;\n\n                if cursor > this_buffer.len() {\n                    return Err(Error::NotEnoughSpace);\n                }\n\n                if is_alternate {\n                    this_buffer[*this_len] = b'0';\n                    this_buffer[*this_len + 1] = b'b';\n                }\n\n                write_integer_fn!(@as_unsigned $sign, n, $Unsigned);\n\n                loop {\n                    cursor-=1;\n                    let digit = (n & 1) as u8;\n                    this_buffer[cursor] = hex_as_ascii(digit, f.hex_fmt());\n                    n >>= 1;\n                    if n == 0 { break }\n                }\n\n                *this_len+=len;\n                Ok(())\n            }\n\n            match flags.num_fmt() {\n                NumberFormatting::Decimal=>self.$display_fn(number),\n                NumberFormatting::Hexadecimal=>hex(self, number, flags),\n                NumberFormatting::Binary=>binary(self, number, flags),\n            }\n        }\n    };\n    (@unsigned_abs signed, $n:ident) => (\n        let mut $n = $n.unsigned_abs();\n    );\n    (@unsigned_abs unsigned, $n:ident) => (\n        let mut $n = $n.0;\n    );\n    (@as_unsigned signed, $n:ident, $Unsigned:ident) => (\n        let mut $n = $n as $Unsigned;\n    );\n    (@as_unsigned unsigned, $n:ident, $Unsigned:ident) => (\n        let mut $n = $n;\n    );\n    (@write_sign signed, $self_len:ident, $self_buffer:ident, $n:ident) => ({\n        if $n < 0 {\n            $self_buffer[*$self_len] = b'-';\n        }\n    });\n    (@write_sign unsigned, $self_len:ident, $self_buffer:ident, $n:ident) => ({});\n}\n\n/// Checks that a range is valid for indexing a string,\n/// assuming that the range is in-bounds, and start <= end.\n#[inline]\nconst fn is_valid_str_range(s: &[u8], Range { start, end }: Range<usize>) -> bool {\n    let len = s.len();\n\n    (end == len || ((s[end] as i8) >= -0x40)) && (start == len || ((s[start] as i8) >= -0x40))\n}\n\n/// Checks that an index is valid for indexing a string,\n/// assuming that the index is in-bounds.\n#[inline]\nconst fn is_valid_str_index(s: &[u8], index: usize) -> bool {\n    let len = s.len();\n\n    index == len || ((s[index] as i8) >= -0x40)\n}\n\nimpl<'w, E> StrWriterMut<'w, E> {\n    /// Writes a subslice of `s` with Display formatting.\n    ///\n    /// This is a workaround for being unable to do `&foo[start..end]` at compile time.\n    ///\n    /// # Additional Errors\n    ///\n    /// This method returns `Error::NotOnCharBoundary` if the range is not\n    /// on a character boundary.\n    ///\n    /// Out of bounds range bounds are treated as being at `s.len()`,\n    /// this only returns an error on an in-bounds index that is not on a character boundary.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    /// use const_format::{FormattingFlags, StrWriterMut};\n    ///\n    /// let mut len = 0;\n    /// let mut buffer = [0; 64];\n    /// let mut writer = StrWriterMut::from_custom_cleared(&mut buffer, &mut len);\n    ///\n    /// let _ = writer.write_str_range(\"FOO BAR BAZ\", 4..7);\n    ///\n    /// assert_eq!(writer.as_str(), \"BAR\");\n    ///\n    /// ```\n    ///\n    pub const fn write_str_range(&mut self, s: &str, range: Range<usize>) -> Result<(), Error> {\n        let bytes = s.as_bytes();\n        let Range { start, end } = saturate_range(bytes, &range);\n\n        if !is_valid_str_range(bytes, start..end) {\n            return Err(Error::NotOnCharBoundary);\n        }\n\n        self.write_str_inner(bytes, start, end)\n    }\n\n    /// Writes `s` with Display formatting.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    ///\n    /// use const_format::{FormattingFlags, StrWriterMut};\n    ///\n    /// let mut len = 0;\n    /// let mut buffer = [0; 64];\n    /// let mut writer = StrWriterMut::from_custom_cleared(&mut buffer, &mut len);\n    ///\n    /// let _ = writer.write_str(\"FOO BAR BAZ\");\n    ///\n    /// assert_eq!(writer.as_str(), \"FOO BAR BAZ\");\n    ///\n    /// ```\n    ///\n    pub const fn write_str(&mut self, s: &str) -> Result<(), Error> {\n        let bytes = s.as_bytes();\n\n        self.write_str_inner(bytes, 0, s.len())\n    }\n\n    /// Writes `character` with Display formatting\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    ///\n    /// use const_format::StrWriterMut;\n    ///\n    /// let mut len = 0;\n    /// let mut buffer = [0; 64];\n    /// let mut writer = StrWriterMut::from_custom_cleared(&mut buffer, &mut len);\n    ///\n    /// let _ = writer.write_char('3');\n    /// let _ = writer.write_char('5');\n    /// let _ = writer.write_char('8');\n    ///\n    /// assert_eq!(writer.as_str(), \"358\");\n    ///\n    /// ```\n    ///\n    pub const fn write_char(&mut self, character: char) -> Result<(), Error> {\n        let fmt = crate::char_encoding::char_to_display(character);\n        self.write_str_inner(fmt.encoded(), 0, fmt.len())\n    }\n\n    /// Writes a subslice of `ascii` with Display formatting.\n    ///\n    /// Out of bounds range bounds are treated as being at `s.len()`.\n    ///\n    /// This is a workaround for being unable to do `&foo[start..end]` at compile time.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    ///\n    /// use const_format::{FormattingFlags, StrWriterMut, ascii_str};\n    ///\n    /// let mut len = 0;\n    /// let mut buffer = [0; 64];\n    /// let mut writer = StrWriterMut::from_custom_cleared(&mut buffer, &mut len);\n    ///\n    /// let _ = writer.write_ascii_range(ascii_str!(\"FOO BAR BAZ\"), 4..7);\n    ///\n    /// assert_eq!(writer.as_str(), \"BAR\");\n    ///\n    /// ```\n    ///\n    pub const fn write_ascii_range(\n        &mut self,\n        ascii: AsciiStr<'_>,\n        range: Range<usize>,\n    ) -> Result<(), Error> {\n        let bytes = ascii.as_bytes();\n        let Range { start, end } = saturate_range(bytes, &range);\n\n        self.write_str_inner(bytes, start, end)\n    }\n\n    /// Writes `ascii` with Display formatting.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    ///\n    /// use const_format::{FormattingFlags, StrWriterMut, ascii_str};\n    ///\n    /// let mut len = 0;\n    /// let mut buffer = [0; 64];\n    /// let mut writer = StrWriterMut::from_custom_cleared(&mut buffer, &mut len);\n    ///\n    /// let _ = writer.write_ascii(ascii_str!(\"FOO BAR BAZ\"));\n    ///\n    /// assert_eq!(writer.as_str(), \"FOO BAR BAZ\");\n    ///\n    /// ```\n    ///\n    pub const fn write_ascii(&mut self, ascii: AsciiStr<'_>) -> Result<(), Error> {\n        let bytes = ascii.as_bytes();\n\n        self.write_str_inner(bytes, 0, bytes.len())\n    }\n\n    /// Writes an ascii `character`, `repeated` times.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    ///\n    /// use const_format::{FormattingFlags, StrWriterMut};\n    ///\n    /// let mut len = 0;\n    /// let mut buffer = [0; 64];\n    /// let mut writer = StrWriterMut::from_custom_cleared(&mut buffer, &mut len);\n    ///\n    /// let _ = writer.write_ascii_repeated(b'A', 10);\n    ///\n    /// assert_eq!(writer.as_str(), \"AAAAAAAAAA\");\n    ///\n    /// ```\n    ///\n    pub const fn write_ascii_repeated(\n        &mut self,\n        mut character: u8,\n        repeated: usize,\n    ) -> Result<(), Error> {\n        borrow_fields!(self, self_len, self_buffer);\n\n        // Truncating non-ascii u8s\n        character &= 0b111_1111;\n\n        let end = *self_len + repeated;\n\n        if end > self_buffer.len() {\n            return Err(Error::NotEnoughSpace);\n        }\n\n        while *self_len < end {\n            self_buffer[*self_len] = character;\n            *self_len += 1;\n        }\n\n        Ok(())\n    }\n\n    #[inline(always)]\n    const fn write_str_inner(\n        &mut self,\n        bytes: &[u8],\n        mut start: usize,\n        end: usize,\n    ) -> Result<(), Error> {\n        borrow_fields!(self, self_len, self_buffer);\n\n        let len = end - start;\n\n        if *self_len + len > self_buffer.len() {\n            return Err(Error::NotEnoughSpace);\n        }\n\n        while start < end {\n            self_buffer[*self_len] = bytes[start];\n            *self_len += 1;\n            start += 1;\n        }\n\n        Ok(())\n    }\n}\n\n/// Debug-formatted string writing\nimpl<'w, E> StrWriterMut<'w, E> {\n    /// Writes a subslice of `s` with  Debug-like formatting.\n    ///\n    /// This is a workaround for being unable to do `&foo[start..end]` at compile time.\n    ///\n    /// # Additional Errors\n    ///\n    /// This method returns `Error::NotOnCharBoundary` if the range is not\n    /// on a character boundary.\n    ///\n    /// Out of bounds range bounds are treated as being at `s.len()`,\n    /// this only returns an error on an in-bounds index that is not on a character boundary.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    ///\n    /// use const_format::{FormattingFlags, StrWriterMut};\n    ///\n    /// let mut len = 0;\n    /// let mut buffer = [0; 64];\n    /// let mut writer = StrWriterMut::from_custom_cleared(&mut buffer, &mut len);\n    ///\n    /// let _ = writer.write_str_range_debug(\"FOO\\nBAR\\tBAZ\", 3..8);\n    ///\n    /// assert_eq!(writer.as_str(), r#\"\"\\nBAR\\t\"\"#);\n    ///\n    /// ```\n    ///\n    pub const fn write_str_range_debug(\n        &mut self,\n        s: &str,\n        range: Range<usize>,\n    ) -> Result<(), Error> {\n        let bytes = s.as_bytes();\n        let Range { start, end } = saturate_range(bytes, &range);\n\n        if !is_valid_str_range(bytes, start..end) {\n            return Err(Error::NotOnCharBoundary);\n        }\n\n        self.write_str_debug_inner(bytes, start, end)\n    }\n\n    /// Writes `s` with Debug-like formatting.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    ///\n    /// use const_format::{FormattingFlags, StrWriterMut};\n    ///\n    /// let mut len = 0;\n    /// let mut buffer = [0; 64];\n    /// let mut writer = StrWriterMut::from_custom_cleared(&mut buffer, &mut len);\n    ///\n    /// let _ = writer.write_str_debug(\"FOO\\nBAR\\tBAZ\");\n    ///\n    /// assert_eq!(writer.as_str(), r#\"\"FOO\\nBAR\\tBAZ\"\"#);\n    ///\n    /// ```\n    ///\n    pub const fn write_str_debug(&mut self, str: &str) -> Result<(), Error> {\n        let bytes = str.as_bytes();\n        self.write_str_debug_inner(bytes, 0, str.len())\n    }\n\n    /// Writes `character` with Debug formatting.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    ///\n    /// use const_format::StrWriterMut;\n    ///\n    /// let mut len = 0;\n    /// let mut buffer = [0; 64];\n    /// let mut writer = StrWriterMut::from_custom_cleared(&mut buffer, &mut len);\n    ///\n    /// let _ = writer.write_str(\" \");\n    /// let _ = writer.write_char_debug('\\\\');\n    /// let _ = writer.write_str(\" \");\n    /// let _ = writer.write_char_debug('A');\n    /// let _ = writer.write_str(\" \");\n    /// let _ = writer.write_char_debug('0');\n    /// let _ = writer.write_str(\" \");\n    /// let _ = writer.write_char_debug('\\'');\n    /// let _ = writer.write_str(\" \");\n    ///\n    /// assert_eq!(writer.as_str(), r#\" '\\\\' 'A' '0' '\\'' \"#);\n    ///\n    /// ```\n    ///\n    pub const fn write_char_debug(&mut self, character: char) -> Result<(), Error> {\n        let fmt = crate::char_encoding::char_to_debug(character);\n        self.write_str_inner(fmt.encoded(), 0, fmt.len())\n    }\n\n    /// Writes a subslice of `ascii` with Debug-like formatting.\n    ///\n    /// Out of bounds range bounds are treated as being at `s.len()`.\n    ///\n    /// This is a workaround for being unable to do `&foo[start..end]` at compile time.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    ///\n    /// use const_format::{FormattingFlags, StrWriterMut, ascii_str};\n    ///\n    /// let mut len = 0;\n    /// let mut buffer = [0; 64];\n    /// let mut writer = StrWriterMut::from_custom_cleared(&mut buffer, &mut len);\n    ///\n    /// let _ = writer.write_ascii_range_debug(ascii_str!(\"FOO\\nBAR\\tBAZ\"), 3..8);\n    ///\n    /// assert_eq!(writer.as_str(), r#\"\"\\nBAR\\t\"\"#);\n    ///\n    /// ```\n    ///\n    pub const fn write_ascii_range_debug(\n        &mut self,\n        ascii: AsciiStr<'_>,\n        range: Range<usize>,\n    ) -> Result<(), Error> {\n        let bytes = ascii.as_bytes();\n        let Range { start, end } = saturate_range(bytes, &range);\n\n        self.write_str_debug_inner(bytes, start, end)\n    }\n\n    /// Writes `ascii` with Debug-like formatting.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    ///\n    /// use const_format::{FormattingFlags, StrWriterMut, ascii_str};\n    ///\n    /// let mut len = 0;\n    /// let mut buffer = [0; 64];\n    /// let mut writer = StrWriterMut::from_custom_cleared(&mut buffer, &mut len);\n    ///\n    /// let _ = writer.write_ascii_debug(ascii_str!(\"FOO\\nBAR\\tBAZ\"));\n    ///\n    /// assert_eq!(writer.as_str(), r#\"\"FOO\\nBAR\\tBAZ\"\"#);\n    ///\n    /// ```\n    ///\n    pub const fn write_ascii_debug(&mut self, ascii: AsciiStr<'_>) -> Result<(), Error> {\n        let bytes = ascii.as_bytes();\n        self.write_str_debug_inner(bytes, 0, bytes.len())\n    }\n\n    #[inline(always)]\n    const fn write_str_debug_inner(\n        &mut self,\n        bytes: &[u8],\n        mut start: usize,\n        end: usize,\n    ) -> Result<(), Error> {\n        borrow_fields!(self, self_len, self_buffer);\n\n        let len = end - start;\n\n        // + 2 for the quote characters around the string.\n        if *self_len + len + 2 > self_buffer.len() {\n            return Err(Error::NotEnoughSpace);\n        }\n\n        // The amount of bytes available for escapes,\n        // not counting the `writte_c`.\n        let mut remaining_for_escapes = (self_buffer.len() - 2 - len - *self_len) as isize;\n        let mut written = *self_len;\n\n        self_buffer[written] = b'\"';\n        written += 1;\n\n        while start != end {\n            let c = bytes[start];\n            let mut written_c = c;\n\n            let shifted;\n\n            if c < 128\n                && ({\n                    shifted = 1 << c;\n                    (FOR_ESCAPING.is_escaped & shifted) != 0\n                })\n            {\n                self_buffer[written] = b'\\\\';\n                written += 1;\n\n                if (FOR_ESCAPING.is_backslash_escaped & shifted) != 0 {\n                    remaining_for_escapes -= 1;\n                    if remaining_for_escapes < 0 {\n                        return Err(Error::NotEnoughSpace);\n                    }\n                    written_c = ForEscaping::get_backslash_escape(c);\n                } else {\n                    remaining_for_escapes -= 3;\n                    if remaining_for_escapes < 0 {\n                        return Err(Error::NotEnoughSpace);\n                    }\n                    self_buffer[written] = b'x';\n                    written += 1;\n                    self_buffer[written] = hex_as_ascii(c >> 4, HexFormatting::Upper);\n                    written += 1;\n                    written_c = hex_as_ascii(c & 0xF, HexFormatting::Upper);\n                };\n            }\n\n            self_buffer[written] = written_c;\n            written += 1;\n            start += 1;\n        }\n\n        self_buffer[written] = b'\"';\n        written += 1;\n\n        *self_len = written;\n\n        Ok(())\n    }\n}\n\nwrite_integer_fn! {\n    display_attrs(\n        /// Write `number` with display formatting.\n        ///\n        /// # Example\n        ///\n        /// ```rust\n        ///\n        /// use const_format::{Formatter, FormattingFlags, StrWriterMut, ascii_str};\n        ///\n        /// let mut len = 0;\n        /// let mut buffer = [0; 64];\n        /// let mut writer = StrWriterMut::from_custom_cleared(&mut buffer, &mut len);\n        ///\n        /// let _ = writer.write_u8_display(137);\n        ///\n        /// assert_eq!(writer.as_str(), \"137\");\n        ///\n        /// ```\n        ///\n    )\n    debug_attrs(\n        /// Writes `number` with debug formatting.\n        ///\n        /// # Example\n        ///\n        /// ```rust\n        ///\n        /// use const_format::{FormattingFlags, StrWriterMut};\n        ///\n        /// const fn debug_fmt<'a>(\n        ///     writer: &'a mut StrWriterMut<'_>,\n        ///     flag: FormattingFlags\n        /// ) -> &'a str {\n        ///     writer.clear();\n        ///     let _ = writer.write_u8_debug(63, flag);\n        ///     writer.as_str()\n        /// }\n        ///\n        /// let reg_flag = FormattingFlags::NEW.set_alternate(false);\n        /// let alt_flag = FormattingFlags::NEW.set_alternate(true);\n        ///\n        /// let mut len = 0;\n        /// let mut buffer = [0; 64];\n        /// let mut writer = StrWriterMut::from_custom_cleared(&mut buffer, &mut len);\n        ///\n        /// assert_eq!(debug_fmt(&mut writer, reg_flag),                   \"63\"     );\n        /// assert_eq!(debug_fmt(&mut writer, reg_flag.set_hexadecimal()), \"3F\"     );\n        /// assert_eq!(debug_fmt(&mut writer, reg_flag.set_lower_hexadecimal()), \"3f\");\n        /// assert_eq!(debug_fmt(&mut writer, reg_flag.set_binary()),      \"111111\" );\n        /// assert_eq!(debug_fmt(&mut writer, alt_flag),                   \"63\"     );\n        /// assert_eq!(debug_fmt(&mut writer, alt_flag.set_hexadecimal()), \"0x3F\"   );\n        /// assert_eq!(debug_fmt(&mut writer, alt_flag.set_lower_hexadecimal()), \"0x3f\");\n        /// assert_eq!(debug_fmt(&mut writer, alt_flag.set_binary()),      \"0b111111\");\n        ///\n        /// ```\n        ///\n    )\n    (write_u8_display, write_u8_debug, unsigned, u8, u8)\n}\nwrite_integer_fn! {\n    display_attrs(\n        /// Writes `number` with display formatting\n        ///\n        /// For an example,\n        /// you can look at the one for the [`write_u8_display`] method.\n        ///\n        /// [`write_u8_display`]: #method.write_u8_display\n    )\n    debug_attrs(\n        /// Writes `number` with debug formatting.\n        ///\n        /// For an example,\n        /// you can look at the one for the [`write_u8_debug`] method.\n        ///\n        /// [`write_u8_debug`]: #method.write_u8_debug\n    )\n    (write_u16_display, write_u16_debug, unsigned, u16, u16)\n    (write_u32_display, write_u32_debug, unsigned, u32, u32)\n    (write_u64_display, write_u64_debug, unsigned, u64, u64)\n    (write_u128_display, write_u128_debug, unsigned, u128, u128)\n    (write_usize_display, write_usize_debug, unsigned, usize, usize)\n\n    (write_i8_display, write_i8_debug, signed, i8, u8)\n    (write_i16_display, write_i16_debug, signed, i16, u16)\n    (write_i32_display, write_i32_debug, signed, i32, u32)\n    (write_i64_display, write_i64_debug, signed, i64, u64)\n    (write_i128_display, write_i128_debug, signed, i128, u128)\n    (write_isize_display, write_isize_debug, signed, isize, usize)\n}\n"
  },
  {
    "path": "const_format/src/fmt.rs",
    "content": "//! [`std::fmt`](https://doc.rust-lang.org/std/fmt/)-like\n//! api that can be used at compile-time.\n//!\n//! # Features\n//!\n//! This module requires the \"fmt\" feature to be exported, and Rust 1.83.0,\n//! because it uses `&mut` in `const fn`s.\n//!\n//! # Implementing the formatting methods\n//!\n//! Users of this library can implement debug and display formatting by\n//! defining `const_debug_fmt` and `const_display_fmt` inherent methods\n//! with the\n//! ```ignore\n//! // use const_format::{Formatter, Error};\n//! const fn const_debug_fmt(&self, &mut Formatter<'_>) -> Result<(), Error>\n//! const fn const_display_fmt(&self, &mut Formatter<'_>) -> Result<(), Error>\n//! ```\n//! signatures,\n//! and implementing the [`FormatMarker`] trait.\n//!\n//! # Limitations\n//!\n//! ### Generic impls\n//!\n//! Because the formatting of custom types is implemented with duck typing,\n//! it's not possible to format generic types, instead you must do either of these:\n//!\n//! - Provide all the implementations ahead of time, what [`impl_fmt`] is for.\n//!\n//! - Provide a macro that formats the type.\n//! The `call_debug_fmt` macro is a version of this that formats generic std types.\n//!\n//! <span id = \"fmtsyntax\"></span>\n//! # Formatting Syntax\n//!\n//! The formatting macros all share the formatting syntax,\n//! modeled after the syntax of the formatting macros of the standard library.\n//!\n//! ### Arguments\n//!\n//! Arguments in the format string can be named and positional in these ways:\n//!\n//! - Implicitly positional(eg: `formatc!(\"{}\", 20u8)`):<br>\n//! Starts at the 0th positional argument and increments with every use.\n//!\n//! - Explicit positional(eg: `formatc!(\"{0}\", 10u8)`).\n//!\n//! - Named, passed to the macro as named arguments (eg: `formatc!(\"{foo}\", foo = 10u8)`).\n//!\n//! - Named, from constant (eg: `formatc!(\"{FOO}\")`):\n//! Uses the `FOO` constant from the enclosing scope.\n//!\n//! - Named, from locals (eg: `writec!(writable, \"{foo}\")`):\n//! Uses the `foo` local variable from the enclosing scope,\n//! only usable with the [`writec`] macro.\n//!\n//! ### Formatters\n//!\n//! The format arguments can be formatted in these ways:\n//!\n//! - Debug formatting (eg: `formatc!(\"{:?}\", 0u8)` ):<br>\n//! Similar to how Debug formatting in the standard library works,\n//! except that it does not escape unicode characters.\n//!\n//! - Display formatting (eg: `formatc!(\"{}\", 0u8)`, `formatc!(\"{:}\", 0u8)` )\n//!\n//! - Lowercase hexadecimal formatting (eg: `formatc!(\"{:x}\", 0u8)`):<br>\n//! Writes numbers in lowercase hexadecimal.\n//! This can be combined with debug formatting with the `\"{:x?}\"` formatter.\n//!\n//! - Uppercase hexadecimal formatting (eg: `formatc!(\"{:X}\", 0u8)`):<br>\n//! Writes numbers in uppercase hexadecimal.\n//! This can be combined with debug formatting with the `\"{:X?}\"` formatter.\n//!\n//! - Binary formatting (eg: `formatc!(\"{:b}\", 0u8)`):<br>\n//! This can be combined with debug formatting with the `\"{:b?}\"` formatter.\n//!\n//! ### Alternate flag\n//!\n//! The alternate flag allows types to format themselves in an alternate way,\n//! written as \"#\" in a format string argument. eg:`\"{:#}\", \"{:#?}\"`.\n//!\n//! This is the built-in behavior for the alternate flag:\n//!\n//! - The Debug formater (eg: `formatc!(\"{:#?}\", FOO)`):\n//! pretty print structs and enums.\n//!\n//! - The hexadecimal formater (eg: `formatc!(\"{:#x}\", FOO)`):\n//! prefixes numbers with `0x`.\n//!\n//! - The binary formater (eg: `formatc!(\"{:#b}\", FOO)`):\n//! prefixes numbers with `0b`.\n//!\n//! ### Additional specifiers\n//!\n//! `const_format` macros don't support width, fill, alignment, sign,\n//! or precision specifiers.\n//!\n//! <span id=\"custom-formatting-section\"></span>\n//! ### Custom formatting\n//!\n//! Arguments can access a [`Formatter`] for custom formatting with an\n//! `|identifier|` before the expression.\n//!\n//! The expression will be evaluated every time it is used in the formatting string.\n//!\n//! The expression can evaluate to either a `()` or a `Result<(), const_format::Error>`.\n//!\n//! Note: this doesn't distinguish between debug and display formatting.\n//!\n//! [Link to full example of custom formatting](#custom-formatting-example)\n//!\n//! # Examples\n//!\n//! ### Derive\n//!\n//! This example demonstrates how you can derive [`ConstDebug`], and use it with the `fmt` API.\n//!\n//! It uses the \"derive\" feature\n//!\n#![cfg_attr(feature = \"derive\", doc = \"```rust\")]\n#![cfg_attr(not(feature = \"derive\"), doc = \"```ignore\")]\n//!\n//! use const_format::{Error, Formatter, FormattingFlags, PWrapper, StrWriter};\n//! use const_format::{ConstDebug, try_, unwrap, writec};\n//!\n//! use std::ops::Range;\n//!\n//! #[derive(ConstDebug)]\n//! pub struct Foo {\n//!     range: Option<Range<usize>>,\n//!     point: Point,\n//! }\n//!\n//! #[derive(ConstDebug)]\n//! pub struct Point {\n//!     x: u32,\n//!     y: u32,\n//! }\n//!\n//! const CAP: usize = 90;\n//! const fn build_string() -> StrWriter<[u8; CAP]> {\n//!     let mut writer = StrWriter::new([0; CAP]);\n//!\n//!     let foo = Foo {\n//!         range: Some(0..10),\n//!         point: Point{ x: 13, y: 21 },\n//!     };\n//!\n//!     unwrap!(writec!(writer, \"{:X?}\", foo));\n//!\n//!     writer\n//! }\n//!\n//! const STRING: &str = {\n//!     const STR: &StrWriter = &build_string();\n//!     STR.as_str()\n//! };\n//!\n//! // The formatter\n//! assert_eq!(\n//!     STRING,\n//!     \"Foo { range: Some(0..A), point: Point { x: D, y: 15 } }\",\n//! );\n//!\n//! ```\n//!\n//!\n//! ### No proc macros\n//!\n//! This example demonstrates how you can use the `fmt` api without using any proc macros.\n//!\n//! ```rust\n//!\n//! use const_format::{Error, Formatter, FormattingFlags, PWrapper, StrWriter};\n//! use const_format::{call_debug_fmt, coerce_to_fmt, impl_fmt, try_};\n//!\n//! use std::cmp::Ordering;\n//!\n//! pub struct Foo<T, U> {\n//!     a: u32,\n//!     b: u32,\n//!     c: T,\n//!     d: [Ordering; 3],\n//!     ignored: U,\n//! }\n//!\n//! //\n//! impl_fmt!{\n//!     // The type parameters of the impl must be written with trailing commas\n//!     impl[U,] Foo<u32, U>;\n//!     impl[U,] Foo<&str, U>;\n//!\n//!     pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {\n//!         let mut f = f.debug_struct(\"Foo\");\n//!\n//!         // PWrapper is a wrapper for std types, which defines the formatter methods for them.\n//!         try_!(PWrapper(self.a).const_debug_fmt(f.field(\"a\")));\n//!\n//!         try_!(PWrapper(self.b).const_debug_fmt(f.field(\"b\")));\n//!\n//!         // The `coerce_to_fmt` macro automatically wraps std types in `PWrapper`\n//!         // and does nothing with non-std types.\n//!         try_!(coerce_to_fmt!(self.c).const_debug_fmt(f.field(\"c\")));\n//!\n//!         // This macro allows debug formatting of some generic types which\n//!         // wrap non-std types, including:\n//!         // - arrays   - slices    - Option    - newtype wrappers\n//!         call_debug_fmt!(array, self.d, f.field(\"d\"));\n//!\n//!         f.finish()\n//!     }\n//! }\n//!\n//! const CAP: usize = 128;\n//!\n//! const fn build_string() -> StrWriter<[u8; CAP]> {\n//!     let flags = FormattingFlags::NEW.set_alternate(true);\n//!     let mut writer = StrWriter::new([0; CAP]);\n//!\n//!     const_format::unwrap!(\n//!         Foo {\n//!             a: 5,\n//!             b: 8,\n//!             c: 13,\n//!             d: [Ordering::Less, Ordering::Equal, Ordering::Greater],\n//!             ignored: (),\n//!         }.const_debug_fmt(&mut Formatter::from_sw(&mut writer, flags))\n//!     );\n//!\n//!     writer\n//! }\n//!\n//! const STRING: &str = {\n//!     const S: &StrWriter = &build_string();\n//!     S.as_str()\n//! };\n//!\n//! assert_eq!(\n//!     STRING,\n//!     \"\\\n//! Foo {\n//!     a: 5,\n//!     b: 8,\n//!     c: 13,\n//!     d: [\n//!         Less,\n//!         Equal,\n//!         Greater,\n//!     ],\n//! }\\\n//!     \",\n//! );\n//!\n//!\n//! ```\n//!\n//! <span id=\"custom-formatting-example\"></span>\n//! ### Custom formatting\n//!\n//! This example demonstrates how you can do [custom formatting](#custom-formatting-section),\n//! by using a `Formatter` directly.\n//!\n//! ```rust\n//!\n//! use const_format::{call_debug_fmt, formatc};\n//!\n//! // Positional argument\n//! assert_eq!(formatc!(\"{}\", |fmt| fmt.write_ascii_repeated(b'a', 4) ), \"aaaa\");\n//!\n//! // Named argument\n//! assert_eq!(formatc!(\"{foo}\", foo = |fmt| fmt.write_ascii_repeated(b'0', 10) ), \"0000000000\");\n//!\n//! // Repeating a positional argument multiple times\n//! assert_eq!(formatc!(\"{0}{0}{0}\", |fmt| fmt.write_str(\"hi\") ), \"hihihi\");\n//!\n//! // Using debug formatting is no different to display formatting:\n//! assert_eq!(formatc!(\"{0:?}{0:?}{0:?}\", |fmt| fmt.write_str(\"hi\") ), \"hihihi\");\n//!\n//! // But binary/hex formatting, and the alternate flag, do have an effect:\n//! assert_eq!(\n//!     formatc!(\n//!         \"{0}\\n{0:x}\\n{0:X}\\n{0:b}\\n{0:#x}\\n{0:#X}\\n{0:#b}\",\n//!         |fmt| call_debug_fmt!(array, [3u8, 13], fmt),\n//!     ),\n//!     \"\\\n//!         [3, 13]\\n\\\n//!         [3, d]\\n\\\n//!         [3, D]\\n\\\n//!         [11, 1101]\\n\\\n//!         [\\n    0x3,\\n    0xd,\\n]\\n\\\n//!         [\\n    0x3,\\n    0xD,\\n]\\n\\\n//!         [\\n    0b11,\\n    0b1101,\\n]\\\n//!     \",\n//! );\n//!\n//! ```\n//!\n//!\n//! [`writec`]: ../macro.writec.html\n//! [`Formatter`]: ./struct.Formatter.html\n//! [`FormatMarker`]: ../marker_traits/trait.FormatMarker.html\n//! [`ConstDebug`]: ../derive.ConstDebug.html\n//!\n//!\n//!\n//!\n//!\n\nmod error;\nmod formatter;\nmod std_type_impls;\nmod str_writer;\nmod str_writer_mut;\n\npub use crate::formatting::{FormattingFlags, NumberFormatting};\n\npub use self::{\n    error::{Error, Result, ToResult},\n    formatter::{ComputeStrLength, DebugList, DebugSet, DebugStruct, DebugTuple, Formatter},\n    str_writer::StrWriter,\n    str_writer_mut::{NoEncoding, StrWriterMut, Utf8Encoding},\n};\n"
  },
  {
    "path": "const_format/src/for_assert_macros.rs",
    "content": "#![allow(non_fmt_panics)]\n\nuse crate::pargument::PArgument;\n\n#[track_caller]\npub const fn assert_(cond: bool, message: &'static str) {\n    if cond {\n        panic!(\"{}\", message)\n    }\n}\n\n// The `T` type parameter is there just so that the PARGUMENTS associated constant\n// is evaluated lazily.\npub trait ConcatArgsIf<T, const COND: bool> {\n    const PARGUMENTS: &'static [PArgument];\n}\n\nimpl<S, T> ConcatArgsIf<T, false> for S {\n    const PARGUMENTS: &'static [PArgument] = &[];\n}\n"
  },
  {
    "path": "const_format/src/for_examples.rs",
    "content": "//! Types for the documentation examples.\n//!\n//! # Features\n//!\n//! This module is only exported with the \"fmt\" feature\n\nuse crate::{Error, Formatter, PWrapper};\n\n/// An example struct which implements const debug formatting.\n#[derive(Debug, Copy, Clone)]\npub struct Point3 {\n    ///\n    pub x: u32,\n    ///\n    pub y: u32,\n    ///\n    pub z: u32,\n}\n\nimpl_fmt! {\n    impl Point3;\n\n    ///\n    pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {\n        let mut f = f.debug_struct(\"Point3\");\n        try_!(PWrapper(self.x).const_debug_fmt(f.field(\"x\")));\n        try_!(PWrapper(self.y).const_debug_fmt(f.field(\"y\")));\n        try_!(PWrapper(self.z).const_debug_fmt(f.field(\"z\")));\n        f.finish()\n    }\n\n    ///\n    pub const fn const_eq(&self, other: &Self) -> bool {\n        self.x == other.x &&\n        self.y == other.y &&\n        self.z == other.z\n    }\n}\n\n/// An example unit struct which implements const debug formatting.\n#[derive(Debug, Copy, Clone)]\npub struct Unit;\n\nimpl_fmt! {\n    impl Unit;\n\n    ///\n    pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {\n        f.debug_struct(\"Unit\").finish()\n    }\n\n    ///\n    pub const fn const_eq(&self, _other: &Self) -> bool {\n        true\n    }\n}\n"
  },
  {
    "path": "const_format/src/formatting.rs",
    "content": "#[doc(hidden)]\n#[derive(Debug, Copy, Clone, PartialEq, Eq)]\npub enum Formatting {\n    Debug,\n    Display,\n}\n\nimpl Formatting {\n    /// Whether the current variant is `Display`\n    #[inline(always)]\n    pub const fn is_display(self) -> bool {\n        matches!(self, Formatting::Display)\n    }\n}\n\n/// How numbers are formatted in debug formatters.\n///\n/// Hexadecimal or binary formatting in the formatting string from this crate imply\n/// debug formatting.\n///\n///\n#[derive(Debug, Copy, Clone, PartialEq, Eq)]\npub enum NumberFormatting {\n    /// Formats numbers as decimal\n    Decimal,\n    /// Formats numbers as hexadecimal\n    Hexadecimal,\n    /// Formats numbers as binary\n    Binary,\n}\n\n#[doc(hidden)]\n#[derive(Debug, Copy, Clone, PartialEq, Eq)]\n#[repr(u8)]\npub enum HexFormatting {\n    // micro-optimization\n    // by having these values for the discriminants,\n    // going from a number greater than 9 and smaller than 16\n    // to their ascii digits is as simple as `number + (hex_fmt as u8)`\n    Upper = b'A' - 10,\n    Lower = b'a' - 10,\n}\n\nimpl NumberFormatting {\n    #[cfg(test)]\n    #[cfg(feature = \"fmt\")]\n    pub(crate) const ALL: &'static [Self; 3] = &[\n        NumberFormatting::Decimal,\n        NumberFormatting::Hexadecimal,\n        NumberFormatting::Binary,\n    ];\n}\n\n////////////////////////////////////////////////////////////////////////////////\n\n/// This type bundles configuration for how to format data into strings, including.\n///\n/// # Number formatting\n///\n/// How numbers are formatted in debug formatters,\n/// It can be accessed with the `num_fmt` method, and set with the `set_num_fmt` method.\n///\n/// Each type of number formatting corresponds to a [`NumberFormatting`] variant:\n///\n/// - `NumberFormatting::Decimal` (eg: `formatc!(\"{:?}\", FOO)`):\n/// formats numbers as decimal.\n///\n/// - `NumberFormatting::Hexadecimal`  (eg: `formatc!(\"{:x}\", FOO)`):\n/// formats numbers as hexadecimal.\n///\n/// - `NumberFormatting::Binary` (eg: `formatc!(\"{:b}\", FOO)`):\n/// formats numbers as binary.\n///\n/// Hexadecimal or binary formatting in the formatting string from this crate imply\n/// debug formatting,\n/// and can be used to for example print an array of binary numbers.\n///\n/// Note: Lowercase hexadecimal formatting requires calling the\n/// [`set_lower_hexadecimal`](#method.set_lower_hexadecimal) method.\n///\n/// # Alternate flag\n///\n/// A flag that types can use to be formatted differently when it's enabled,\n/// checked with the `.is_alternate()` method.\n///\n/// The default behavior when it is enabled is this:\n///\n/// - The Debug formater (eg: `formatc!(\"{:#?}\", FOO)`):\n/// pretty print structs and enums.\n///\n/// - The hexadecimal formater (eg: `formatc!(\"{:#x}\", FOO)`):\n/// prefixes numbers with `0x`.\n///\n/// - The binary formater (eg: `formatc!(\"{:#b}\", FOO)`):\n/// prefixes numbers with `0b`.`\n///\n/// [`Formatter`]: ./struct.Formatter.html\n///\n#[must_use]\n#[derive(Debug, Copy, Clone)]\npub struct FormattingFlags {\n    num_fmt: NumberFormatting,\n    // Whether the `NumberFormatting` prints hexadecimal digits in lowercase\n    // (e.g: 0xf00, 0xF00)\n    //\n    // move this in 0.3.0 to `NumberFormatting`.\n    hex_fmt: HexFormatting,\n    is_alternate: bool,\n}\n\n#[doc(hidden)]\nimpl FormattingFlags {\n    pub const __REG: Self = Self::NEW.set_alternate(false).set_decimal();\n    pub const __HEX: Self = Self::NEW.set_alternate(false).set_hexadecimal();\n    pub const __LOWHEX: Self = Self::NEW.set_alternate(false).set_lower_hexadecimal();\n    pub const __BIN: Self = Self::NEW.set_alternate(false).set_binary();\n\n    pub const __A_REG: Self = Self::NEW.set_alternate(true).set_decimal();\n    pub const __A_HEX: Self = Self::NEW.set_alternate(true).set_hexadecimal();\n    pub const __A_LOWHEX: Self = Self::NEW.set_alternate(true).set_lower_hexadecimal();\n    pub const __A_BIN: Self = Self::NEW.set_alternate(true).set_binary();\n}\nimpl FormattingFlags {\n    #[doc(hidden)]\n    pub const DEFAULT: Self = Self {\n        num_fmt: NumberFormatting::Decimal,\n        hex_fmt: HexFormatting::Upper,\n        is_alternate: false,\n    };\n\n    /// Constructs a `FormattingFlags` with these values:\n    ///\n    /// - number formatting: NumberFormatting::Decimal\n    ///\n    /// - is alternate: false\n    ///\n    pub const NEW: Self = Self {\n        num_fmt: NumberFormatting::Decimal,\n        hex_fmt: HexFormatting::Upper,\n        is_alternate: false,\n    };\n\n    /// Constructs a `FormattingFlags` with these values:\n    ///\n    /// - number formatting: NumberFormatting::Decimal\n    ///\n    /// - is alternate: false\n    ///\n    #[inline]\n    pub const fn new() -> Self {\n        Self::NEW\n    }\n\n    /// Sets the integer formatting,\n    ///\n    /// This usually doesn't affect the outputted text in display formatting.\n    #[inline]\n    pub const fn set_num_fmt(mut self, num_fmt: NumberFormatting) -> Self {\n        self.num_fmt = num_fmt;\n        self\n    }\n\n    /// Sets the number formatting to `NumberFormatting::Decimal`.\n    ///\n    /// This means that numbers are written as decimal.\n    #[inline]\n    pub const fn set_decimal(mut self) -> Self {\n        self.num_fmt = NumberFormatting::Decimal;\n        self\n    }\n\n    /// Sets the number formatting to `NumberFormatting::Hexadecimal`.\n    ///\n    /// This means that numbers are written as uppercase hexadecimal.\n    #[inline]\n    pub const fn set_hexadecimal(mut self) -> Self {\n        self.num_fmt = NumberFormatting::Hexadecimal;\n        self.hex_fmt = HexFormatting::Upper;\n        self\n    }\n\n    /// Sets the number formatting to `NumberFormatting::Hexadecimal`,\n    /// and uses lowercase for alphabetic hexadecimal digits.\n    ///\n    /// This means that numbers are written as lowercase hexadecimal.\n    #[inline]\n    pub const fn set_lower_hexadecimal(mut self) -> Self {\n        self.num_fmt = NumberFormatting::Hexadecimal;\n        self.hex_fmt = HexFormatting::Lower;\n        self\n    }\n\n    /// Sets the number formatting to `NumberFormatting::Binary`.\n    ///\n    /// This means that numbers are written as binary.\n    #[inline]\n    pub const fn set_binary(mut self) -> Self {\n        self.num_fmt = NumberFormatting::Binary;\n        self\n    }\n\n    /// Sets whether the formatting flag is enabled.\n    #[inline]\n    pub const fn set_alternate(mut self, is_alternate: bool) -> Self {\n        self.is_alternate = is_alternate;\n        self\n    }\n\n    /// Gets the current `NumberFormatting`.\n    #[inline]\n    pub const fn num_fmt(self) -> NumberFormatting {\n        self.num_fmt\n    }\n\n    /// Gets whether the alternate flag is enabled\n    #[inline]\n    pub const fn is_alternate(self) -> bool {\n        self.is_alternate\n    }\n\n    pub(crate) const fn hex_fmt(self) -> HexFormatting {\n        self.hex_fmt\n    }\n}\n\n////////////////////////////////////////////////////////////////////////////////\n\n#[doc(hidden)]\n/// For writing into an array from the start\npub struct LenAndArray<T: ?Sized> {\n    /// The amount of elements written in `array`\n    pub len: usize,\n    pub array: T,\n}\n\n#[doc(hidden)]\n/// For writing into an array from the end\npub struct StartAndArray<T: ?Sized> {\n    /// The first element in `array`\n    pub start: usize,\n    pub array: T,\n}\n\n////////////////////////////////////////////////////////////////////////////////\n\n#[doc(hidden)]\npub struct ForEscaping {\n    pub is_escaped: u128,\n    pub is_backslash_escaped: u128,\n    pub escape_char: [u8; 16],\n}\n\nimpl ForEscaping {\n    /// Gets the backslash escape for a character that is kwown to be escaped with a backslash.\n    #[inline(always)]\n    pub const fn get_backslash_escape(b: u8) -> u8 {\n        FOR_ESCAPING.escape_char[(b & 0b1111) as usize]\n    }\n}\n\n#[doc(hidden)]\n/// Converts 0..=0xF to its ascii representation of '0'..='9' and 'A'..='F'\n#[inline(always)]\npub const fn hex_as_ascii(n: u8, hex_fmt: HexFormatting) -> u8 {\n    if n < 10 {\n        n + b'0'\n    } else {\n        n + (hex_fmt as u8)\n    }\n}\n\n#[doc(hidden)]\n// Really clippy? Array indexing can panic you know.\n#[allow(clippy::no_effect)]\npub const FOR_ESCAPING: &ForEscaping = {\n    let mut is_backslash_escaped = 0;\n\n    let escaped = [\n        (b'\\t', b't'),\n        (b'\\n', b'n'),\n        (b'\\r', b'r'),\n        (b'\\'', b'\\''),\n        (b'\"', b'\"'),\n        (b'\\\\', b'\\\\'),\n    ];\n\n    // Using the fact that the characters above all have different bit patterns for\n    // the lowest 4 bits.\n    let mut escape_char = [0u8; 16];\n\n    __for_range! {i in 0..escaped.len() =>\n        let (code, escape) = escaped[i];\n        is_backslash_escaped |= 1 << code;\n\n        let ei = (code & 0b1111) as usize;\n        let prev_escape = escape_char[ei] as usize;\n        [\"Oh no, some escaped character uses the same 4 lower bits as another\"][prev_escape];\n        escape_char[ei] = escape;\n    }\n\n    // Setting all the control characters as being escaped.\n    let is_escaped = is_backslash_escaped | 0xFFFF_FFFF;\n\n    &ForEscaping {\n        escape_char,\n        is_backslash_escaped,\n        is_escaped,\n    }\n};\n"
  },
  {
    "path": "const_format/src/lib.rs",
    "content": "//! Compile-time string formatting.\n//!\n//! This crate provides types and macros for formatting strings at compile-time.\n//!\n//! # Rust versions\n//!\n//! There are some features that require a variety of Rust versions,\n//! the sections below describe the features that are available for each version.\n//!\n//! ### Rust 1.71.0\n//!\n//! These macros are available in Rust 1.71.0:\n//!\n//! - [`concatcp`]:\n//! Concatenates `integers`, `bool`, `char`, and `&str` constants into a `&'static str` constant.\n//!\n//! - [`formatcp`]:\n//! [`format`]-like formatting which takes `integers`, `bool`, `char`, and `&str` constants,\n//! and emits a `&'static str` constant.\n//!\n//! - [`str_get`]:\n//! Indexes a `&'static str` constant, returning `None` when the index is out of bounds.\n//!\n//! - [`str_index`]:\n//! Indexes a `&'static str` constant.\n//!\n//! - [`str_repeat`]:\n//! Creates a `&'static str` by repeating a `&'static str` constant `times` times.\n//!\n//! - [`str_splice`]:\n//! Replaces a substring in a `&'static str` constant.\n//!\n//! - [`map_ascii_case`]:\n//! Converts a `&'static str` constant to a different casing style,\n//! determined by a [`Case`] argument.\n//!\n//! - [`str_replace`]:\n//! Replaces all the instances of a pattern in a `&'static str` constant with\n//! another `&'static str` constant.\n//!\n//! - [`str_split`]:\n//! Splits a string constant\n//!\n//! The `\"assertcp\"` feature enables the [`assertcp`], [`assertcp_eq`],\n//! and [`assertcp_ne`] macros.\n//! These macros are like the standard library assert macros,\n//! but evaluated at compile-time,\n//! with the limitation that they can only have primitive types as arguments\n//! (just like [`concatcp`] and [`formatcp`]).\n//!\n//! ### Rust 1.83.0\n//!\n//! By enabling the \"fmt\" feature, you can use a [`std::fmt`]-like API.\n//!\n//! This requires Rust 1.83.0, because it uses mutable references in const fn.\n//!\n//! All the other features of this crate are implemented on top of the [`const_format::fmt`] API:\n//!\n//! - [`concatc`]:\n//! Concatenates many standard library and user defined types into a `&'static str` constant.\n//!\n//! - [`formatc`]:\n//! [`format`]-like macro that can format many standard library and user defined types into\n//! a `&'static str` constant.\n//!\n//! - [`writec`]:\n//! [`write`]-like macro that can format many standard library and user defined types\n//! into a type that implements [`WriteMarker`].\n//!\n//! The `\"derive\"` feature enables the [`ConstDebug`] macro,\n//! and the `\"fmt\"` feature.<br>\n//! [`ConstDebug`] derives the [`FormatMarker`] trait,\n//! and implements an inherent `const_debug_fmt` method for compile-time debug formatting.\n//!\n//! The `\"assertc\"` feature enables the [`assertc`], [`assertc_eq`], [`assertc_ne`] macros,\n//! and the `\"fmt\"` feature.<br>\n//! These macros are like the standard library assert macros, but evaluated at compile-time.\n//!\n//! # Examples\n//!\n//! ### Concatenation of primitive types\n//!\n//! ```rust\n//! use const_format::concatcp;\n//!\n//! const NAME: &str = \"Bob\";\n//! const FOO: &str = concatcp!(NAME, \", age \", 21u8,\"!\");\n//!\n//! assert_eq!(FOO, \"Bob, age 21!\");\n//! ```\n//!\n//! ### Formatting primitive types\n//!\n//! ```rust\n//! use const_format::formatcp;\n//!\n//! const NAME: &str = \"John\";\n//!\n//! const FOO: &str = formatcp!(\"{NAME}, age {}!\", compute_age(NAME));\n//!\n//! assert_eq!(FOO, \"John, age 24!\");\n//!\n//! # const fn compute_age(s: &str) -> usize { s.len() * 6 }\n//!\n//! ```\n//!\n//! ### Formatting custom types\n//!\n//! This example demonstrates how you can use the [`ConstDebug`] derive macro,\n//! and then format the type into a `&'static str` constant.\n//!\n//! This example requires the `\"derive\"` feature\n//! and Rust 1.83.0, because it uses `&mut` in a const context.\n//!\n#![cfg_attr(feature = \"derive\", doc = \"```rust\")]\n#![cfg_attr(not(feature = \"derive\"), doc = \"```ignore\")]\n//!\n//! use const_format::{ConstDebug, formatc};\n//!\n//! #[derive(ConstDebug)]\n//! struct Message{\n//!     ip: [Octet; 4],\n//!     value: &'static str,\n//! }\n//!\n//! #[derive(ConstDebug)]\n//! struct Octet(u8);\n//!\n//! const MSG: Message = Message{\n//!     ip: [Octet(127), Octet(0), Octet(0), Octet(1)],\n//!     value: \"Hello, World!\",\n//! };\n//!\n//! const FOO: &str = formatc!(\"{:?}\", MSG);\n//!\n//! assert_eq!(\n//!     FOO,\n//!     \"Message { ip: [Octet(127), Octet(0), Octet(0), Octet(1)], value: \\\"Hello, World!\\\" }\"\n//! );\n//!\n//! ```\n//!\n//! ### Formatted const assertions\n//!\n//! This example demonstrates how you can use the [`assertcp_ne`] macro to\n//! do compile-time inequality assertions with formatted error messages.\n//!\n//! This requires the `\"assertcp\"` feature.\n//!\n#![cfg_attr(feature = \"assertcp\", doc = \"```compile_fail\")]\n#![cfg_attr(not(feature = \"assertcp\"), doc = \"```ignore\")]\n//! use const_format::assertcp_ne;\n//!\n//! macro_rules! check_valid_pizza{\n//!     ($user:expr, $topping:expr) => {\n//!         assertcp_ne!(\n//!             $topping,\n//!             \"pineapple\",\n//!             \"You can't put pineapple on pizza, {}\",\n//!             $user,\n//!         );\n//!     }\n//! }\n//!\n//! check_valid_pizza!(\"John\", \"salami\");\n//! check_valid_pizza!(\"Dave\", \"sausage\");\n//! check_valid_pizza!(\"Bob\", \"pineapple\");\n//!\n//! # fn main(){}\n//! ```\n//!\n//! This is the compiler output:\n//!\n//! ```text\n//! error[E0080]: evaluation of constant value failed\n//!   --> src/lib.rs:178:27\n//!    |\n//! 20 | check_valid_pizza!(\"Bob\", \"pineapple\");\n//!    |                           ^^^^^^^^^^^ the evaluated program panicked at '\n//! assertion failed: `(left != right)`\n//!  left: `\"pineapple\"`\n//! right: `\"pineapple\"`\n//! You can't put pineapple on pizza, Bob\n//! ', src/lib.rs:20:27\n//!\n//!\n//! ```\n//!\n//! <div id=\"macro-limitations\"></div>\n//!\n//! # Limitations\n//!\n//! All of the macros from `const_format` have these limitations:\n//!\n//! - The formatting macros that expand to\n//! `&'static str`s can only use constants from concrete types,\n//! so while a `Type::<u8>::FOO` argument would be fine,\n//! `Type::<T>::FOO` would not be (`T` being a type parameter).\n//!\n//! - Integer arguments must have a type inferrable from context,\n//! [more details in the Integer arguments section](#integer-args).\n//!\n//! - They cannot be used places that take string literals.\n//! So `#[doc = \"foobar\"]` cannot be replaced with `#[doc = concatcp!(\"foo\", \"bar\") ]`.\n//!\n//! <span id=\"integer-args\"></span>\n//!\n//! ### Integer arguments\n//!\n//! Integer arguments must have a type inferrable from context.\n//! so if you only pass an integer literal it must have a suffix.\n//!\n//! Example of what does compile:\n//!\n//! ```rust\n//! const N: u32 = 1;\n//! assert_eq!(const_format::concatcp!(N + 1, 2 + N), \"23\");\n//!\n//! assert_eq!(const_format::concatcp!(2u32, 2 + 1u8, 3u8 + 1), \"234\");\n//! ```\n//!\n//! Example of what does not compile:\n//! ```compile_fail\n//! assert_eq!(const_format::concatcp!(1 + 1, 2 + 1), \"23\");\n//! ```\n//!\n//! # Renaming crate\n//!\n//! All function-like macros from `const_format` can be used when the crate is renamed.\n//!\n//! The [`ConstDebug`] derive macro has the `#[cdeb(crate = \"foo::bar\")]` attribute to\n//! tell it where to find the `const_format` crate.\n//!\n//! Example of renaming the `const_format` crate in the Cargo.toml file:\n//! ```toml\n//! [dependencies]\n//! cfmt = {version = \"0.*\", package = \"const_format\"}\n//! ```\n//!\n//! # Cargo features\n//!\n//! - `\"fmt\"`: Enables the [`std::fmt`]-like API and `\"rust_1_83\"` feature,\n//! requires Rust 1.83.0 because it uses mutable references in const fn.<br>\n//! This feature includes the [`formatc`]/[`writec`] formatting macros.\n//!\n//! - `\"derive\"`: requires Rust 1.83.0, implies the `\"fmt\"` feature,\n//! provides the [`ConstDebug`] derive macro to format user-defined types at compile-time.<br>\n//! This implicitly uses the `syn` crate, so clean compiles take a bit longer than without the feature.\n//!\n//! - `\"assertc\"`: requires Rust 1.83.0, implies the `\"fmt\"` feature,\n//! enables the [`assertc`], [`assertc_eq`], and [`assertc_ne`] assertion macros.<br>\n//! This feature was previously named `\"assert\"`,\n//! but it was renamed to avoid confusion with the `\"assertcp\"` feature.\n//!\n//! - `\"assertcp\"`:\n//! Enables the [`assertcp`], [`assertcp_eq`], and [`assertcp_ne`] assertion macros.\n//!\n//! - `\"rust_1_83\"`:\n//! Makes macros that evaluate to a value become compatible with [inline const patterns].\n//!\n//! # No-std support\n//!\n//! `const_format` is unconditionally `#![no_std]`, it can be used anywhere Rust can be used.\n//!\n//! # Minimum Supported Rust Version\n//!\n//! `const_format` requires Rust 1.71.0.\n//!\n//! Features that require newer versions of Rust, or the nightly compiler,\n//! need to be explicitly enabled with cargo features.\n//!\n//!\n//! [`assertc`]: ./macro.assertc.html\n//!\n//! [`assertc_eq`]: ./macro.assertc_eq.html\n//!\n//! [`assertc_ne`]: ./macro.assertc_ne.html\n//!\n//! [`assertcp`]: ./macro.assertcp.html\n//!\n//! [`assertcp_eq`]: ./macro.assertcp_eq.html\n//!\n//! [`assertcp_ne`]: ./macro.assertcp_ne.html\n//!\n//! [`concatcp`]: ./macro.concatcp.html\n//!\n//! [`formatcp`]: ./macro.formatcp.html\n//!\n//! [`format`]: https://doc.rust-lang.org/std/macro.format.html\n//!\n//! [`std::fmt`]: https://doc.rust-lang.org/std/fmt/index.html\n//!\n//! [`const_format::fmt`]: ./fmt/index.html\n//!\n//! [`concatc`]: ./macro.concatc.html\n//!\n//! [`formatc`]: ./macro.formatc.html\n//!\n//! [`writec`]: ./macro.writec.html\n//!\n//! [`write`]: https://doc.rust-lang.org/std/macro.write.html\n//!\n//! [`Formatter`]: ./fmt/struct.Formatter.html\n//!\n//! [`StrWriter`]: ./fmt/struct.StrWriter.html\n//!\n//! [`ConstDebug`]: ./derive.ConstDebug.html\n//!\n//! [`FormatMarker`]: ./marker_traits/trait.FormatMarker.html\n//!\n//! [`WriteMarker`]: ./marker_traits/trait.WriteMarker.html\n//!\n//! [`map_ascii_case`]: ./macro.map_ascii_case.html\n//!\n//! [`Case`]: ./enum.Case.html\n//!\n//!\n//! [`str_get`]: ./macro.str_get.html\n//!\n//! [`str_index`]: ./macro.str_index.html\n//!\n//! [`str_repeat`]: ./macro.str_repeat.html\n//!\n//! [`str_splice`]: ./macro.str_splice.html\n//!\n//! [`str_replace`]: ./macro.str_replace.html\n//!\n//! [`str_split`]: ./macro.str_split.html\n//!\n//! [`str::replace`]: https://doc.rust-lang.org/std/primitive.str.html#method.replace\n//!\n//! [inline const patterns]: https://doc.rust-lang.org/1.83.0/unstable-book/language-features/inline-const-pat.html\n//!\n#![no_std]\n#![cfg_attr(feature = \"__docsrs\", feature(doc_cfg))]\n#![deny(rust_2018_idioms)]\n// This lint is silly\n#![allow(clippy::blacklisted_name)]\n// This lint is silly\n#![allow(clippy::needless_doctest_main)]\n#![deny(clippy::missing_safety_doc)]\n#![deny(clippy::shadow_unrelated)]\n#![deny(clippy::wildcard_imports)]\n// All The methods that take self by value are for small Copy types\n#![allow(clippy::wrong_self_convention)]\n#![allow(clippy::init_numbered_fields)]\n#![deny(missing_docs)]\n\ninclude! {\"const_debug_derive.rs\"}\n\n#[macro_use]\nmod macros;\n\nmod formatting;\n\n#[cfg(feature = \"assertc\")]\nmod equality;\n\n#[doc(hidden)]\n#[cfg(feature = \"assertcp\")]\n#[macro_use]\npub mod for_assert_macros;\n\nmod char_encoding;\n\nmod pargument;\n\nmod const_generic_concatcp;\n\n#[cfg_attr(feature = \"__docsrs\", doc(cfg(feature = \"fmt\")))]\n#[cfg(feature = \"fmt\")]\npub mod utils;\n\n#[doc(hidden)]\n#[cfg(any(feature = \"fmt\", feature = \"assertcp\"))]\nmod slice_cmp;\n\n#[doc(hidden)]\npub mod __hidden_utils;\n\n#[cfg_attr(feature = \"__docsrs\", doc(cfg(feature = \"fmt\")))]\n#[cfg(feature = \"fmt\")]\npub mod for_examples;\n\n#[cfg_attr(feature = \"__docsrs\", doc(cfg(feature = \"fmt\")))]\n#[cfg(feature = \"fmt\")]\npub mod marker_traits;\n\n#[cfg(feature = \"__test\")]\npub mod test_utils;\n\n#[cfg(feature = \"__test\")]\n#[allow(missing_docs)]\npub mod doctests;\n\n#[cfg_attr(feature = \"__docsrs\", doc(cfg(feature = \"fmt\")))]\n#[cfg(feature = \"fmt\")]\npub mod fmt;\n\n#[cfg(feature = \"fmt\")]\n#[doc(hidden)]\npub mod msg;\n\n#[cfg_attr(feature = \"__docsrs\", doc(cfg(feature = \"fmt\")))]\n#[cfg_attr(not(feature = \"fmt\"), doc(hidden))]\npub mod wrapper_types;\n\n#[doc(hidden)]\npub mod __ascii_case_conv;\n\n#[doc(hidden)]\npub mod __str_methods;\n\npub use __str_methods::SplicedStr;\n\npub use __ascii_case_conv::Case;\n\n#[cfg(feature = \"fmt\")]\n#[doc(no_inline)]\npub use crate::fmt::{Error, Formatter, FormattingFlags, Result, StrWriter, StrWriterMut};\n\n#[cfg(feature = \"fmt\")]\npub use crate::wrapper_types::ascii_str::AsciiStr;\n\n#[cfg(feature = \"fmt\")]\npub use crate::wrapper_types::sliced::Sliced;\n\n#[cfg_attr(not(feature = \"fmt\"), doc(hidden))]\npub use crate::wrapper_types::pwrapper::PWrapper;\n\n#[doc(hidden)]\n#[allow(non_snake_case)]\npub mod __cf_osRcTFl4A {\n    pub use crate::*;\n}\n\n#[doc(hidden)]\npub mod pmr {\n    pub use {bool, str, u8, usize};\n\n    pub use const_format_proc_macros::{__concatcp_impl, __formatcp_impl, respan_to};\n\n    #[cfg(feature = \"fmt\")]\n    pub use const_format_proc_macros::{__formatc_if_impl, __formatc_impl, __writec_impl};\n\n    #[cfg(feature = \"assertcp\")]\n    pub use const_format_proc_macros::__formatcp_if_impl;\n\n    pub use core::{\n        cmp::Reverse,\n        convert::identity,\n        mem::transmute,\n        num::Wrapping,\n        ops::Range,\n        option::Option::{self, None, Some},\n        result::Result::{self, Err, Ok},\n    };\n\n    pub use crate::const_generic_concatcp::__priv_concatenate;\n\n    #[cfg(feature = \"assertcp\")]\n    pub use crate::for_assert_macros::{assert_, ConcatArgsIf};\n\n    #[cfg(feature = \"fmt\")]\n    pub use crate::{\n        fmt::{ComputeStrLength, Error, Formatter, StrWriter, StrWriterMut, ToResult},\n        marker_traits::{\n            FormatMarker, IsAFormatMarker, IsAWriteMarker, IsNotStdKind, IsStdKind, WriteMarker,\n        },\n    };\n\n    pub use crate::{\n        formatting::{\n            hex_as_ascii, ForEscaping, Formatting, FormattingFlags, HexFormatting, LenAndArray,\n            NumberFormatting, StartAndArray, FOR_ESCAPING,\n        },\n        pargument::{PArgument, PConvWrapper, PVariant},\n        wrapper_types::PWrapper,\n    };\n\n    #[doc(hidden)]\n    #[repr(transparent)]\n    pub struct __AssertStr {\n        pub x: &'static str,\n    }\n\n    #[doc(hidden)]\n    #[repr(transparent)]\n    pub struct __AssertType<T> {\n        pub x: T,\n    }\n}\n\n#[cfg(all(feature = \"__test\", feature = \"derive\", feature = \"assertcp\"))]\nidentity! {\n    #[doc = include_str!(\"../../README.md\")]\n    pub struct ReadmeTest;\n}\n\n#[cfg(all(test, not(feature = \"__test\")))]\ncompile_error! { \"tests must be run with the \\\"__test\\\" feature\" }\n"
  },
  {
    "path": "const_format/src/macros/assertions/assertc_macros.rs",
    "content": "macro_rules! with_shared_docs {(\n    $(#[$before_clarification:meta])*\n    ;clarification\n    $(#[$before_syntax:meta])*\n    ;syntax\n    $(#[$after_syntax:meta])*\n    ;error_message\n    $(#[$after_error_message:meta])*\n    ;limitations\n    $item:item\n) => (\n    $(#[$before_clarification])*\n    ///\n    /// This macro requires the `\"assertc\"` feature to be exported.\n    ///\n    $(#[$before_syntax])*\n    ///\n    /// This macro uses [the same syntax](./fmt/index.html#fmtsyntax)\n    /// for the format string and supports the same formatting arguments as the\n    /// [`formatc`] macro.\n    ///\n    $(#[$after_syntax])*\n    $(#[$after_error_message])*\n    /// # Limitations\n    ///\n    /// This macro has these limitations:\n    ///\n    /// - It can only use constants that involve concrete types,\n    /// so while a `Type::<u8>::FOO` in an argument would be fine,\n    /// `Type::<T>::FOO` would not be (`T` being a type parameter).\n    ///\n    /// - Integer arguments must have a type inferrable from context,\n    /// [as described in the integer arguments section in the root module\n    /// ](./index.html#integer-args).\n    ///\n    /// [`PWrapper`]: ./struct.PWrapper.html\n    /// [`formatc`]: ./macro.formatc.html\n    /// [`FormatMarker`]: ./marker_traits/trait.FormatMarker.html\n    ///\n    $item\n)}\n\n////////////////////////////////////////////////////////////////////////////////\n\nwith_shared_docs! {\n    /// Compile-time assertions with formatting.\n    ///\n    ;clarification\n    ;syntax\n    ;error_message\n    ;limitations\n    ///\n    /// # Examples\n    ///\n    /// ### Passing assertion\n    ///\n    /// ```rust\n    ///\n    /// use const_format::assertc;\n    ///\n    /// use std::mem::size_of;\n    ///\n    /// assertc!(\n    ///     size_of::<&str>() == size_of::<&[u8]>(),\n    ///     \"The size of `&str`({} bytes) and `&[u8]`({} bytes) aren't the same?!?!\",\n    ///     size_of::<&str>(),\n    ///     size_of::<&[u8]>(),\n    /// );\n    ///\n    /// # fn main(){}\n    /// ```\n    ///\n    /// ### Failing assertion\n    ///\n    /// This example demonstrates a failing assertion,\n    /// and how the compiler error looks like as of 2023-10-14.\n    ///\n    /// ```compile_fail\n    ///\n    /// use const_format::assertc;\n    ///\n    /// const L: u64 = 2;\n    /// const R: u64 = 2;\n    ///\n    /// assertc!(L + R == 5, \"{} plus {} isn't 5, buddy\", L,  R);\n    ///\n    /// # fn main(){}\n    /// ```\n    ///\n    /// This is the compiler output:\n    ///\n    /// ```text\n    /// error[E0080]: evaluation of constant value failed\n    ///   --> const_format/src/macros/assertions/assertc_macros.rs:109:10\n    ///    |\n    /// 11 | assertc!(L + R == 5, \"{} plus {} isn't 5, buddy\", L,  R);\n    ///    |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at '\n    /// assertion failed.\n    /// 2 plus 2 isn't 5, buddy\n    /// ', const_format/src/macros/assertions/assertc_macros.rs:11:10\n    /// ```\n    ///\n    #[cfg_attr(feature = \"__docsrs\", doc(cfg(feature = \"assertc\")))]\n    #[macro_export]\n    macro_rules! assertc {\n        ($($parameters:tt)*) => (\n            $crate::__assertc_inner!{\n                __formatc_if_impl\n                ($($parameters)*)\n                ($($parameters)*)\n            }\n        );\n    }\n}\n\n////////////////////////////////////////////////////////////////////////////////\n\nmacro_rules! assert_eq_docs {\n    (\n        $(#[$documentation:meta])*\n        ;documentation\n        $item:item\n    ) => (\n        with_shared_docs! {\n            $(#[$documentation])*\n            ;clarification\n            /// # Arguments\n            ///\n            /// This macro accepts these types for comparison and debug printing:\n            ///\n            /// - Standard library types for which  [`PWrapper`] wrapping that type\n            /// has a `const_eq` method.\n            /// This includes all integer types, `&str`, slices/arrays of integers/`&str`,\n            /// Options of integers/`&str`, etc.\n            ///\n            /// - non-standard-library types that implement [`FormatMarker`] with debug formatting<br>\n            /// and have a `const fn const_eq(&self, other:&Self) -> bool` inherent method,\n            ///\n            ;syntax\n            ;error_message\n            ;limitations\n            $item\n        }\n    )\n}\n\nassert_eq_docs! {\n    /// Compile-time equality assertion with formatting.\n    ///\n    ;documentation\n    ///\n    /// # Examples\n    ///\n    /// ### Passing assertion\n    ///\n    /// ```rust\n    ///\n    /// use const_format::assertc_eq;\n    ///\n    /// use std::mem::size_of;\n    ///\n    /// assertc_eq!(size_of::<usize>(), size_of::<[usize;1]>());\n    ///\n    /// const TWO: u32 = 2;\n    /// assertc_eq!(TWO, TWO, \"Oh no {} doesn't equal itself!!\", TWO);\n    ///\n    /// # fn main(){}\n    /// ```\n    ///\n    /// ### Failing assertion\n    ///\n    /// This example demonstrates a failing assertion,\n    /// and how the compiler error looks like as of 2023-10-14.\n    ///\n    /// ```compile_fail\n    ///\n    /// use const_format::assertc_eq;\n    ///\n    /// use std::mem::size_of;\n    ///\n    /// assertc_eq!(size_of::<u32>(), size_of::<u8>());\n    ///\n    /// # fn main(){}\n    /// ```\n    ///\n    /// This is the compiler output:\n    ///\n    /// ```text\n    /// error[E0080]: evaluation of constant value failed\n    ///   --> const_format/src/macros/assertions/assertc_macros.rs:222:13\n    ///    |\n    /// 10 | assertc_eq!(size_of::<u32>(), size_of::<u8>());\n    ///    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at '\n    /// assertion failed: `(left == right)`\n    ///  left: `4`\n    /// right: `1`', const_format/src/macros/assertions/assertc_macros.rs:10:13\n    /// ```\n    ///\n    /// ### Comparing user-defined types\n    ///\n    /// This example demonstrates how you can assert that two values of a\n    /// user-defined type are equal.\n    ///\n    #[cfg_attr(feature = \"derive\", doc = \"```compile_fail\")]\n    #[cfg_attr(not(feature = \"derive\"), doc = \"```ignore\")]\n    ///\n    /// use const_format::{Formatter, PWrapper};\n    /// use const_format::{ConstDebug, assertc_eq, try_};\n    ///\n    /// const POINT: Point = Point{ x: 5, y: 8, z: 13 };\n    /// const OTHER_POINT: Point = Point{ x: 21, y: 34, z: 55 };\n    ///\n    /// assertc_eq!(POINT, OTHER_POINT);\n    ///\n    /// #[derive(ConstDebug)]\n    /// pub struct Point {\n    ///     pub x: u32,\n    ///     pub y: u32,\n    ///     pub z: u32,\n    /// }\n    ///\n    /// impl Point {\n    ///     pub const fn const_eq(&self, other: &Self) -> bool {\n    ///         self.x == other.x &&\n    ///         self.y == other.y &&\n    ///         self.z == other.z\n    ///     }\n    /// }\n    /// ```\n    ///\n    /// This is the compiler output:\n    ///\n    /// ```text\n    /// error[E0080]: evaluation of constant value failed\n    ///   --> src/macros/assertions.rs:331:14\n    ///    |\n    /// 12 |  assertc_eq!(POINT, OTHER_POINT);\n    ///    |              ^^^^^^^^^^^^^^^^^^ the evaluated program panicked at '\n    /// assertion failed: `(left == right)`\n    ///  left: `Point {\n    ///     x: 5,\n    ///     y: 8,\n    ///     z: 13,\n    /// }`\n    /// right: `Point {\n    ///     x: 21,\n    ///     y: 34,\n    ///     z: 55,\n    /// }`', src/macros/assertions.rs:12:14\n    ///\n    /// error: aborting due to previous error\n    ///\n    /// ```\n    ///\n    #[cfg_attr(feature = \"__docsrs\", doc(cfg(feature = \"assertc\")))]\n    #[macro_export]\n    macro_rules! assertc_eq {\n        ($($parameters:tt)*) => (\n            $crate::__assertc_equality_inner!{\n                ($($parameters)*)\n                ($($parameters)*)\n                ( == )\n                (\"==\")\n            }\n        );\n    }\n}\n\nassert_eq_docs! {\n    /// Compile-time inequality assertion with formatting.\n    ///\n    ;documentation\n    ///\n    /// # Examples\n    ///\n    /// ### Passing assertion\n    ///\n    /// ```rust\n    ///\n    /// use const_format::assertc_ne;\n    ///\n    /// use std::mem::size_of;\n    ///\n    /// assertc_ne!(size_of::<u32>(), size_of::<[u32; 2]>());\n    ///\n    /// const TWO: u32 = 2;\n    /// const THREE: u32 = 3;\n    /// assertc_ne!(TWO, THREE, \"Oh no {} somehow equals {}!!\", TWO, THREE);\n    ///\n    /// # fn main(){}\n    /// ```\n    ///\n    /// ### Failing assertion\n    ///\n    /// This example demonstrates a failing assertion,\n    /// and how the compiler error looks like as of 2023-10-14.\n    ///\n    /// ```compile_fail\n    ///\n    /// use const_format::assertc_ne;\n    ///\n    /// use std::mem::size_of;\n    ///\n    /// type Foo = u32;\n    ///\n    /// assertc_ne!(size_of::<u32>(), size_of::<Foo>());\n    ///\n    /// # fn main(){}\n    /// ```\n    ///\n    /// This is the compiler output:\n    ///\n    /// ```text\n    /// error[E0080]: evaluation of constant value failed\n    ///   --> const_format/src/macros/assertions/assertc_macros.rs:350:13\n    ///    |\n    /// 12 | assertc_ne!(size_of::<u32>(), size_of::<Foo>());\n    ///    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at '\n    /// assertion failed: `(left != right)`\n    ///  left: `4`\n    /// right: `4`', const_format/src/macros/assertions/assertc_macros.rs:12:13\n    /// ```\n    ///\n    /// ### Comparing user-defined types\n    ///\n    /// This example demonstrates how you can assert that two values of a\n    /// user-defined type are unequal.\n    ///\n    #[cfg_attr(feature = \"derive\", doc = \"```compile_fail\")]\n    #[cfg_attr(not(feature = \"derive\"), doc = \"```ignore\")]\n    ///\n    /// use const_format::{Formatter, PWrapper};\n    /// use const_format::{ConstDebug, assertc_ne, try_};\n    ///\n    /// const POINT: Point = Point{ x: 5, y: 8, z: 13 };\n    ///\n    /// assertc_ne!(POINT, POINT);\n    ///\n    /// #[derive(ConstDebug)]\n    /// pub struct Point {\n    ///     pub x: u32,\n    ///     pub y: u32,\n    ///     pub z: u32,\n    /// }\n    ///\n    /// impl Point {\n    ///     pub const fn const_eq(&self, other: &Self) -> bool {\n    ///         self.x == other.x &&\n    ///         self.y == other.y &&\n    ///         self.z == other.z\n    ///     }\n    /// }\n    /// ```\n    ///\n    /// This is the compiler output:\n    ///\n    /// ```text\n    /// error[E0080]: evaluation of constant value failed\n    ///   --> src/macros/assertions.rs:451:14\n    ///    |\n    /// 11 |  assertc_ne!(POINT, POINT);\n    ///    |              ^^^^^^^^^^^^ the evaluated program panicked at '\n    /// assertion failed: `(left != right)`\n    ///  left: `Point {\n    ///     x: 5,\n    ///     y: 8,\n    ///     z: 13,\n    /// }`\n    /// right: `Point {\n    ///     x: 5,\n    ///     y: 8,\n    ///     z: 13,\n    /// }`', src/macros/assertions.rs:11:14\n    ///\n    /// error: aborting due to previous error\n    ///\n    /// ```\n    ///\n    #[cfg_attr(feature = \"__docsrs\", doc(cfg(feature = \"assertc\")))]\n    #[macro_export]\n    macro_rules! assertc_ne {\n        ($($parameters:tt)*) => (\n            $crate::__assertc_equality_inner!{\n                ($($parameters)*)\n                ($($parameters)*)\n                ( != )\n                (\"!=\")\n            }\n        );\n    }\n}\n\n#[doc(hidden)]\n#[macro_export]\nmacro_rules! __assertc_equality_inner {\n    (\n        ($($parameters:tt)*)\n        (\n            $left:expr,\n            $right:expr\n            $(, $fmt_literal:expr $(,$fmt_arg:expr)*)? $(,)?\n        )\n        ($($op:tt)*)\n        ($op_str:expr)\n    )=>{\n        const _: () = {\n            use $crate::__cf_osRcTFl4A;\n            use $crate::pmr::respan_to as __cf_respan_to;\n\n            const LEFT: $crate::pmr::bool = {\n                // Have to use `respan_to` to make the `multiple coerce found` error\n                // point at the `$left` argument here.\n                use $crate::coerce_to_fmt as __cf_coerce_to_fmt;\n                match [&$left, &$right] {\n                    __cf_respan_to!(($left) [left, right]) =>\n                        __cf_respan_to!(($left) __cf_coerce_to_fmt!(left).const_eq(right)),\n                }\n            };\n            const RIGHT: $crate::pmr::bool = true;\n\n            $crate::__assertc_common!{\n                __formatc_if_impl\n                ($($parameters)*)\n                (LEFT $($op)* RIGHT)\n                (\n                    concat!(\n                        \"\\nassertion failed: `(left \",\n                        $op_str,\n                        \" right)`\\n\",\n                        \" left: `{left_NHPMWYD3NJA:#?}`\\n\\\n                         right: `{right_NHPMWYD3NJA:#?}`\",\n                        $(\"\\n\", $fmt_literal, \"\\n\")?\n                    ),\n                    $($($fmt_arg,)*)?\n                    left_NHPMWYD3NJA = $left,\n                    right_NHPMWYD3NJA = $right\n                )\n            }\n        };\n    }\n}\n"
  },
  {
    "path": "const_format/src/macros/assertions/assertcp_macros.rs",
    "content": "macro_rules! with_shared_docs {(\n    $(#[$before_clarification:meta])*\n    ;clarification\n    $(#[$before_syntax:meta])*\n    ;syntax\n    $(#[$after_syntax:meta])*\n    ;limitations\n    $item:item\n) => (\n    $(#[$before_clarification])*\n    ///\n    /// [For **examples** look here](#examples)\n    ///\n    /// This macro requires the `\"assertcp\"` feature to be exported.<br>\n    ///\n    $(#[$before_syntax])*\n    /// # Syntax\n    ///\n    /// This macro uses the same syntax\n    /// for the format string and formatting arguments as the\n    /// [`formatcp`](crate::formatcp) macro.\n    ///\n    $(#[$after_syntax])*\n    /// # Limitations\n    ///\n    /// This macro can only take constants of these types as arguments:\n    ///\n    /// - `&str`\n    ///\n    /// - `i*`/`u*` (all the primitive integer types).\n    ///\n    /// - `char`\n    ///\n    /// - `bool`\n    ///\n    /// This macro also has these limitations:\n    ///\n    /// - It can only use constants that involve concrete types,\n    /// so while a `Type::<u8>::FOO` in an argument would be fine,\n    /// `Type::<T>::FOO` would not be (`T` being a type parameter).\n    ///\n    /// - Integer arguments must have a type inferrable from context,\n    /// [as described in the integer arguments section in the root module\n    /// ](./index.html#integer-args).\n    ///\n    $item\n)}\n\nwith_shared_docs! {\n    /// Compile-time assertion with formatting.\n    ///\n    ;clarification\n    ;syntax\n    ;limitations\n    ///\n    /// # Examples\n    ///\n    /// ### Passing assertion\n    ///\n    /// ```rust\n    /// use const_format::assertcp;\n    ///\n    /// use std::mem::align_of;\n    ///\n    /// assertcp!(\n    ///     align_of::<&str>() == align_of::<usize>(),\n    ///     \"The alignment of `&str`({} bytes) and `usize`({} bytes) isn't the same?!?!\",\n    ///     align_of::<&str>(),\n    ///     align_of::<usize>(),\n    /// );\n    ///\n    /// # fn main(){}\n    /// ```\n    ///\n    /// ### Failing assertion\n    ///\n    /// This example demonstrates a failing assertion,\n    /// and how the compiler error looks like as of 2023-10-14.\n    ///\n    /// ```compile_fail\n    /// use const_format::assertcp;\n    ///\n    /// const L: u64 = 2;\n    /// const R: u32 = 5;\n    ///\n    /// assertcp!(L.pow(R) == 64, \"{L} to the {R} isn't 64, it's {}\", L.pow(R));\n    ///\n    /// # fn main(){}\n    /// ```\n    ///\n    /// This is the compiler output:\n    ///\n    /// ```text\n    /// error[E0080]: evaluation of constant value failed\n    ///  --> const_format/src/macros/assertions/assertcp_macros.rs:116:11\n    ///   |\n    /// 9 | assertcp!(L.pow(R) == 64, \"{L} to the {R} isn't 64, it's {}\", L.pow(R));\n    ///   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at '\n    /// assertion failed.\n    /// 2 to the 5 isn't 64, it's 32\n    /// ', const_format/src/macros/assertions/assertcp_macros.rs:9:11\n    ///\n    /// ```\n    ///\n    #[cfg_attr(feature = \"__docsrs\", doc(cfg(feature = \"assertcp\")))]\n    #[macro_export]\n    macro_rules! assertcp {\n        ($($parameters:tt)*) => (\n            $crate::__assertc_inner!{\n                __formatcp_if_impl\n                ($($parameters)*)\n                ($($parameters)*)\n            }\n        );\n    }\n}\n\n#[doc(hidden)]\n#[macro_export]\nmacro_rules! __assertcp_equality_inner {\n    (\n        ($($parameters:tt)*)\n        (\n            $left:expr,\n            $right:expr\n            $(, $fmt_literal:expr $(,$fmt_arg:expr)*)? $(,)?\n        )\n        ($($op:tt)*)\n        ($op_str:expr)\n    )=>{\n        #[allow(non_snake_case)]\n        const _: () = {\n            use $crate::__cf_osRcTFl4A;\n            const ARGS_NHPMWYD3NJA:\n                ($crate::pmr::bool, $crate::pmr::PArgument, $crate::pmr::PArgument)\n            = {\n                let left = $crate::PWrapper($left);\n                let right = $crate::pmr::PConvWrapper($right);\n                let cond = left.const_eq(&right.0);\n                let fmt = $crate::pmr::FormattingFlags::NEW.set_alternate(true);\n                (\n                    cond,\n                    $crate::pmr::PConvWrapper(left.0).to_pargument_debug(fmt),\n                    right.to_pargument_debug(fmt),\n                )\n            };\n\n            $crate::__assertc_common!{\n                __formatcp_if_impl\n                ($($parameters)*)\n                (ARGS_NHPMWYD3NJA.0 $($op)* true)\n                (\n                    concat!(\n                        \"\\nassertion failed: `(left \",\n                        $op_str,\n                        \" right)`\\n\",\n                        \" left: `{left_NHPMWYD3NJA:#?}`\\n\\\n                         right: `{right_NHPMWYD3NJA:#?}`\",\n                        $(\"\\n\", $fmt_literal, \"\\n\")?\n                    ),\n                    $($($fmt_arg,)*)?\n                    left_NHPMWYD3NJA = ARGS_NHPMWYD3NJA.1,\n                    right_NHPMWYD3NJA = ARGS_NHPMWYD3NJA.2\n                )\n            }\n        };\n    }\n}\n\nwith_shared_docs! {\n    /// Compile-time equality assertion with formatting.\n    ///\n    ;clarification\n    ;syntax\n    ;limitations\n    ///\n    /// # Examples\n    ///\n    /// ### Passing assertion\n    ///\n    /// ```rust\n    /// use const_format::assertcp_eq;\n    ///\n    /// const NAME: &str = \"Bob\";\n    ///\n    /// assertcp_eq!(NAME, \"Bob\", \"Guessed wrong, the right value is {}\", NAME);\n    ///\n    /// const SUM: u8 = 1 + 2 + 3;\n    /// assertcp_eq!(6u8, SUM, \"Guessed wrong, the right value is {}\", SUM);\n    /// ```\n    ///\n    /// ### Failing assertion\n    ///\n    /// This example demonstrates a failing assertion,\n    /// and how the compiler error looks like as of 2023-10-14.\n    ///\n    /// ```compile_fail\n    /// use const_format::assertcp_eq;\n    ///\n    /// use std::mem::size_of;\n    ///\n    /// #[repr(C)]\n    /// struct Type(u16, u16, u16);\n    ///\n    /// assertcp_eq!(size_of::<Type>(), size_of::<[u16; 2]>(), \"Whoops, `Type` is too large\");\n    ///\n    /// ```\n    ///\n    /// This is the compiler output:\n    ///\n    /// ```text\n    /// error[E0080]: evaluation of constant value failed\n    ///   --> const_format/src/macros/assertions/assertcp_macros.rs:235:14\n    ///    |\n    /// 12 | assertcp_eq!(size_of::<Type>(), size_of::<[u16; 2]>(), \"Whoops, `Type` is too large\");\n    ///    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at '\n    /// assertion failed: `(left == right)`\n    ///  left: `6`\n    /// right: `4`\n    /// Whoops, `Type` is too large\n    /// ', const_format/src/macros/assertions/assertcp_macros.rs:12:14\n    ///\n    /// ```\n    ///\n    #[cfg_attr(feature = \"__docsrs\", doc(cfg(feature = \"assertcp\")))]\n    #[macro_export]\n    macro_rules! assertcp_eq {\n        ($($parameters:tt)*) => (\n            $crate::__assertcp_equality_inner!{\n                ($($parameters)*)\n                ($($parameters)*)\n                ( == )\n                (\"==\")\n            }\n        );\n    }\n}\nwith_shared_docs! {\n    /// Compile-time inequality assertion with formatting.\n    ///\n    ;clarification\n    ;syntax\n    ;limitations\n    ///\n    /// # Examples\n    ///\n    /// ### Passing assertion\n    ///\n    /// ```rust\n    /// use const_format::assertcp_ne;\n    ///\n    /// assertcp_ne!(std::mem::size_of::<usize>(), 1usize, \"Oh no, usize is tiny!\");\n    ///\n    /// const CHAR: char = ';';\n    /// assertcp_ne!(CHAR, '.', \"CHAR must not be a dot!\");\n    /// ```\n    ///\n    /// ### Failing assertion\n    ///\n    /// This example demonstrates a failing assertion,\n    /// and how the compiler error looks like as of 2023-10-14.\n    ///\n    /// ```compile_fail\n    /// use const_format::assertcp_ne;\n    ///\n    /// const NAME: &str = \"\";\n    /// assertcp_ne!(NAME, \"\", \"NAME must not be empty!\");\n    ///\n    /// ```\n    ///\n    /// This is the compiler output:\n    ///\n    /// ```text\n    /// error[E0080]: evaluation of constant value failed\n    ///  --> const_format/src/macros/assertions/assertcp_macros.rs:297:14\n    ///   |\n    /// 8 | assertcp_ne!(NAME, \"\", \"NAME must not be empty!\");\n    ///   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at '\n    /// assertion failed: `(left != right)`\n    ///  left: `\"\"`\n    /// right: `\"\"`\n    /// NAME must not be empty!\n    /// ', const_format/src/macros/assertions/assertcp_macros.rs:8:14\n    /// ```\n    ///\n    #[cfg_attr(feature = \"__docsrs\", doc(cfg(feature = \"assertcp\")))]\n    #[macro_export]\n    macro_rules! assertcp_ne {\n        ($($parameters:tt)*) => (\n            $crate::__assertcp_equality_inner!{\n                ($($parameters)*)\n                ($($parameters)*)\n                ( != )\n                (\"!=\")\n            }\n        );\n    }\n}\n"
  },
  {
    "path": "const_format/src/macros/assertions.rs",
    "content": "#[cfg(feature = \"assertc\")]\nmod assertc_macros;\n\n#[cfg(feature = \"assertcp\")]\nmod assertcp_macros;\n\n#[doc(hidden)]\n#[macro_export]\nmacro_rules! __assertc_inner {\n    (\n        $fmt_macro:ident\n        ($($parameters:tt)*)\n        ($cond:expr $(, $fmt_literal:expr $(,$fmt_arg:expr)*)? $(,)?)\n    ) => {\n        #[allow(non_snake_case)]\n        const _: () = {\n            use $crate::__cf_osRcTFl4A;\n\n            $crate::__assertc_common!{\n                $fmt_macro\n                ($($parameters)*)\n                ($cond)\n                (\n                    concat!(\n                        \"\\nassertion failed.\\n\",\n                        $($fmt_literal,)?\n                        \"\\n\",\n                    )\n                    $($(,$fmt_arg)*)?\n                )\n            }\n        };\n    }\n}\n\n#[doc(hidden)]\n#[macro_export]\nmacro_rules! __assertc_common {\n    (\n        $fmt_macro:ident\n        ($($span:tt)*)\n        ($cond:expr)\n        ($($fmt_literal:expr $(,$fmt_arg:expr)*)?)\n    ) => (\n        const PANIC_IF_TRUE_NHPMWYD3NJA: bool = !($cond);\n\n        const MSG_NHPMWYD3NJA: &str = $crate::pmr::$fmt_macro!(\n            (PANIC_IF_TRUE_NHPMWYD3NJA)\n            ($($fmt_literal,)?),\n            $($($fmt_arg,)*)?\n        );\n\n        __cf_osRcTFl4A::pmr::respan_to!{\n            ($($span)*)\n            __cf_osRcTFl4A::pmr::assert_(PANIC_IF_TRUE_NHPMWYD3NJA, MSG_NHPMWYD3NJA)\n        }\n    );\n}\n"
  },
  {
    "path": "const_format/src/macros/call_debug_fmt.rs",
    "content": "/// For debug formatting of some specific generic std types, and other types.\n///\n/// # Errors\n///\n/// This macro propagates errors from the debug formatting methods that\n/// it calls, by `return`ing them.\n///\n/// # Macro variants\n///\n/// The macro has these variants:\n///\n/// - `slice` (also `array`): to format a slice or an array of *any debug type.\n///\n/// - `Option`: to format an `Option` of *any debug type.\n///\n/// - `newtype`: to format a single field tuple struct (eg: `struct Foo(Bar);`)\n/// which wraps *any debug type.\n///\n/// - `std`: to format the standard library types, where `PWrapper<ThatType>`\n/// has a `const_debug_fmt` method.<br>\n///\n/// - `other`: to format non-standard-library types that have a `const_debug_fmt` method.\n///\n/// *\"any debug type\" meaning types that have a `const_debug_fmt` method\n///\n/// # Example\n///\n/// ### Printing all of them\n///\n/// Printing all of the kinds of types this supports.\n///\n/// ```rust\n///\n/// use const_format::{\n///     for_examples::{Point3, Unit},\n///     Error, Formatter, FormattingFlags, StrWriter,\n///     call_debug_fmt, try_, unwrap,\n/// };\n///\n/// use std::num::Wrapping;\n///\n/// const CAP: usize = 512;\n///\n/// // `call_debug_fmt` implicitly returns on error,\n/// // so the function has to return a `Result<_, const_format::Error>`\n/// const fn make() -> Result<StrWriter<[u8; CAP]>, Error> {\n///     let mut writer = StrWriter::new([0; CAP]);\n///     let mut fmt = Formatter::from_sw(&mut writer, FormattingFlags::NEW);\n///     let mut fmt = fmt.debug_struct(\"Foo\");\n///\n///     let point = Point3{ x: 5, y: 8, z: 13 };\n///\n///     call_debug_fmt!(array, [Unit, Unit], fmt.field(\"array\") );\n///     call_debug_fmt!(slice, [0u8, 1], fmt.field(\"slice\") );\n///     call_debug_fmt!(Option, Some(point), fmt.field(\"option\") );\n///     call_debug_fmt!(newtype NumWrapping, Wrapping(255u16), fmt.field(\"newtype\") );\n///     call_debug_fmt!(std, false, fmt.field(\"std_\") );\n///     call_debug_fmt!(other, point, fmt.field(\"other\") );\n///\n///     try_!(fmt.finish());\n///     Ok(writer)\n/// }\n///\n/// const TEXT: &str = {\n///     const PROM: &StrWriter<[u8]> = &unwrap!(make());\n///     PROM.as_str()\n/// };\n///\n/// const EXPECTED: &str = \"\\\n///     Foo { \\\n///         array: [Unit, Unit], \\\n///         slice: [0, 1], \\\n///         option: Some(Point3 { x: 5, y: 8, z: 13 }), \\\n///         newtype: NumWrapping(255), \\\n///         std_: false, \\\n///         other: Point3 { x: 5, y: 8, z: 13 } \\\n///     }\\\n/// \";\n///\n/// assert_eq!(TEXT, EXPECTED);\n///\n/// ```\n///\n/// ### Used as `formatc` argument\n///\n/// This macro can be used in the formatting macros by using the Formatter in the argument,<br>\n/// with the `|formatter_ident| expression_that_uses_formatter ` syntax.\n///\n///\n/// ```rust\n///\n/// use const_format::{\n///     for_examples::{Point3, Unit},\n///     Error, Formatter, FormattingFlags, StrWriter,\n///     call_debug_fmt, formatc, try_, unwrap,\n/// };\n///\n/// use std::num::Wrapping;\n///\n/// const POINT: Point3 = Point3{ x: 5, y: 8, z: 13 };\n///\n/// const TEXT: &str = formatc!(\n///     \"a: {},b: {},c: {},d: {},e: {},f: {},\",\n///     |fmt| call_debug_fmt!(array, [Unit, Unit], fmt ),\n///     |fmt| call_debug_fmt!(slice, [0u8, 1], fmt ),\n///     |fmt| call_debug_fmt!(Option, Some(POINT), fmt ),\n///     |fmt| call_debug_fmt!(newtype NumWrapping, Wrapping(255u16), fmt ),\n///     |fmt| call_debug_fmt!(std, false, fmt ),\n///     |fmt| call_debug_fmt!(other, POINT, fmt ),\n/// );\n///\n/// const EXPECTED: &str = \"\\\n///     a: [Unit, Unit],\\\n///     b: [0, 1],\\\n///     c: Some(Point3 { x: 5, y: 8, z: 13 }),\\\n///     d: NumWrapping(255),\\\n///     e: false,\\\n///     f: Point3 { x: 5, y: 8, z: 13 },\\\n/// \";\n///\n/// assert_eq!(TEXT, EXPECTED);\n///\n/// # Ok::<(), const_format::Error>(())\n/// ```\n///\n#[cfg_attr(feature = \"__docsrs\", doc(cfg(feature = \"fmt\")))]\n#[macro_export]\nmacro_rules! call_debug_fmt {\n    (array, $expr:expr, $formatter:expr $(,)* ) => {{\n        match (&$expr, $formatter.borrow_mutably()) {\n            (expr, formatter) => {\n                let mut n = 0;\n                let len = expr.len();\n                let mut f = formatter.debug_list();\n                while n != len {\n                    $crate::__call_debug_fmt_dispatch!(&expr[n], f.entry());\n                    n += 1;\n                }\n                $crate::try_!(f.finish());\n            }\n        }\n    }};\n    (slice, $expr:expr, $formatter:expr $(,)*) => {\n        $crate::call_debug_fmt!(array, $expr, $formatter)\n    };\n    (Option, $expr:expr, $formatter:expr $(,)*) => {{\n        match $formatter.borrow_mutably() {\n            formatter => $crate::try_!(match &$expr {\n                $crate::pmr::Some(x) => {\n                    let mut f = formatter.debug_tuple(\"Some\");\n                    $crate::__call_debug_fmt_dispatch!(x, f.field());\n                    f.finish()\n                }\n                $crate::pmr::None => formatter.write_str(\"None\"),\n            }),\n        }\n    }};\n    (newtype $name:ident, $expr:expr, $formatter:expr $(,)*) => {\n        match (&$expr, $formatter.borrow_mutably()) {\n            (newtype_, formatter) => {\n                let mut f = formatter.debug_tuple(stringify!($name));\n                $crate::__call_debug_fmt_dispatch!(&newtype_.0, f.field());\n                $crate::try_!(f.finish());\n            }\n        }\n    };\n    (std, $expr:expr, $formatter:expr $(,)*) => {\n        if let Err(e) = $crate::coerce_to_fmt!(&$expr).const_debug_fmt($formatter) {\n            return Err(e);\n        }\n    };\n    (other, $expr:expr, $formatter:expr $(,)*) => {\n        if let Err(e) = $expr.const_debug_fmt($formatter) {\n            return Err(e);\n        }\n    };\n}\n\n#[doc(hidden)]\n#[macro_export]\nmacro_rules! __call_debug_fmt_dispatch {\n    ($e:expr, $f:expr) => {\n        if let Err(e) = $crate::coerce_to_fmt!(&$e).const_debug_fmt($f) {\n            return Err(e);\n        }\n    };\n}\n"
  },
  {
    "path": "const_format/src/macros/constructors.rs",
    "content": "/// Constructs an [`AsciiStr`] constant from an ascii string,\n///\n/// # Compile-time errors\n///\n/// This macro produces a compile-time error by indexing an empty array with\n/// the index of the first non-ascii byte.\n///\n/// # Example\n///\n/// ```rust\n/// use const_format::ascii_str;\n///\n/// let fooo = ascii_str!(\"hello\");\n///\n/// assert_eq!(fooo.as_str(), \"hello\");\n///\n/// // You can pass constants as arguments!\n/// const BAR_S: &str = \"world\";\n/// let bar = ascii_str!(BAR_S);\n///\n/// assert_eq!(bar.as_str(), \"world\");\n///\n/// ```\n///\n/// ```compile_fail\n/// use const_format::ascii_str;\n///\n/// let fooo = ascii_str!(\"Γειά σου Κόσμε!\");\n///\n/// ```\n///\n/// [`AsciiStr`]: ./struct.AsciiStr.html\n///\n#[cfg_attr(feature = \"__docsrs\", doc(cfg(feature = \"fmt\")))]\n#[cfg(feature = \"fmt\")]\n#[macro_export]\nmacro_rules! ascii_str {\n    ($str:expr $(,)*) => {{\n        const __CF_ASCII_STR_CONSTANT: $crate::AsciiStr<'static> = {\n            match $crate::AsciiStr::new($str.as_bytes()) {\n                Ok(x) => x,\n                $crate::pmr::Err(e) => [][e.invalid_from],\n            }\n        };\n        __CF_ASCII_STR_CONSTANT\n    }};\n}\n"
  },
  {
    "path": "const_format/src/macros/fmt_macros.rs",
    "content": "/// Concatenates constants of primitive types into a `&'static str`.\n///\n/// Each argument is stringified after evaluating it, so `concatcp!(1u8 + 3) == \"4\"`\n///\n/// [For **examples** look here](#examples)\n///\n/// `concatcp` stands for \"concatenate constants (of) primitives\"\n///\n/// # Limitations\n///\n/// This macro can only take constants of these types as inputs:\n///\n/// - `&str`\n///\n/// - `i*`/`u*` (all the primitive integer types).\n///\n/// - `char`\n///\n/// - `bool`\n///\n/// This macro also shares\n/// [the limitations described in here](./index.html#macro-limitations)\n/// as well.\n///\n/// # Examples\n///\n/// ### Literal arguments\n///\n///\n/// ```rust\n/// use const_format::concatcp;\n///\n/// const MSG: &str = concatcp!(2u8, \"+\", 2u8, '=', 2u8 + 2);\n///\n/// assert_eq!(MSG, \"2+2=4\");\n///\n/// ```\n///\n/// ### `const` arguments\n///\n/// ```rust\n/// use const_format::concatcp;\n///\n/// const PASSWORD: &str = \"password\";\n///\n/// const fn times() -> u64 { 10 }\n///\n/// const MSG: &str =\n///     concatcp!(\"The password is \\\"\", PASSWORD, \"\\\", you can only guess \", times(), \" times.\");\n///\n/// assert_eq!(MSG, r#\"The password is \"password\", you can only guess 10 times.\"#);\n///\n/// ```\n///\n#[macro_export]\nmacro_rules! concatcp {\n    ()=>{\"\"};\n    ($($arg: expr),* $(,)?)=>(\n        $crate::__str_const! {{\n            use $crate::__cf_osRcTFl4A;\n            $crate::pmr::__concatcp_impl!{\n                $( ( $arg ), )*\n            }\n        }}\n    );\n}\n\n#[doc(hidden)]\n#[macro_export]\nmacro_rules! __concatcp_inner {\n    ($variables:expr) => {{\n        #[doc(hidden)]\n        const ARR_LEN: usize = $crate::pmr::PArgument::calc_len($variables);\n\n        #[doc(hidden)]\n        const CONCAT_ARR: &$crate::pmr::LenAndArray<[u8; ARR_LEN]> =\n            &$crate::pmr::__priv_concatenate($variables);\n\n        #[doc(hidden)]\n        #[allow(clippy::transmute_ptr_to_ptr)]\n        const CONCAT_STR: &str = unsafe {\n            // This transmute truncates the length of the array to the amound of written bytes.\n            let slice =\n                $crate::pmr::transmute::<&[u8; ARR_LEN], &[u8; CONCAT_ARR.len]>(&CONCAT_ARR.array);\n\n            $crate::__priv_transmute_bytes_to_str!(slice)\n        };\n        CONCAT_STR\n    }};\n}\n\n////////////////////////////////////////////////////////////////////////////////\n\n/// Formats constants of primitive types into a `&'static str`\n///\n/// [For **examples** look here](#examples)\n///\n/// `formatcp` stands for \"format constants (of) primitives\"\n///\n/// # Syntax\n///\n/// This macro uses a limited version of the syntax from the standard library [`format`] macro,\n/// it can do these things:\n///\n/// - Take positional arguments: `formatcp!(\"{}{0}\", \"hello\" )`\n///\n/// - Take named arguments: `formatcp!(\"{a}{a}\", a = \"hello\" )`\n///\n/// - Use constants from scope as arguments: `formatcp!(\"{FOO}\")`<br>\n/// equivalent to the [`format_args_implicits` RFC]\n///\n/// - Use Debug-like formatting (eg: `formatcp!(\"{:?}\", \"hello\" )`:<br>\n/// Similar to how `Debug` formatting in the standard library works,\n/// except that it does not escape unicode characters.\n///\n/// - Use LowerHex formatting (eg: `formatcp!(\"{:x}\", \"hello\" )`):<br>\n/// Formats numbers as lowercase hexadecimal.\n/// The alternate version (written as `\"{:#x}\"`) prefixes the number with `0x`\n///\n/// - Use UpperHex formatting (eg: `formatcp!(\"{:X}\", \"hello\" )`):<br>\n/// Formats numbers as capitalized hexadecimal.\n/// The alternate version (written as `\"{:#X}\"`) prefixes the number with `0x`\n///\n/// - Use Binary formatting (eg: `formatcp!(\"{:b}\", \"hello\" )`)<br>\n/// The alternate version (written as `\"{:#b}\"`) prefixes the number with `0b`\n///\n/// - Use Display formatting: `formatcp!(\"{}\", \"hello\" )`\n///\n///\n/// # Limitations\n///\n/// This macro can only take constants of these types as inputs:\n///\n/// - `&str`\n///\n/// - `i*`/`u*` (all the primitive integer types).\n///\n/// - `char`\n///\n/// - `bool`\n///\n/// This macro also shares\n/// [the limitations described in here](./index.html#macro-limitations)\n/// as well.\n///\n/// # Formating behavior\n///\n/// ### Debug-like\n///\n/// The `{:?}` formatter formats things similarly to how Debug does it.\n///\n/// For `&'static str` it does these things:\n/// - Prepend and append the double quote character (`\"`).\n/// - Escape the `'\\t'`,`'\\n'`,`'\\r'`,`'\\\\'`, `'\\''`, and`'\\\"'` characters.\n/// - Escape control characters with `\\xYY`,\n/// where `YY` is the hexadecimal value of the control character.\n///\n/// Example:\n/// ```\n/// use const_format::formatcp;\n///\n/// assert_eq!(formatcp!(\"{:?}\", r#\" \\ \" ó \"#), r#\"\" \\\\ \\\" ó \"\"#);\n/// ```\n///\n/// For `char` it does these things:\n/// - Prepend and append the single quote character (`'`).\n/// - Uses the same escapes as `&'static str`.\n///\n/// ### Display\n///\n/// The `{}`/`{:}` formatter produces the same output as in [`format`].\n///\n///\n/// # Examples\n///\n/// ### Implicit argument\n///\n/// ```rust\n/// use const_format::formatcp;\n///\n/// const NAME: &str = \"John\";\n///\n/// const MSG: &str = formatcp!(\"Hello {NAME}, your name is {} bytes long\", NAME.len());\n///\n/// assert_eq!(MSG, \"Hello John, your name is 4 bytes long\");\n///\n/// ```\n///\n/// ### Repeating arguments\n///\n/// ```rust\n/// use const_format::formatcp;\n///\n/// const MSG: &str = formatcp!(\"{0}{S}{0}{S}{0}\", \"SPAM\", S = \"   \");\n///\n/// assert_eq!(MSG, \"SPAM   SPAM   SPAM\");\n///\n/// ```\n///\n/// ### Debug-like and Display formatting\n///\n/// ```rust\n/// use const_format::formatcp;\n///\n/// {\n///     const TEXT: &str = r#\"hello \" \\ world\"#;\n///     const MSG: &str = formatcp!(\"{TEXT}____{TEXT:?}\");\n///    \n///     assert_eq!(MSG, r#\"hello \" \\ world____\"hello \\\" \\\\ world\"\"#);\n/// }\n/// {\n///     const CHARS: &str = formatcp!(\"{0:?} - {0} - {1} - {1:?}\", '\"', '👀');\n///    \n///     assert_eq!(CHARS, r#\"'\\\"' - \" - 👀 - '👀'\"#);\n/// }\n/// ```\n///\n/// ### Additional specifiers\n///\n/// `const_format` macros don't support width, fill, alignment, sign,\n/// or precision specifiers.\n///\n/// [`format`]: https://doc.rust-lang.org/std/macro.format.html\n///\n/// [`format_args_implicits` RFC]:\n/// https://github.com/rust-lang/rfcs/blob/master/text/2795-format-args-implicit-identifiers.md\n///\n///\n#[macro_export]\nmacro_rules! formatcp {\n    ($format_string:expr $( $(, $expr:expr )+ )? $(,)? ) => (\n        $crate::__str_const! {{\n            use $crate::__cf_osRcTFl4A;\n\n            $crate::pmr::__formatcp_impl!(\n                ($format_string)\n                $(, $($expr,)+)?\n            )\n        }}\n    );\n}\n\n////////////////////////////////////////////////////////////////////////////////\n\n/// Concatenates constants of standard library and/or user-defined types into a `&'static str`.\n///\n/// User defined types must implement the [`FormatMarker`] trait and\n/// and have a `const_display_fmt` method (as described in the trait) to be concatenated.\n///\n/// # Stable equivalent\n///\n/// For an equivalent macro which can be used in stable Rust,\n/// but can only concatenate primitive types,\n/// you can use the [`concatcp`](crate::concatcp) macro.\n///\n/// # Limitations\n///\n/// This macro has [the limitations described in here](./index.html#macro-limitations).\n///\n/// # Examples\n///\n/// ### With standard library types\n///\n/// ```rust\n///\n/// use const_format::concatc;\n///\n/// assert_eq!(concatc!(\"There is \", 99u8, \" monkeys!\"), \"There is 99 monkeys!\");\n///\n/// ```\n///\n/// ### With user-defined types\n///\n/// ```rust\n///\n/// use const_format::{Formatter, Sliced, concatc, impl_fmt};\n///\n/// const STRING: &str = \"foo bar baz\";\n///\n/// assert_eq!(concatc!(Sliced(STRING, 4..7), ' ', Foo), \"bar table\");\n///\n/// struct Foo;\n///\n/// impl_fmt!{\n///     impl Foo;\n///     const fn const_display_fmt(&self, fmt: &mut Formatter<'_>) -> const_format::Result {\n///         fmt.write_str(\"table\")\n///     }\n/// }\n/// ```\n///\n///\n/// [`FormatMarker`]: ./marker_traits/trait.FormatMarker.html\n///\n#[cfg_attr(feature = \"__docsrs\", doc(cfg(feature = \"fmt\")))]\n#[cfg(feature = \"fmt\")]\n#[macro_export]\nmacro_rules! concatc {\n    ()=>{\"\"};\n    ($($anything:tt)*)=>(\n        $crate::__str_const! {{\n            use $crate::__cf_osRcTFl4A;\n\n            $crate::__concatc_expr!(($($anything)*) ($($anything)*))\n            as &'static $crate::pmr::str\n        }}\n    )\n}\n\n#[doc(hidden)]\n#[cfg(feature = \"fmt\")]\n#[macro_export]\nmacro_rules! __concatc_expr {\n    (($($arg: expr),* $(,)?) ($($span:tt)*) )=>({\n        const fn fmt_NHPMWYD3NJA(\n            mut fmt: $crate::fmt::Formatter<'_>,\n        ) -> $crate::Result {\n            use $crate::coerce_to_fmt as __cf_coerce_to_fmt;\n            use $crate::pmr::respan_to as __cf_respan_to;\n            use $crate::try_ as __cf_try;\n\n            $({\n                let __cf_respan_to!(($arg) fmt) = &mut fmt;\n                __cf_respan_to!(($arg)\n                    __cf_try!(__cf_coerce_to_fmt!($arg).const_display_fmt(fmt))\n                );\n            })*\n\n            $crate::pmr::Ok(())\n        }\n\n        $crate::__concatc_inner!(fmt_NHPMWYD3NJA, true, $($span)*)\n    })\n}\n\n#[doc(hidden)]\n#[macro_export]\nmacro_rules! __concatc_inner {\n    ($debug_fmt_fn:ident, $cond:expr, $($span:tt)*) => {{\n        const fn len_nhpmwyd3nj() -> usize {\n            if $cond {\n                let mut strlen = __cf_osRcTFl4A::pmr::ComputeStrLength::new();\n                let fmt = strlen.make_formatter(__cf_osRcTFl4A::FormattingFlags::NEW);\n                match $debug_fmt_fn(fmt) {\n                    __cf_osRcTFl4A::pmr::Ok(()) => strlen.len(),\n                    __cf_osRcTFl4A::pmr::Err(_) => 0,\n                }\n            } else {\n                0\n            }\n        }\n\n        const LEN_NHPMWYD3NJA: usize = len_nhpmwyd3nj();\n\n        const fn str_writer_nhpmwyd3nja(\n        ) -> __cf_osRcTFl4A::msg::ErrorTupleAndStrWriter<[u8; LEN_NHPMWYD3NJA]> {\n            let mut writer = __cf_osRcTFl4A::pmr::StrWriter::new([0; LEN_NHPMWYD3NJA]);\n            let error = if $cond {\n                $debug_fmt_fn(__cf_osRcTFl4A::pmr::Formatter::from_sw(\n                    &mut writer,\n                    __cf_osRcTFl4A::FormattingFlags::NEW,\n                ))\n            } else {\n                __cf_osRcTFl4A::pmr::Ok(())\n            };\n\n            __cf_osRcTFl4A::msg::ErrorTupleAndStrWriter {\n                error: __cf_osRcTFl4A::msg::ErrorTuple::new(error, &writer),\n                writer,\n            }\n        }\n\n        const STR_WRITER_NHPMWYD3NJA: &__cf_osRcTFl4A::msg::ErrorTupleAndStrWriter<\n            [u8; LEN_NHPMWYD3NJA],\n        > = &str_writer_nhpmwyd3nja();\n\n        const _: __cf_osRcTFl4A::msg::Ok = <<__cf_osRcTFl4A::msg::ErrorPicker<\n            [(); STR_WRITER_NHPMWYD3NJA.error.error_variant],\n            [(); STR_WRITER_NHPMWYD3NJA.error.capacity],\n        > as __cf_osRcTFl4A::msg::ErrorAsType>::Type>::NEW;\n\n        const STR_NHPMWYD3NJA: &str = STR_WRITER_NHPMWYD3NJA.writer.unsize().as_str();\n\n        STR_NHPMWYD3NJA\n    }};\n}\n\n////////////////////////////////////////////////////////////////////////////////\n\n/// Formats constants of standard library and/or user-defined types into a `&'static str`.\n///\n/// User-defined types must implement the [`FormatMarker`] trait\n/// (as described in the docs for that trait) to be usable with this macro.\n///\n/// # Stable equivalent\n///\n/// For an equivalent macro which can be used in stable Rust,\n/// but can only format primitive types,\n/// you can use the [`formatcp`](crate::formatcp) macro.\n///\n/// # Syntax\n///\n/// This macro uses the syntax described in\n/// [the const_format::fmt module](./fmt/index.html#fmtsyntax)\n///\n/// # Limitations\n///\n/// This macro has [the limitations described in here](./index.html#macro-limitations).\n///\n/// # Example\n///\n/// ```rust\n///\n/// use const_format::for_examples::Point3;\n/// use const_format::formatc;\n///\n/// // Formatting a non-std struct.\n/// const POINT: &str = formatc!(\"{:?}\", Point3{x: 8, y: 13, z: 21});\n///\n/// // Formatting a number as decimal, hexadecimal, and binary\n/// const NUMBER: &str = formatc!(\"{0},{0:x},{0:b}\", 10u8);\n///\n/// // Formatting the numbers in an array as decimal, hexadecimal, and binary.\n/// // You can use the name of cnstants from scope, as well as named arguments.\n/// const ARR: &[u32] = &[9, 25];\n/// const ARRAY: &str = formatc!(\"{ARR:?},{ARR:X},{ARR:b}\");\n///\n///\n/// assert_eq!(POINT, \"Point3 { x: 8, y: 13, z: 21 }\");\n/// assert_eq!(NUMBER, \"10,a,1010\");\n/// assert_eq!(ARRAY, \"[9, 25],[9, 19],[1001, 11001]\");\n///\n/// ```\n///\n/// ### Custom formatting.\n///\n/// This example demonstrates how you can access the [`Formatter`] in arguments\n/// to do custom formatting.\n///\n/// For more details on this you can look\n/// [in the fmt module](./fmt/index.html#custom-formatting-section).\n///\n/// ```rust\n///\n/// use const_format::for_examples::Point3;\n/// use const_format::{formatc, try_};\n///\n/// const P: Point3 = Point3{x: 5, y: 13, z: 21};\n///\n/// const STR: &str = formatc!(\"{0};{0:#X};{0:#b}\", |fmt|{\n///     try_!(fmt.write_u32_debug(P.x));\n///     try_!(fmt.write_str(\" \"));\n///     try_!(fmt.write_u32_debug(P.y));\n///     try_!(fmt.write_char('.'));\n/// });\n///\n/// assert_eq!(STR, \"5 13.;0x5 0xD.;0b101 0b1101.\");\n///\n/// ```\n/// [`Formatter`]: crate::fmt::Formatter\n/// [`FormatMarker`]: crate::marker_traits::FormatMarker\n///\n///\n#[macro_export]\n#[cfg_attr(feature = \"__docsrs\", doc(cfg(feature = \"fmt\")))]\n#[cfg(feature = \"fmt\")]\nmacro_rules! formatc {\n    ($format_string:expr $( $(, $expr:expr )+ )? $(,)? ) => (\n        $crate::__str_const! {{\n            use $crate::__cf_osRcTFl4A;\n\n            $crate::pmr::__formatc_impl!{\n                ($format_string)\n                $(, $($expr,)+)?\n            }\n        }}\n    );\n}\n\n/// Writes some formatted standard library and/or user-defined types into a buffer.\n///\n/// This macro evaluates to a `Result<(), const_format::Error>` which must be handled.\n///\n/// # Syntax\n///\n/// The syntax is similar to that of other formatting macros in this crate:\n///\n/// ```ignore\n/// ẁritec!(\n///     writer_expression,\n///     \"formatting literal\",\n///     positional_arg_0_expression,\n///     positional_arg_1_expression,\n///     named_arg_foo = expression,\n///     named_arg_bar = expression,\n/// )\n/// ```\n///\n/// The syntax is otherwise the same as described in\n/// [the `const_format::fmt` module](./fmt/index.html#fmtsyntax).\n///\n/// # Writers\n///\n/// The first argument must be a type that implements the [`WriteMarker`] trait,\n/// and has these inherent methods:\n/// ```ignore\n/// const fn borrow_mutably(&mut self) -> &mut Self\n/// const fn make_formatter(&mut self, flags: FormattingFlags) -> Formatter<'_>\n/// ```\n///\n/// [This example](#custom-writable-example) below shows how to use this macro\n/// with a custom type.\n///\n/// # Limitations\n///\n/// Integer arguments must have a type inferrable from context,\n/// [more details in the Integer arguments section](./index.html#integer-args).\n///\n/// # Examples\n///\n/// ### Ẁriting a Display impl.\n///\n/// ```\n///\n/// use const_format::{Error, Formatter, StrWriter};\n/// use const_format::{impl_fmt, try_, writec};\n///\n/// pub struct Foo(u32, &'static str);\n///\n/// impl_fmt!{\n///     impl Foo;\n///     pub const fn const_display_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {\n///         try_!(writec!(f, \"{},\", self.0));\n///         try_!(writec!(f, \"{:?};\", self.1));\n///         Ok(())\n///     }\n/// }\n///\n/// // Coerces the `&mut StrWriter<[u8; 128]>` to `&mut StrWriter<[u8]>`.\n/// // This is necessary because the `as_str` method is defined for `StrWriter<[u8]>`.\n/// let writer: &mut StrWriter = &mut StrWriter::new([0; 128]);\n/// writec!(writer, \"{}\", Foo(100, \"bar\"))?;\n///\n/// assert_eq!(writer.as_str(), r#\"100,\"bar\";\"#);\n///\n/// # Ok::<(), const_format::Error>(())\n/// ```\n///\n/// <span id=\"custom-writable-example\"></span>\n/// ### Writing to a custom type\n///\n/// This example demonstrates how you can use the `ẁritec` macro with a custom type,\n/// in this case it's a buffer that is cleared every time it's written.\n///\n/// ```rust\n///\n/// use const_format::marker_traits::{IsNotAStrWriter, WriteMarker};\n/// use const_format::{Formatter, FormattingFlags};\n/// use const_format::writec;\n///\n/// const ARRAY_CAP: usize = 20;\n/// struct Array {\n///     len: usize,\n///     arr: [u8; ARRAY_CAP],\n/// }\n///\n/// impl WriteMarker for Array{\n///     type Kind = IsNotAStrWriter;\n///     type This = Self;\n/// }\n///\n/// impl Array {\n///     // Gets the part of the array that has been written to.\n///     pub const fn as_bytes(&self) -> &[u8] {\n///         const_format::utils::slice_up_to_len(&self.arr, self.len)\n///     }\n///\n///     pub const fn borrow_mutably(&mut self) -> &mut Self {\n///         self\n///     }\n///\n///     pub const fn make_formatter(&mut self, flags: FormattingFlags) -> Formatter<'_> {\n///         Formatter::from_custom_cleared(&mut self.arr, &mut self.len, flags)\n///     }\n/// }\n///\n///\n/// let mut buffer = Array{ arr: [0; ARRAY_CAP], len: 0 };\n///\n/// writec!(buffer, \"{:?}\", [3u8, 5, 8, 13, 21])?;\n/// assert_eq!(buffer.as_bytes(), b\"[3, 5, 8, 13, 21]\");\n///\n/// writec!(buffer, \"{}{}\", \"Hello, world!\", 100u16)?;\n/// assert_eq!(buffer.as_bytes(), b\"Hello, world!100\");\n///\n/// # Ok::<(), const_format::Error>(())\n/// ```\n///\n/// ### Custom formatting.\n///\n/// This example demonstrates how you can access the [`Formatter`] in arguments\n/// to do custom formatting.\n///\n/// Note that `return` inside arguments returns from the function around the `writec`.\n///\n/// For more details on this you can look\n/// [in the fmt module](./fmt/index.html#custom-formatting-section).\n///\n/// ```rust\n///\n/// use const_format::for_examples::Point3;\n/// use const_format::{StrWriter, call_debug_fmt, try_, writec};\n///\n/// const P: Point3 = Point3{x: 5, y: 13, z: 21};\n///\n/// let writer: &mut StrWriter = &mut StrWriter::new([0; 128]);\n///\n/// writec!(\n///     writer,\n///     \"The options are: {}, and {}\",\n///     |fmt| call_debug_fmt!(Option, Some(P), fmt),\n///     |fmt| call_debug_fmt!(Option, None::<Point3>, fmt),\n/// )?;\n///\n/// assert_eq!(writer.as_str(), \"The options are: Some(Point3 { x: 5, y: 13, z: 21 }), and None\");\n///\n/// # Ok::<(), const_format::Error>(())\n/// ```\n///\n/// ### Locals in the format string\n///\n/// This example demonstrates how you can format local variables,\n/// by using their identifiers in the format string.\n///\n/// ```rust\n///\n/// use const_format::{Formatter, FormattingFlags, StrWriter, try_, writec};\n///\n/// const fn writeit(mut fmt: Formatter<'_>, foo: u32, bar: &str) -> const_format::Result {\n///     try_!(writec!(fmt, \"{foo},{foo:?},{foo:#x},{foo:#b};\"));\n///     try_!(writec!(fmt, \"{bar},{bar:?}\"));\n///     Ok(())\n/// }\n///\n/// let writer: &mut StrWriter = &mut StrWriter::new([0; 128]);\n///\n/// writeit(writer.make_formatter(FormattingFlags::NEW), 100, \"hello\")?;\n///\n/// assert_eq!(writer.as_str(), r#\"100,100,0x64,0b1100100;hello,\"hello\"\"#);\n///\n/// # Ok::<(), const_format::Error>(())\n/// ```\n///\n/// [`Formatter`]: ./fmt/struct.Formatter.html\n/// [`WriteMarker`]: ./marker_traits/trait.WriteMarker.html\n///\n///\n///\n///\n#[macro_export]\n#[cfg_attr(feature = \"__docsrs\", doc(cfg(feature = \"fmt\")))]\n#[cfg(feature = \"fmt\")]\nmacro_rules! writec {\n    ( $writer:expr, $format_string:expr $( $(, $expr:expr )+ )? $(,)? ) => ({\n        use $crate::__cf_osRcTFl4A;\n\n        $crate::pmr::__writec_impl!{\n            ($writer)\n            ($format_string)\n            $(, $($expr,)+)?\n        }\n    });\n}\n"
  },
  {
    "path": "const_format/src/macros/helper_macros.rs",
    "content": "#[doc(hidden)]\n#[macro_export]\nmacro_rules! __for_range{\n    ( $var:ident in $range:expr => $($for_body:tt)* )=>({\n        let $crate::pmr::Range{start: mut $var, end} = $range;\n        while $var < end {\n            {$($for_body)*}\n            $var+=1;\n        }\n    })\n}\n\n#[allow(unused_macros)]\nmacro_rules! identity {\n    ($($tt:tt)*) => { $($tt)* };\n}\n\n#[cfg(not(feature = \"rust_1_83\"))]\n#[doc(hidden)]\n#[macro_export]\nmacro_rules! __str_const {\n    ($e:expr) => {\n        $crate::pmr::__AssertStr { x: $e }.x\n    };\n}\n\n#[cfg(feature = \"rust_1_83\")]\n#[doc(hidden)]\n#[macro_export]\nmacro_rules! __str_const {\n    ($e:expr) => {\n        const { $crate::pmr::__AssertStr { x: $e }.x }\n    };\n}\n\n#[cfg(not(feature = \"rust_1_83\"))]\n#[doc(hidden)]\n#[macro_export]\nmacro_rules! __const {\n    ($ty:ty => $e:expr) => {\n        $crate::pmr::__AssertType::<$ty> { x: $e }.x\n    };\n}\n\n#[cfg(feature = \"rust_1_83\")]\n#[doc(hidden)]\n#[macro_export]\nmacro_rules! __const {\n    ($ty:ty => $e:expr) => {\n        const { $crate::pmr::__AssertType::<$ty> { x: $e }.x }\n    };\n}\n\n#[doc(hidden)]\n#[macro_export]\nmacro_rules! iter_copy_slice{\n    ( $var:ident in $array:expr => $($for_body:tt)* )=>({\n        let mut array: &[_] = &$array;\n        while let [$var, ref rem @ ..] = *array {\n            {$($for_body)*}\n            array = rem;\n        }\n    })\n}\n\n#[doc(hidden)]\n#[macro_export]\nmacro_rules! __write_pvariant {\n    (char, $parg:expr, $elem:ident => $out:ident) => {{\n        let encoded = $elem.encoded();\n        let len = $elem.len();\n\n        let mut start = 0;\n        while start < len {\n            $out.array[$out.len] = encoded[start];\n            $out.len += 1;\n            start += 1;\n        }\n    }};\n    (int, $parg:expr, $elem:ident => $out:ident) => {{\n        let wrapper = $crate::pmr::PWrapper($elem);\n\n        let debug_display;\n        let bin;\n        let hex;\n\n        let sa: &$crate::pmr::StartAndArray<[_]> = match $parg.fmt {\n            $crate::pmr::Formatting::Display => {\n                debug_display = wrapper.to_start_array_display();\n                &debug_display\n            }\n            $crate::pmr::Formatting::Debug => match $parg.fmt_flags.num_fmt() {\n                $crate::pmr::NumberFormatting::Decimal => {\n                    debug_display = wrapper.to_start_array_debug();\n                    &debug_display\n                }\n                $crate::pmr::NumberFormatting::Binary => {\n                    bin = wrapper.to_start_array_binary($parg.fmt_flags);\n                    &bin\n                }\n                $crate::pmr::NumberFormatting::Hexadecimal => {\n                    hex = wrapper.to_start_array_hexadecimal($parg.fmt_flags);\n                    &hex\n                }\n            },\n        };\n\n        let mut start = sa.start;\n        while start < sa.array.len() {\n            $out.array[$out.len] = sa.array[start];\n            $out.len += 1;\n            start += 1;\n        }\n    }};\n    (str, $parg:expr, $elem:ident => $out:ident) => {{\n        let str = $elem.as_bytes();\n        let is_display = $parg.fmt.is_display();\n        let mut i = 0;\n        if is_display {\n            while i < str.len() {\n                $out.array[$out.len] = str[i];\n                $out.len += 1;\n                i += 1;\n            }\n        } else {\n            $out.array[$out.len] = b'\"';\n            $out.len += 1;\n            while i < str.len() {\n                use $crate::pmr::{hex_as_ascii, ForEscaping, FOR_ESCAPING};\n\n                let c = str[i];\n                let mut written_c = c;\n                if c < 128 {\n                    let shifted = 1 << c;\n\n                    if (FOR_ESCAPING.is_escaped & shifted) != 0 {\n                        $out.array[$out.len] = b'\\\\';\n                        $out.len += 1;\n                        if (FOR_ESCAPING.is_backslash_escaped & shifted) == 0 {\n                            $out.array[$out.len] = b'x';\n                            $out.array[$out.len + 1] =\n                                hex_as_ascii(c >> 4, $crate::pmr::HexFormatting::Upper);\n                            $out.len += 2;\n                            written_c = hex_as_ascii(c & 0b1111, $crate::pmr::HexFormatting::Upper);\n                        } else {\n                            written_c = ForEscaping::get_backslash_escape(c);\n                        };\n                    }\n                }\n                $out.array[$out.len] = written_c;\n                $out.len += 1;\n                i += 1;\n            }\n            $out.array[$out.len] = b'\"';\n            $out.len += 1;\n        }\n    }};\n}\n"
  },
  {
    "path": "const_format/src/macros/impl_fmt.rs",
    "content": "/// For implementing debug or display formatting \"manually\".\n///\n/// # Generated code\n///\n/// This macro generates:\n///\n/// - An implementation of the [`FormatMarker`] trait for all the `impl`d types,\n///\n/// - All the listed impls, by repeating the methods (and other associated items)\n/// passed to this macro in each of the impls.\n///\n/// # Example\n///\n/// ### Generic type\n///\n/// This demonstrates how you can implement debug formatting for a generic struct.\n///\n/// ```rust\n///\n/// use const_format::{Error, Formatter, PWrapper, StrWriter};\n/// use const_format::{formatc, impl_fmt, try_};\n///\n/// use std::marker::PhantomData;\n///\n/// pub struct Tupled<T>(u32, T);\n///\n/// // Implements debug formatting for:\n/// // - Tupled<PhantomData<T>>\n/// // - Tupled<bool>\n/// // - Tupled<Option<bool>>\n/// // Repeating the `const_debug_fmt` function definition in each of those 3 impls.\n/// impl_fmt!{\n///     // The trailing comma is required\n///     impl[T,] Tupled<PhantomData<T>>\n///     where[ T: 'static ];\n///\n///     impl[] Tupled<bool>;\n///     impl Tupled<Option<bool>>;\n///     \n///     pub const fn const_debug_fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {\n///         let mut fmt = fmt.debug_tuple(\"Tupled\");\n///\n///         // PWrapper implements const_debug_fmt methods for many std types.\n///         //\n///         // You can use `call_debug_fmt` for formatting generic std types\n///         // if this doesn't work\n///         try_!(PWrapper(self.0).const_debug_fmt(fmt.field()));\n///         try_!(PWrapper(self.1).const_debug_fmt(fmt.field()));\n///\n///         fmt.finish()\n///     }\n/// }\n///\n/// const S_PHANTOM: &str = formatc!(\"{:?}\", Tupled(3, PhantomData::<u32>));\n/// const S_BOOL: &str = formatc!(\"{:?}\", Tupled(5, false));\n/// const S_OPTION: &str = formatc!(\"{:?}\", Tupled(8, Some(true)));\n///\n/// assert_eq!(S_PHANTOM, \"Tupled(3, PhantomData)\");\n/// assert_eq!(S_BOOL, \"Tupled(5, false)\");\n/// assert_eq!(S_OPTION, \"Tupled(8, Some(true))\");\n///\n///\n/// ```\n///\n/// ### Enum\n///\n/// This demonstrates how you can implement debug formatting for an enum,\n/// using this macro purely for implementing the [`FormatMarker`] trait.\n///\n/// ```rust\n///\n/// use const_format::{Error, Formatter, PWrapper, StrWriter};\n/// use const_format::{formatc, impl_fmt, try_};\n///\n/// use std::cmp::Ordering;\n///\n/// pub enum Enum {\n///     Braced{ord: Ordering},\n///     Tupled(u32, u32),\n///     Unit,\n/// }\n///\n/// impl_fmt!{\n///     impl Enum;\n///     \n///     pub const fn const_debug_fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {\n///         match self {\n///             Self::Braced{ord} => {\n///                 let mut fmt = fmt.debug_struct(\"Braced\");\n///\n///                 // PWrapper implements const_debug_fmt methods for many std types.\n///                 //\n///                 // You can use `call_debug_fmt` for formatting generic std types\n///                 // if this doesn't work\n///                 try_!(PWrapper(*ord).const_debug_fmt(fmt.field(\"ord\")));\n///\n///                 fmt.finish()\n///             }\n///             Self::Tupled(f0,f1) => {\n///                 let mut fmt = fmt.debug_tuple(\"Tupled\");\n///\n///                 try_!(PWrapper(*f0).const_debug_fmt(fmt.field()));\n///                 try_!(PWrapper(*f1).const_debug_fmt(fmt.field()));\n///\n///                 fmt.finish()\n///             }\n///             Self::Unit => {\n///                 fmt.debug_tuple(\"Unit\").finish()\n///             }\n///         }\n///     }\n/// }\n///\n/// const S_BRACED: &str = formatc!(\"{:?}\", Enum::Braced{ord: Ordering::Greater});\n/// const S_TUPLED: &str = formatc!(\"{:?}\", Enum::Tupled(5, 8));\n/// const S_UNIT: &str = formatc!(\"{:?}\", Enum::Unit);\n///\n/// assert_eq!(S_BRACED, \"Braced { ord: Greater }\");\n/// assert_eq!(S_TUPLED, \"Tupled(5, 8)\");\n/// assert_eq!(S_UNIT, \"Unit\");\n///\n/// ```\n///\n/// [`FormatMarker`]: ./marker_traits/trait.FormatMarker.html\n///\n#[cfg_attr(feature = \"__docsrs\", doc(cfg(feature = \"fmt\")))]\n#[macro_export]\nmacro_rules! impl_fmt {\n    (\n        is_std_type;\n        $($rem:tt)*\n    ) => (\n        $crate::__impl_fmt_recursive!{\n            impls[\n                is_std_type = true;\n            ]\n            tokens[$($rem)*]\n        }\n    );\n    (\n        $($rem:tt)*\n    ) => (\n        $crate::__impl_fmt_recursive!{\n            impls[\n                is_std_type = false;\n            ]\n            tokens[$($rem)*]\n        }\n    );\n}\n\n#[doc(hidden)]\n#[macro_export]\nmacro_rules! __impl_fmt_recursive{\n    (\n        impls[$($impls:tt)*]\n\n        tokens[\n            $(#[$impl_attr:meta])*\n            impl[$($impl_:tt)*] $type:ty\n            $(where[ $($where:tt)* ])?;\n\n            $($rem:tt)*\n        ]\n    ) => (\n        $crate::__impl_fmt_recursive!{\n\n            impls[\n                $($impls)*\n                (\n                    $(#[$impl_attr])*\n                    #[allow(unused_mut)]\n                    impl[$($impl_)*] $type\n                    where[ $($($where)*)? ];\n                )\n            ]\n            tokens[\n                $($rem)*\n            ]\n        }\n    );\n    // The same as the above macro branch, but it doesn't require the `[]` in `impl[]`\n    (\n        impls[$($impls:tt)*]\n\n        tokens[\n            $(#[$impl_attr:meta])*\n            impl $type:ty\n            $(where[ $($where:tt)* ])?;\n\n            $($rem:tt)*\n        ]\n    ) => (\n        $crate::__impl_fmt_recursive!{\n\n            impls[\n                $($impls)*\n                (\n                    $(#[$impl_attr])*\n                    #[allow(unused_mut)]\n                    impl[] $type\n                    where[ $($($where)*)? ];\n                )\n            ]\n            tokens[\n                $($rem)*\n            ]\n        }\n    );\n    (\n        impls $impls:tt\n        tokens[\n            $($rem:tt)*\n        ]\n    ) => (\n        $crate::__impl_fmt_inner!{\n            @all_impls\n            impls $impls\n            ($($rem)*)\n        }\n    );\n}\n\n#[doc(hidden)]\n#[macro_export]\nmacro_rules! __impl_fmt_inner {\n    (@all_impls\n        impls [\n            is_std_type = $is_std_type:ident;\n            $( $an_impl:tt )+\n        ]\n\n        $stuff:tt\n    )=>{\n        $(\n            $crate::__impl_fmt_inner!{\n                @impl_get_type_kind\n                is_std_type = $is_std_type;\n                $an_impl\n            }\n\n            $crate::__impl_fmt_inner!{\n                @an_impl\n                is_std_type = $is_std_type;\n                $an_impl\n                $stuff\n            }\n        )+\n    };\n    (@impl_get_type_kind\n        is_std_type = true;\n        (\n            $(#[$impl_attr:meta])*\n            impl[$($impl_:tt)*] $type:ty\n            where[ $($where:tt)* ];\n        )\n    )=>{\n        $(#[$impl_attr])*\n        impl<$($impl_)*> $crate::pmr::FormatMarker for $type\n        where\n            $($where)*\n        {\n            type Kind = $crate::pmr::IsStdKind;\n            type This = Self;\n        }\n\n        $(#[$impl_attr])*\n        impl<$($impl_)* __T> $crate::pmr::IsAFormatMarker<IsStdKind, $type, __T>\n        where\n            $($where)*\n        {\n            #[inline(always)]\n            pub const fn coerce(self, reference: &$type) -> PWrapper<$type> {\n                PWrapper(*reference)\n            }\n        }\n    };\n    (@impl_get_type_kind\n        is_std_type = false;\n        (\n            $(#[$impl_attr:meta])*\n            impl[$($impl_:tt)*] $type:ty\n            where[ $($where:tt)* ];\n        )\n    )=>{\n        $(#[$impl_attr])*\n        impl<$($impl_)*> $crate::pmr::FormatMarker for $type\n        where\n            $($where)*\n        {\n            type Kind = $crate::pmr::IsNotStdKind;\n            type This = Self;\n        }\n    };\n    (@an_impl\n        is_std_type = $is_std_type:ident;\n        (\n            $(#[$impl_attr:meta])*\n            impl[$($impl_:tt)*] $type:ty\n            where[ $($where:tt)* ];\n        )\n        (\n            $($everything:tt)*\n        )\n    )=>{\n        $(#[$impl_attr])*\n        impl<$($impl_)*> $crate::__impl_fmt_inner!(@self_ty $type, $is_std_type )\n        where\n            $($where)*\n        {\n            $($everything)*\n        }\n    };\n\n    (@self_ty $self:ty, /*is_std_type*/ true )=>{\n        $crate::pmr::PWrapper<$self>\n    };\n    (@self_ty $self:ty, /*is_std_type*/ false )=>{\n        $self\n    };\n\n}\n"
  },
  {
    "path": "const_format/src/macros/map_ascii_case.rs",
    "content": "/// Converts the casing style of a `&'static str` constant,\n/// ignoring non-ascii unicode characters.\n///\n/// This nacro is equivalent to a function with this signature:\n///\n/// ```rust\n/// const fn map_ascii_case(case: const_format::Case, input: &'static str) -> &'static str\n/// # {\"\"}\n/// ```\n///\n/// The [`Case`](enum.Case.html) parameter determines the casing style of the returned string.\n///\n/// # Ascii\n///\n/// This only transforms ascii characters because broader unicode case conversion,\n/// while possible, is much harder to implement purely with `const fn`s.\n///\n/// Non-ascii characters are treated as though they're alphabetic ascii characters.\n///\n/// # Ignored characters\n///\n/// These casing styles treat non-alphanumeric ascii characters as spaces,\n/// removing them from the returned string:\n///\n/// - `Case::Pascal`\n/// - `Case::Camel`\n/// - `Case::Snake`\n/// - `Case::UpperSnake`\n/// - `Case::Kebab`\n/// - `Case::UpperKebab`\n///\n/// # Example\n///\n/// ```rust\n/// use const_format::{Case, map_ascii_case};\n///\n/// {\n///     const LOW: &str = map_ascii_case!(Case::Lower, \"hello WORLD\");\n///     assert_eq!(LOW, \"hello world\");\n/// }\n/// {\n///     const IN: &str = \"hello WORLD каждому\";\n///     const OUT: &str = map_ascii_case!(Case::Upper, IN);\n///     // non-ascii characters are ignored by map_ascii_case.\n///     assert_eq!(OUT, \"HELLO WORLD каждому\");\n/// }\n///\n/// const IN2: &str = \"hello fooкаждому100Bar#qux\";\n/// {\n///     const OUT: &str = map_ascii_case!(Case::Pascal, IN2);\n///     assert_eq!(OUT, \"HelloFooкаждому100BarQux\");\n/// }\n/// {\n///     const OUT: &str = map_ascii_case!(Case::Camel, IN2);\n///     assert_eq!(OUT, \"helloFooкаждому100BarQux\");\n/// }\n/// {\n///     const OUT: &str = map_ascii_case!(Case::Snake, IN2);\n///     assert_eq!(OUT, \"hello_fooкаждому_100_bar_qux\");\n/// }\n/// {\n///     const OUT: &str = map_ascii_case!(Case::UpperSnake, IN2);\n///     assert_eq!(OUT, \"HELLO_FOOкаждому_100_BAR_QUX\");\n/// }\n/// {\n///     const OUT: &str = map_ascii_case!(Case::Kebab, IN2);\n///     assert_eq!(OUT, \"hello-fooкаждому-100-bar-qux\");\n/// }\n/// {\n///     const OUT: &str = map_ascii_case!(Case::UpperKebab, IN2);\n///     assert_eq!(OUT, \"HELLO-FOOкаждому-100-BAR-QUX\");\n/// }\n///\n///\n/// ```\n#[macro_export]\nmacro_rules! map_ascii_case {\n    ($case:expr, $str:expr) => {\n        $crate::__str_const! {{\n            const S_OSRCTFL4A: &$crate::pmr::str = $str;\n            const CASE_OSRCTFL4A: $crate::Case = $case;\n            {\n                const L: $crate::pmr::usize =\n                    $crate::__ascii_case_conv::size_after_conversion(CASE_OSRCTFL4A, S_OSRCTFL4A);\n\n                const OB: &[$crate::pmr::u8; L] =\n                    &$crate::__ascii_case_conv::convert_str::<L>(CASE_OSRCTFL4A, S_OSRCTFL4A);\n\n                const OS: &$crate::pmr::str = unsafe { $crate::__priv_transmute_bytes_to_str!(OB) };\n\n                OS\n            }\n        }}\n    };\n}\n"
  },
  {
    "path": "const_format/src/macros/str_methods.rs",
    "content": "/// Replaces all the instances of `$pattern` in `$input`\n/// (a `&'static str` constant) with `$replace_with` (a `&'static str` constant).\n///\n/// # Signature\n///\n/// This macro acts like a function of this signature:\n/// ```rust\n/// # trait Pattern {}\n/// fn str_replace(\n///     input: &'static str,\n///     pattern: impl Pattern,\n///     replace_with: &'static str,\n/// ) -> &'static str\n/// # {\"\"}\n/// ```\n/// and is evaluated at compile-time.\n///\n/// Where `pattern` can be any of these types:\n///\n/// - `&'static str`\n///\n/// - `char`\n///\n/// - `u8`: required to be ascii (`0` up to `127` inclusive).\n///\n/// # Example\n///\n///\n/// ```rust\n/// use const_format::str_replace;\n///\n/// // Passing a string pattern\n/// assert_eq!(\n///     str_replace!(\"The incredible shrinking man.\", \"i\", \"eee\"),\n///     \"The eeencredeeeble shreeenkeeeng man.\",\n/// );\n///\n/// // Passing a char pattern\n/// assert_eq!(\n///     str_replace!(\"The incredible shrinking man.\", ' ', \"---\"),\n///     \"The---incredible---shrinking---man.\",\n/// );\n///\n/// // Passing an ascii u8 pattern.\n/// assert_eq!(\n///     str_replace!(\"The incredible shrinking man.\", b'i', \"eee\"),\n///     \"The eeencredeeeble shreeenkeeeng man.\",\n/// );\n///\n/// // Removing all instances of the pattern\n/// assert_eq!(\n///     str_replace!(\"remove haire\", \"re\", \"\"),\n///     \"move hai\",\n/// );\n///\n/// // This shows that all the arguments can be `const`s, they don't have to be literals.\n/// {\n///     const IN: &str = \"Foo Boo Patoo\";\n///     const REPLACING: &str = \"oo\";\n///     const REPLACE_WITH: &str = \"uh\";\n///     assert_eq!(str_replace!(IN, REPLACING, REPLACE_WITH), \"Fuh Buh Patuh\");\n/// }\n/// ```\n///\n/// [`str::replace`]: https://doc.rust-lang.org/std/primitive.str.html#method.replace\n#[macro_export]\nmacro_rules! str_replace {\n    ($input:expr, $pattern:expr, $replace_with:expr $(,)*) => {\n        $crate::__str_const! {{\n            const ARGS_OSRCTFL4A: $crate::__str_methods::ReplaceInput =\n                $crate::__str_methods::ReplaceInputConv($input, $pattern, $replace_with).conv();\n\n            {\n                const OB: &[$crate::pmr::u8; ARGS_OSRCTFL4A.replace_length()] =\n                    &ARGS_OSRCTFL4A.replace();\n\n                const OS: &$crate::pmr::str = unsafe { $crate::__priv_transmute_bytes_to_str!(OB) };\n\n                OS\n            }\n        }}\n    };\n}\n\n/// Creates a `&'static str` by repeating a `&'static str` constant `times` times\n///\n/// This is evaluated at compile-time.\n///\n/// # Example\n///\n/// ```rust\n/// use const_format::str_repeat;\n///\n/// {\n///     const OUT: &str = str_repeat!(\"hi \", 4);\n///     assert_eq!(OUT, \"hi hi hi hi \")\n/// }\n/// {\n///     const IN: &str = \"bye \";\n///     const REPEAT: usize = 5;\n///     const OUT: &str = str_repeat!(IN, REPEAT);\n///     assert_eq!(OUT, \"bye bye bye bye bye \")\n/// }\n///\n/// ```\n///\n/// ### Failing\n///\n/// If this macro would produce too large a string,\n/// it causes a compile-time error.\n///\n/// ```compile_fail\n/// const_format::str_repeat!(\"hello\", usize::MAX / 4);\n/// ```\n///\n#[cfg_attr(\n    feature = \"__test\",\n    doc = r##\"\n```rust\nconst_format::str_repeat!(\"hello\", usize::MAX.wrapping_add(4));\n```\n\"##\n)]\n#[macro_export]\nmacro_rules! str_repeat {\n    ($string:expr, $times:expr  $(,)*) => {\n        $crate::__str_const! {{\n            const P_OSRCTFL4A: &$crate::__str_methods::StrRepeatArgs =\n                &$crate::__str_methods::StrRepeatArgs($string, $times);\n\n            {\n                use $crate::__hidden_utils::PtrToRef;\n                use $crate::pmr::{str, transmute, u8};\n\n                const P: &$crate::__str_methods::StrRepeatArgs = P_OSRCTFL4A;\n\n                $crate::pmr::respan_to! {\n                    ($string)\n                    const _ASSERT_VALID_LEN: () = P.assert_valid();\n                }\n\n                const OUT_B: &[u8; P.out_len] = &unsafe {\n                    let ptr = P.str.as_ptr() as *const [u8; P.str_len];\n                    transmute::<[[u8; P.str_len]; P.repeat], [u8; P.out_len]>(\n                        [*PtrToRef { ptr }.reff; P.repeat],\n                    )\n                };\n                const OUT_S: &str = unsafe { $crate::__priv_transmute_bytes_to_str!(OUT_B) };\n                OUT_S\n            }\n        }}\n    };\n}\n\n/// Replaces a substring in a `&'static str` constant.\n/// Returns both the new resulting `&'static str`, and the replaced substring.\n///\n/// # Alternatives\n///\n/// For an alternative which only returns the string with the applied replacement,\n/// you can use [`str_splice_out`].\n///\n/// # Signature\n///\n/// This macro acts like a function of this signature:\n/// ```rust\n/// # trait SomeIndex {}\n/// fn str_splice(\n///     input: &'static str,\n///     range: impl SomeIndex,\n///     replace_with: &'static str,\n/// ) -> const_format::SplicedStr\n/// # {unimplemented!()}\n/// ```\n/// and is evaluated at compile-time.\n///\n/// ### `range` argument\n///\n/// The `range` parameter determines what part of `input` is replaced,\n/// and can be any of these types:\n///\n/// - `usize`: the starting index of a char, only includes that char.\n/// - `Range<usize>`\n/// - `RangeTo<usize>`\n/// - `RangeFrom<usize>`\n/// - `RangeInclusive<usize>`\n/// - `RangeToInclusive<usize>`\n/// - `RangeFull`\n///\n/// [`SplicedStr`] contains:\n/// - `output`: a `&'static str` with the substring at `range` in `input` replaced with\n/// `replace_with`.\n/// - `removed`: the substring at `range` in `input`.\n///\n/// # Example\n///\n/// ```rust\n/// use const_format::{str_splice, SplicedStr};\n///\n/// const OUT: SplicedStr = str_splice!(\"foo bar baz\", 4..=6, \"is\");\n/// assert_eq!(OUT , SplicedStr{output: \"foo is baz\", removed: \"bar\"});\n///\n/// // You can pass `const`ants to this macro, not just literals\n/// {\n///     const IN: &str = \"this is bad\";\n///     const INDEX: std::ops::RangeFrom<usize> = 8..;\n///     const REPLACE_WITH: &str = \"... fine\";\n///     const OUT: SplicedStr = str_splice!(IN, INDEX, REPLACE_WITH);\n///     assert_eq!(OUT , SplicedStr{output: \"this is ... fine\", removed: \"bad\"});\n/// }\n/// {\n///     const OUT: SplicedStr = str_splice!(\"ABC豆-\", 3, \"DEFGH\");\n///     assert_eq!(OUT , SplicedStr{output: \"ABCDEFGH-\", removed: \"豆\"});\n/// }\n/// ```\n///\n/// ### Invalid index\n///\n/// Invalid indices cause compilation errors.\n///\n/// ```compile_fail\n/// const_format::str_splice!(\"foo\", 0..10, \"\");\n/// ```\n#[cfg_attr(\n    feature = \"__test\",\n    doc = r#\"\n```rust\nconst_format::str_splice!(\"foo\", 0..3, \"\");\n```\n\n```compile_fail\nconst_format::str_splice!(\"foo\", 0..usize::MAX, \"\");\n```\n\n```rust\nassert_eq!(\n    const_format::str_splice!(\"効率的\", 3..6, \"A\"),\n    const_format::SplicedStr{output: \"効A的\", removed: \"率\"} ,\n);\n```\n\n```compile_fail\nassert_eq!(\n    const_format::str_splice!(\"効率的\", 1..6, \"A\"),\n    const_format::SplicedStr{output: \"効A的\", removed: \"率\"} ,\n);\n```\n\n```compile_fail\nassert_eq!(\n    const_format::str_splice!(\"効率的\", 3..5, \"A\"),\n    const_format::SplicedStr{output: \"効A的\", removed: \"率\"} ,\n);\n```\n\n\"#\n)]\n///\n///\n/// [`SplicedStr`]: ./struct.SplicedStr.html\n/// [`str_splice_out`]: ./macro.str_splice_out.html\n#[macro_export]\nmacro_rules! str_splice {\n    ($string:expr, $index:expr, $insert:expr $(,)*) => {\n        $crate::__const! {\n            $crate::__str_methods::SplicedStr =>\n            $crate::__str_splice!($string, $index, $insert)\n        }\n    };\n}\n\n/// Alternative version of [`str_splice`] which only returns the string\n/// with the applied replacement.\n///\n/// # Example\n///\n/// ```rust\n/// use const_format::{str_splice_out, SplicedStr};\n///\n/// const OUT: &str = str_splice_out!(\"foo bar baz\", 4..=6, \"is\");\n/// assert_eq!(OUT , \"foo is baz\");\n///\n/// // You can pass `const`ants to this macro, not just literals\n/// {\n///     const IN: &str = \"this is bad\";\n///     const INDEX: std::ops::RangeFrom<usize> = 8..;\n///     const REPLACE_WITH: &str = \"... fine\";\n///     const OUT: &str = str_splice_out!(IN, INDEX, REPLACE_WITH);\n///     assert_eq!(OUT , \"this is ... fine\");\n/// }\n/// {\n///     const OUT: &str = str_splice_out!(\"ABC豆-\", 3, \"DEFGH\");\n///     assert_eq!(OUT , \"ABCDEFGH-\");\n/// }\n/// ```\n///\n/// [`str_splice`]: ./macro.str_splice.html\n#[macro_export]\nmacro_rules! str_splice_out {\n    ($string:expr, $index:expr, $insert:expr $(,)*) => {\n        $crate::__str_const! {\n            $crate::__str_splice!($string, $index, $insert).output\n        }\n    };\n}\n\n#[doc(hidden)]\n#[macro_export]\nmacro_rules! __str_splice {\n    ($string:expr, $index:expr, $insert:expr) => {{\n        const P_OSRCTFL4A: $crate::__str_methods::StrSpliceArgs =\n            $crate::__str_methods::StrSplceArgsConv($string, $index, $insert).conv();\n        {\n            use $crate::__hidden_utils::PtrToRef;\n            use $crate::__str_methods::{DecomposedString, SplicedStr, StrSpliceArgs};\n            use $crate::pmr::{str, u8};\n\n            const P: &StrSpliceArgs = &P_OSRCTFL4A;\n\n            type DecompIn =\n                DecomposedString<[u8; P.used_rstart], [u8; P.used_rlen], [u8; P.suffix_len]>;\n\n            type DecompOut =\n                DecomposedString<[u8; P.used_rstart], [u8; P.insert_len], [u8; P.suffix_len]>;\n\n            $crate::pmr::respan_to! {\n                ($string)\n                const _ASSERT_VALID_INDEX: () = P.index_validity.assert_valid();\n            }\n\n            const OUT_A: (&DecompOut, &str) = unsafe {\n                let input = PtrToRef {\n                    ptr: P.str.as_ptr() as *const DecompIn,\n                }\n                .reff;\n                let insert = PtrToRef {\n                    ptr: P.insert.as_ptr() as *const [u8; P.insert_len],\n                }\n                .reff;\n\n                (\n                    &DecomposedString {\n                        prefix: input.prefix,\n                        middle: *insert,\n                        suffix: input.suffix,\n                    },\n                    $crate::__priv_transmute_bytes_to_str!(&input.middle),\n                )\n            };\n\n            const OUT: SplicedStr = unsafe {\n                let output = OUT_A.0 as *const DecompOut as *const [u8; P.out_len];\n                SplicedStr {\n                    output: $crate::__priv_transmute_raw_bytes_to_str!(output),\n                    removed: OUT_A.1,\n                }\n            };\n\n            OUT\n        }\n    }};\n}\n\n/// Indexes a `&'static str` constant.\n///\n///\n/// # Signature\n///\n/// This macro acts like a function of this signature:\n/// ```rust\n/// # trait SomeIndex {}\n/// fn str_index(input: &'static str, range: impl SomeIndex) -> &'static str\n/// # {unimplemented!()}\n/// ```\n/// and is evaluated at compile-time.\n///\n/// This accepts\n/// [the same `range` arguments as `str_splice`](macro.str_splice.html#range-argument)\n///\n/// # Example\n///\n/// ```\n/// use const_format::str_index;\n///\n/// use std::ops::RangeFrom;\n///\n/// assert_eq!(str_index!(\"foo bar baz\", ..7), \"foo bar\");\n/// assert_eq!(str_index!(\"foo bar baz\", 4..7), \"bar\");\n/// assert_eq!(str_index!(\"foo bar baz\", 4..), \"bar baz\");\n///\n/// {\n///     const IN: &str = \"hello world\";\n///     const INDEX: RangeFrom<usize> = 6..;\n///     // You can pass `const`ants to this macro, not just literals\n///     const OUT_0: &str = str_index!(IN, INDEX);\n///     assert_eq!(OUT_0, \"world\");\n/// }\n/// {\n///     const OUT: &str = str_index!(\"hello world\", 4);\n///     assert_eq!(OUT, \"o\");\n/// }\n///\n/// ```\n///\n/// ### Invalid index\n///\n/// Invalid indices cause compilation errors.\n///\n/// ```compile_fail\n/// const_format::str_index!(\"foo\", 0..10);\n/// ```\n#[cfg_attr(\n    feature = \"__test\",\n    doc = r#\"\n```rust\nassert_eq!(const_format::str_index!(\"効率的\", 3..6), \"率\");\n```\n\n```compile_fail\nassert_eq!(const_format::str_index!(\"効率的\", 3..5), \"率\");\n```\n```compile_fail\nassert_eq!(const_format::str_index!(\"効率的\", 4..6), \"率\");\n```\n\"#\n)]\n///\n///\n#[macro_export]\nmacro_rules! str_index {\n    ($string:expr, $index:expr $(,)*) => {\n        $crate::__str_const! {{\n            const P_OSRCTFL4A: $crate::__str_methods::StrIndexArgs =\n                $crate::__str_methods::StrIndexArgsConv($string, $index).conv();\n\n            {\n                $crate::pmr::respan_to! {\n                    ($string)\n                    const _ASSERT_VALID_INDEX: () =\n                        P_OSRCTFL4A.index_validity.assert_valid();\n                }\n\n                use $crate::__hidden_utils::PtrToRef;\n                use $crate::__str_methods::DecomposedString;\n                type DecompIn = DecomposedString<\n                    [u8; P_OSRCTFL4A.used_rstart],\n                    [u8; P_OSRCTFL4A.used_rlen],\n                    [u8; 0],\n                >;\n\n                const OUT: &'static str = unsafe {\n                    let input = PtrToRef {\n                        ptr: P_OSRCTFL4A.str.as_ptr() as *const DecompIn,\n                    }\n                    .reff;\n                    $crate::__priv_transmute_raw_bytes_to_str!(&input.middle)\n                };\n\n                OUT\n            }\n        }}\n    };\n}\n\n/// Indexes a `&'static str` constant,\n/// returning `None` when the index is not on a character boundary.\n///\n///\n/// # Signature\n///\n/// This macro acts like a function of this signature:\n/// ```rust\n/// # trait SomeIndex {}\n/// fn str_get(input: &'static str, range: impl SomeIndex) -> Option<&'static str>\n/// # {unimplemented!()}\n/// ```\n/// and is evaluated at compile-time.\n///\n/// This accepts\n/// [the same `range` arguments as `str_splice`](macro.str_splice.html#range-argument)\n///\n/// # Example\n///\n/// ```\n/// use const_format::str_get;\n///\n/// use std::ops::RangeFrom;\n///\n/// assert_eq!(str_get!(\"foo 鉄 baz\", ..7), Some(\"foo 鉄\"));\n/// assert_eq!(str_get!(\"foo 鉄 baz\", 4..7), Some(\"鉄\"));\n/// assert_eq!(str_get!(\"foo 鉄 baz\", 4..100), None);\n///\n///\n/// {\n///     const IN: &str = \"hello 鉄\";\n///     const INDEX: RangeFrom<usize> = 6..;\n///     // You can pass `const`ants to this macro, not just literals\n///     const OUT: Option<&str> = str_get!(IN, INDEX);\n///     assert_eq!(OUT, Some(\"鉄\"));\n/// }\n/// {\n///     const OUT: Option<&str> = str_get!(\"hello 鉄\", 4);\n///     assert_eq!(OUT, Some(\"o\"));\n/// }\n/// {\n///     // End index not on a character boundary\n///     const OUT: Option<&str> = str_get!(\"hello 鉄\", 0..7);\n///     assert_eq!(OUT, None);\n/// }\n/// {\n///     // Out of bounds indexing\n///     const OUT: Option<&str> = str_get!(\"hello 鉄\", 0..1000 );\n///     assert_eq!(OUT, None);\n/// }\n///\n/// ```\n#[cfg_attr(\n    feature = \"__test\",\n    doc = r#\"\n```rust\nassert_eq!(const_format::str_get!(\"効率的\", 3..6), Some(\"率\"));\nassert_eq!(const_format::str_get!(\"効率的\", 3..5), None);\nassert_eq!(const_format::str_get!(\"効率的\", 4..6), None);\n```\n\"#\n)]\n///\n#[macro_export]\nmacro_rules! str_get {\n    ($string:expr, $index:expr $(,)*) => {\n        $crate::__const! {\n            $crate::pmr::Option<&'static $crate::pmr::str> => {\n            const P_OSRCTFL4A: $crate::__str_methods::StrIndexArgs =\n                $crate::__str_methods::StrIndexArgsConv($string, $index).conv();\n\n            {\n                use $crate::__hidden_utils::PtrToRef;\n                use $crate::__str_methods::DecomposedString;\n                type DecompIn = DecomposedString<\n                    [u8; P_OSRCTFL4A.used_rstart],\n                    [u8; P_OSRCTFL4A.used_rlen],\n                    [u8; 0],\n                >;\n\n                const OUT: $crate::pmr::Option<&'static $crate::pmr::str> = unsafe {\n                    if P_OSRCTFL4A.index_validity.is_valid() {\n                        let input = PtrToRef {\n                            ptr: P_OSRCTFL4A.str.as_ptr() as *const DecompIn,\n                        }\n                        .reff;\n\n                        $crate::pmr::Some($crate::__priv_transmute_raw_bytes_to_str!(&input.middle))\n                    } else {\n                        $crate::pmr::None\n                    }\n                };\n\n                OUT\n            }\n        }}\n    };\n}\n\n/// Splits `$string` (a `&'static str` constant) with `$splitter`,\n/// returning an array of `&'static str`s.\n///\n/// # Alternatives\n///\n/// For an alternative macro which will be usable in slice patterns\n/// (once [`inline_const_pat`] is stabilized)\n/// you can use [`str_split_pat`].\n///\n/// # Signature\n///\n/// This macro acts like a function of this signature:\n/// ```rust\n/// # const LEN: usize = 0;\n/// # trait Splitter {}\n/// fn str_split(string: &'static str, splitter: impl Splitter) -> [&'static str; LEN]\n/// # { [] }\n/// ```\n/// and is evaluated at compile-time.\n///\n/// `impl Splitter` is any of these types:\n///\n/// - `&'static str`\n///\n/// - `char`\n///\n/// - `u8`: only ascii values (0 up to 127 inclusive) are allowed\n///\n/// The value of `LEN` depends on the `string` and `splitter` arguments.\n///\n///\n/// # Example\n///\n/// ```rust\n/// use const_format::str_split;\n///\n/// assert_eq!(str_split!(\"this is nice\", ' '), [\"this\", \"is\", \"nice\"]);\n///\n/// assert_eq!(str_split!(\"Hello, world!\", \", \"), [\"Hello\", \"world!\"]);\n///\n/// // A `\"\"` splitter outputs all chars individually (`str::split` does the same)\n/// assert_eq!(str_split!(\"🧡BAR🧠\", \"\"), [\"\", \"🧡\", \"B\", \"A\", \"R\", \"🧠\", \"\"]);\n///\n/// // Splitting the string with an ascii byte\n/// assert_eq!(str_split!(\"dash-separated-string\", b'-'), [\"dash\", \"separated\", \"string\"]);\n///\n/// {\n///     const STR: &str = \"foo bar baz\";\n///     const SPLITTER: &str = \" \";\n///\n///     // both arguments to the `str_aplit` macro can be non-literal constants\n///     const SPLIT: [&str; 3] = str_split!(STR, SPLITTER);\n///\n///     assert_eq!(SPLIT, [\"foo\", \"bar\", \"baz\"]);\n/// }\n///\n/// ```\n///\n/// [`inline_const_pat`]: https://doc.rust-lang.org/1.83.0/unstable-book/language-features/inline-const-pat.html\n/// [`str_split_pat`]: crate::str_split_pat\n#[macro_export]\nmacro_rules! str_split {\n    ($string:expr, $splitter:expr $(,)?) => {{\n        const ARGS_OSRCTFL4A: $crate::__str_methods::SplitInput =\n            $crate::__str_methods::SplitInputConv($string, $splitter).conv();\n\n        {\n            const OB: [&$crate::pmr::str; ARGS_OSRCTFL4A.length()] = ARGS_OSRCTFL4A.split_it();\n            OB\n        }\n    }};\n}\n\n/// Version of [`str_split`] which evaluates to a `&'static [&'static str]`.\n///\n/// # Example\n///\n/// Using the currently unstable [`inline_const_pat`] feature to use this macro in patterns:\n///\n/// ```rust\n/// # /*\n/// #![feature(inline_const_pat)]\n/// # */\n///\n/// use const_format::str_split_pat;\n///\n/// assert!(is_it(&[\"foo\", \"bar\", \"baz\"]));\n/// assert!(!is_it(&[\"foo\", \"bar\"]));\n///\n/// fn is_it(slice: &[&str]) -> bool {\n///     const SEP: char = ' ';\n/// # /*\n///     matches!(slice, str_split_pat!(\"foo bar baz\", SEP))\n/// # */\n/// #   slice == str_split_pat!(\"foo bar baz\", SEP)\n/// }\n/// ```\n///\n/// [`inline_const_pat`]: https://doc.rust-lang.org/1.83.0/unstable-book/language-features/inline-const-pat.html\n#[macro_export]\nmacro_rules! str_split_pat {\n    ($string:expr, $splitter:expr $(,)?) => {\n        $crate::__const! {&'static [&'static $crate::pmr::str] => {\n            const ARGS_OSRCTFL4A: $crate::__str_methods::SplitInput =\n                $crate::__str_methods::SplitInputConv($string, $splitter).conv();\n\n            {\n                const OB: [&$crate::pmr::str; ARGS_OSRCTFL4A.length()] = ARGS_OSRCTFL4A.split_it();\n                &OB\n            }\n        }}\n    };\n}\n"
  },
  {
    "path": "const_format/src/macros.rs",
    "content": "#[macro_use]\nmod assertions;\n\n#[macro_use]\n#[cfg(feature = \"fmt\")]\nmod call_debug_fmt;\n\n#[macro_use]\nmod constructors;\n\n#[macro_use]\nmod helper_macros;\n\n#[macro_use]\nmod fmt_macros;\n\n#[macro_use]\n#[cfg(feature = \"fmt\")]\nmod impl_fmt;\n\n#[macro_use]\nmod map_ascii_case;\n\n#[macro_use]\nmod str_methods;\n\n/// For returning early on an error, otherwise evaluating to `()`.\n///\n/// # Example\n///\n/// ```rust\n///\n/// use const_format::{Error, StrWriter};\n/// use const_format::{try_, writec};\n///\n/// const fn write_stuff(buffer: &mut StrWriter) -> Result<&[u8], Error> {\n///     try_!(writec!(buffer, \"Foo{},Bar{},Baz{},\", 8u32, 13u32, 21u32));\n///     Ok(buffer.as_bytes())\n/// }\n///\n/// let mut buffer = StrWriter::new([0; 32]);\n/// assert_eq!(write_stuff(&mut buffer)?, \"Foo8,Bar13,Baz21,\".as_bytes());\n///\n/// # Ok::<(), Error>(())\n/// ```\n#[cfg_attr(feature = \"__docsrs\", doc(cfg(feature = \"fmt\")))]\n#[cfg(feature = \"fmt\")]\n#[macro_export]\nmacro_rules! try_ {\n    ($e:expr) => {\n        if let $crate::pmr::Err(e) = $e {\n            return $crate::pmr::Err(e);\n        }\n    };\n}\n\n/// Equivalent to `Result::unwrap`, for use with [`const_format::Error`] errors.\n///\n/// You can use this when you know for certain that no error will happen.\n///\n/// [`const_format::Error`]: ./fmt/enum.Error.html\n///\n/// # Example\n///\n/// ```rust\n///\n/// use const_format::{StrWriter, unwrap, writec};\n///\n/// const CAP: usize = 11;\n/// const TEXT: &str = {\n///     const S: &StrWriter = &{\n///         let mut writer = StrWriter::new([0; CAP]);\n///         unwrap!(writec!(writer, \"foo bar baz\"));\n///         writer\n///     };\n///     S.as_str()\n/// };\n/// assert_eq!(TEXT, \"foo bar baz\")\n///\n/// ```\n#[cfg_attr(feature = \"__docsrs\", doc(cfg(feature = \"fmt\")))]\n#[cfg(feature = \"fmt\")]\n#[macro_export]\nmacro_rules! unwrap {\n    ($e:expr $(,)*) => {\n        match $e {\n            $crate::pmr::Ok(x) => x,\n            $crate::pmr::Err(error) => $crate::Error::unwrap(&error),\n        }\n    };\n}\n\n/// Equivalent to `Result::unwrap_or_else` but allows returning from the enclosing function.\n///\n/// # Examples\n///\n/// ### Early return\n///\n/// ```rust\n///\n/// use const_format::unwrap_or_else;\n///\n/// const fn unwrap_square(number: Result<u32, u32>) -> u64 {\n///     let n = unwrap_or_else!(number, |n| return n as u64 ) as u64;\n///     n * n\n/// }\n///\n/// assert_eq!(unwrap_square(Ok(10)), 100);\n/// assert_eq!(unwrap_square(Ok(30)), 900);\n/// assert_eq!(unwrap_square(Err(100)), 100);\n///\n/// ```\n///\n/// ### As unwrap_or\n///\n/// ```rust\n///\n/// use const_format::{AsciiStr, unwrap_or_else};\n///\n/// const FOO: AsciiStr = unwrap_or_else!(AsciiStr::new(b\"AB\\x80\"), |_| AsciiStr::empty() );\n///\n/// const BAR: AsciiStr = unwrap_or_else!(AsciiStr::new(b\"bar\"), |_| loop{} );\n///\n/// assert_eq!(FOO.as_str(), \"\");\n/// assert_eq!(BAR.as_str(), \"bar\");\n///\n/// ```\n#[cfg_attr(feature = \"__docsrs\", doc(cfg(feature = \"fmt\")))]\n#[cfg(feature = \"fmt\")]\n#[macro_export]\nmacro_rules! unwrap_or_else {\n    ($e:expr, |$($error:ident)? $(_)*| $orelse:expr ) => {\n        match $e {\n            $crate::pmr::Ok(x) => x,\n            $crate::pmr::Err($($error,)?..) => $orelse,\n        }\n    };\n}\n\n/// Coerces a reference to a type that has a `const_*_fmt` method.\n///\n/// # Behavior\n///\n/// For arrays it coerces them into a slice, and wraps them in a [`PWrapper`].\n///\n/// For std types, it wraps them in a [`PWrapper`], which implements the\n/// `const_*_fmt` methods.\n///\n/// For non-std types, it just returns back the same reference.\n///\n/// # Example\n///\n/// ```rust\n///\n/// use const_format::{\n///     for_examples::Unit,\n///     Formatter, FormattingFlags, PWrapper, StrWriter,\n///     coerce_to_fmt,\n/// };\n///\n/// const CAP: usize = 128;\n/// const fn make_strwriter() -> StrWriter<[u8; CAP]> {\n///     let mut writer = StrWriter::new([0; CAP]);\n///     let mut fmt = Formatter::from_sw(&mut writer, FormattingFlags::NEW);\n///\n///     // This is equivalent to the `PWrapper::slice(&[0u8, 1])` below\n///     let _ = coerce_to_fmt!([0u8, 1]).const_debug_fmt(&mut fmt);\n///     let _ = fmt.write_str(\",\");\n///\n///     let _ = PWrapper::slice(&[0u8, 1]).const_debug_fmt(&mut fmt);\n///     let _ = fmt.write_str(\",\");\n///\n///\n///     // This is equivalent to the `PWrapper(100u32)` line\n///     let _ = coerce_to_fmt!(100u32).const_debug_fmt(&mut fmt);\n///     let _ = fmt.write_str(\",\");\n///\n///     let _ = PWrapper(100u32).const_debug_fmt(&mut fmt);\n///     let _ = fmt.write_str(\",\");\n///\n///\n///     // This is equivalent to the `Unit.const_debug_fmt(&mut fmt)` line\n///     let _ = coerce_to_fmt!(Unit).const_debug_fmt(&mut fmt);\n///\n///\n///     let _ = fmt.write_str(\",\");\n///     let _ = Unit.const_debug_fmt(&mut fmt);\n///\n///     writer\n/// }\n///\n/// const TEXT: &str = {\n///     const TEXT_: &StrWriter = &make_strwriter();\n///     TEXT_.as_str()\n/// };\n///\n/// assert_eq!(TEXT, \"[0, 1],[0, 1],100,100,Unit,Unit\");\n///\n/// ```\n///\n/// [`PWrapper`]: ./struct.PWrapper.html\n#[cfg_attr(feature = \"__docsrs\", doc(cfg(feature = \"fmt\")))]\n#[cfg(feature = \"fmt\")]\n#[macro_export]\nmacro_rules! coerce_to_fmt {\n    ($reference:expr) => {{\n        match $reference {\n            ref reference => {\n                let marker = $crate::pmr::IsAFormatMarker::NEW;\n                if false {\n                    marker.infer_type(reference);\n                }\n                marker.coerce(marker.unreference(reference))\n            }\n        }\n    }};\n}\n\n/// Converts a `&'static StrWriter` to a `&'static str`, in a `const`/`static` initializer.\n///\n/// This is usable in `const` or `static` initializers,\n/// but not inside of `const fn`s.\n///\n/// **Deprecated:** This macro is deprecated because\n/// the [`StrWriter::as_str`](crate::StrWriter::as_str) method\n/// allows converting a`&'static StrWriter` to a `&'static str`.\n///\n/// # Example\n///\n/// ```rust\n///\n/// use const_format::StrWriter;\n/// use const_format::{strwriter_as_str, unwrap, writec};\n///\n///\n/// const CAP: usize = 128;\n///\n/// const __STR: &StrWriter = &{\n///     let mut writer =  StrWriter::new([0; CAP]);\n///\n///     // Writing the array with debug formatting, and the integers with hexadecimal formatting.\n///     unwrap!(writec!(writer, \"{:x}\", [3u32, 5, 8, 13, 21, 34]));\n///\n///     writer\n/// };\n///\n/// const STR: &str = strwriter_as_str!(__STR);\n///\n/// fn main() {\n///     assert_eq!(STR, \"[3, 5, 8, d, 15, 22]\");\n/// }\n/// ```\n///\n#[cfg_attr(feature = \"__docsrs\", doc(cfg(feature = \"fmt\")))]\n#[cfg(feature = \"fmt\")]\n#[deprecated(since = \"0.2.19\", note = \"Use `StrWriter::as_str` instead\")]\n#[macro_export]\nmacro_rules! strwriter_as_str {\n    ($expr:expr) => {\n        unsafe {\n            let writer: &'static $crate::StrWriter = $expr;\n            #[allow(clippy::transmute_bytes_to_str)]\n            $crate::__priv_transmute_bytes_to_str!(writer.as_bytes())\n        }\n    };\n}\n\n#[cfg_attr(feature = \"__docsrs\", doc(cfg(feature = \"fmt\")))]\n#[cfg(feature = \"fmt\")]\nmacro_rules! std_kind_impl {\n    (\n        impl[$($impl:tt)*] $self:ty\n        $(where[ $($where_:tt)* ])?\n    )=>{\n        impl<$($impl)*> $crate::pmr::FormatMarker for $self\n        where\n            $($($where_)*)?\n        {\n            type Kind = $crate::pmr::IsStdKind;\n            type This = Self;\n        }\n\n        impl<$($impl)* __T> $crate::pmr::IsAFormatMarker<$crate::pmr::IsStdKind, $self, __T>\n        where\n            $($($where_)*)?\n        {\n            #[inline(always)]\n            pub const fn coerce(self, reference: &$self) -> $crate::pmr::PWrapper<$self> {\n                $crate::pmr::PWrapper(*reference)\n            }\n        }\n    }\n}\n\n#[macro_export]\n#[doc(hidden)]\nmacro_rules! __priv_transmute_bytes_to_str {\n    ($bytes:expr) => {{\n        let bytes: &'static [$crate::pmr::u8] = $bytes;\n        let string: &'static $crate::pmr::str = {\n            $crate::__hidden_utils::PtrToRef {\n                ptr: bytes as *const [$crate::pmr::u8] as *const str,\n            }\n            .reff\n        };\n        string\n    }};\n}\n\n#[macro_export]\n#[doc(hidden)]\nmacro_rules! __priv_transmute_raw_bytes_to_str {\n    ($bytes:expr) => {{\n        let bytes: *const [$crate::pmr::u8] = $bytes;\n        let string: &'static $crate::pmr::str = {\n            $crate::__hidden_utils::PtrToRef {\n                ptr: bytes as *const str,\n            }\n            .reff\n        };\n        string\n    }};\n}\n"
  },
  {
    "path": "const_format/src/marker_traits/format_marker.rs",
    "content": "//! Marker trait for types that implement the const formatting methods.\n//!\n//!\n\nuse crate::wrapper_types::PWrapper;\n\nuse core::marker::PhantomData;\n\n////////////////////////////////////////////////////////////////////////////////\n\n/// Marker trait for types that implement the const formatting methods.\n///\n/// Debug formatting can be derived using the [`ConstDebug`] derive macro.\n///\n/// # Implementors\n///\n/// Types that implement this trait are also expected to implement at least one of\n/// these inherent methods:\n///\n/// ```ignore\n/// // use const_format::{Error, Format};\n///\n/// const fn const_debug_fmt(&self, &mut Formatter<'_>) -> Result<(), Error>\n///\n/// const fn const_display_fmt(&self, &mut Formatter<'_>) -> Result<(), Error>\n/// ```\n///\n/// # Coercions\n///\n/// The [`Kind`](#associatedtype.Kind) and [`This`](#associatedtype.This) associated types\n/// are used in the [`IsAFormatMarker`] marker type\n/// to automatically wrap types in [`PWrapper`] if they're from the standard library,\n/// otherwise leaving them unwrapped.\n///\n/// # Examples\n///\n/// ### Display formatting\n///\n/// This example demonstrates how you can implement display formatting,\n/// without using the [`impl_fmt`] macro.\n///\n/// ```rust\n///\n/// use const_format::{\n///     marker_traits::{FormatMarker, IsNotStdKind},\n///     Error, Formatter, StrWriter,\n///     formatc, writec,\n/// };\n///\n/// use std::cmp::Ordering;\n///\n///\n/// struct Compared(u32, Ordering, u32);\n///\n/// // This is what the `impl_fmt` macro implements implicitly for all non-std types\n/// impl FormatMarker for Compared {\n///     type Kind = IsNotStdKind;\n///     type This = Self;\n/// }\n///\n/// impl Compared {\n///     pub const fn const_display_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {\n///         let op = match self.1 {\n///             Ordering::Less => \"<\",\n///             Ordering::Equal => \"==\",\n///             Ordering::Greater => \">\",\n///         };\n///         writec!(f, \"{} {} {}\", self.0, op, self.2)\n///     }\n/// }\n///\n/// const S_0: &str = formatc!(\"{}\", Compared(0, Ordering::Less, 1));\n/// const S_1: &str = formatc!(\"{}\", Compared(1, Ordering::Equal, 1));\n/// const S_2: &str = formatc!(\"{}\", Compared(2, Ordering::Greater, 1));\n///\n/// assert_eq!(S_0, \"0 < 1\");\n/// assert_eq!(S_1, \"1 == 1\");\n/// assert_eq!(S_2, \"2 > 1\");\n///\n/// ```\n///\n/// ### Debug formatting\n///\n/// For examples of using the [`ConstDebug`] derive macro,\n/// [look here](crate::ConstDebug#examples).\n///\n/// These are examples of implementing debug formatting using the `impl_fmt` macro for:\n///\n/// - [Tupled structs and tuple variants.](../fmt/struct.DebugTuple.html#example)\n///\n/// - [Braced structs and braced variants.](../fmt/struct.DebugStruct.html#example)\n///\n///\n/// [`IsAFormatMarker`]: ./struct.IsAFormatMarker.html\n/// [`ConstDebug`]: crate::ConstDebug\n/// [`impl_fmt`]: ../macro.impl_fmt.html\n///\npub trait FormatMarker {\n    /// What kind of type this is, this can be one of:\n    ///\n    /// - [`IsArrayKind`]: For slices, and arrays.\n    ///\n    /// - [`IsStdKind`]: Any other standard library type.\n    ///\n    /// - [`IsNotStdKind`]: Any type that is not from the standard library.\n    ///\n    /// [`IsArrayKind`]: ./struct.IsArrayKind.html\n    /// [`IsStdKind`]: ./struct.IsStdKind.html\n    /// [`IsNotStdKind`]: ./struct.IsNotStdKind.html\n    type Kind;\n\n    /// The type after dereferencing,\n    /// implemented as `type This = Self;` for all non-reference types\n    type This: ?Sized;\n}\n\n/// Marker type for arrays and slices,\n/// used as the [`Kind`] associated type  in [`FormatMarker`].\n///\n/// [`Kind`]: ./trait.FormatMarker.html#associatedtype.Kind\n///\npub struct IsArrayKind<T>(PhantomData<T>);\n\n/// Marker type for the remaining standard library types,,\n/// used as the [`Kind`] associated type  in [`FormatMarker`].\n///\n/// [`Kind`]: ./trait.FormatMarker.html#associatedtype.Kind\n///\npub struct IsStdKind;\n\n/// Marker type for non-standard library types,\n/// used as the [`Kind`] associated type  in [`FormatMarker`].\n///\n/// [`Kind`]: ./trait.FormatMarker.html#associatedtype.Kind\n///\npub struct IsNotStdKind;\n\nmacro_rules! std_kind_impls {\n    ($($ty:ty),* $(,)* ) => (\n        $(\n            impl FormatMarker for $ty {\n                type Kind = IsStdKind;\n                type This = Self;\n            }\n\n            impl<T> IsAFormatMarker<IsStdKind, $ty, T> {\n                /// Copies the value from `reference`, and wraps it in a `PWrapper`\n                #[inline(always)]\n                pub const fn coerce(self, reference: &$ty) -> PWrapper<$ty> {\n                    PWrapper(*reference)\n                }\n            }\n        )*\n    )\n}\n\n///////////////////////////////////////////////////////////////////////////////\n\n/// Hack used to automatically wrap standard library types inside [`PWrapper`],\n/// while leaving user defined types unwrapped.\n///\n/// # Type parameters\n///\n/// `K` is `<R as FormatMarker>::Kind`\n/// The kind of type that `T` is,\n/// [a slice](./struct.IsArrayKind.html),\n/// [other std types](./struct.IsStdKind.html),\n/// [non-std types](./struct.IsNotStdKind.html).\n///\n/// `T` is `<R as FormatMarker>::This`:\n/// The `R` type after removing all layers of references.\n///\n/// `R`: a type that implements [`FormatMarker`].\n///\n/// # Coerce Method\n///\n/// The `coerce` method is what does the conversion from a `&T` depending on\n/// the `K` type parameter:\n///\n/// - [`IsArrayKind`]: the reference is coerced to a slice, and wrapped in a [`PWrapper`].\n///\n/// - [`IsStdKind`]: the referenced value is copied, and wrapped in a [`PWrapper`].\n///\n/// - [`IsNotStdKind`]: the reference is simply returned as a `&T`.\n///\n#[allow(clippy::type_complexity)]\npub struct IsAFormatMarker<K, T: ?Sized, R: ?Sized>(\n    PhantomData<(\n        PhantomData<fn() -> PhantomData<K>>,\n        PhantomData<fn() -> PhantomData<T>>,\n        PhantomData<fn() -> PhantomData<R>>,\n    )>,\n);\n\nimpl<K, T: ?Sized, R: ?Sized> Copy for IsAFormatMarker<K, T, R> {}\n\nimpl<K, T: ?Sized, R: ?Sized> Clone for IsAFormatMarker<K, T, R> {\n    fn clone(&self) -> Self {\n        *self\n    }\n}\n\nimpl<R> IsAFormatMarker<R::Kind, R::This, R>\nwhere\n    R: ?Sized + FormatMarker,\n{\n    /// Constructs an `IsAFormatMarker`\n    pub const NEW: Self = Self(PhantomData);\n}\n\nimpl<K, T: ?Sized, R: ?Sized> IsAFormatMarker<K, T, R> {\n    /// Infers the type parameters by taking a reference to `R` .\n    ///\n    /// The `K` and `T` type parameters are determined by `R` in\n    /// the [`NEW`] associated constant.\n    ///\n    /// [`NEW`]: #associatedconstant.NEW\n    #[inline(always)]\n    pub const fn infer_type(self, _: &R) -> Self {\n        self\n    }\n\n    /// Removes layers of references by coercing the argument.\n    #[inline(always)]\n    pub const fn unreference(self, r: &T) -> &T {\n        r\n    }\n}\n\n/////////////////////////////////////////////////////////////////////////////\n\nimpl<U, T: ?Sized, R: ?Sized> IsAFormatMarker<IsArrayKind<U>, T, R> {\n    /// Coerces an array to a slice, then wraps the slice in a `PWrapper`\n    #[inline(always)]\n    pub const fn coerce(self, slice: &[U]) -> PWrapper<&[U]> {\n        PWrapper(slice)\n    }\n}\n\nimpl<T: ?Sized, R: ?Sized> IsAFormatMarker<IsNotStdKind, T, R> {\n    /// An identity function, just takes `reference` and returns it.\n    #[inline(always)]\n    pub const fn coerce(self, reference: &T) -> &T {\n        reference\n    }\n}\n\n/////////////////////////////////////////////////////////////////////////////\n\nstd_kind_impls! {\n    i8, u8,\n    i16, u16,\n    i32, u32,\n    i64, u64,\n    i128, u128,\n    isize, usize,\n    bool, char,\n}\n\nimpl FormatMarker for str {\n    type Kind = IsStdKind;\n    type This = Self;\n}\n\nimpl<R: ?Sized> IsAFormatMarker<IsStdKind, str, R> {\n    /// Wraps `reference` in a `PWrapper`.\n    #[inline(always)]\n    pub const fn coerce(self, reference: &str) -> PWrapper<&str> {\n        PWrapper(reference)\n    }\n}\n\nimpl<T, const N: usize> FormatMarker for [T; N] {\n    type Kind = IsArrayKind<T>;\n    type This = Self;\n}\n\nimpl<T> FormatMarker for [T] {\n    type Kind = IsArrayKind<T>;\n    type This = [T];\n}\n\nimpl<T> FormatMarker for &T\nwhere\n    T: ?Sized + FormatMarker,\n{\n    type Kind = T::Kind;\n    type This = T::This;\n}\n\nimpl<T> FormatMarker for &mut T\nwhere\n    T: ?Sized + FormatMarker,\n{\n    type Kind = T::Kind;\n    type This = T::This;\n}\n"
  },
  {
    "path": "const_format/src/marker_traits/write_marker.rs",
    "content": "//! Marker trait for types that can be written to.\n//!\n//!\n\nuse crate::fmt::{Formatter, StrWriter, StrWriterMut};\n\nuse core::marker::PhantomData;\n\n////////////////////////////////////////////////////////////////////////////////\n\n/// Marker trait for types that can be written into.\n///\n/// # Implementors\n///\n/// Types that implement this trait are also expected to implement these inherent methods:\n///\n/// ```ignore\n/// // use const_format::{FormattingFlags, Formatter};\n///\n/// const fn borrow_mutably(&mut self) -> &mut Self\n/// const fn make_formatter(&mut self, flags: FormattingFlags) -> Formatter<'_>\n/// ```\n///\n/// # Coercions\n///\n/// The [`Kind`](#associatedtype.Kind) and [`This`](#associatedtype.This) associated types\n/// are used in the [`IsAWriteMarker`] marker type\n/// to convert a `&mut StrWriter<_>` to a `StrWriterMut<'_>`,\n/// and leave other mutable references unconverted.\n///\n/// # Example\n///\n/// Implementing this trait for a String-like inline allocated type.\n///\n/// ```rust\n///\n/// use const_format::marker_traits::{IsNotAStrWriter, WriteMarker};\n/// use const_format::{Formatter, FormattingFlags};\n/// use const_format::writec;\n///\n/// mod arraystring {\n///     use const_format::marker_traits::{IsNotAStrWriter, WriteMarker};\n///     use const_format::{Formatter, FormattingFlags};\n///\n///     const ARRAY_CAP: usize = 64;\n///     pub struct ArrayString  {\n///         len: usize,\n///         arr: [u8; ARRAY_CAP],\n///     }\n///    \n///     impl WriteMarker for ArrayString  {\n///         type Kind = IsNotAStrWriter;\n///         type This = Self;\n///     }\n///    \n///     impl ArrayString {\n///         pub const fn new() -> Self {\n///             Self { len: 0, arr: [0; ARRAY_CAP] }\n///         }\n///         \n///         // Gets the part of the array that has been written to.\n///         pub const fn as_bytes(&self) -> &[u8] {\n///             const_format::utils::slice_up_to_len(&self.arr, self.len)\n///         }\n///    \n///         pub const fn borrow_mutably(&mut self) -> &mut Self {\n///             self\n///         }\n///    \n///         pub const fn make_formatter(&mut self, flags: FormattingFlags) -> Formatter<'_> {\n///             Formatter::from_custom(&mut self.arr, &mut self.len, flags)\n///         }\n///     }\n/// }\n/// use arraystring::ArrayString;\n///\n///\n/// let mut buffer = ArrayString::new();\n///\n/// writec!(buffer, \"{:?}\", [3u8, 5])?;\n/// assert_eq!(buffer.as_bytes(), b\"[3, 5]\");\n///\n/// writec!(buffer, \"{}{:b}\", \"Hello, world!\", 100u16)?;\n/// assert_eq!(buffer.as_bytes(), b\"[3, 5]Hello, world!1100100\");\n///\n/// # Ok::<(), const_format::Error>(())\n/// ```\npub trait WriteMarker {\n    /// Whether this is a StrWriter or not, this can be either of\n    /// [`IsAStrWriter`] or [`IsNotAStrWriter`]\n    ///\n    /// [`IsAStrWriter`]: crate::marker_traits::IsAStrWriter\n    /// [`IsNotAStrWriter`]: crate::marker_traits::IsNotAStrWriter\n    type Kind;\n\n    /// The type after dereferencing,\n    /// implemented as `type This = Self;` for all non-reference types\n    type This: ?Sized;\n}\n\n/// Marker type for `StrWriter`'s [`Kind`] in [`WriteMarker`]s\n///\n/// [`Kind`]: ./trait.WriteMarker.html#associatedtype.Kind\n/// [`WriteMarker`]: ./trait.WriteMarker.html\n///\npub struct IsAStrWriter;\n\n/// Marker type for the [`Kind`] of all non-`StrWriter` types that implement [`WriteMarker`].\n///\n/// [`Kind`]: ./trait.WriteMarker.html#associatedtype.Kind\n/// [`WriteMarker`]: ./trait.WriteMarker.html\n///\npub struct IsNotAStrWriter;\n\n///////////////////////////////////////////////////////////////////////////////\n\nimpl<T: ?Sized> WriteMarker for StrWriter<T> {\n    type Kind = IsAStrWriter;\n    type This = Self;\n}\n\nimpl WriteMarker for StrWriterMut<'_> {\n    type Kind = IsNotAStrWriter;\n    type This = Self;\n}\n\nimpl WriteMarker for Formatter<'_> {\n    type Kind = IsNotAStrWriter;\n    type This = Self;\n}\n\nimpl<T> WriteMarker for &T\nwhere\n    T: ?Sized + WriteMarker,\n{\n    type Kind = T::Kind;\n    type This = T::This;\n}\n\nimpl<T> WriteMarker for &mut T\nwhere\n    T: ?Sized + WriteMarker,\n{\n    type Kind = T::Kind;\n    type This = T::This;\n}\n\n///////////////////////////////////////////////////////////////////////////////\n\n/// Hack used to automatically convert a\n/// mutable reference to a [`StrWriter`] to a [`StrWriterMut`],\n/// and do nothing with other types.\n///\n/// The conversion is done with the `coerce` methods.\n///\n///\n/// # Type parameters\n///\n/// `K` is `<R as WriteMarker>::Kind`\n/// The kind of type that `T` is, either a [`IsAStrWriter`] or [`IsNotAStrWriter`]\n///\n/// `T` is `<R as WriteMarker>::This`:\n/// The `R` type after removing all layers of references.\n///\n/// `R`: A type that implements `WriteMarker`.\n///\n/// # Coerce Method\n///\n/// The `coerce` method is what does the conversion from a `&mut T`\n/// depending on the `K` type parameter:\n///\n/// - [`IsAStrWriter`]: the reference is converted into a `StrWriterMut<'_>`.\n///\n/// - [`IsNotAStrWriter`]: the reference is simply returned unchanged.\n///  \n///\n/// [`StrWriter`]: ../fmt/struct.StrWriter.html\n///\n/// [`StrWriterMut`]: ../fmt/struct.StrWriterMut.html\n///\n/// [`IsAStrWriter`]: ./struct.IsAStrWriter.html\n///\n/// [`IsNotAStrWriter`]: ./struct.IsNotAStrWriter.html\n///\n#[allow(clippy::type_complexity)]\npub struct IsAWriteMarker<K, T: ?Sized, R: ?Sized>(\n    PhantomData<(\n        PhantomData<fn() -> PhantomData<K>>,\n        PhantomData<fn() -> PhantomData<T>>,\n        PhantomData<fn() -> PhantomData<R>>,\n    )>,\n);\n\nimpl<K, T: ?Sized, R: ?Sized> Copy for IsAWriteMarker<K, T, R> {}\n\nimpl<K, T: ?Sized, R: ?Sized> Clone for IsAWriteMarker<K, T, R> {\n    fn clone(&self) -> Self {\n        *self\n    }\n}\n\nimpl<R> IsAWriteMarker<R::Kind, R::This, R>\nwhere\n    R: ?Sized + WriteMarker,\n{\n    /// Constructs a `IsAWriteMarker`\n    pub const NEW: Self = Self(PhantomData);\n}\n\n/////////////////////////////////////////////////////////////////////////////\n\nimpl<K, T: ?Sized, R: ?Sized> IsAWriteMarker<K, T, R> {\n    /// Infers the type parmaeters of this `IsAWriteMarker` with the passed reference.\n    #[inline(always)]\n    pub const fn infer_type(self, _: &R) -> Self {\n        self\n    }\n}\n\n/////////////////////////////////////////////////////////////////////////////\n\nimpl<T: ?Sized, R: ?Sized> IsAWriteMarker<IsAStrWriter, StrWriter<T>, R> {\n    /// Converts the `&mut StrWriter` to a `StrWriterMut<'_>`.\n    #[inline(always)]\n    pub const fn coerce(self, mutref: &mut StrWriter) -> StrWriterMut<'_> {\n        mutref.as_mut()\n    }\n}\n\nimpl<T: ?Sized, R: ?Sized> IsAWriteMarker<IsNotAStrWriter, T, R> {\n    /// An idntity function, just takes`mutref` and returns it.\n    #[inline(always)]\n    pub const fn coerce(self, mutref: &mut T) -> &mut T {\n        mutref\n    }\n}\n\n/////////////////////////////////////////////////////////////////////////////\n"
  },
  {
    "path": "const_format/src/marker_traits.rs",
    "content": "//! Marker traits for types that can be formatted and/or be written to.\n//!\n//! # Features\n//!\n//! This module is only exported with the \"fmt\" feature\n\nmod format_marker;\nmod write_marker;\n\n#[doc(inline)]\npub use self::{\n    format_marker::{FormatMarker, IsAFormatMarker, IsArrayKind, IsNotStdKind, IsStdKind},\n    write_marker::{IsAStrWriter, IsAWriteMarker, IsNotAStrWriter, WriteMarker},\n};\n"
  },
  {
    "path": "const_format/src/msg.rs",
    "content": "#![allow(non_camel_case_types)]\n\nuse crate::fmt::{Error, StrWriter};\n\nuse core::marker::PhantomData;\n\nmacro_rules! type_level_error {\n    (\n        arguments($($args:tt)*)\n\n        $($error:ident => $error_ty:ident<$($error_param:ident),*> ,)*\n    ) => {\n        type_level_error!{\n            @inner\n            arguments($($args)*)\n\n            Result::Ok(()), Ok => Ok<>,\n            $(\n                Result::Err(Error::$error), $error => $error_ty<$($error_param),*>,\n            )*\n        }\n    };\n    (@inner\n        arguments($cap:ident)\n\n        $($matched:pat , $error:ident => $error_ty:ident<$($error_param:ident),*> ,)*\n    ) => {\n\n        enum ErrorKind {\n            $($error,)*\n        }\n\n        impl ErrorTuple {\n            pub const EMPTY: ErrorTuple = ErrorTuple{\n                error_variant: ErrorKind::Ok as usize,\n                capacity: 0,\n            };\n\n            pub const fn new(opt: Result<(), Error>, writer: &StrWriter) -> Self{\n                let variant = match opt {\n                    $($matched => ErrorKind::$error as usize,)*\n                };\n\n                Self{\n                    error_variant: variant,\n                    capacity: writer.capacity(),\n                }\n            }\n\n        }\n\n\n        $(\n            pub struct $error_ty<$($error_param,)*>(PhantomData<($($error_param,)*)>);\n\n            impl<$($error_param,)*> $error_ty<$($error_param,)*> {\n                pub const NEW: Self = Self(PhantomData);\n            }\n\n            impl<$cap> ErrorAsType for ErrorPicker<[(); ErrorKind::$error as usize], $cap> {\n                type Type = $error_ty<$($error_param,)*>;\n            }\n        )*\n    }\n}\n\npub struct ErrorTupleAndStrWriter<A> {\n    pub error: ErrorTuple,\n    pub writer: StrWriter<A>,\n}\n\npub struct ErrorPicker<E, Cap>(PhantomData<fn() -> (E, Cap)>);\n\npub struct ErrorTuple {\n    pub error_variant: usize,\n    pub capacity: usize,\n}\n\npub trait ErrorAsType {\n    type Type;\n}\n\ntype_level_error! {\n    arguments(cap)\n\n    NotEnoughSpace => not_enough_space_to_write_text_in_StrWriter_with_this_capacity<cap>,\n\n    NotAscii => input_text_was_not_ascii<>,\n\n    NotOnCharBoundary => NotOnCharBoundary<>,\n}\n"
  },
  {
    "path": "const_format/src/pargument.rs",
    "content": "#![allow(clippy::wrong_self_convention)]\n\nuse crate::{\n    char_encoding::FmtChar,\n    formatting::{Formatting, FormattingFlags},\n    wrapper_types::PWrapper,\n};\n\n#[doc(hidden)]\n/// The uniform representation for every argument of the concatcp macro.\npub struct PArgument {\n    pub elem: PVariant,\n    pub fmt_len: usize,\n    pub fmt: Formatting,\n    pub fmt_flags: FormattingFlags,\n}\n\nimpl PArgument {\n    /// Calculates the length of the string after adding up all the PArguments\n    pub const fn calc_len(mut args: &[PArgument]) -> usize {\n        let mut sum = 0;\n\n        while let [curr, rem @ ..] = args {\n            args = rem;\n            sum += curr.fmt_len;\n        }\n\n        sum\n    }\n}\n\n#[doc(hidden)]\npub enum PVariant {\n    Str(&'static str),\n    Int(Integer),\n    Char(FmtChar),\n}\n\n#[derive(Debug, Copy, Clone)]\npub struct Integer {\n    pub is_negative: bool,\n    pub unsigned: u128,\n    pub mask: &'static u128, // A mask which disables the bits that weren't in the original number\n}\n\n#[doc(hidden)]\npub struct PConvWrapper<T>(pub T);\n\nmacro_rules! pconvwrapper_impls {\n    ( $( ($Signed:ty, $Unsigned:ty) )* ) => (\n        pconvwrapper_impls!{\n            @inner to_pargument_display, compute_display_len, Formatting::Display;\n            $(($Signed, $Unsigned))*\n        }\n        pconvwrapper_impls!{\n            @inner to_pargument_debug, compute_debug_len, Formatting::Debug;\n            $(($Signed, $Unsigned))*\n        }\n\n        $(\n            #[doc(hidden)]\n            impl PConvWrapper<$Signed>{\n                pub const fn to_integer(self)->Integer{\n                    Integer{\n                        is_negative: self.0 < 0,\n                        unsigned: PWrapper(self.0).unsigned_abs() as u128,\n                        mask: &(((!(0 as $Signed)) as $Unsigned) as u128),\n                    }\n                }\n            }\n\n            #[doc(hidden)]\n            impl PConvWrapper<$Unsigned>{\n                pub const fn to_integer(self)->Integer{\n                    Integer{\n                        is_negative: false,\n                        unsigned: self.0 as u128,\n                        mask: &((!(0 as $Unsigned)) as u128),\n                    }\n                }\n            }\n        )*\n    );\n    (@inner\n        $method:ident,\n        $called:ident,\n        $formatting:expr;\n        $( ($Signed:ty, $Unsigned:ty) )*\n    ) => (\n        $(\n            #[doc(hidden)]\n            impl PConvWrapper<$Signed> {\n                pub const fn $method(self, fmt_flags: FormattingFlags)->PArgument{\n                    PArgument {\n                        fmt_len: $crate::pmr::PWrapper(self.0).$called(fmt_flags),\n                        fmt: $formatting,\n                        fmt_flags,\n                        elem: PVariant::Int(self.to_integer()),\n                    }\n                }\n            }\n\n            #[doc(hidden)]\n            impl PConvWrapper<$Unsigned> {\n                pub const fn $method(self, fmt_flags: FormattingFlags)->PArgument{\n                    PArgument {\n                        fmt_len: $crate::pmr::PWrapper(self.0).$called(fmt_flags),\n                        fmt: $formatting,\n                        fmt_flags,\n                        elem: PVariant::Int(self.to_integer()),\n                    }\n                }\n            }\n        )*\n    );\n}\n\npconvwrapper_impls! {\n    (i8, u8)\n    (i16, u16)\n    (i32, u32)\n    (i64, u64)\n    (i128, u128)\n    (isize, usize)\n}\n\n#[doc(hidden)]\nimpl PConvWrapper<PArgument> {\n    #[inline]\n    pub const fn to_pargument_display(self, _: FormattingFlags) -> PArgument {\n        self.0\n    }\n    #[inline]\n    pub const fn to_pargument_debug(self, _: FormattingFlags) -> PArgument {\n        self.0\n    }\n}\n\n#[doc(hidden)]\nimpl PConvWrapper<bool> {\n    #[inline]\n    pub const fn to_pargument_display(self, _: FormattingFlags) -> PArgument {\n        PConvWrapper(if self.0 { \"true\" } else { \"false\" })\n            .to_pargument_display(FormattingFlags::DEFAULT)\n    }\n    #[inline]\n    pub const fn to_pargument_debug(self, fmt_flags: FormattingFlags) -> PArgument {\n        self.to_pargument_display(fmt_flags)\n    }\n}\n\n#[doc(hidden)]\nimpl PConvWrapper<char> {\n    #[inline]\n    pub const fn to_pargument_display(self, fmt_flags: FormattingFlags) -> PArgument {\n        let elem = crate::char_encoding::char_to_display(self.0);\n        PArgument {\n            fmt_len: elem.len(),\n            fmt_flags,\n            fmt: Formatting::Display,\n            elem: PVariant::Char(elem),\n        }\n    }\n    #[inline]\n    pub const fn to_pargument_debug(self, fmt_flags: FormattingFlags) -> PArgument {\n        let elem = crate::char_encoding::char_to_debug(self.0);\n        PArgument {\n            fmt_len: elem.len(),\n            fmt_flags,\n            fmt: Formatting::Debug,\n            elem: PVariant::Char(elem),\n        }\n    }\n}\n\n#[doc(hidden)]\nimpl PConvWrapper<&'static str> {\n    #[inline]\n    pub const fn to_pargument_display(self, fmt_flags: FormattingFlags) -> PArgument {\n        PArgument {\n            fmt_len: PWrapper(self.0).compute_display_len(fmt_flags),\n            fmt_flags,\n            fmt: Formatting::Display,\n            elem: PVariant::Str(self.0),\n        }\n    }\n    #[inline]\n    pub const fn to_pargument_debug(self, fmt_flags: FormattingFlags) -> PArgument {\n        PArgument {\n            fmt_len: PWrapper(self.0).compute_debug_len(fmt_flags),\n            fmt_flags,\n            fmt: Formatting::Debug,\n            elem: PVariant::Str(self.0),\n        }\n    }\n}\n"
  },
  {
    "path": "const_format/src/slice_cmp.rs",
    "content": "/// A const equivalent of `&str` equality comparison.\n///\n/// # Example\n///\n#[cfg_attr(feature = \"fmt\", doc = \"```rust\")]\n#[cfg_attr(not(feature = \"fmt\"), doc = \"```ignore\")]\n/// use const_format::utils::str_eq;\n///\n/// const STRS: &[&str] = &[\n///     \"foo\",\n///     \"fooooo\",\n///     \"bar\",\n///     \"baz\",\n/// ];\n///\n/// const ARE_0_0_EQ: bool = str_eq(STRS[0], STRS[0]);\n/// const ARE_0_1_EQ: bool = str_eq(STRS[0], STRS[1]);\n///\n/// const ARE_1_1_EQ: bool = str_eq(STRS[1], STRS[1]);\n/// const ARE_1_2_EQ: bool = str_eq(STRS[1], STRS[2]);\n///\n/// const ARE_2_2_EQ: bool = str_eq(STRS[2], STRS[2]);\n/// const ARE_2_3_EQ: bool = str_eq(STRS[2], STRS[3]);\n///\n/// assert!(  ARE_0_0_EQ );\n/// assert!( !ARE_0_1_EQ );\n///\n/// assert!(  ARE_1_1_EQ );\n/// assert!( !ARE_1_2_EQ );\n///\n/// assert!(  ARE_2_2_EQ );\n/// assert!( !ARE_2_3_EQ );\n///\n/// ```\n///\npub const fn str_eq(left: &str, right: &str) -> bool {\n    u8_slice_eq(left.as_bytes(), right.as_bytes())\n}\n\n/// A const equivalent of `&[u8]` equality comparison.\n///\n/// # Example\n///\n#[cfg_attr(feature = \"fmt\", doc = \"```rust\")]\n#[cfg_attr(not(feature = \"fmt\"), doc = \"```ignore\")]\n/// use const_format::utils::u8_slice_eq;\n///\n/// const SLICES: &[&[u8]] = &[\n///     &[10, 20],\n///     &[10, 20, 30, 40],\n///     &[3, 5, 8, 13],\n///     &[4, 9, 16, 25],\n/// ];\n///\n/// const ARE_0_0_EQ: bool = u8_slice_eq(SLICES[0], SLICES[0]);\n/// const ARE_0_1_EQ: bool = u8_slice_eq(SLICES[0], SLICES[1]);\n///\n/// const ARE_1_1_EQ: bool = u8_slice_eq(SLICES[1], SLICES[1]);\n/// const ARE_1_2_EQ: bool = u8_slice_eq(SLICES[1], SLICES[2]);\n///\n/// const ARE_2_2_EQ: bool = u8_slice_eq(SLICES[2], SLICES[2]);\n/// const ARE_2_3_EQ: bool = u8_slice_eq(SLICES[2], SLICES[3]);\n///\n/// assert!(  ARE_0_0_EQ );\n/// assert!( !ARE_0_1_EQ );\n///\n/// assert!(  ARE_1_1_EQ );\n/// assert!( !ARE_1_2_EQ );\n///\n/// assert!(  ARE_2_2_EQ );\n/// assert!( !ARE_2_3_EQ );\n///\n/// ```\n///\npub const fn u8_slice_eq(left: &[u8], right: &[u8]) -> bool {\n    if left.len() != right.len() {\n        return false;\n    }\n\n    let mut i = 0;\n    while i != left.len() {\n        if left[i] != right[i] {\n            return false;\n        }\n        i += 1;\n    }\n\n    true\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    #[test]\n    fn slice_eq_test() {\n        assert!(u8_slice_eq(&[], &[]));\n        assert!(!u8_slice_eq(&[], &[0]));\n        assert!(!u8_slice_eq(&[0], &[]));\n        assert!(u8_slice_eq(&[0], &[0]));\n        assert!(!u8_slice_eq(&[0], &[1]));\n        assert!(!u8_slice_eq(&[1], &[0]));\n        assert!(!u8_slice_eq(&[0], &[0, 1]));\n        assert!(!u8_slice_eq(&[0, 1], &[0]));\n        assert!(u8_slice_eq(&[0, 1], &[0, 1]));\n        assert!(!u8_slice_eq(&[0, 1], &[0, 2]));\n    }\n\n    #[test]\n    fn str_eq_test() {\n        assert!(str_eq(\"\", \"\"));\n        assert!(!str_eq(\"\", \"0\"));\n        assert!(!str_eq(\"0\", \"\"));\n        assert!(str_eq(\"0\", \"0\"));\n        assert!(!str_eq(\"0\", \"1\"));\n        assert!(!str_eq(\"1\", \"0\"));\n        assert!(!str_eq(\"0\", \"0, 1\"));\n        assert!(!str_eq(\"0, 1\", \"0\"));\n        assert!(!str_eq(\"0, 1\", \"1\"));\n        assert!(str_eq(\"0, 1\", \"0, 1\"));\n        assert!(!str_eq(\"0, 1\", \"0, 2\"));\n    }\n}\n"
  },
  {
    "path": "const_format/src/test_utils.rs",
    "content": "#![allow(missing_docs)]\n\n#[doc(hidden)]\n#[macro_export]\nmacro_rules! __identity {\n    ($($tt:tt)*) => {$($tt)*};\n}\n\n#[doc(hidden)]\n#[macro_export]\nmacro_rules! __declare_rng_ext {\n    () => {\n        pub trait RngExt {\n            fn as_rng(&self) -> &fastrand::Rng;\n\n            fn pick<'a, T>(&self, slice: &'a [T]) -> &'a T {\n                &slice[self.as_rng().usize(0..slice.len())]\n            }\n\n            fn char_(&self, bounds: core::ops::RangeInclusive<char>) -> char {\n                let this = self.as_rng();\n\n                if let None = bounds.clone().next() {\n                    panic!(\"There are no chars in the {:?} bounds\", bounds);\n                }\n\n                let u32_bounds = u32::from(*bounds.start())..=u32::from(*bounds.end());\n\n                loop {\n                    if let Some(x) = core::char::from_u32(this.u32(u32_bounds.clone())) {\n                        break x;\n                    }\n                }\n            }\n\n            fn unicode_char(&self) -> char {\n                let this = self.as_rng();\n                let range = this\n                    .pick(&[\n                        '\\u{0000}'..='\\u{007F}',\n                        '\\u{0080}'..='\\u{07FF}',\n                        '\\u{0800}'..='\\u{FFFF}',\n                        '\\u{10000}'..='\\u{10FFFF}',\n                    ])\n                    .clone();\n                this.char_(range)\n            }\n        }\n\n        impl RngExt for fastrand::Rng {\n            fn as_rng(&self) -> &fastrand::Rng {\n                self\n            }\n        }\n    };\n}\n\npub const ALL_ASCII: &str = \"\\\n \\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\\n \\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f \\\n !\\\"#$%&\\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\]\\\n ^_`abcdefghijklmnopqrstuvwxyz{|}~\\x7f\\u{80}\\u{81}\\u{90}\\u{91}\\\n\";\n\npub const ALL_ASCII_ESCAPED: &str = \"\\\n \\\\x00\\\\x01\\\\x02\\\\x03\\\\x04\\\\x05\\\\x06\\\\x07\\\\x08\\\\t\\\\n\\\\x0B\\\\x0C\\\\r\\\\x0E\\\\x0F\\\n \\\\x10\\\\x11\\\\x12\\\\x13\\\\x14\\\\x15\\\\x16\\\\x17\\\\x18\\\\x19\\\\x1A\\\\x1B\\\\x1C\\\\x1D\\\\x1E\\\\x1F \\\n !\\\\\\\"#$%&\\\\\\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\\\\\]\\\n ^_`abcdefghijklmnopqrstuvwxyz{|}~\\x7f\\u{80}\\u{81}\\u{90}\\u{91}\\\n\";\n"
  },
  {
    "path": "const_format/src/utils.rs",
    "content": "//! Miscelaneous functions.\n\nuse core::ops::Range;\n\n/// Newtype wrapper to get around limitations in `const fn`s\npub(crate) struct Constructor<T>(#[allow(dead_code)] fn() -> T);\n\npub use crate::slice_cmp::{str_eq, u8_slice_eq};\n\n#[doc(hidden)]\n#[inline]\npub const fn saturate_range(s: &[u8], range: &Range<usize>) -> Range<usize> {\n    let len = s.len();\n    let end = min_usize(range.end, len);\n    min_usize(range.start, end)..end\n}\n\n#[doc(hidden)]\n#[repr(C)]\npub union Dereference<'a, T: ?Sized> {\n    pub ptr: *const T,\n    pub reff: &'a T,\n}\n\n////////////////////////////////////////////////////////////////////////////////\n\n/// The same as [`slice_up_to_len`]\n///\n/// (this function only exists for backwards compatibility)\n#[deprecated(since = \"0.2.36\", note = \"redundant, same as `slice_up_to_len`\")]\n#[inline(always)]\npub const fn slice_up_to_len_alt<T>(slice: &[T], len: usize) -> &[T] {\n    slice_up_to_len(slice, len)\n}\n\n////////////////////////////////////////////////////////////////////////////////\n\n/// A const equivalent of `&slice[..len]`.\n///\n/// If `slice.len() < len`, this simply returns `slice` back.\n///\n/// # Example\n///\n/// ```rust\n/// use const_format::utils::slice_up_to_len;\n///\n/// const FIBB: &[u16] = &[3, 5, 8, 13, 21, 34, 55, 89];\n///\n/// const TWO: &[u16] = slice_up_to_len(FIBB, 2);\n/// const FOUR: &[u16] = slice_up_to_len(FIBB, 4);\n/// const ALL: &[u16] = slice_up_to_len(FIBB, usize::MAX);\n///\n/// assert_eq!(TWO, &[3, 5]);\n/// assert_eq!(FOUR, &[3, 5, 8, 13]);\n/// assert_eq!(FIBB, ALL);\n///\n/// ```\n#[inline(always)]\npub const fn slice_up_to_len<T>(slice: &[T], len: usize) -> &[T] {\n    if len > slice.len() {\n        return slice;\n    }\n\n    slice.split_at(len).0\n}\n\n////////////////////////////////////////////////////////////////////////////////\n\npub(crate) const fn min_usize(l: usize, r: usize) -> usize {\n    if l < r {\n        l\n    } else {\n        r\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    #[test]\n    fn test_slice_up_to_len_alt() {\n        let mut list = [0u16; 256];\n\n        (100..).zip(list.iter_mut()).for_each(|(i, m)| *m = i);\n\n        for i in 0..list.len() {\n            assert_eq!(slice_up_to_len_alt(&list, i), &list[..i]);\n        }\n    }\n\n    #[test]\n    fn slice_in_bounds() {\n        assert_eq!(slice_up_to_len(&[3, 5], 0), []);\n        assert_eq!(slice_up_to_len(&[3, 5], 1), [3]);\n        assert_eq!(slice_up_to_len(&[3, 5], 2), [3, 5]);\n        assert_eq!(slice_up_to_len(&[3, 5], 3), [3, 5]);\n        assert_eq!(slice_up_to_len(&[3, 5], 4), [3, 5]);\n    }\n}\n"
  },
  {
    "path": "const_format/src/wrapper_types/ascii_str.rs",
    "content": "// use crate::fmt::Error;\n\n#[cfg(feature = \"fmt\")]\nuse crate::fmt::{Error, Formatter};\n\nuse core::fmt::{self, Display};\n\n////////////////////////////////////////////////////////////////////////////////\n\n/// An ascii string slice.\n///\n/// You can also construct an `AsciiStr` at compile-time with the [`ascii_str`] macro,\n/// erroring at compile if the constant isn't ascii.\n///\n/// # Example\n///\n/// ```rust\n/// use const_format::wrapper_types::{AsciiStr, NotAsciiError};\n/// use const_format::ascii_str;\n///\n/// const HELLO: AsciiStr = unwrap_ascii(AsciiStr::new(b\"hello\"));\n/// const EURO: AsciiStr = unwrap_ascii(AsciiStr::new(\"foo €\".as_bytes()));\n///\n/// assert_eq!(HELLO.as_str(), \"hello\");\n/// assert_eq!(EURO.as_str(), \"<error>\");\n/// assert_eq!(AsciiStr::new(\"foo €\".as_bytes()), Err(NotAsciiError{invalid_from: 4}));\n///\n/// const fn unwrap_ascii(res: Result<AsciiStr<'_>, NotAsciiError>) -> AsciiStr<'_> {\n///     match res {\n///         Ok(x) => x,\n///         Err(_) => ascii_str!(\"<error>\"),\n///     }\n/// }\n///\n/// ```\n///\n/// [`ascii_str`]: ./macro.ascii_str.html\n///\n#[cfg_attr(feature = \"__docsrs\", doc(cfg(feature = \"fmt\")))]\n#[derive(Debug, Copy, Clone, PartialEq, Eq, Ord, PartialOrd, Hash)]\npub struct AsciiStr<'a>(&'a [u8]);\n\nimpl<'a> AsciiStr<'a> {\n    /// Constructs this  AsciiStr from a possibly non-ascii str slice.\n    ///\n    /// Returns a `NonAsciiError` error on the first non-ascii byte.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    /// use const_format::wrapper_types::{AsciiStr, NotAsciiError};\n    ///\n    /// let ok = AsciiStr::from_str(\"foo bar\").unwrap();\n    ///\n    /// assert_eq!(ok.as_str(), \"foo bar\");\n    /// assert_eq!(AsciiStr::from_str(\"foo bar ½\"), Err(NotAsciiError{invalid_from: 8}));\n    ///\n    /// ```\n    #[inline(always)]\n    pub const fn from_str(s: &'a str) -> Result<Self, NotAsciiError> {\n        Self::new(s.as_bytes())\n    }\n\n    /// Constructs this  AsciiStr from a possibly non-ascii byte slice.\n    ///\n    /// Returns a `NonAsciiError` error on the first non-ascii byte.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    /// use const_format::wrapper_types::{AsciiStr, NotAsciiError};\n    ///\n    /// let ok = AsciiStr::new(b\"foo bar\").unwrap();\n    ///\n    /// assert_eq!(ok.as_str(), \"foo bar\");\n    /// assert_eq!(AsciiStr::new(b\"foo bar \\x80\"), Err(NotAsciiError{invalid_from: 8}));\n    ///\n    /// ```\n    pub const fn new(s: &'a [u8]) -> Result<Self, NotAsciiError> {\n        __for_range! {i in 0..s.len()=>\n            if s[i] > 127 {\n                return Err(NotAsciiError{invalid_from: i});\n            }\n        }\n        Ok(AsciiStr(s))\n    }\n\n    /// Constructs an empty `AsciiStr`\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    /// use const_format::AsciiStr;\n    ///\n    /// assert_eq!(AsciiStr::empty().as_str(), \"\");\n    /// ```\n    pub const fn empty() -> Self {\n        Self(&[])\n    }\n\n    /// Queries the length of the `AsciiStr`\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    /// use const_format::{AsciiStr, ascii_str};\n    ///\n    /// assert_eq!(AsciiStr::empty().len(), 0);\n    /// assert_eq!(ascii_str!(\"hello\").len(), 5);\n    /// ```\n    #[inline(always)]\n    pub const fn len(self) -> usize {\n        self.0.len()\n    }\n\n    /// Queries whether this `AsciiStr` is empty.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    /// use const_format::{AsciiStr, ascii_str};\n    ///\n    /// assert_eq!(AsciiStr::empty().is_empty(), true);\n    /// assert_eq!(ascii_str!(\"hello\").is_empty(), false);\n    /// ```\n    #[inline(always)]\n    pub const fn is_empty(self) -> bool {\n        self.0.is_empty()\n    }\n\n    /// Accessor for the wrapped ascii string.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    /// use const_format::{AsciiStr, ascii_str};\n    ///\n    /// assert_eq!(AsciiStr::empty().as_bytes(), b\"\");\n    /// assert_eq!(ascii_str!(\"hello\").as_bytes(), b\"hello\");\n    /// ```\n    #[inline(always)]\n    pub const fn as_bytes(self) -> &'a [u8] {\n        self.0\n    }\n\n    /// Accessor for the wrapped ascii string.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    /// use const_format::{AsciiStr, ascii_str};\n    ///\n    /// assert_eq!(AsciiStr::empty().as_str(), \"\");\n    /// assert_eq!(ascii_str!(\"hello\").as_str(), \"hello\");\n    /// ```\n    #[inline]\n    pub const fn as_str(self) -> &'a str {\n        unsafe { core::str::from_utf8_unchecked(self.0) }\n    }\n}\n\n////////////////////////////////////////////////////////////////////////////////\n\n/// Error from [`AsciiStr`] constructor, caused by a byte not being valid ascii.\n///\n/// [`AsciiStr`]: ../struct.AsciiStr.html\n#[derive(Debug, Copy, Clone, PartialEq)]\npub struct NotAsciiError {\n    /// The first non-ascii byte in the byte slice.\n    pub invalid_from: usize,\n}\n\nimpl Display for NotAsciiError {\n    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {\n        fmt.write_str(\"error: the input bytes were not valid ascii\")\n    }\n}\n\n////////////////////////////////////////////////////////////////////////////////\n\n#[cfg(feature = \"fmt\")]\nimpl_fmt! {\n    impl AsciiStr<'_>;\n\n    ///\n    pub const fn const_display_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {\n        f.write_ascii(*self)\n    }\n\n    ///\n    pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {\n        f.write_ascii_debug(*self)\n    }\n}\n\n////////////////////////////////////////////////////////////////////////////////\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    #[cfg(feature = \"fmt\")]\n    use crate::fmt::ComputeStrLength;\n\n    use arrayvec::ArrayString;\n\n    #[test]\n    fn basic() {\n        {\n            let ok = AsciiStr::new(\"hello!\".as_bytes()).unwrap();\n            assert_eq!(ok.as_bytes(), \"hello!\".as_bytes());\n            assert_eq!(ok.as_str(), \"hello!\");\n        }\n        {\n            let err = AsciiStr::from_str(\"Φοο!\").unwrap_err();\n            assert_eq!(err.invalid_from, 0)\n        }\n        {\n            let err = AsciiStr::from_str(\"hello Φοο!\").unwrap_err();\n            assert_eq!(err.invalid_from, 6)\n        }\n    }\n\n    // This doesn't use unsafe code\n    #[cfg(not(miri))]\n    #[test]\n    fn only_ascii_constructible() {\n        let mut string = ArrayString::<1024>::new();\n        let min = '\\u{20}';\n        let max = '\\u{80}';\n        assert!(!max.is_ascii());\n        for end in min..=max {\n            for start in min..=end {\n                string.clear();\n                for n in start..=end {\n                    string.push(n);\n                }\n                let res = AsciiStr::new(string.as_bytes());\n                assert_eq!(res.is_ok(), string.as_bytes().is_ascii());\n\n                if let Ok(ascii) = res {\n                    assert_eq!(ascii.as_bytes(), string.as_bytes());\n                }\n            }\n        }\n    }\n\n    #[cfg(feature = \"fmt\")]\n    #[test]\n    fn formatting() {\n        use crate::fmt::{FormattingFlags, NumberFormatting, StrWriter};\n\n        const fn inner_debug(\n            ascii: AsciiStr<'_>,\n            writer: &mut StrWriter,\n            flags: FormattingFlags,\n        ) -> Result<usize, Error> {\n            try_!(ascii.const_debug_fmt(&mut writer.make_formatter(flags)));\n\n            let mut str_len = ComputeStrLength::new();\n            try_!(ascii.const_debug_fmt(&mut str_len.make_formatter(flags)));\n\n            Ok(str_len.len())\n        }\n\n        const fn inner_display(\n            ascii: AsciiStr<'_>,\n            writer: &mut StrWriter,\n            flags: FormattingFlags,\n        ) -> Result<usize, Error> {\n            try_!(ascii.const_display_fmt(&mut writer.make_formatter(flags)));\n\n            let mut str_len = ComputeStrLength::new();\n            try_!(ascii.const_display_fmt(&mut str_len.make_formatter(flags)));\n\n            Ok(str_len.len())\n        }\n\n        fn test_case(\n            ascii: AsciiStr<'_>,\n            writer: &mut StrWriter,\n            flags: FormattingFlags,\n            expected_debug: &str,\n            expected_display: &str,\n        ) {\n            writer.clear();\n            let len = inner_debug(ascii, writer, flags).unwrap();\n\n            assert_eq!(writer.as_str(), expected_debug);\n            assert_eq!(writer.len(), len, \"{}\", writer.as_str());\n\n            writer.clear();\n            let len = inner_display(ascii, writer, flags).unwrap();\n\n            assert_eq!(writer.as_str(), expected_display);\n            assert_eq!(writer.len(), len, \"{}\", writer.as_str());\n        }\n\n        let writer: &mut StrWriter = &mut StrWriter::new([0; 128]);\n\n        let foo = AsciiStr::new(\"\\0\\x10hello\\tworld\\n\".as_bytes()).unwrap();\n\n        for num_fmt in NumberFormatting::ALL.iter().copied() {\n            for is_alt in [false, true].iter().copied() {\n                let flag = FormattingFlags::NEW\n                    .set_num_fmt(num_fmt)\n                    .set_alternate(is_alt);\n                test_case(\n                    foo,\n                    writer,\n                    flag,\n                    \"\\\"\\\\x00\\\\x10hello\\\\tworld\\\\n\\\"\",\n                    foo.as_str(),\n                );\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "const_format/src/wrapper_types/pwrapper/tests.rs",
    "content": "use crate::{\n    formatting::{FormattingFlags, NumberFormatting as NF},\n    pargument::PConvWrapper,\n    wrapper_types::PWrapper,\n};\n\nuse arrayvec::ArrayString;\n\nuse core::fmt::{self, Write};\n\nfn get_digits_display(n: impl fmt::Display) -> ArrayString<64> {\n    let mut buff = ArrayString::<64>::new();\n    write!(buff, \"{}\", n).unwrap();\n    buff\n}\nfn get_hex_digits(n: impl fmt::UpperHex) -> ArrayString<64> {\n    let mut buff = ArrayString::<64>::new();\n    write!(buff, \"{:X}\", n).unwrap();\n    buff\n}\nfn get_lower_hex_digits(n: impl fmt::LowerHex) -> ArrayString<64> {\n    let mut buff = ArrayString::<64>::new();\n    write!(buff, \"{:x}\", n).unwrap();\n    buff\n}\nfn get_binary_digits(n: impl fmt::Binary) -> ArrayString<192> {\n    let mut buff = ArrayString::<192>::new();\n    write!(buff, \"{:b}\", n).unwrap();\n    buff\n}\n\nconst DEF_FLAGS: FormattingFlags = FormattingFlags::DEFAULT;\n\n// This doesn't use unsafe code\n#[cfg(not(miri))]\nmacro_rules! check_number_of_digits_ {\n    ($ty:ty) => {{\n        fn number_of_digits_test_case(val: $ty) {\n            let display_digits = get_digits_display(val);\n            let hex_digits = get_hex_digits(val);\n            let lower_hex_digits = get_lower_hex_digits(val);\n            let binary_digits = get_binary_digits(val);\n            let wrapper = PWrapper(val);\n\n            {\n                assert_eq!(\n                    wrapper.compute_display_len(DEF_FLAGS),\n                    display_digits.len(),\n                    \"const_display_len\"\n                );\n                assert_eq!(\n                    wrapper.compute_debug_len(DEF_FLAGS),\n                    display_digits.len(),\n                    \"const_debug_len \"\n                );\n                assert_eq!(\n                    wrapper.compute_debug_len(DEF_FLAGS.set_num_fmt(NF::Hexadecimal)),\n                    hex_digits.len(),\n                    \"const_debug_len hexadecimal\"\n                );\n                assert_eq!(\n                    wrapper.compute_debug_len(DEF_FLAGS.set_lower_hexadecimal()),\n                    lower_hex_digits.len(),\n                    \"const_debug_len lower hexadecimal\"\n                );\n                assert_eq!(\n                    wrapper.compute_debug_len(DEF_FLAGS.set_num_fmt(NF::Binary)),\n                    binary_digits.len(),\n                    \"const_debug_len binary\"\n                );\n            }\n\n            {\n                let integer = PWrapper(PConvWrapper(val).to_integer());\n\n                let sa = integer.to_start_array_display();\n                assert_eq!(\n                    &sa.array[sa.start..],\n                    display_digits.as_bytes(),\n                    \"const_display_len\"\n                );\n\n                let sa = integer.to_start_array_debug();\n                assert_eq!(\n                    &sa.array[sa.start..],\n                    display_digits.as_bytes(),\n                    \"const_debug_len \"\n                );\n\n                let sa = integer.to_start_array_hexadecimal(FormattingFlags::NEW);\n                assert_eq!(\n                    &sa.array[sa.start..],\n                    hex_digits.as_bytes(),\n                    \"const_debug_len hexadecimal\"\n                );\n\n                let sa = integer\n                    .to_start_array_hexadecimal(FormattingFlags::NEW.set_lower_hexadecimal());\n                assert_eq!(\n                    &sa.array[sa.start..],\n                    lower_hex_digits.as_bytes(),\n                    \"const_debug_len lower hexadecimal\"\n                );\n\n                let sa = integer.to_start_array_binary(FormattingFlags::NEW);\n                assert_eq!(\n                    &sa.array[sa.start..],\n                    binary_digits.as_bytes(),\n                    \"const_debug_len binary\"\n                );\n            }\n        }\n\n        let zero: $ty = 0;\n        let one: $ty = 1;\n        let two: $ty = 2;\n\n        number_of_digits_test_case(zero);\n        number_of_digits_test_case(one);\n        number_of_digits_test_case(two);\n\n        let mut n: $ty = 10;\n\n        loop {\n            number_of_digits_test_case(n - 1);\n            number_of_digits_test_case(n);\n            number_of_digits_test_case(n + 1);\n\n            match n.checked_mul(10) {\n                Some(next) => n = next,\n                None => break,\n            }\n        }\n\n        let max_s2: $ty = <$ty>::MAX - 2;\n        let max_s1: $ty = <$ty>::MAX - 1;\n        let max_s0: $ty = <$ty>::MAX;\n\n        number_of_digits_test_case(max_s2);\n        number_of_digits_test_case(max_s1);\n        number_of_digits_test_case(max_s0);\n    }};\n}\n\n// This doesn't use unsafe code\n#[cfg(not(miri))]\n#[test]\nfn pwrapper_methods() {\n    check_number_of_digits_!(i8);\n    check_number_of_digits_!(u8);\n    check_number_of_digits_!(i16);\n    check_number_of_digits_!(u16);\n    check_number_of_digits_!(i32);\n    check_number_of_digits_!(u32);\n    check_number_of_digits_!(u64);\n    check_number_of_digits_!(i64);\n    check_number_of_digits_!(usize);\n    check_number_of_digits_!(isize);\n    check_number_of_digits_!(u128);\n    check_number_of_digits_!(i128);\n}\n\n#[cfg(feature = \"fmt\")]\n#[test]\nfn wrapped_formatting() {\n    use crate::fmt::{Error, StrWriter};\n\n    const fn inner(writer: &mut StrWriter) -> Result<(), Error> {\n        try_!(writec!(writer, \"{},\", PWrapper(3u8)));\n        try_!(writec!(writer, \"{},\", PWrapper(5u16)));\n        try_!(writec!(writer, \"{},\", PWrapper(8u32)));\n        try_!(writec!(writer, \"{},\", PWrapper(\"hello\")));\n        Ok(())\n    }\n\n    let writer: &mut StrWriter = &mut StrWriter::new([0; 128]);\n\n    inner(writer).unwrap();\n\n    assert_eq!(writer.as_str(), \"3,5,8,hello,\");\n}\n"
  },
  {
    "path": "const_format/src/wrapper_types/pwrapper.rs",
    "content": "#![allow(unexpected_cfgs)]\n\nuse crate::{\n    formatting::{FormattingFlags, NumberFormatting, StartAndArray, FOR_ESCAPING},\n    pargument::Integer,\n};\n\nuse core::ops::Range;\n\n#[cfg(test)]\nmod tests;\n\n/// Wrapper for many std types,\n/// which implements the `const_debug_fmt` and/or `const_display_fmt` methods for them.\n///\n/// The macros from this crate automatically wraps std types in this type,\n/// so you only need to use it if you're manually calling the `const_*_fmt` methods.\n///\n/// ### Constructors\n///\n/// Most std types can be wrapped in this type simply by doing `PWrapper(value)`.\n///\n/// To wrap arrays, there is the [`PWrapper::slice`](#method.slice) constructor\n/// for convenience.\n///\n/// ### Excluded std types\n///\n/// Note that this type does not implement the formatting methods\n/// for std types which wrap non-std types,\n/// only for a selection of wrapped std types.\n///\n/// You can use the [`call_debug_fmt`] macro to format arrays/slices/Options of\n/// any type that can be const debug formatted.\n///\n/// # Example\n///\n/// This example demonstrates how you can implement debug formatting for a type\n/// using PWrapper to write std types.\n///\n#[cfg_attr(feature = \"fmt\", doc = \"```rust\")]\n#[cfg_attr(not(feature = \"fmt\"), doc = \"```ignore\")]\n///\n/// use const_format::{Error, Formatter, PWrapper};\n/// use const_format::{impl_fmt, formatc, try_};\n///\n/// use core::num::NonZeroU32;\n///\n/// pub struct Divide(pub u32, pub u32);\n///\n/// impl_fmt!{\n///     impl Divide;\n///     \n///     pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {\n///         let Self(left, right) = *self;\n///         let divided = self.0 / self.1;\n///\n///         let mut f = f.debug_struct(\"Divide\");\n///         try_!(PWrapper(self.0).const_debug_fmt(f.field(\"numerator\")));\n///         try_!(PWrapper(self.1).const_debug_fmt(f.field(\"denominator\")));\n///         try_!(PWrapper(divided).const_debug_fmt(f.field(\"divided\")));\n///         f.finish()\n///     }\n/// }\n///\n/// const TEXT: &str = formatc!(\"{:?}\", Divide(34, 11));\n/// const T_HEX: &str = formatc!(\"{:X?}\", Divide(34, 11));\n/// const T_BIN: &str = formatc!(\"{:b?}\", Divide(34, 11));\n///\n/// assert_eq!(TEXT, \"Divide { numerator: 34, denominator: 11, divided: 3 }\");\n/// assert_eq!(T_HEX, \"Divide { numerator: 22, denominator: B, divided: 3 }\");\n/// assert_eq!(T_BIN, \"Divide { numerator: 100010, denominator: 1011, divided: 11 }\");\n/// ```\n///\n/// [`call_debug_fmt`]: ./macro.call_debug_fmt.html\n/// [`writec`]: ./macro.writec.html\n///\n#[cfg_attr(feature = \"__docsrs\", doc(cfg(feature = \"fmt\")))]\n#[derive(Copy, Clone)]\npub struct PWrapper<T>(pub T);\n\nimpl<'a, T> PWrapper<&'a [T]> {\n    /// For constructing from a reference to an array.\n    ///\n    /// With slices you can do `PWrapper(slice)` as well.\n    #[inline(always)]\n    pub const fn slice(x: &'a [T]) -> Self {\n        Self { 0: x }\n    }\n}\n\nmacro_rules! compute_hex_count {\n    ($bits:expr, $int:expr, $with_0x:expr) => {{\n        let with_0x = ($with_0x as usize) << 1;\n        let i = ($bits - $int.leading_zeros()) as usize;\n        (if i == 0 {\n            1\n        } else {\n            (i >> 2) + ((i & 3) != 0) as usize\n        }) + with_0x\n    }};\n}\nmacro_rules! compute_binary_count {\n    ($bits:expr, $int:expr, $with_0b:expr) => {{\n        let with_0b = ($with_0b as usize) << 1;\n        let i = ($bits - $int.leading_zeros()) as usize;\n        (if i == 0 { 1 } else { i }) + with_0b\n    }};\n}\n\nmacro_rules! impl_number_of_digits {\n    (num number_of_digits;delegate $n:ident $len:ident)=>{\n        $n.number_of_digits()\n    };\n    (num number_of_digits;128 $n:ident $len:ident)=>{{\n        if $n >= 1_0000_0000_0000_0000{$n /= 1_0000_0000_0000_0000; $len += 16;}\n        impl_number_of_digits!(num number_of_digits;64 $n $len)\n    }};\n    (num number_of_digits;64 $n:ident $len:ident)=>{{\n        if $n >= 1_0000_0000_0000{$n /= 1_0000_0000_0000; $len += 12;}\n        impl_number_of_digits!(num number_of_digits;32 $n $len)\n    }};\n    (num number_of_digits;32 $n:ident $len:ident)=>{{\n        if $n >= 1_0000_0000{$n /= 100_000_000; $len += 8;}\n        impl_number_of_digits!(num number_of_digits;16 $n $len)\n    }};\n    (num number_of_digits;16 $n:ident $len:ident)=>{{\n        if $n >= 1_0000{$n /= 1_0000; $len += 4;}\n        impl_number_of_digits!(num number_of_digits;8 $n $len)\n    }};\n    (num number_of_digits;8 $n:ident $len:ident)=>{{\n        if $n >= 100{$n /= 100; $len += 2;}\n        if $n >= 10{            $len += 1;}\n        $len\n    }};\n    (@shared $This:ty, $bits:tt)=>{\n        impl PWrapper<$This> {\n            /// Computes how long much space is necessary to write this integer as a literal.\n            #[allow(unused_mut,unused_variables)]\n            #[doc(hidden)]\n            pub const fn compute_debug_len(self, fmt: FormattingFlags)-> usize {\n                match fmt.num_fmt() {\n                    NumberFormatting::Decimal=>\n                        self.compute_display_len(fmt),\n                    NumberFormatting::Hexadecimal=>\n                        compute_hex_count!($bits, self.0, fmt.is_alternate()),\n                    NumberFormatting::Binary=>\n                        compute_binary_count!($bits, self.0, fmt.is_alternate()),\n                }\n            }\n\n            /// Computes how long much space is necessary to\n            /// write this integer as a hexadecimal literal.\n            pub const fn hexadecimal_len(self, fmt: FormattingFlags)-> usize {\n                compute_hex_count!($bits, self.0, fmt.is_alternate())\n            }\n\n            /// Computes how long much space is necessary to\n            /// write this integer as a binary literal.\n            pub const fn binary_len(self, fmt: FormattingFlags)-> usize {\n                compute_binary_count!($bits, self.0, fmt.is_alternate())\n            }\n        }\n    };\n    (impl_either;\n        signed,\n        ($This:ty, $Unsigned:ty),\n        $bits:tt $(,)?\n    )=>{\n        impl_number_of_digits!{@shared $This, $bits}\n\n        impl PWrapper<$This> {\n            /// Returns the absolute value of this integer, as the equivalent unsigned type.\n            pub const fn unsigned_abs(self) -> $Unsigned {\n                self.0.wrapping_abs() as $Unsigned\n            }\n\n            #[allow(unused_mut,unused_variables)]\n            #[doc(hidden)]\n            pub const fn compute_display_len(self, _: FormattingFlags)-> usize {\n                let mut n = self.0.wrapping_abs() as $Unsigned;\n                let mut len = 1 + (self.0 < 0) as usize;\n                impl_number_of_digits!(num number_of_digits;$bits n len)\n            }\n\n\n        }\n    };\n    (impl_either;\n        unsigned,\n        ($This:ty, $Unsigned:ty),\n        $bits:tt $(,)?\n    )=>{\n        impl_number_of_digits!{@shared $This, $bits}\n\n        impl PWrapper<$This> {\n            /// Returns the absolute value of this integer, as the equivalent unsigned type.\n            pub const fn unsigned_abs(self) -> $Unsigned {\n                self.0\n            }\n\n            #[doc(hidden)]\n            pub const fn compute_display_len(self, _: FormattingFlags)-> usize {\n                let mut n = self.0;\n                let mut len = 1usize;\n                impl_number_of_digits!(num number_of_digits;$bits n len)\n            }\n        }\n    };\n}\n\nimpl_number_of_digits! {impl_either; signed  , (i8, u8), 8}\nimpl_number_of_digits! {impl_either; signed  , (i16, u16), 16}\nimpl_number_of_digits! {impl_either; signed  , (i32, u32), 32}\nimpl_number_of_digits! {impl_either; signed  , (i64, u64), 64}\nimpl_number_of_digits! {impl_either; signed  , (i128, u128), 128}\nimpl_number_of_digits! {impl_either; unsigned, (u8, u8), 8}\nimpl_number_of_digits! {impl_either; unsigned, (u16, u16), 16}\nimpl_number_of_digits! {impl_either; unsigned, (u32, u32), 32}\nimpl_number_of_digits! {impl_either; unsigned, (u64, u64), 64}\nimpl_number_of_digits! {impl_either; unsigned, (u128, u128), 128}\n\n#[cfg(target_pointer_width = \"16\")]\ntype UWord = u16;\n#[cfg(target_pointer_width = \"32\")]\ntype UWord = u32;\n#[cfg(target_pointer_width = \"64\")]\ntype UWord = u64;\n#[cfg(target_pointer_width = \"128\")]\ntype UWord = u128;\n\n#[cfg(target_pointer_width = \"16\")]\ntype IWord = i16;\n#[cfg(target_pointer_width = \"32\")]\ntype IWord = i32;\n#[cfg(target_pointer_width = \"64\")]\ntype IWord = i64;\n#[cfg(target_pointer_width = \"128\")]\ntype IWord = i128;\n\nmacro_rules! impl_for_xsize {\n    ($XSize:ident, $XWord:ident) => {\n        impl PWrapper<$XSize> {\n            /// Computes how long much space is necessary to write this integer as a literal.\n            #[inline(always)]\n            pub const fn compute_display_len(self, fmt: FormattingFlags) -> usize {\n                PWrapper(self.0 as $XWord).compute_display_len(fmt)\n            }\n\n            /// Computes how long much space is necessary to write this integer as a literal.\n            #[inline(always)]\n            pub const fn compute_debug_len(self, fmt: FormattingFlags) -> usize {\n                PWrapper(self.0 as $XWord).compute_debug_len(fmt)\n            }\n\n            /// Computes how long much space is necessary to\n            /// write this integer as a hexadecimal literal.\n            #[inline(always)]\n            pub const fn hexadecimal_len(self, fmt: FormattingFlags) -> usize {\n                PWrapper(self.0 as $XWord).hexadecimal_len(fmt)\n            }\n\n            /// Computes how long much space is necessary to\n            /// write this integer as a binary literal.\n            #[inline(always)]\n            pub const fn binary_len(self, fmt: FormattingFlags) -> usize {\n                PWrapper(self.0 as $XWord).binary_len(fmt)\n            }\n        }\n    };\n}\n\nimpl_for_xsize! {usize, UWord}\nimpl_for_xsize! {isize, IWord}\n\nimpl PWrapper<usize> {\n    /// Returns the absolute value of this integer.\n    pub const fn unsigned_abs(self) -> usize {\n        self.0\n    }\n}\n\nimpl PWrapper<isize> {\n    /// Returns the absolute value of this integer, as the equivalent unsigned type.\n    pub const fn unsigned_abs(self) -> usize {\n        self.0.wrapping_abs() as usize\n    }\n}\n\nimpl Integer {\n    #[inline]\n    const fn as_negative(self) -> i128 {\n        (self.unsigned as i128).wrapping_neg()\n    }\n}\n\n#[doc(hidden)]\nimpl PWrapper<Integer> {\n    pub const fn to_start_array_binary(self, flags: FormattingFlags) -> StartAndArray<[u8; 130]> {\n        let mut n = if self.0.is_negative {\n            self.0.as_negative() as u128\n        } else {\n            self.0.unsigned\n        };\n\n        n &= *self.0.mask;\n\n        let mut out = StartAndArray {\n            start: 130,\n            array: [0u8; 130],\n        };\n\n        loop {\n            out.start -= 1;\n            let digit = (n & 1) as u8;\n            out.array[out.start] = b'0' + digit;\n            n >>= 1;\n            if n == 0 {\n                break;\n            }\n        }\n\n        if flags.is_alternate() {\n            out.start -= 1;\n            out.array[out.start] = b'b';\n            out.start -= 1;\n            out.array[out.start] = b'0';\n        }\n\n        out\n    }\n\n    pub const fn to_start_array_hexadecimal(\n        self,\n        flags: FormattingFlags,\n    ) -> StartAndArray<[u8; 34]> {\n        let mut n = if self.0.is_negative {\n            self.0.as_negative() as u128\n        } else {\n            self.0.unsigned\n        };\n\n        n &= *self.0.mask;\n\n        let mut out = StartAndArray {\n            start: 34,\n            array: [0u8; 34],\n        };\n\n        loop {\n            out.start -= 1;\n            let digit = (n & 0xF) as u8;\n            out.array[out.start] = match digit {\n                0..=9 => b'0' + digit,\n                _ => digit + flags.hex_fmt() as u8,\n            };\n            n >>= 4;\n            if n == 0 {\n                break;\n            }\n        }\n\n        if flags.is_alternate() {\n            out.start -= 1;\n            out.array[out.start] = b'x';\n            out.start -= 1;\n            out.array[out.start] = b'0';\n        }\n\n        out\n    }\n\n    pub const fn to_start_array_display(self) -> StartAndArray<[u8; 40]> {\n        let mut out = StartAndArray {\n            start: 40,\n            array: [0u8; 40],\n        };\n\n        let mut n = self.0.unsigned;\n\n        loop {\n            out.start -= 1;\n            let digit = (n % 10) as u8;\n            out.array[out.start] = b'0' + digit;\n            n /= 10;\n            if n == 0 {\n                break;\n            }\n        }\n\n        if self.0.is_negative {\n            out.start -= 1;\n            out.array[out.start] = b'-';\n        }\n\n        out\n    }\n\n    #[inline(always)]\n    pub const fn to_start_array_debug(self) -> StartAndArray<[u8; 40]> {\n        self.to_start_array_display()\n    }\n}\n\nimpl PWrapper<&[u8]> {\n    /// Computes how much space is necessary to write the wrapped `&[u8]` as a utf8 string,\n    /// with debug formatting\n    pub const fn compute_utf8_debug_len(self) -> usize {\n        self.compute_utf8_debug_len_in_range(0..self.0.len())\n    }\n\n    /// Computes how much space is necessary to write `&self.0[range]` as a utf8 string,\n    /// with debug formatting\n    pub const fn compute_utf8_debug_len_in_range(self, mut range: Range<usize>) -> usize {\n        let mut sum = range.end - range.start;\n        while range.start < range.end {\n            let c = self.0[range.start];\n            if c < 128 {\n                let shifted = 1 << c;\n                if (FOR_ESCAPING.is_escaped & shifted) != 0 {\n                    sum += if (FOR_ESCAPING.is_backslash_escaped & shifted) == 0 {\n                        3 // `\\x01` only add 3 characters\n                    } else {\n                        1 // Escaped with a backslash\n                    };\n                }\n            }\n            range.start += 1;\n        }\n        sum + 2 // The quote characters\n    }\n}\n\nimpl PWrapper<&str> {\n    /// Computes how much space is necessary to write a `&str` with debug formatting\n    #[inline(always)]\n    #[doc(hidden)]\n    pub const fn compute_debug_len(self, _: FormattingFlags) -> usize {\n        PWrapper(self.0.as_bytes()).compute_utf8_debug_len()\n    }\n\n    /// Computes how much space is necessary to write a `&str` with display formatting\n    #[inline(always)]\n    #[doc(hidden)]\n    pub const fn compute_display_len(self, _: FormattingFlags) -> usize {\n        self.0.len()\n    }\n}\n\n#[cfg(feature = \"fmt\")]\nconst _: () = {\n    use crate::marker_traits::{FormatMarker, IsNotStdKind};\n\n    impl<P> FormatMarker for PWrapper<P> {\n        type Kind = IsNotStdKind;\n        type This = Self;\n    }\n};\n\n///////////////////////////////////////////////////////////////////////////\n\n#[cfg(feature = \"assertcp\")]\nmacro_rules! impl_eq_for_primitives {\n    (\n        (l=$l:ident, r=$r:ident)\n\n        $(\n            impl[$($impl_:tt)*] $type:ty = $comparison:expr;\n        )*\n\n    ) => (\n        $(\n            impl<$($impl_)*> PWrapper<$type> {\n                /// This method is only available with the \"assert\" feature.\n                pub const fn const_eq(&self, $r:&$type) -> bool {\n                    let $l = self.0;\n                    $comparison\n                }\n            }\n        )*\n    )\n}\n\n#[cfg(feature = \"assertcp\")]\nimpl_eq_for_primitives! {\n    (l = l, r = r)\n\n    impl[] u8 = l == *r;\n    impl[] i8 = l == *r;\n    impl[] u16 = l == *r;\n    impl[] i16 = l == *r;\n    impl[] u32 = l == *r;\n    impl[] i32 = l == *r;\n    impl[] u64 = l == *r;\n    impl[] i64 = l == *r;\n    impl[] u128 = l == *r;\n    impl[] i128 = l == *r;\n    impl[] usize = l == *r;\n    impl[] isize = l == *r;\n    impl[] bool = l == *r;\n    impl[] char = l == *r;\n    impl[] &str = crate::slice_cmp::str_eq(l, r);\n}\n"
  },
  {
    "path": "const_format/src/wrapper_types/sliced.rs",
    "content": "use crate::{\n    fmt::{Error, Formatter},\n    wrapper_types::AsciiStr,\n};\n\nuse core::ops::{Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive};\n\n/// Wrapper for writing a range of a string slice.\n///\n/// This is a workaround for not being able to do `&string[start..end]` at compile-time.\n///\n/// # Example\n///\n/// ```rust\n///\n/// use const_format::Sliced;\n/// use const_format::{concatc, formatc};\n///\n/// const NUMS: &str = \"0123456789\";\n/// const SRC: &str = \"foo bar baz\";\n///\n/// assert_eq!(concatc!(Sliced(NUMS, 1..=4)), \"1234\");\n/// assert_eq!(concatc!(Sliced(SRC, 0..5), \"ros.\"), \"foo bros.\");\n///\n/// assert_eq!(formatc!(\"{}\", Sliced(NUMS, 4..)), \"456789\");\n/// assert_eq!(formatc!(\"{}t\", Sliced(SRC, 4..7)), \"bart\");\n///\n/// ```\n#[cfg_attr(feature = \"__docsrs\", doc(cfg(feature = \"fmt\")))]\npub struct Sliced<T, R>(pub T, pub R);\n\nimpl_fmt! {\n    impl['a,] Sliced<&'a str, Range<usize>>;\n    impl['a,] Sliced<&'a str, RangeFrom<usize>>;\n    impl['a,] Sliced<&'a str, RangeFull>;\n    impl['a,] Sliced<&'a str, RangeInclusive<usize>>;\n    impl['a,] Sliced<&'a str, RangeTo<usize>>;\n    impl['a,] Sliced<&'a str, RangeToInclusive<usize>>;\n\n    ///\n    #[inline]\n    pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {\n        f.write_str_range_debug(self.0, self.range())\n    }\n\n    ///\n    #[inline]\n    pub const fn const_display_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {\n        f.write_str_range(self.0, self.range())\n    }\n}\n\nimpl_fmt! {\n    impl['a,] Sliced<AsciiStr<'a>, Range<usize>>;\n    impl['a,] Sliced<AsciiStr<'a>, RangeFrom<usize>>;\n    impl['a,] Sliced<AsciiStr<'a>, RangeFull>;\n    impl['a,] Sliced<AsciiStr<'a>, RangeInclusive<usize>>;\n    impl['a,] Sliced<AsciiStr<'a>, RangeTo<usize>>;\n    impl['a,] Sliced<AsciiStr<'a>, RangeToInclusive<usize>>;\n\n    ///\n    #[inline]\n    pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {\n        f.write_ascii_range_debug(self.0, self.range())\n    }\n\n    ///\n    #[inline]\n    pub const fn const_display_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {\n        f.write_ascii_range(self.0, self.range())\n    }\n}\n\nimpl<T> Sliced<T, Range<usize>> {\n    #[inline(always)]\n    const fn range(&self) -> Range<usize> {\n        self.1.start..self.1.end\n    }\n}\n\nimpl<T> Sliced<T, RangeFrom<usize>> {\n    #[inline(always)]\n    const fn range(&self) -> Range<usize> {\n        self.1.start..usize::MAX\n    }\n}\n\nimpl<T> Sliced<T, RangeFull> {\n    #[inline(always)]\n    const fn range(&self) -> Range<usize> {\n        0..usize::MAX\n    }\n}\n\nconst UM: usize = usize::MAX >> 1;\n\nimpl<T> Sliced<T, RangeInclusive<usize>> {\n    // If people are somehow indexing over a thing that's larger than isize::MAX,\n    // then we have problems.\n    #[inline(always)]\n    const fn range(&self) -> Range<usize> {\n        *self.1.start()..(*self.1.end() & UM) + 1\n    }\n}\n\nimpl<T> Sliced<T, RangeTo<usize>> {\n    #[inline(always)]\n    const fn range(&self) -> Range<usize> {\n        0..self.1.end\n    }\n}\n\nimpl<T> Sliced<T, RangeToInclusive<usize>> {\n    // If people are somehow indexing over a thing that's larger than isize::MAX,\n    // then we have problems.\n    #[inline(always)]\n    const fn range(&self) -> Range<usize> {\n        0..(self.1.end & UM) + 1\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    use crate::fmt::{FormattingFlags, StrWriter};\n\n    macro_rules! test_case {\n        (\n            $writer:ident,\n            $str_val:expr,\n            $range:expr,\n            $expected:expr\n        ) => {{\n            const fn inner(fmt: &mut Formatter<'_>) -> Result<(), Error> {\n                let string = Sliced($str_val, $range);\n\n                try_!(string.const_display_fmt(fmt));\n                try_!(fmt.write_str(\";\"));\n                try_!(string.const_debug_fmt(fmt));\n\n                Ok(())\n            }\n            $writer.clear();\n            inner(&mut $writer.make_formatter(FormattingFlags::NEW)).unwrap();\n\n            assert_eq!($writer.as_str(), $expected, \"range = {:?}\", $range);\n        }};\n    }\n\n    const S: &str = \"\\x00\\n\\t3456789\\x06\\x07\";\n\n    macro_rules! generate_test {\n        ($str_val:expr) => {\n            let writer: &mut StrWriter = &mut StrWriter::new([0u8; 512]);\n\n            test_case!(writer, $str_val, 2..9, \"\\t345678;\\\"\\\\t345678\\\"\");\n\n            test_case!(\n                writer,\n                $str_val,\n                2..,\n                \"\\t3456789\\x06\\x07;\\\"\\\\t3456789\\\\x06\\\\x07\\\"\"\n            );\n\n            test_case!(\n                writer,\n                $str_val,\n                ..,\n                \"\\x00\\n\\t3456789\\x06\\x07;\\\"\\\\x00\\\\n\\\\t3456789\\\\x06\\\\x07\\\"\"\n            );\n\n            test_case!(\n                writer,\n                $str_val,\n                ..9,\n                \"\\x00\\n\\t345678;\\\"\\\\x00\\\\n\\\\t345678\\\"\"\n            );\n\n            test_case!(writer, $str_val, 2..=9, \"\\t3456789;\\\"\\\\t3456789\\\"\");\n            test_case!(\n                writer,\n                $str_val,\n                2..=!0,\n                \"\\t3456789\\x06\\x07;\\\"\\\\t3456789\\\\x06\\\\x07\\\"\"\n            );\n\n            test_case!(\n                writer,\n                $str_val,\n                ..=9,\n                \"\\x00\\n\\t3456789;\\\"\\\\x00\\\\n\\\\t3456789\\\"\"\n            );\n            test_case!(\n                writer,\n                $str_val,\n                ..=!0,\n                \"\\x00\\n\\t3456789\\x06\\x07;\\\"\\\\x00\\\\n\\\\t3456789\\\\x06\\\\x07\\\"\"\n            );\n        };\n    }\n\n    #[test]\n    fn str_tests() {\n        generate_test!(S);\n    }\n    #[test]\n    fn asciistr_tests() {\n        const ASCII: AsciiStr<'_> = ascii_str!(S);\n        generate_test!(ASCII);\n    }\n}\n"
  },
  {
    "path": "const_format/src/wrapper_types.rs",
    "content": "//! Some wrapper types.\n//!\n//! # Features\n//!\n//! This module is only exported with the \"fmt\" feature.\n\n#[cfg(feature = \"fmt\")]\npub(crate) mod ascii_str;\n\npub(crate) mod pwrapper;\n\n#[cfg(feature = \"fmt\")]\npub(crate) mod sliced;\n\n#[cfg(feature = \"fmt\")]\npub use self::ascii_str::NotAsciiError;\n\n#[doc(no_inline)]\n#[cfg(feature = \"fmt\")]\npub use crate::{AsciiStr, Sliced};\n\n#[doc(no_inline)]\npub use crate::PWrapper;\n"
  },
  {
    "path": "const_format/tests/fmt_tests/display_formatting.rs",
    "content": "use cfmt_a::{\n    fmt::{ComputeStrLength, Error, Formatter, FormattingFlags, StrWriter},\n    try_,\n    wrapper_types::PWrapper,\n};\n\n#[derive(Copy, Clone)]\nstruct DisplayFoo {\n    x: u32,\n    y: &'static str,\n    z: bool,\n    debug: i8,\n}\n\nimpl DisplayFoo {\n    pub const fn const_display_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {\n        try_!(PWrapper(self.x).const_display_fmt(f));\n        try_!(PWrapper(\"  \").const_display_fmt(f));\n        try_!(PWrapper(self.y).const_display_fmt(f));\n        try_!(PWrapper(\"  \").const_display_fmt(f));\n        try_!(PWrapper(self.z).const_display_fmt(f));\n        try_!(PWrapper(\"  \").const_display_fmt(f));\n        try_!(PWrapper(self.debug).const_debug_fmt(f));\n        Ok(())\n    }\n}\n\nconst fn inner(\n    this: &DisplayFoo,\n    writer: &mut StrWriter,\n    flags: FormattingFlags,\n) -> Result<usize, Error> {\n    try_!(this.const_display_fmt(&mut writer.make_formatter(flags)));\n\n    let mut str_len = ComputeStrLength::new();\n    try_!(this.const_display_fmt(&mut str_len.make_formatter(flags)));\n\n    Ok(str_len.len())\n}\n\n#[test]\nfn test_display_foo() {\n    fn test_case(\n        this: &DisplayFoo,\n        writer: &mut StrWriter,\n        flags: FormattingFlags,\n        expected: &str,\n    ) {\n        writer.clear();\n        let len = inner(this, writer, flags).unwrap();\n\n        assert_eq!(writer.as_str(), expected);\n        assert_eq!(writer.len(), len, \"{}\", writer.as_str());\n    }\n\n    let writer: &mut StrWriter = &mut StrWriter::new([0; 1024]);\n\n    {\n        let this = DisplayFoo {\n            x: 3,\n            y: \"--\\n5\\n--\",\n            z: false,\n            debug: 15,\n        };\n        let flag = FormattingFlags::NEW.set_alternate(false);\n        test_case(&this, writer, flag, \"3  --\\n5\\n--  false  15\");\n        test_case(\n            &this,\n            writer,\n            flag.set_hexadecimal(),\n            \"3  --\\n5\\n--  false  F\",\n        );\n        test_case(\n            &this,\n            writer,\n            flag.set_binary(),\n            \"3  --\\n5\\n--  false  1111\",\n        );\n\n        let altflag = FormattingFlags::NEW.set_alternate(true);\n        test_case(&this, writer, altflag, \"3  --\\n5\\n--  false  15\");\n        test_case(\n            &this,\n            writer,\n            altflag.set_hexadecimal(),\n            \"3  --\\n5\\n--  false  0xF\",\n        );\n        test_case(\n            &this,\n            writer,\n            altflag.set_binary(),\n            \"3  --\\n5\\n--  false  0b1111\",\n        );\n    }\n\n    {\n        let this = DisplayFoo {\n            x: 3,\n            y: \"--\\n5\\n--\",\n            z: true,\n            debug: -2,\n        };\n        let flag = FormattingFlags::NEW.set_alternate(false);\n        test_case(&this, writer, flag, \"3  --\\n5\\n--  true  -2\");\n        test_case(\n            &this,\n            writer,\n            flag.set_hexadecimal(),\n            \"3  --\\n5\\n--  true  FE\",\n        );\n        test_case(\n            &this,\n            writer,\n            flag.set_binary(),\n            \"3  --\\n5\\n--  true  11111110\",\n        );\n\n        let altflag = FormattingFlags::NEW.set_alternate(true);\n        test_case(&this, writer, altflag, \"3  --\\n5\\n--  true  -2\");\n        test_case(\n            &this,\n            writer,\n            altflag.set_hexadecimal(),\n            \"3  --\\n5\\n--  true  0xFE\",\n        );\n        test_case(\n            &this,\n            writer,\n            altflag.set_binary(),\n            \"3  --\\n5\\n--  true  0b11111110\",\n        );\n    }\n}\n\n/*////////////////////////////////////////////////////////////////////////////////\nTesting Display formatting for non-primitive integer or `&str` types,\nbecause those types are already tested in other tests.\n*/////////////////////////////////////////////////////////////////////////////////\n\nuse std::num::{NonZeroI8, NonZeroIsize, NonZeroU8, NonZeroUsize};\n\nmacro_rules! unwrap_opt {\n    ($opt:expr) => {\n        match $opt {\n            Some(x) => x,\n            None => loop {},\n        }\n    };\n}\n\n#[test]\nfn display_fmt_other_types() {\n    const fn inner(fmt: &mut Formatter<'_>) -> cfmt_a::Result {\n        cfmt_a::writec!(\n            fmt,\n            concat!(\"{},{};\", \"{},{};{},{};{},{};{},{};{},{},{},{};\",),\n            false,\n            true,\n            unwrap_opt!(NonZeroI8::new(-13)),\n            unwrap_opt!(NonZeroI8::new(21)),\n            unwrap_opt!(NonZeroIsize::new(-13)),\n            unwrap_opt!(NonZeroIsize::new(21)),\n            unwrap_opt!(NonZeroU8::new(3)),\n            unwrap_opt!(NonZeroU8::new(13)),\n            unwrap_opt!(NonZeroUsize::new(3)),\n            unwrap_opt!(NonZeroUsize::new(13)),\n            'o',\n            'ñ',\n            '个',\n            '\\u{100000}',\n        )\n    }\n\n    let flags = [\n        FormattingFlags::NEW.set_alternate(false).set_decimal(),\n        FormattingFlags::NEW.set_alternate(false).set_hexadecimal(),\n        FormattingFlags::NEW.set_alternate(false).set_binary(),\n        FormattingFlags::NEW.set_alternate(true).set_decimal(),\n        FormattingFlags::NEW.set_alternate(true).set_hexadecimal(),\n        FormattingFlags::NEW.set_alternate(true).set_binary(),\n    ];\n\n    let writer: &mut StrWriter = &mut StrWriter::new([0; 1024]);\n    for flag in flags.iter().copied() {\n        writer.clear();\n\n        inner(&mut writer.make_formatter(flag)).unwrap();\n\n        assert_eq!(\n            writer.as_str(),\n            \"false,true;-13,21;-13,21;3,13;3,13;o,ñ,个,\\u{100000};\",\n        );\n    }\n}\n"
  },
  {
    "path": "const_format/tests/fmt_tests/formatted_writing.rs",
    "content": "use cfmt_a::{\n    __for_range,\n    fmt::{ComputeStrLength, Error, Formatter, FormattingFlags, StrWriter},\n    try_,\n    wrapper_types::PWrapper,\n};\n\n#[derive(Debug, Copy, Clone)]\nstruct Foo {\n    x: u32,\n    y: &'static str,\n    z: &'static [u8],\n}\n\nimpl Foo {\n    pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {\n        let mut f = f.debug_struct(\"Foo\");\n        try_!(PWrapper(self.x).const_debug_fmt(f.field(\"x\")));\n        try_!(PWrapper(self.y).const_debug_fmt(f.field(\"y\")));\n        try_!(PWrapper(self.z).const_debug_fmt(f.field(\"z\")));\n        f.finish()\n    }\n}\n\n#[derive(Debug, Copy, Clone)]\nstruct Bar {\n    x: u32,\n    y: &'static str,\n    z: [u8; 5],\n    foo: Foo,\n}\n\nimpl Bar {\n    pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {\n        let mut f = f.debug_struct(\"Bar\");\n        try_!(PWrapper(self.x).const_debug_fmt(f.field(\"x\")));\n        try_!(PWrapper(self.y).const_debug_fmt(f.field(\"y\")));\n        try_!(PWrapper::slice(&self.z).const_debug_fmt(f.field(\"z\")));\n        try_!(self.foo.const_debug_fmt(f.field(\"foo\")));\n        f.finish()\n    }\n}\n\n#[test]\nfn check_debug_formatting() {\n    // Ensuring that all of this code can run at compile-time\n    const fn inner(\n        bar: &Bar,\n        writer: &mut StrWriter,\n        flags: FormattingFlags,\n    ) -> Result<usize, Error> {\n        try_!(bar.const_debug_fmt(&mut writer.make_formatter(flags)));\n\n        let mut str_len = ComputeStrLength::new();\n        try_!(bar.const_debug_fmt(&mut str_len.make_formatter(flags)));\n\n        Ok(str_len.len())\n    }\n\n    fn test_case(bar: &Bar, writer: &mut StrWriter, flags: FormattingFlags, expected: &str) {\n        writer.clear();\n        let len = inner(&bar, writer, flags).unwrap();\n\n        assert_eq!(writer.as_str(), expected);\n        assert_eq!(writer.len(), len, \"{}\", writer.as_str());\n    }\n\n    let foo = Foo {\n        x: 100,\n        y: \"hello\\nworld\",\n        z: &[3, 5, 8, 13],\n    };\n\n    let bar = Bar {\n        x: 21,\n        y: \"foo\\tbar\",\n        z: [34, 55, 89, 144, 233],\n        foo,\n    };\n\n    let flags = FormattingFlags::DEFAULT;\n\n    let writer: &mut StrWriter = &mut StrWriter::new([0; 1024]);\n\n    // decimal + not alternate\n    test_case(\n        &bar,\n        writer,\n        flags.set_alternate(false),\n        \"\\\n            Bar { \\\n                x: 21, y: \\\"foo\\\\tbar\\\", z: [34, 55, 89, 144, 233], \\\n                foo: Foo { x: 100, y: \\\"hello\\\\nworld\\\", z: [3, 5, 8, 13] } \\\n            }\\\n        \",\n    );\n\n    // hexadecimal + not alternate\n    test_case(\n        &bar,\n        writer,\n        flags.set_alternate(false).set_hexadecimal(),\n        \"\\\n            Bar { \\\n                x: 15, y: \\\"foo\\\\tbar\\\", z: [22, 37, 59, 90, E9], \\\n                foo: Foo { x: 64, y: \\\"hello\\\\nworld\\\", z: [3, 5, 8, D] } \\\n            }\\\n        \",\n    );\n\n    test_case(\n        &bar,\n        writer,\n        flags.set_alternate(false).set_binary(),\n        \"\\\n            Bar { \\\n                x: 10101, y: \\\"foo\\\\tbar\\\", z: [100010, 110111, 1011001, 10010000, 11101001], \\\n                foo: Foo { x: 1100100, y: \\\"hello\\\\nworld\\\", z: [11, 101, 1000, 1101] } \\\n            }\\\n        \",\n    );\n\n    const ALTERNATE: &str = \"\\\nBar {\n    x: 21,\n    y: \\\"foo\\\\tbar\\\",\n    z: [\n        34,\n        55,\n        89,\n        144,\n        233,\n    ],\n    foo: Foo {\n        x: 100,\n        y: \\\"hello\\\\nworld\\\",\n        z: [\n            3,\n            5,\n            8,\n            13,\n        ],\n    },\n}\";\n    const ALTERNATE_HEX: &str = \"\\\nBar {\n    x: 0x15,\n    y: \\\"foo\\\\tbar\\\",\n    z: [\n        0x22,\n        0x37,\n        0x59,\n        0x90,\n        0xE9,\n    ],\n    foo: Foo {\n        x: 0x64,\n        y: \\\"hello\\\\nworld\\\",\n        z: [\n            0x3,\n            0x5,\n            0x8,\n            0xD,\n        ],\n    },\n}\";\n\n    const ALTERNATE_BINARY: &str = \"\\\nBar {\n    x: 0b10101,\n    y: \\\"foo\\\\tbar\\\",\n    z: [\n        0b100010,\n        0b110111,\n        0b1011001,\n        0b10010000,\n        0b11101001,\n    ],\n    foo: Foo {\n        x: 0b1100100,\n        y: \\\"hello\\\\nworld\\\",\n        z: [\n            0b11,\n            0b101,\n            0b1000,\n            0b1101,\n        ],\n    },\n}\";\n\n    test_case(&bar, writer, flags.set_alternate(true), ALTERNATE);\n    test_case(\n        &bar,\n        writer,\n        flags.set_alternate(true).set_hexadecimal(),\n        ALTERNATE_HEX,\n    );\n    test_case(\n        &bar,\n        writer,\n        flags.set_alternate(true).set_binary(),\n        ALTERNATE_BINARY,\n    );\n}\n\n////////////////////////////////////////////////////////////////////////////////\n\npub struct Set(&'static [Foo]);\n\nimpl Set {\n    pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {\n        let mut f = f.debug_set();\n        __for_range! {i in 0..self.0.len()=>\n            try_!(self.0[i].const_debug_fmt(f.entry()));\n        }\n        f.finish()\n    }\n}\n\n#[test]\nfn check_set_formatting() {\n    const fn inner(\n        set: &Set,\n        writer: &mut StrWriter,\n        flags: FormattingFlags,\n    ) -> Result<usize, Error> {\n        try_!(set.const_debug_fmt(&mut writer.make_formatter(flags)));\n\n        let mut str_len = ComputeStrLength::new();\n        try_!(set.const_debug_fmt(&mut str_len.make_formatter(flags)));\n\n        Ok(str_len.len())\n    }\n\n    fn test_case(bar: &Set, writer: &mut StrWriter, flags: FormattingFlags, expected: &str) {\n        writer.clear();\n        let len = inner(&bar, writer, flags).unwrap();\n\n        assert_eq!(writer.as_str(), expected);\n        assert_eq!(writer.len(), len, \"{}\", writer.as_str());\n    }\n\n    let flags = FormattingFlags::DEFAULT;\n\n    let writer: &mut StrWriter = &mut StrWriter::new([0; 1024]);\n\n    let set = Set(&[Foo {\n        x: 100,\n        y: \"hello\\nworld\",\n        z: &[],\n    }]);\n\n    test_case(\n        &set,\n        writer,\n        flags,\n        \"{Foo { x: 100, y: \\\"hello\\\\nworld\\\", z: [] }}\",\n    );\n    test_case(\n        &set,\n        writer,\n        flags.set_hexadecimal(),\n        \"{Foo { x: 64, y: \\\"hello\\\\nworld\\\", z: [] }}\",\n    );\n    test_case(\n        &set,\n        writer,\n        flags.set_binary(),\n        \"{Foo { x: 1100100, y: \\\"hello\\\\nworld\\\", z: [] }}\",\n    );\n\n    const ALTERNATE: &str = \"\\\n{\n    Foo {\n        x: 100,\n        y: \\\"hello\\\\nworld\\\",\n        z: [],\n    },\n}\\\n    \";\n\n    const ALTERNATE_HEX: &str = \"\\\n{\n    Foo {\n        x: 0x64,\n        y: \\\"hello\\\\nworld\\\",\n        z: [],\n    },\n}\\\n    \";\n\n    const ALTERNATE_BINARY: &str = \"\\\n{\n    Foo {\n        x: 0b1100100,\n        y: \\\"hello\\\\nworld\\\",\n        z: [],\n    },\n}\\\n    \";\n\n    test_case(&set, writer, flags.set_alternate(true), ALTERNATE);\n    test_case(\n        &set,\n        writer,\n        flags.set_alternate(true).set_hexadecimal(),\n        ALTERNATE_HEX,\n    );\n    test_case(\n        &set,\n        writer,\n        flags.set_alternate(true).set_binary(),\n        ALTERNATE_BINARY,\n    );\n}\n"
  },
  {
    "path": "const_format/tests/fmt_tests/formatter_methods/debug_methods.rs",
    "content": "use super::{remove_margin, write_with_flag};\n\nuse cfmt_a::{\n    fmt::{Error, Formatter, FormattingFlags},\n    impl_fmt, try_, PWrapper,\n};\n\n////////////////////////////////////////////////////////////////////////////////\n\nconst fn format_b_field(b: &'static [u32], fmt: &mut Formatter<'_>) -> Result<(), Error> {\n    let is_uneven = b[0] % 2 != 0;\n    let flags = FormattingFlags::NEW\n        .set_alternate(is_uneven)\n        .set_hexadecimal();\n\n    PWrapper(b).const_debug_fmt(&mut fmt.make_formatter(flags))\n}\n\n////////////////////////////////////////////////////////////////////////////////\n\nstruct BracedStruct {\n    a: u32,\n    b: &'static [u32],\n    rec: Option<&'static BracedStruct>,\n}\n\nimpl_fmt! {\n    impl BracedStruct;\n\n    pub const fn const_debug_fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {\n        let mut fmt = fmt.debug_struct(\"BracedStruct\");\n        {\n            let mut fmt = fmt.field(\"margin\");\n            let margin = fmt.margin();\n            try_!(fmt.write_usize_display(margin));\n        }\n        try_!(fmt.field(\"a\").write_u32_debug(self.a));\n        try_!(format_b_field(self.b, fmt.field(\"b\")));\n        if let Some(x) = self.rec {\n            try_!(x.const_debug_fmt(fmt.field(\"rec\")));\n        }\n        fmt.finish()\n    }\n}\n\n#[test]\nfn formatting_struct() {\n    let expected = remove_margin(\n        \"\n        BracedStruct {\n            margin: 4,\n            a: 3,\n            b: [\n                0x9,\n                0xC,\n                0xF,\n            ],\n            rec: BracedStruct {\n                margin: 8,\n                a: 8,\n                b: [A, E, 12],\n                rec: BracedStruct {\n                    margin: 12,\n                    a: 21,\n                    b: [\n                        0xF,\n                        0x14,\n                        0x19,\n                    ],\n                },\n            },\n        }\\\n    \",\n    );\n\n    let list = BracedStruct {\n        a: 3,\n        b: &[9, 12, 15],\n        rec: Some(&BracedStruct {\n            a: 8,\n            b: &[10, 14, 18],\n            rec: Some(&BracedStruct {\n                a: 21,\n                b: &[15, 20, 25],\n                rec: None,\n            }),\n        }),\n    };\n\n    let flags = FormattingFlags::NEW.set_alternate(true);\n\n    write_with_flag(flags, &expected, &|mut fmt| {\n        list.const_debug_fmt(&mut fmt).unwrap();\n    })\n}\n\n////////////////////////////////////////////////////////////////////////////////\n\nstruct TupleStruct {\n    a: u32,\n    b: &'static [u32],\n    rec: Option<&'static TupleStruct>,\n}\n\nimpl_fmt! {\n    impl TupleStruct;\n\n    pub const fn const_debug_fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {\n        let mut fmt = fmt.debug_tuple(\"TupleStruct\");\n        {\n            let mut fmt = fmt.field();\n            let margin = fmt.margin();\n            try_!(fmt.write_usize_display(margin));\n        }\n        try_!(fmt.field().write_u32_debug(self.a));\n        try_!(format_b_field(self.b, fmt.field()));\n        if let Some(x) = self.rec {\n            try_!(x.const_debug_fmt(fmt.field()));\n        }\n        fmt.finish()\n    }\n}\n\n#[test]\nfn formatting_tuple() {\n    let expected = remove_margin(\n        \"\n        TupleStruct(\n            4,\n            3,\n            [\n                0x9,\n                0xC,\n                0xF,\n            ],\n            TupleStruct(\n                8,\n                8,\n                [A, E, 12],\n                TupleStruct(\n                    12,\n                    21,\n                    [\n                        0xF,\n                        0x14,\n                        0x19,\n                    ],\n                ),\n            ),\n        )\\\n    \",\n    );\n\n    let list = TupleStruct {\n        a: 3,\n        b: &[9, 12, 15],\n        rec: Some(&TupleStruct {\n            a: 8,\n            b: &[10, 14, 18],\n            rec: Some(&TupleStruct {\n                a: 21,\n                b: &[15, 20, 25],\n                rec: None,\n            }),\n        }),\n    };\n\n    let flags = FormattingFlags::NEW.set_alternate(true);\n\n    write_with_flag(flags, &expected, &|mut fmt| {\n        list.const_debug_fmt(&mut fmt).unwrap();\n    })\n}\n\n////////////////////////////////////////////////////////////////////////////////\n\nstruct List {\n    a: u32,\n    b: &'static [u32],\n    rec: Option<&'static List>,\n}\n\nimpl_fmt! {\n    impl List;\n\n    pub const fn const_debug_fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {\n        let mut fmt = fmt.debug_list();\n        {\n            let mut fmt = fmt.entry();\n            let margin = fmt.margin();\n            try_!(fmt.write_usize_display(margin));\n        }\n        try_!(fmt.entry().write_u32_debug(self.a));\n        try_!(format_b_field(self.b, fmt.entry()));\n        if let Some(x) = self.rec {\n            try_!(x.const_debug_fmt(fmt.entry()));\n        }\n        fmt.finish()\n    }\n}\n\n#[test]\nfn formatting_list() {\n    let expected = remove_margin(\n        \"\n        [\n            4,\n            3,\n            [\n                0x9,\n                0xC,\n                0xF,\n            ],\n            [\n                8,\n                8,\n                [A, E, 12],\n                [\n                    12,\n                    21,\n                    [\n                        0xF,\n                        0x14,\n                        0x19,\n                    ],\n                ],\n            ],\n        ]\\\n    \",\n    );\n\n    let list = List {\n        a: 3,\n        b: &[9, 12, 15],\n        rec: Some(&List {\n            a: 8,\n            b: &[10, 14, 18],\n            rec: Some(&List {\n                a: 21,\n                b: &[15, 20, 25],\n                rec: None,\n            }),\n        }),\n    };\n\n    let flags = FormattingFlags::NEW.set_alternate(true);\n\n    write_with_flag(flags, &expected, &|mut fmt| {\n        list.const_debug_fmt(&mut fmt).unwrap();\n    })\n}\n\n////////////////////////////////////////////////////////////////////////////////\n\nstruct Set {\n    a: u32,\n    b: &'static [u32],\n    rec: Option<&'static Set>,\n}\n\nimpl_fmt! {\n    impl Set;\n\n    pub const fn const_debug_fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {\n        let mut fmt = fmt.debug_set();\n        {\n            let mut fmt = fmt.entry();\n            let margin = fmt.margin();\n            try_!(fmt.write_usize_display(margin));\n        }\n        try_!(fmt.entry().write_u32_debug(self.a));\n        try_!(format_b_field(self.b, fmt.entry()));\n        if let Some(x) = self.rec {\n            try_!(x.const_debug_fmt(fmt.entry()));\n        }\n        fmt.finish()\n    }\n}\n\n#[test]\nfn formatting_set() {\n    let expected = remove_margin(\n        \"\n        {\n            4,\n            3,\n            [\n                0x9,\n                0xC,\n                0xF,\n            ],\n            {\n                8,\n                8,\n                [A, E, 12],\n                {\n                    12,\n                    21,\n                    [\n                        0xF,\n                        0x14,\n                        0x19,\n                    ],\n                },\n            },\n        }\\\n    \",\n    );\n\n    let set = Set {\n        a: 3,\n        b: &[9, 12, 15],\n        rec: Some(&Set {\n            a: 8,\n            b: &[10, 14, 18],\n            rec: Some(&Set {\n                a: 21,\n                b: &[15, 20, 25],\n                rec: None,\n            }),\n        }),\n    };\n\n    let flags = FormattingFlags::NEW.set_alternate(true);\n\n    write_with_flag(flags, &expected, &|mut fmt| {\n        set.const_debug_fmt(&mut fmt).unwrap();\n    })\n}\n"
  },
  {
    "path": "const_format/tests/fmt_tests/formatter_methods.rs",
    "content": "use cfmt_a::{\n    ascii_str,\n    fmt::{ComputeStrLength, Formatter, FormattingFlags},\n    AsciiStr,\n};\n\nmod debug_methods;\n\n////////////////////////////////////////////////////////////////////////////////\n\nmacro_rules! append_str {\n    ($formatter:ident, $str:expr; $($statement:stmt;)*) => (\n        $(\n            $statement\n            $formatter.write_str($str).unwrap();\n        )*\n    )\n}\n\nfn write_with_flag(flags: FormattingFlags, expected: &str, takes_fmt: &dyn Fn(Formatter<'_>)) {\n    let mut len = 0;\n    let mut buffer = [0; 4096];\n\n    fn reset_start(buffer: &mut [u8], expected: &str) {\n        buffer[..expected.len()].iter_mut().for_each(|x| *x = 0)\n    }\n\n    takes_fmt(Formatter::from_custom(&mut buffer, &mut len, flags));\n    let found = std::str::from_utf8(&buffer[..len]).unwrap();\n    assert_eq!(found, expected, \"\\n{}\\n{}\\n\", found, expected);\n\n    len = usize::MAX / 2;\n    reset_start(&mut buffer, expected);\n    takes_fmt(Formatter::from_custom_cleared(&mut buffer, &mut len, flags));\n    let found = std::str::from_utf8(&buffer[..len]).unwrap();\n    assert_eq!(found, expected, \"\\n{}\\n{}\\n\", found, expected);\n\n    let mut compute = ComputeStrLength::new();\n    takes_fmt(compute.make_formatter(flags));\n    assert_eq!(compute.len(), expected.len());\n}\n\n// This ensures that all integer methods have the correct type.\n#[test]\nfn write_integers() {\n    fn inner(mut fmt: Formatter<'_>) {\n        append_str!(fmt,\",\";\n            fmt.write_u8_display(17_u8).unwrap();\n            fmt.write_u16_display(18_u16).unwrap();\n            fmt.write_u32_display(19_u32).unwrap();\n            fmt.write_u64_display(20_u64).unwrap();\n            fmt.write_u128_display(21_u128).unwrap();\n            fmt.write_usize_display(22_usize).unwrap();\n            fmt.write_i8_display(23_i8).unwrap();\n            fmt.write_i16_display(24_i16).unwrap();\n            fmt.write_i32_display(25_i32).unwrap();\n            fmt.write_i64_display(26_i64).unwrap();\n            fmt.write_i128_display(27_i128).unwrap();\n            fmt.write_isize_display(28_isize).unwrap();\n            fmt.write_u8_debug(29_u8).unwrap();\n            fmt.write_u16_debug(30_u16).unwrap();\n            fmt.write_u32_debug(31_u32).unwrap();\n            fmt.write_u64_debug(32_u64).unwrap();\n            fmt.write_u128_debug(33_u128).unwrap();\n            fmt.write_usize_debug(34_usize).unwrap();\n            fmt.write_i8_debug(35_i8).unwrap();\n            fmt.write_i16_debug(36_i16).unwrap();\n            fmt.write_i32_debug(37_i32).unwrap();\n            fmt.write_i64_debug(38_i64).unwrap();\n            fmt.write_i128_debug(39_i128).unwrap();\n            fmt.write_isize_debug(40_isize).unwrap();\n            fmt.write_i8_debug(-41_i8).unwrap();\n            fmt.write_i16_debug(-42_i16).unwrap();\n            fmt.write_i32_debug(-43_i32).unwrap();\n            fmt.write_i64_debug(-44_i64).unwrap();\n            fmt.write_i128_debug(-45_i128).unwrap();\n            fmt.write_isize_debug(-46_isize).unwrap();\n        );\n    }\n\n    {\n        let expected = \"\\\n            17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,\\\n            -41,-42,-43,-44,-45,-46,\\\n        \";\n\n        write_with_flag(FormattingFlags::NEW, expected, &inner);\n    }\n    {\n        let expected = format!(\n            \"\\\n                17,18,19,20,21,22,23,24,25,26,27,28,1D,1E,1F,20,21,22,23,24,25,26,27,28,D7,\\\n                FFD6,FFFFFFD5,FFFFFFFFFFFFFFD4,FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3,{:X},\\\n            \",\n            -46_isize\n        );\n\n        write_with_flag(FormattingFlags::NEW.set_hexadecimal(), &expected, &inner);\n    }\n    {\n        let expected = format!(\n            \"\\\n                17,18,19,20,21,22,23,24,25,26,27,28,11101,\\\n                11110,11111,100000,100001,100010,100011,100100,100101,100110,100111,101000,\\\n                11010111,1111111111010110,11111111111111111111111111010101,\\\n                1111111111111111111111111111111111111111111111111111111111010100,\\\n                1111111111111111111111111111111111111111111111111111111111111111\\\n                1111111111111111111111111111111111111111111111111111111111010011,\\\n                {:b},\\\n            \",\n            -46_isize\n        );\n\n        write_with_flag(FormattingFlags::NEW.set_binary(), &expected, &inner);\n    }\n}\n\n#[test]\nfn write_str_methods() {\n    const A_FOO: AsciiStr = ascii_str!(\"hello\\n\\x1F bar\\t\\rbaz\");\n    const A_BAR: AsciiStr = ascii_str!(\"what\\0the\");\n    const FOO: &str = \"hello\\n\\x1F bar\\t\\rbaz\";\n\n    fn inner(mut fmt: Formatter<'_>) {\n        append_str!(fmt,\";;\";\n            fmt.write_str_range(FOO, 1..6).unwrap();\n            fmt.write_str(\"\\nABCD\\n\").unwrap();\n            fmt.write_ascii_range(A_FOO, 6..11).unwrap();\n            fmt.write_ascii(A_BAR).unwrap();\n            fmt.write_ascii_repeated(b'-', 4).unwrap();\n            fmt.write_str_range_debug(FOO, 1..6).unwrap();\n            fmt.write_str_debug(\"\\nABCD\\n\").unwrap();\n            fmt.write_ascii_range_debug(A_FOO, 6..11).unwrap();\n            fmt.write_ascii_debug(A_BAR).unwrap();\n        );\n    }\n\n    let expected = \"\\\n        ello\\n;;\\nABCD\\n;;\\x1F bar;;what\\0the;;----;;\\\n        \\\"ello\\\\n\\\";;\\\"\\\\nABCD\\\\n\\\";;\\\"\\\\x1F bar\\\";;\\\"what\\\\x00the\\\";;\\\n    \";\n\n    write_with_flag(FormattingFlags::NEW, expected, &inner);\n}\n\n////////////////////////////////////////////////////////////////////////////////\n\nfn remove_margin(s: &str) -> String {\n    let margin = s\n        .lines()\n        .skip(1)\n        .filter_map(|s| {\n            let trimmed = s.trim_start();\n            if trimmed.is_empty() {\n                None\n            } else {\n                Some(s.len() - trimmed.len())\n            }\n        })\n        .min()\n        .unwrap();\n\n    s.lines()\n        .skip(1)\n        .map(|s| s.get(margin..).unwrap_or(\"\"))\n        .collect::<Vec<_>>()\n        .join(\"\\n\")\n}\n"
  },
  {
    "path": "const_format/tests/fmt_tests/std_impl_tests.rs",
    "content": "use cfmt_a::{\n    coerce_to_fmt,\n    fmt::{ComputeStrLength, Error, FormattingFlags, StrWriter},\n    try_,\n    wrapper_types::PWrapper,\n};\n\nuse core::{\n    cmp::Ordering,\n    marker::{PhantomData, PhantomPinned},\n    num::NonZeroU8,\n    ops::{Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive},\n    ptr::NonNull,\n    sync::atomic::Ordering as AtomicOrdering,\n};\n\nconst FLAGS: &[FormattingFlags] = &[\n    FormattingFlags::NEW,\n    FormattingFlags::NEW.set_alternate(true).set_hexadecimal(),\n];\n\nmacro_rules! test_fmt {\n    (\n        $Ty:ty;\n        $( ($value:expr, $expected_debug:expr, $expected_hex:expr $(,)? )  )+\n    ) => ({\n        const fn inner(\n            this: &PWrapper<$Ty>,\n            writer: &mut StrWriter,\n            flags: FormattingFlags,\n        ) -> Result<usize, Error> {\n            try_!(this.const_debug_fmt(&mut writer.make_formatter(flags)));\n\n            let mut str_len = ComputeStrLength::new();\n            try_!(this.const_debug_fmt(&mut str_len.make_formatter(flags)));\n\n            Ok(str_len.len())\n        }\n\n        fn test_case(this: &PWrapper<$Ty>, expected: &str, expected_hex: &str) {\n            let writer: &mut StrWriter = &mut StrWriter::new([0; 256]);\n\n            for (&expected, &flag) in [expected,expected_hex].iter().zip(FLAGS.iter()) {\n                writer.clear();\n                let len = inner(this, writer, flag).unwrap();\n\n                assert_eq!(writer.as_str(), expected);\n                assert_eq!(writer.len(), len, \"{}\", writer.as_str());\n            }\n        }\n\n        $({\n            test_case( &coerce_to_fmt!(&$value) , $expected_debug, $expected_hex);\n        })*\n    });\n}\n\n#[test]\nfn array_impls() {\n    test_fmt! {&[u8];\n        (\n            [8u8, 13, 21, 34],\n            \"[8, 13, 21, 34]\",\n            \"[\\n    0x8,\\n    0xD,\\n    0x15,\\n    0x22,\\n]\",\n        )\n    }\n    test_fmt! {&[&str];\n        (\n            [\"foo\\n\", \"bar\\t\"],\n            \"[\\\"foo\\\\n\\\", \\\"bar\\\\t\\\"]\",\n            \"[\\n    \\\"foo\\\\n\\\",\\n    \\\"bar\\\\t\\\",\\n]\"\n        )\n    }\n    test_fmt! {&[char];\n        (\n            ['f', 'o', '\\n', '\\t', 'ñ', '个', '\\u{100000}'],\n            \"['f', 'o', '\\\\n', '\\\\t', 'ñ', '个', '\\u{100000}']\",\n            \"[\\n    'f',\\n    'o',\\n    '\\\\n',\\\n              \\n    '\\\\t',\\n    'ñ',\\n    '个',\\\n              \\n    '\\u{100000}',\\n\\\n            ]\"\n        )\n    }\n}\n\n#[test]\nfn range_impls() {\n    test_fmt! {Range<usize>; (11..64, \"11..64\", \"0xB..0x40\") }\n    test_fmt! {RangeFrom<usize>; (11.., \"11..\", \"0xB..\") }\n    test_fmt! {RangeFull; (.., \"..\", \"..\") }\n    test_fmt! {RangeInclusive<usize>; (11..=64, \"11..=64\", \"0xB..=0x40\") }\n    test_fmt! {RangeTo<usize>; (..64, \"..64\", \"..0x40\") }\n    test_fmt! {RangeToInclusive<usize>; (..=64, \"..=64\", \"..=0x40\") }\n}\n\n#[test]\nfn options() {\n    test_fmt! {Option<&str>;\n        (None::<&str>, \"None\", \"None\")\n        (Some(\"hello\\n\"), \"Some(\\\"hello\\\\n\\\")\", \"Some(\\n    \\\"hello\\\\n\\\",\\n)\")\n    }\n    test_fmt! {Option<u8>;\n        (None::<u8>, \"None\", \"None\")\n        (Some(10u8), \"Some(10)\", \"Some(\\n    0xA,\\n)\")\n    }\n    test_fmt! {Option<bool>;\n        (None::<bool>, \"None\", \"None\")\n        (Some(false), \"Some(false)\", \"Some(\\n    false,\\n)\")\n        (Some(true), \"Some(true)\", \"Some(\\n    true,\\n)\")\n    }\n    test_fmt! {Option<char>;\n        (None::<char>, \"None\", \"None\")\n        (Some('4'), \"Some('4')\", \"Some(\\n    '4',\\n)\")\n        (Some('\\x00'), \"Some('\\\\x00')\", \"Some(\\n    '\\\\x00',\\n)\")\n    }\n    test_fmt! {Option<NonZeroU8>;\n        (None::<NonZeroU8>, \"None\", \"None\")\n        (NonZeroU8::new(10), \"Some(10)\", \"Some(\\n    0xA,\\n)\")\n    }\n    test_fmt! {Option<NonNull<u8>>;\n        (None::<NonNull<u8>>, \"None\", \"None\")\n        (Some(NonNull::<u8>::dangling()), \"Some(<pointer>)\", \"Some(\\n    <pointer>,\\n)\")\n    }\n}\n\n#[test]\nfn pointers() {\n    test_fmt! {*const u8; (core::ptr::null(), \"<pointer>\", \"<pointer>\") }\n    test_fmt! {*mut u8; (core::ptr::null_mut(), \"<pointer>\", \"<pointer>\") }\n    test_fmt! {NonNull<u8>; (NonNull::dangling(), \"<pointer>\", \"<pointer>\") }\n}\n\n#[test]\nfn marker() {\n    test_fmt! {PhantomData<()>; (PhantomData, \"PhantomData\", \"PhantomData\") }\n    test_fmt! {PhantomPinned; (PhantomPinned, \"PhantomPinned\", \"PhantomPinned\") }\n    test_fmt! {(); ((), \"()\", \"()\") }\n}\n\n#[test]\nfn miscelaneous_enums() {\n    test_fmt! {\n        Ordering;\n        (Ordering::Less, \"Less\", \"Less\")\n        (Ordering::Equal, \"Equal\", \"Equal\")\n        (Ordering::Greater, \"Greater\", \"Greater\")\n    }\n    test_fmt! {\n        AtomicOrdering;\n        (AtomicOrdering::Relaxed, \"Relaxed\", \"Relaxed\")\n        (AtomicOrdering::Release, \"Release\", \"Release\")\n    }\n}\n\n#[test]\nfn chars() {\n    test_fmt! {\n        char;\n        ('\\\\', r#\"'\\\\'\"#, r#\"'\\\\'\"#)\n        ('\\'', r#\"'\\''\"#, r#\"'\\''\"#)\n        ('\\\"', r#\"'\\\"'\"#, r#\"'\\\"'\"#)\n        ('\\n', r#\"'\\n'\"#, r#\"'\\n'\"#)\n        ('\\r', r#\"'\\r'\"#, r#\"'\\r'\"#)\n        ('\\t', r#\"'\\t'\"#, r#\"'\\t'\"#)\n        ('o', r#\"'o'\"#, r#\"'o'\"#)\n        ('ñ', r#\"'ñ'\"#, r#\"'ñ'\"#)\n        ('个', r#\"'个'\"#, r#\"'个'\"#)\n        // non-ascii characters are always written unescaped\n        ('\\u{100000}', \"'\\u{100000}'\", \"'\\u{100000}'\")\n    }\n}\n"
  },
  {
    "path": "const_format/tests/fmt_tests/str_writer_methods.rs",
    "content": "use crate::RngExt;\n\nuse cfmt_a::{\n    fmt::{Error, FormattingFlags, StrWriter, StrWriterMut},\n    formatcp,\n    test_utils::{ALL_ASCII, ALL_ASCII_ESCAPED},\n    utils::saturate_range,\n    wrapper_types::{AsciiStr, PWrapper},\n};\n\nuse arrayvec::ArrayString;\n\nuse fastrand::Rng;\n\nuse core::{fmt::Write, ops::Range};\n\n#[derive(Debug, Copy, Clone)]\nenum Formatting {\n    Debug,\n    Display,\n}\n\nmacro_rules! write_integer_tests {\n    (\n        $(($display_fn:ident, $debug_fn:ident, $type:ident))*\n    ) => ({\n        $({\n            let writer: &mut StrWriter = &mut StrWriter::new([0; 1024]);\n            let mut writer = writer.as_mut();\n\n            assert!( writer.is_empty() );\n\n            let snapshot = writer.len();\n            let mut string = ArrayString::<1024>::new();\n\n            let flags = FormattingFlags::DEFAULT;\n\n            for number in &[$type::MIN, $type::MAX][..] {\n                let mut number = *number;\n\n                loop {\n                    writer.truncate(snapshot).unwrap();\n                    string.clear();\n\n                    // Adding some padding at the end so that numbers can't accidentally overlap\n                    writer.$display_fn(number).unwrap();\n                    writer.write_str(\"_\").unwrap();\n                    writer.$debug_fn(number, flags.set_decimal()).unwrap();\n                    writer.write_str(\"_\").unwrap();\n                    writer.$debug_fn(number, flags.set_binary()).unwrap();\n                    writer.write_str(\"_\").unwrap();\n                    writer.$debug_fn(number, flags.set_hexadecimal()).unwrap();\n                    writer.write_str(\"__\").unwrap();\n\n                    assert!( !writer.is_empty() );\n\n\n                    let fmt = &mut writer.make_formatter(flags);\n                    PWrapper(number).const_display_fmt(fmt).unwrap();\n                    writer.write_str(\"_\").unwrap();\n\n                    let fmt = &mut writer.make_formatter(flags.set_decimal());\n                    PWrapper(number).const_debug_fmt(fmt).unwrap();\n                    writer.write_str(\"_\").unwrap();\n\n                    let fmt = &mut writer.make_formatter(flags.set_binary());\n                    PWrapper(number).const_debug_fmt(fmt).unwrap();\n                    writer.write_str(\"_\").unwrap();\n\n                    let fmt = &mut writer.make_formatter(flags.set_hexadecimal());\n                    PWrapper(number).const_debug_fmt(fmt).unwrap();\n\n\n                    write!(\n                        string,\n                        \"{0}_{0:?}_{0:b}_{0:X}__{0}_{0:?}_{0:b}_{0:X}\",\n                        number\n                    ).unwrap();\n\n                    assert_eq!(\n                        writer.as_bytes(),\n                        string.as_bytes(),\n                        \"\\n\\ntype:{}\\n\\n\",\n                        stringify!($type)\n                    );\n\n                    // This assertion must go after the as_bytes one\n                    assert_eq!(\n                        writer.as_str(),\n                        string.as_str(),\n                        \"\\n\\ntype:{}\\n\\n\",\n                        stringify!($type)\n                    );\n\n                    if number == 0 {\n                        break;\n                    }\n\n                    let prev = number;\n                    number = number / 3 * 2;\n                    if number > 2 {\n                        number += prev % 2;\n                    }\n                }\n            }\n\n        })*\n    })\n}\n\n// This is really slow in miri.\n#[cfg(not(miri))]\n#[test]\nfn test_write_ints() {\n    write_integer_tests! {\n        (write_u8_display, write_u8_debug, u8)\n        (write_u16_display, write_u16_debug, u16)\n        (write_u32_display, write_u32_debug, u32)\n        (write_u64_display, write_u64_debug, u64)\n        (write_u128_display, write_u128_debug, u128)\n        (write_usize_display, write_usize_debug, usize)\n        (write_i8_display, write_i8_debug, i8)\n        (write_i16_display, write_i16_debug, i16)\n        (write_i32_display, write_i32_debug, i32)\n        (write_i64_display, write_i64_debug, i64)\n        (write_i128_display, write_i128_debug, i128)\n        (write_isize_display, write_isize_debug, isize)\n    }\n}\n\n#[test]\nfn basic() {\n    assert_eq!(\n        formatcp!(\"{:?}\", r#\" !Aq¡\\\"🧡🧠₀₁ \"#),\n        r#\"\" !Aq¡\\\\\\\"🧡🧠₀₁ \"\"#\n    );\n}\n\n#[test]\nfn saturate_range_tests() {\n    let all_ascii = ALL_ASCII.as_bytes();\n    let len = ALL_ASCII.len();\n\n    let same_ranges = [0..len, 1..len - 1, 2..len - 2, 3..len - 3];\n\n    for range in same_ranges.iter() {\n        assert_eq!(saturate_range(all_ascii, range), *range);\n    }\n\n    let saturated_ranges = [(10..!0, 10..len), (!0..10, 10..10), (!0..!0, len..len)];\n\n    for (range, expected) in saturated_ranges.iter().cloned() {\n        assert_eq!(saturate_range(all_ascii, &range), expected);\n    }\n}\n\nstruct WriteArgs<'sw, 's> {\n    writer: StrWriterMut<'sw>,\n    input: &'s str,\n    range: Range<usize>,\n    sat_range: Range<usize>,\n}\n\nfn test_unescaped_str_fn(\n    formatting: Formatting,\n    rng: &mut dyn FnMut() -> char,\n    write: &mut dyn FnMut(WriteArgs<'_, '_>) -> Result<(), cfmt_a::fmt::Error>,\n) {\n    #[cfg(not(miri))]\n    let tries = 64;\n\n    #[cfg(miri)]\n    let tries = 1;\n\n    #[cfg(not(miri))]\n    const CAP: usize = 32;\n\n    #[cfg(miri)]\n    const CAP: usize = 10;\n\n    for _ in 0..tries {\n        let mut input = ArrayString::<CAP>::new();\n        while input.try_push(rng()).is_ok() {}\n\n        let input = input.as_str();\n        let input_bytes = input.as_bytes();\n\n        let writer: &mut StrWriter = &mut StrWriter::new([0; 192]);\n\n        for end in 0..input.len() {\n            for start in 0..end + 2 {\n                writer.clear();\n                let mut writer = writer.as_mut();\n\n                let toosmall: &mut StrWriter = &mut StrWriter::new([0; 8]);\n                let toosmall = toosmall.as_mut();\n\n                let range = start..end;\n                let sat_range = saturate_range(input_bytes, &range);\n\n                writer.write_u8_display(0).unwrap();\n                writer.write_u8_display(0).unwrap();\n                let __just_dont_panic = write(WriteArgs {\n                    writer: toosmall,\n                    input,\n                    range: range.clone(),\n                    sat_range: sat_range.clone(),\n                });\n                let res = write(WriteArgs {\n                    writer: writer.reborrow(),\n                    input,\n                    range: range.clone(),\n                    sat_range: sat_range.clone(),\n                });\n                writer.write_u8_display(0).unwrap();\n                writer.write_u8_display(0).unwrap();\n\n                let bytes = writer.as_bytes();\n\n                // 00.....00 with Display\n                // 00\".....\"00 with Debug\n                let around = match formatting {\n                    Formatting::Display { .. } => 2,\n                    Formatting::Debug { .. } => 3,\n                };\n\n                assert_eq!(&bytes[..2], b\"00\");\n                assert_eq!(&bytes[bytes.len() - 2..], b\"00\");\n\n                assert_eq!(res.is_ok(), input.get(sat_range.clone()).is_some());\n\n                if res.is_ok() {\n                    assert_eq!(\n                        &bytes[around..bytes.len() - around],\n                        &input_bytes[sat_range.clone()],\n                        \"\\n\\nbytes: {:?}\\n\\n\",\n                        bytes,\n                    );\n                }\n            }\n        }\n    }\n}\n\n#[test]\nfn write_str() {\n    let rng = Rng::with_seed(1989152812982806979);\n    test_unescaped_str_fn(\n        Formatting::Display,\n        &mut || rng.unicode_char(),\n        &mut |mut p| p.writer.write_str_range(p.input, p.range),\n    );\n    test_unescaped_str_fn(\n        Formatting::Display,\n        &mut || rng.unicode_char(),\n        &mut |mut p| {\n            let input = p.input.get(p.sat_range).ok_or(Error::NotOnCharBoundary)?;\n            p.writer.write_str(input)\n        },\n    );\n}\n\n#[test]\nfn write_ascii() {\n    let rng = Rng::with_seed(1989152812982806979);\n    let mut rng_fn = || rng.char_('\\0'..='\\u{7F}');\n    test_unescaped_str_fn(Formatting::Display, &mut rng_fn, &mut |mut p| {\n        let ascii = AsciiStr::new(p.input.as_bytes()).unwrap();\n        p.writer.write_ascii_range(ascii, p.range)\n    });\n    test_unescaped_str_fn(Formatting::Display, &mut rng_fn, &mut |mut p| {\n        let ascii = AsciiStr::new(&p.input.as_bytes()[p.sat_range]).unwrap();\n        p.writer.write_ascii(ascii)\n    });\n}\n\nfn is_it_escaped(c: char) -> bool {\n    matches!(c, '\\0'..='\\u{1F}' | '\\\\' | '\"' | '\\'')\n}\n\n#[test]\nfn write_str_debug() {\n    {\n        let rng = Rng::with_seed(1989152812982806979);\n        let mut rng_fn = || loop {\n            let c = rng.unicode_char();\n            if !is_it_escaped(c) {\n                break c;\n            }\n        };\n        test_unescaped_str_fn(Formatting::Debug, &mut rng_fn, &mut |mut p| {\n            p.writer.write_str_range_debug(p.input, p.range)\n        });\n        test_unescaped_str_fn(Formatting::Debug, &mut rng_fn, &mut |mut p| {\n            let input = p.input.get(p.sat_range).ok_or(Error::NotOnCharBoundary)?;\n            p.writer.write_str_debug(input)\n        });\n    }\n\n    // Testing that all ascii characters are escaped as expected\n    let writer: &mut StrWriter = &mut StrWriter::new([0; 512]);\n    let mut writer = writer.as_mut();\n\n    let snapshot = writer.len();\n    {\n        writer.truncate(snapshot).unwrap();\n        writer.write_str_debug(ALL_ASCII).unwrap();\n\n        let bytes = writer.as_bytes();\n        assert_eq!(bytes[0], b'\"');\n        assert_eq!(&bytes[1..bytes.len() - 1], ALL_ASCII_ESCAPED.as_bytes());\n        assert_eq!(bytes[bytes.len() - 1], b'\"');\n    }\n    {\n        let all_ascii = AsciiStr::new(&ALL_ASCII.as_bytes()[..128]).unwrap();\n\n        writer.truncate(snapshot).unwrap();\n        writer.write_ascii_debug(all_ascii).unwrap();\n        let end = ALL_ASCII_ESCAPED.find('\\u{80}').unwrap();\n\n        let bytes = writer.as_bytes();\n        assert_eq!(bytes[0], b'\"');\n        assert_eq!(\n            &bytes[1..bytes.len() - 1],\n            &ALL_ASCII_ESCAPED.as_bytes()[..end]\n        );\n        assert_eq!(bytes[bytes.len() - 1], b'\"');\n    }\n\n    // Testing that escaping random ranges in ALL_ASCII produces escaped strings\n    // that can be found in ALL_ASCII_ESCAPED\n    {\n        let rng = Rng::with_seed(1989152812982806979);\n        fn write_range(rng: &Rng, mut w: StrWriterMut<'_>) -> Range<usize> {\n            let gen_range = || rng.usize(..ALL_ASCII.len())..rng.usize(..ALL_ASCII.len());\n            let start = w.len();\n            while let Err(_) = w.write_str_range_debug(ALL_ASCII, gen_range()) {}\n            let end = w.len();\n            start + 1..end - 1\n        }\n\n        #[cfg(not(miri))]\n        const ITERATIONS: usize = 1000;\n\n        #[cfg(miri)]\n        const ITERATIONS: usize = 30;\n\n        for _ in 1..ITERATIONS {\n            writer.truncate(snapshot).unwrap();\n\n            let range_a = write_range(&rng, writer.reborrow());\n            let range_b = write_range(&rng, writer.reborrow());\n            let range_c = write_range(&rng, writer.reborrow());\n\n            let written = writer.as_str();\n\n            let haystack = ALL_ASCII_ESCAPED;\n\n            assert!(\n                haystack.contains(&written[range_a.clone()]),\n                \"{:?} {:?}\",\n                range_a,\n                written\n            );\n            assert!(\n                haystack.contains(&written[range_b.clone()]),\n                \"{:?} {:?}\",\n                range_b,\n                written\n            );\n            assert!(\n                haystack.contains(&written[range_c.clone()]),\n                \"{:?} {:?}\",\n                range_c,\n                written\n            );\n        }\n    }\n}\n\n// Makes sure that a StrWriter that's too small for a string returns an Error\n// instead of panicking\n#[test]\nfn returns_error() {\n    const ZEROES_AROUND_STR: usize = 2;\n\n    fn test_case_(writer: &mut StrWriter, s: &str, extra: usize) {\n        let str_writer_cap = writer.capacity();\n        let mut writer = writer.as_mut();\n        writer.write_u8_display(0).unwrap();\n        writer.write_u8_display(0).unwrap();\n        let res = writer.write_str_debug(s);\n        assert_eq!(&writer.as_bytes()[..2], &b\"00\"[..]);\n\n        if writer.capacity() == extra && str_writer_cap == extra {\n            res.unwrap();\n        } else {\n            res.unwrap_err();\n            assert_eq!(writer.len(), ZEROES_AROUND_STR);\n        }\n    }\n\n    macro_rules! test_case {\n        ($str:expr, $extra:expr) => {{\n            const S: &str = $str;\n            const EXTRA: usize = ZEROES_AROUND_STR + S.len() + $extra + 2;\n            test_case_(&mut StrWriter::new([0; EXTRA - 2]), S, EXTRA);\n            test_case_(&mut StrWriter::new([0; EXTRA - 1]), S, EXTRA);\n            test_case_(&mut StrWriter::new([0; EXTRA]), S, EXTRA);\n        }};\n    }\n\n    test_case!(\"foo\\nb\", 1);\n    test_case!(\"foo\\\"ba\", 1);\n    test_case!(\"foo\\'bar\", 1);\n    test_case!(\"foo\\rbarb\", 1);\n    test_case!(\"foo\\\\barba\", 1);\n    test_case!(\"foo\\u{5}bar\", 3);\n    test_case!(\"foo\\u{11}bar\", 3);\n}\n\n#[test]\nfn remaining_capacity_test() {\n    const CAP: usize = 16;\n\n    let underscored = \"___________________________________\";\n\n    let str_writer: &mut StrWriter = &mut StrWriter::new([0; CAP]);\n    assert_eq!(str_writer.remaining_capacity(), CAP);\n\n    for i in (0..CAP).rev() {\n        str_writer.as_mut().write_str(\"_\").unwrap();\n        assert_eq!(str_writer.remaining_capacity(), i);\n    }\n    assert_eq!(str_writer.remaining_capacity(), 0);\n    assert_eq!(str_writer.as_str(), &underscored[..str_writer.capacity()]);\n\n    str_writer.truncate(5).unwrap();\n    assert_eq!(str_writer.remaining_capacity(), CAP - 5);\n}\n\n#[test]\nfn truncation() {\n    let str_writer: &mut StrWriter = &mut StrWriter::new([0; 4096]);\n    let mut writer = str_writer.as_mut();\n\n    let snapshot = writer.len();\n\n    writer.write_str(\"hello\").unwrap();\n    assert_eq!(writer.as_bytes(), \"hello\".as_bytes());\n\n    writer.truncate(snapshot).unwrap();\n    assert_eq!(writer.as_bytes(), \"\".as_bytes());\n\n    writer.write_str(\"world\").unwrap();\n    assert_eq!(writer.as_bytes(), \"world\".as_bytes());\n\n    {\n        let nested = writer.len();\n\n        writer\n            .write_str(\"\\u{0000}\\u{0080}\\u{0800}\\u{10000}\")\n            .unwrap();\n        assert_eq!(\n            writer.as_bytes(),\n            \"world\\u{0000}\\u{0080}\\u{0800}\\u{10000}\".as_bytes()\n        );\n        let with_foo_len = writer.len();\n\n        writer.truncate(15).unwrap();\n        assert_eq!(\n            writer.as_bytes(),\n            \"world\\u{0000}\\u{0080}\\u{0800}\\u{10000}\".as_bytes()\n        );\n\n        assert_eq!(writer.truncate(14).unwrap_err(), Error::NotOnCharBoundary);\n        assert_eq!(writer.truncate(13).unwrap_err(), Error::NotOnCharBoundary);\n        assert_eq!(writer.truncate(12).unwrap_err(), Error::NotOnCharBoundary);\n\n        writer.truncate(11).unwrap();\n        assert_eq!(\n            writer.as_bytes(),\n            \"world\\u{0000}\\u{0080}\\u{0800}\".as_bytes()\n        );\n\n        let writer = &mut *str_writer;\n\n        assert_eq!(writer.truncate(10).unwrap_err(), Error::NotOnCharBoundary);\n        assert_eq!(writer.truncate(9).unwrap_err(), Error::NotOnCharBoundary);\n\n        writer.truncate(8).unwrap();\n        assert_eq!(writer.as_bytes(), \"world\\u{0000}\\u{0080}\".as_bytes());\n\n        assert_eq!(writer.truncate(7).unwrap_err(), Error::NotOnCharBoundary);\n\n        writer.truncate(6).unwrap();\n        assert_eq!(writer.as_bytes(), \"world\\u{0000}\".as_bytes());\n\n        writer.truncate(nested).unwrap();\n        assert_eq!(writer.as_bytes(), \"world\".as_bytes());\n\n        writer.truncate(with_foo_len).unwrap();\n        assert_eq!(writer.len(), 5);\n    }\n    writer = str_writer.as_mut();\n\n    assert_eq!(writer.as_bytes(), \"world\".as_bytes());\n    writer.truncate(snapshot).unwrap();\n    assert_eq!(writer.as_bytes(), \"\".as_bytes());\n\n    writer.truncate(5).unwrap();\n    assert_eq!(writer.len(), 0);\n}\n\n#[test]\nfn as_bytes() {\n    let writer: &mut StrWriter = &mut StrWriter::new([0; 512]);\n    let mut string = String::new();\n\n    for i in 0..512 {\n        let ascii_char = ((i % 61) + 32) as u8;\n        writer.as_mut().write_ascii_repeated(ascii_char, 1).unwrap();\n        string.push(ascii_char as char);\n\n        assert_eq!(writer.as_bytes(), string.as_bytes());\n        assert_eq!(writer.as_bytes_alt(), string.as_bytes());\n        assert_eq!(writer.as_str(), string.as_str());\n    }\n}\n\n#[test]\nfn clear() {\n    let str_writer: &mut StrWriter = &mut StrWriter::new([0; 16]);\n\n    {\n        let mut writer = str_writer.as_mut();\n\n        writer.write_str(\"hello\").unwrap();\n    }\n\n    assert_eq!(str_writer.as_bytes(), \"hello\".as_bytes());\n    str_writer.clear();\n    assert_eq!(str_writer.as_bytes(), \"\".as_bytes());\n\n    {\n        let mut writer = str_writer.as_mut();\n\n        writer.write_str(\"hello\").unwrap();\n        assert_eq!(writer.as_bytes(), \"hello\".as_bytes());\n        writer.clear();\n        assert_eq!(writer.as_bytes(), \"\".as_bytes());\n    }\n}\n\n#[test]\nfn write_ascii_debug() {\n    let rng = Rng::with_seed(1989152812982806979);\n    let mut rng_fn = || loop {\n        let c = rng.char_('\\0'..='\\u{7F}');\n        if !is_it_escaped(c) {\n            break c;\n        }\n    };\n    test_unescaped_str_fn(Formatting::Debug, &mut rng_fn, &mut |mut p| {\n        let ascii = AsciiStr::new(p.input.as_bytes()).unwrap();\n        p.writer.write_ascii_range_debug(ascii, p.range)\n    });\n    test_unescaped_str_fn(Formatting::Debug, &mut rng_fn, &mut |mut p| {\n        let ascii = AsciiStr::new(&p.input.as_bytes()[p.sat_range]).unwrap();\n        p.writer.write_ascii_debug(ascii)\n    });\n}\n"
  },
  {
    "path": "const_format/tests/fmt_tests/str_writer_mut.rs",
    "content": "use cfmt_a::fmt::{Error, StrWriterMut};\n\n#[test]\nfn from_custom() -> Result<(), Error> {\n    let mut len = 4;\n    let mut buffer = [b' '; 256];\n\n    let mut writer = StrWriterMut::from_custom(&mut buffer, &mut len);\n    assert_eq!(writer.as_bytes(), b\"    \");\n\n    writer.write_str(\"hello\")?;\n    assert_eq!(writer.as_bytes(), b\"    hello\");\n\n    assert_eq!(writer.len(), 9);\n    assert!(writer.buffer().starts_with(b\"    hello\"));\n\n    assert_eq!(len, 9);\n    assert!(buffer.starts_with(b\"    hello\"));\n\n    len = 6;\n    let mut writer = StrWriterMut::from_custom(&mut buffer, &mut len);\n\n    assert_eq!(writer.len(), 6);\n    assert_eq!(writer.as_bytes(), b\"    he\");\n\n    writer.write_str(\"roic\")?;\n    assert_eq!(writer.len(), 10);\n    assert_eq!(writer.as_bytes(), b\"    heroic\");\n    assert!(writer.buffer().starts_with(b\"    heroic\"));\n\n    assert_eq!(len, 10);\n    assert!(buffer.starts_with(b\"    heroic\"));\n\n    Ok(())\n}\n\n#[test]\nfn from_custom_cleared() -> Result<(), Error> {\n    let mut len = 4;\n    let mut buffer = [b' '; 256];\n\n    let mut writer = StrWriterMut::from_custom_cleared(&mut buffer, &mut len);\n    assert_eq!(writer.as_str(), \"\");\n\n    writer.write_str(\"hello\")?;\n    assert_eq!(writer.len(), 5);\n    assert_eq!(writer.as_str(), \"hello\");\n    assert!(writer.buffer().starts_with(b\"hello\"));\n\n    assert_eq!(len, 5);\n    assert!(buffer.starts_with(b\"hello\"));\n\n    let mut writer = StrWriterMut::from_custom_cleared(&mut buffer, &mut len);\n\n    assert!(writer.is_empty());\n    assert_eq!(writer.len(), 0);\n    assert_eq!(writer.as_str(), \"\");\n\n    writer.write_str(\"he\")?;\n    assert!(!writer.is_empty());\n    assert_eq!(writer.len(), 2);\n    assert_eq!(writer.as_str(), \"he\");\n    assert!(writer.buffer().starts_with(b\"he\"));\n\n    writer.write_str(\"roic\")?;\n    assert!(!writer.is_empty());\n    assert_eq!(writer.len(), 6);\n    assert_eq!(writer.as_str(), \"heroic\");\n    assert!(writer.buffer().starts_with(b\"heroic\"));\n\n    assert_eq!(len, 6);\n    assert!(buffer.starts_with(b\"heroic\"));\n\n    Ok(())\n}\n\n#[test]\nfn truncate_no_encoding() -> Result<(), Error> {\n    let bytes = {\n        let mut bytes = \"foo\".as_bytes().to_vec();\n        // These are unicode continuation bytes,\n        // ensuring that the StrWriterMut can be truncated into a continuation byte\n        bytes.push(0xBE);\n        bytes.push(0xBF);\n        bytes\n    };\n\n    // This isn't valid unicode.\n    assert!(std::str::from_utf8(&bytes).is_err());\n\n    let mut buffer = [0; 32];\n    buffer[..bytes.len()].copy_from_slice(&bytes);\n    let mut len = bytes.len();\n    let mut writer = StrWriterMut::from_custom(&mut buffer, &mut len);\n\n    assert_eq!(writer.as_bytes(), b\"foo\\xBE\\xBF\");\n\n    writer.write_str(\" bar baz\")?;\n\n    let all = b\"foo\\xBE\\xBF bar baz\";\n\n    writer.truncate(usize::MAX / 2);\n    assert_eq!(writer.as_bytes(), all);\n\n    let fbb_len = writer.len();\n\n    writer.truncate(fbb_len + 1);\n    assert_eq!(writer.as_bytes(), all);\n\n    for truncate_to in (3..fbb_len).rev() {\n        writer.truncate(truncate_to);\n        assert_eq!(writer.as_bytes(), &all[..truncate_to]);\n    }\n\n    writer.write_str(\"ooooooo\")?;\n    assert_eq!(writer.as_bytes(), b\"fooooooooo\");\n\n    writer.truncate(4);\n    assert_eq!(writer.as_bytes(), b\"fooo\");\n\n    Ok(())\n}\n\n#[test]\nfn clear_test() {\n    const CAP: usize = 512;\n    let mut buffer = [0; CAP];\n    let mut len = 0;\n    let mut writer = StrWriterMut::from_custom_cleared(&mut buffer, &mut len);\n\n    writer.write_str(\"hello\").unwrap();\n    assert_eq!(writer.as_str(), \"hello\");\n\n    writer.write_str(\"world\").unwrap();\n    assert_eq!(writer.as_str(), \"helloworld\");\n\n    writer.clear();\n    assert_eq!(writer.as_str(), \"\");\n    assert_eq!(writer.len(), 0);\n\n    assert_eq!(len, 0);\n\n    let mut writer = StrWriterMut::from_custom_cleared(&mut buffer, &mut len);\n\n    writer.write_str(\"foo\").unwrap();\n    assert_eq!(writer.as_str(), \"foo\");\n\n    writer.write_str(\"bar\").unwrap();\n    assert_eq!(writer.as_str(), \"foobar\");\n}\n\n#[test]\nfn as_bytes() {\n    const CAP: usize = 512;\n    let mut buffer = [0; CAP];\n    let mut len = 0;\n    let mut writer = StrWriterMut::from_custom_cleared(&mut buffer, &mut len);\n    let mut string = String::new();\n\n    for i in 0..CAP {\n        assert_eq!(writer.capacity(), CAP);\n        assert_eq!(writer.remaining_capacity(), CAP - i);\n\n        let ascii_char = ((i % 61) + 32) as u8;\n        writer.write_ascii_repeated(ascii_char, 1).unwrap();\n        string.push(ascii_char as char);\n\n        assert_eq!(writer.as_bytes(), string.as_bytes());\n        assert_eq!(writer.as_bytes_alt(), string.as_bytes());\n        assert_eq!(writer.as_str(), string.as_str());\n\n        assert_eq!(writer.remaining_capacity(), CAP - i - 1);\n    }\n}\n"
  },
  {
    "path": "const_format/tests/fmt_tests_modules.rs",
    "content": "#![cfg(feature = \"fmt\")]\n\n// Prevents importing from const_format, requiring importing from cfmt_b.\nextern crate const_format as cfmt_a;\nextern crate self as const_format;\n\n// Making sure that `const_format` points at this test crate.\npub const NOT_CF: usize = 13;\npub const _ASSERT_NOT_CF: [(); 13] = [(); const_format::NOT_CF];\n\ncfmt_a::__declare_rng_ext! {}\n\nmod fmt_tests {\n    #[cfg(not(feature = \"__only_new_tests\"))]\n    mod display_formatting;\n\n    #[cfg(not(feature = \"__only_new_tests\"))]\n    mod formatted_writing;\n\n    #[cfg(not(feature = \"__only_new_tests\"))]\n    mod formatter_methods;\n\n    #[cfg(not(feature = \"__only_new_tests\"))]\n    mod std_impl_tests;\n\n    #[cfg(not(feature = \"__only_new_tests\"))]\n    mod str_writer_methods;\n\n    #[cfg(not(feature = \"__only_new_tests\"))]\n    mod str_writer_mut;\n}\n"
  },
  {
    "path": "const_format/tests/misc_tests/assertc_tests.rs",
    "content": "#![allow(unreachable_code)]\n#![allow(non_local_definitions)]\n\nuse cfmt_b::for_examples::{Point3, Unit};\nuse cfmt_b::{assertc, assertc_eq, assertc_ne, call_debug_fmt};\n\nstruct Foo;\n\nassertc!(true, \"Hello, world {:?}\", {\n    impl Foo {\n        const BAR: u32 = 10;\n    }\n},);\n\nassertc!(true, concat!(\"Hello\", r#\"world {:?}\"#), {\n    impl Foo {\n        const BAZ: u32 = 11;\n    }\n},);\n\n// braces in arguments that take a formatter should work\nassertc!(\n    true,\n    \"{foo}\\n{}\",\n    |fmt| {\n        impl Foo {\n            const FMT_FOO: u32 = 12;\n        }\n        call_debug_fmt!(array, [100u8], fmt)\n    },\n    foo = |fmt| {\n        impl Foo {\n            const FMT_BAR: u32 = 13;\n        }\n        call_debug_fmt!(array, [Unit, Unit], fmt)\n    },\n);\n\n// single expressions that take the formatter should also work\nassertc!(\n    true,\n    \"{foo}\\n{foo:#?}\\n{}\",\n    |fmt| call_debug_fmt!(array, [100u8], fmt),\n    foo = |fmt| call_debug_fmt!(array, [Unit, Unit], fmt),\n);\n\n#[test]\nfn assertc_emits_formatting() {\n    assert_eq!(Foo::BAR, 10);\n    assert_eq!(Foo::BAZ, 11);\n    assert_eq!(Foo::FMT_FOO, 12);\n    assert_eq!(Foo::FMT_BAR, 13);\n}\n\n// The formatting code should not run if the assertion is true\nassertc!(true, \"{}\", {\n    let _x: u32 = loop {};\n    _x\n});\n\n#[allow(unused_variables)]\nconst _: () = {\n    const POINT: Point3 = Point3 { x: 3, y: 5, z: 8 };\n    const OTHER_POINT: Point3 = Point3 {\n        x: 13,\n        y: 21,\n        z: 34,\n    };\n\n    ////////////////////////////////////////////////////////////////////////////////\n    ////        assertc_eq\n\n    assertc_eq!(POINT, POINT);\n    assertc_eq!(OTHER_POINT, OTHER_POINT);\n\n    assertc_eq!(Unit, Unit);\n\n    assertc_eq!(0u8, 0u8);\n    assertc_eq!(\"foo\", \"foo\", \"hello\");\n    assertc_eq!(Some(\"foo\"), Some(\"foo\"), \"hello {}\", {\n        let x: u32 = loop {};\n        x\n    });\n    assertc_eq!([false], [false], \"{}\", |f| {\n        loop {}\n        f.write_str(\"hello\")\n    });\n\n    ////////////////////////////////////////////////////////////////////////////////\n    ////        assertc_ne\n    assertc_ne!(POINT, OTHER_POINT);\n    assertc_ne!(OTHER_POINT, POINT);\n\n    assertc_ne!(0u8, 3u8);\n    assertc_ne!(\"foo\", \"bar\", \"hello\");\n    assertc_ne!(Some(\"foo\"), Some(\"bar\"), \"hello {}\", {\n        let x: u32 = loop {};\n        x\n    });\n    assertc_ne!([false], [true], \"{}\", |f| {\n        loop {}\n        f.write_str(\"hello\")\n    });\n};\n"
  },
  {
    "path": "const_format/tests/misc_tests/assertcp_tests.rs",
    "content": "#![allow(unreachable_code)]\n#![allow(non_local_definitions)]\n\nuse cfmt_b::{assertcp, assertcp_eq, assertcp_ne};\n\nstruct Foo;\n\n// no need for formatting string\nassertcp!(true);\n\nassertcp!({\n    impl Foo {\n        const NINE: u32 = 9;\n    }\n    true\n});\n\nassertcp!(true, \"Hello, world {:?}\", {\n    impl Foo {\n        const BAR: u32 = 10;\n    }\n    1u8\n},);\n\nassertcp!(true, concat!(\"Hello\", r#\"world {:?}\"#), {\n    impl Foo {\n        const BAZ: u32 = 11;\n    }\n    1u8\n},);\n\n#[test]\nfn assertcp_emits_formatting() {\n    assert_eq!(Foo::NINE, 9);\n    assert_eq!(Foo::BAR, 10);\n    assert_eq!(Foo::BAZ, 11);\n    assert_eq!(Foo::QUX, 12);\n    assert_eq!(Foo::SPAT, 13);\n    assert_eq!(Foo::OOF, 14);\n    assert_eq!(Foo::RAB, 15);\n}\n\n// The formatting code should not run if the assertion is true\nassertcp!(true, \"{}\", {\n    let _x: u32 = loop {};\n    _x\n});\n\nconst X: u8 = 123;\n\n#[allow(unused_variables)]\nconst _: () = {\n    ////////////////////////////////////////////////////////////////////////////////\n    ////        assertcp_eq\n\n    assertcp_eq!(\n        {\n            impl Foo {\n                const QUX: u32 = 12;\n            }\n            0u8\n        },\n        0u8,\n    );\n    assertcp_eq!(false, {\n        impl Foo {\n            const SPAT: u32 = 13;\n        }\n        false\n    },);\n    assertcp_eq!(' ', ' ');\n    assertcp_eq!(\"hello\", \"hello\");\n\n    assertcp_eq!(0u8, 0u8, \"world\");\n    assertcp_eq!(false, false, \"world{}\", 1u8);\n    assertcp_eq!(' ', ' ', \"world{foo}\", foo = 1u8);\n    assertcp_eq!(\"hello\", \"hello\", \"world{X}\");\n\n    ////////////////////////////////////////////////////////////////////////////////\n    ////        assertcp_ne\n\n    assertcp_ne!(\"hello\", \"helo\");\n    assertcp_ne!(0u8, 1u8, \"world\");\n    assertcp_ne!(\n        {\n            impl Foo {\n                const OOF: u32 = 14;\n            }\n            false\n        },\n        true,\n        \"world{}\",\n        {\n            let x: u32 = loop {};\n            x\n        },\n    );\n    assertcp_ne!(\n        ' ',\n        {\n            impl Foo {\n                const RAB: u32 = 15;\n            }\n            'A'\n        },\n        \"world{foo}\",\n        foo = {\n            #[allow(unconditional_panic)]\n            let foo: u8 = [][0];\n            foo\n        },\n    );\n};\n"
  },
  {
    "path": "const_format/tests/misc_tests/call_debug_fmt_macro.rs",
    "content": "use cfmt_b::fmt::{Error, Formatter, FormattingFlags, StrWriter};\nuse cfmt_b::{call_debug_fmt, impl_fmt, try_};\n\nuse core::{cmp::Reverse, num::Wrapping};\n\n#[test]\nfn all_macro_branches() {\n    const fn inner(f: &mut Formatter<'_>) -> Result<(), Error> {\n        call_debug_fmt!(slice, [Some(10u8), None], f);\n        try_!(f.write_str(\"\\n\"));\n\n        call_debug_fmt!(Option, Some(&(0..10)), f);\n        try_!(f.write_str(\"\\n\"));\n\n        call_debug_fmt!(newtype Wrapping, Wrapping(\"hello\"), f);\n        try_!(f.write_str(\"\\n\"));\n\n        call_debug_fmt!(newtype Reverse, Reverse(&Some(10u8)), f);\n        try_!(f.write_str(\"\\n\"));\n\n        call_debug_fmt!(newtype Hello, Hello(false), f);\n        try_!(f.write_str(\"\\n\"));\n\n        call_debug_fmt!(std, 1000u16, f);\n        try_!(f.write_str(\"\\n\"));\n\n        call_debug_fmt!(other, TupleStruct(256), f);\n        try_!(f.write_str(\"\\n\"));\n\n        Ok(())\n    }\n\n    let writer: &mut StrWriter = &mut StrWriter::new([0; 1024]);\n\n    inner(&mut writer.make_formatter(FormattingFlags::NEW)).unwrap();\n\n    assert_eq!(\n        writer.as_str(),\n        \"[Some(10), None]\\n\\\n         Some(0..10)\\n\\\n         Wrapping(\\\"hello\\\")\\n\\\n         Reverse(Some(10))\\n\\\n         Hello(false)\\n\\\n         1000\\n\\\n         TupleStruct(256)\\n\\\n        \",\n    );\n}\n\n#[test]\nfn returns_error() {\n    const fn inner(f: &mut Formatter<'_>) -> Result<(), Error> {\n        call_debug_fmt!(slice, [Some(10u8), None], f);\n        Ok(())\n    }\n\n    let writer: &mut StrWriter = &mut StrWriter::new([0; 4]);\n\n    let err = inner(&mut writer.make_formatter(FormattingFlags::NEW)).unwrap_err();\n\n    assert!(matches!(err, Error::NotEnoughSpace));\n}\n\nstruct Hello<T>(T);\n\nstruct TupleStruct(u32);\n\nimpl_fmt! {\n    impl TupleStruct;\n\n    const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {\n        use cfmt_b::PWrapper;\n\n        let mut f = f.debug_tuple(\"TupleStruct\");\n        try_!(PWrapper(self.0).const_debug_fmt(f.field()));\n        f.finish()\n    }\n}\n"
  },
  {
    "path": "const_format/tests/misc_tests/clippy_warnings.rs",
    "content": "#[deny(clippy::double_parens)]\n#[test]\nfn test_clippy_double_parens_not_triggered() {\n    std::convert::identity(cfmt_b::formatcp!(\"hello\"));\n}\n"
  },
  {
    "path": "const_format/tests/misc_tests/concatc_macro_tests.rs",
    "content": "use cfmt_b::Formatter;\nuse cfmt_b::{ascii_str, concatc, impl_fmt, try_};\n\nuse std::num::NonZeroUsize;\n\nconst STD_TYPES: &str = concatc!(\n    r#\"\\\\\\-hello-\\\\\\\"#,\n    100u8,\n    false,\n    true,\n    match NonZeroUsize::new(34) {\n        Some(x) => x,\n        None => loop {},\n    },\n);\n\nconst USER_TYPES: &str = concatc!(Twice(\"hello \"), ascii_str!(\"world!\"));\n\n#[test]\nfn concatc_test() {\n    assert_eq!(STD_TYPES, r#\"\\\\\\-hello-\\\\\\100falsetrue34\"#);\n    assert_eq!(USER_TYPES, r#\"hello hello world!\"#);\n}\n\nstruct Twice(&'static str);\n\nimpl_fmt! {\n    impl Twice;\n\n    const fn const_display_fmt(&self, fmt:&mut Formatter<'_>) -> cfmt_b::Result {\n        try_!(fmt.write_str(self.0));\n        try_!(fmt.write_str(self.0));\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "const_format/tests/misc_tests/derive_tests/is_a_attributes.rs",
    "content": "use cfmt_b::{\n    coerce_to_fmt,\n    fmt::{Error, Formatter, FormattingFlags, StrWriter},\n    impl_fmt, try_,\n    wrapper_types::PWrapper,\n    ConstDebug,\n};\n\nuse core::marker::PhantomData;\n\npub struct Bar(pub u32);\n\nimpl_fmt! {\n    impl[] Bar;\n\n    const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {\n        let mut f = f.debug_tuple(\"Bar\");\n        try_!(PWrapper(self.0).const_debug_fmt(f.field()));\n        f.finish()\n    }\n}\n\nconst fn fmt_bar_in_hex(this: &Bar, f: &mut Formatter<'_>) -> Result<(), Error> {\n    let flags = f.flags().set_hexadecimal();\n    this.const_debug_fmt(&mut f.make_formatter(flags))\n}\n\n/////////////////////////////////////////////////////////////////\n\npub struct DisplayWrapper<'a, T>(pub &'a T);\n\nimpl_fmt! {\n    impl DisplayWrapper<'_, &str>;\n\n    const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {\n        PWrapper(*self.0).const_display_fmt(f)\n    }\n}\n\n/////////////////////////////////////////////////////////////////\n\nmacro_rules! display_fmt {\n    ($reference:expr, $formatter:expr) => {\n        coerce_to_fmt!($reference).const_display_fmt($formatter)\n    };\n}\n\n/////////////////////////////////////////////////////////////////\n\nmod type_named_option {\n    use super::*;\n\n    pub struct NotDebug;\n\n    pub struct Option<T>(pub PhantomData<T>);\n\n    impl_fmt! {\n        impl[T] Option<T>;\n\n        const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {\n            f.write_str(\"NotAStdOption\")\n        }\n    }\n\n    // This type tests that ``\n    #[derive(ConstDebug)]\n    #[cdeb(crate = \"::cfmt_b\")]\n    pub(super) struct WrapsNamedOption {\n        pub(super) opt_a: self::Option<NotDebug>,\n\n        #[cdeb(is_a(non_std))]\n        pub(super) opt_b: Option<NotDebug>,\n\n        #[cdeb(is_a(not_std))]\n        pub(super) opt_c: Option<NotDebug>,\n    }\n}\n\nuse self::type_named_option::WrapsNamedOption;\n\n/////////////////////////////////////////////////////////////////\n\npub mod path {\n    pub mod to {\n        pub use super::super::Bar;\n    }\n}\n\n// Defining the `alloc` and `std` modules to avoid having to import them here\n// (I'll probably use the real ones in an example)\npub mod alloc {\n    pub mod option {\n        pub use core::option::Option;\n    }\n}\npub mod std {\n    pub mod option {\n        pub use core::option::Option;\n    }\n}\n\n#[derive(ConstDebug)]\n#[cdeb(crate = \"::cfmt_b\")]\nstruct Automatic {\n    slice_a: &'static [Bar],\n    slice_b: &'static &'static [Bar],\n    array_a: [Bar; 2],\n    array_b: &'static [Bar; 2],\n    array_c: &'static &'static [Bar; 2],\n    option_a: Option<Bar>,\n    option_b: core::option::Option<Bar>,\n    option_c: alloc::option::Option<Bar>,\n    option_d: std::option::Option<Bar>,\n}\n\ntype BarSlice = [Bar];\ntype BarArray = [Bar; 2];\ntype BarOption = Option<Bar>;\n\n#[derive(ConstDebug)]\n#[cdeb(crate = \"::cfmt_b\")]\nstruct Manual {\n    #[cdeb(is_a(slice))]\n    slice_a: &'static BarSlice,\n\n    #[cdeb(is_a(slice))]\n    slice_b: &'static &'static BarSlice,\n\n    #[cdeb(is_a(array))]\n    array_a: BarArray,\n\n    #[cdeb(is_a(array))]\n    array_b: &'static BarArray,\n\n    #[cdeb(is_a(array))]\n    array_c: &'static &'static BarArray,\n\n    #[cdeb(is_a(Option))]\n    option_a: BarOption,\n\n    #[cdeb(is_a(option))]\n    option_b: BarOption,\n\n    #[cdeb(is_a(newtype))]\n    newtype: path::to::Bar,\n\n    // This is formatted as a hexadecimal integer\n    #[cdeb(with = \"fmt_bar_in_hex\")]\n    with_fn: path::to::Bar,\n\n    #[cdeb(with_wrapper = \"DisplayWrapper\")]\n    with_wrapper: &'static str,\n\n    #[cdeb(with_macro = \"display_fmt\")]\n    with_macro: &'static str,\n}\n\n#[test]\nfn automatic_type_detection() {\n    const fn inner(f: &mut Formatter<'_>) -> Result<(), Error> {\n        let auto = Automatic {\n            slice_a: &[Bar(3)],\n            slice_b: &(&[Bar(5)] as &[_]),\n            array_a: [Bar(1000), Bar(8)],\n            array_b: &[Bar(2000), Bar(8)],\n            array_c: &&[Bar(3000), Bar(8)],\n            option_a: Some(Bar(13)),\n            option_b: Some(Bar(21)),\n            option_c: Some(Bar(34)),\n            option_d: Some(Bar(55)),\n        };\n\n        try_!(auto.const_debug_fmt(f));\n\n        Ok(())\n    }\n\n    let writer: &mut StrWriter = &mut StrWriter::new([0; 1024]);\n\n    inner(&mut writer.make_formatter(FormattingFlags::NEW)).unwrap();\n\n    assert_eq!(\n        writer.as_str(),\n        \"\\\n            Automatic { \\\n                slice_a: [Bar(3)], \\\n                slice_b: [Bar(5)], \\\n                array_a: [Bar(1000), Bar(8)], \\\n                array_b: [Bar(2000), Bar(8)], \\\n                array_c: [Bar(3000), Bar(8)], \\\n                option_a: Some(Bar(13)), \\\n                option_b: Some(Bar(21)), \\\n                option_c: Some(Bar(34)), \\\n                option_d: Some(Bar(55)) \\\n            }\\\n        \"\n    );\n}\n\n#[test]\nfn manual_type_detection() {\n    const fn inner(f: &mut Formatter<'_>) -> Result<(), Error> {\n        let auto = Manual {\n            slice_a: &[Bar(3)],\n            slice_b: &(&[Bar(5)] as &[_]),\n            array_a: [Bar(1000), Bar(8)],\n            array_b: &[Bar(2000), Bar(8)],\n            array_c: &&[Bar(3000), Bar(8)],\n            option_a: Some(Bar(13)),\n            option_b: Some(Bar(21)),\n            newtype: Bar(34),\n            with_fn: Bar(55),\n            with_wrapper: \"eighty nine\",\n            with_macro: \"-144-\",\n        };\n\n        try_!(auto.const_debug_fmt(f));\n\n        Ok(())\n    }\n\n    let writer: &mut StrWriter = &mut StrWriter::new([0; 1024]);\n\n    inner(&mut writer.make_formatter(FormattingFlags::NEW)).unwrap();\n\n    assert_eq!(\n        writer.as_str(),\n        \"\\\n            Manual { \\\n                slice_a: [Bar(3)], \\\n                slice_b: [Bar(5)], \\\n                array_a: [Bar(1000), Bar(8)], \\\n                array_b: [Bar(2000), Bar(8)], \\\n                array_c: [Bar(3000), Bar(8)], \\\n                option_a: Some(Bar(13)), \\\n                option_b: Some(Bar(21)), \\\n                newtype: Bar(34), \\\n                with_fn: Bar(37), \\\n                with_wrapper: eighty nine, \\\n                with_macro: -144- \\\n            }\\\n        \"\n    );\n}\n\n#[test]\nfn opting_out_of_std() {\n    const fn inner(f: &mut Formatter<'_>) -> Result<(), Error> {\n        let wraps_opt = WrapsNamedOption {\n            opt_a: type_named_option::Option(PhantomData),\n            opt_b: type_named_option::Option(PhantomData),\n            opt_c: type_named_option::Option(PhantomData),\n        };\n        try_!(wraps_opt.const_debug_fmt(f));\n\n        Ok(())\n    }\n\n    let writer: &mut StrWriter = &mut StrWriter::new([0; 1024]);\n\n    inner(&mut writer.make_formatter(FormattingFlags::NEW)).unwrap();\n\n    assert_eq!(\n        writer.as_str(),\n        \"\\\n            WrapsNamedOption { \\\n                opt_a: NotAStdOption, \\\n                opt_b: NotAStdOption, \\\n                opt_c: NotAStdOption \\\n            }\\\n        \"\n    );\n}\n"
  },
  {
    "path": "const_format/tests/misc_tests/derive_tests.rs",
    "content": "use cfmt_b::{\n    fmt::{Error, Formatter, FormattingFlags, StrWriter},\n    try_, writec, ConstDebug,\n};\n\nuse core::marker::PhantomData;\n\nmod is_a_attributes;\n\n///////////////////////////////////////////////////////////////////////////////\n\nstruct Dummy;\n\n#[derive(ConstDebug)]\n#[cdeb(crate = \"::cfmt_b\")]\nstruct Braced {\n    x: u32,\n    y: Option<&'static str>,\n    #[allow(dead_code)]\n    #[cdeb(ignore)]\n    z: (u32, u32),\n    a: bool,\n}\n\n#[derive(ConstDebug)]\n#[cdeb(crate = \"::cfmt_b\")]\n#[cdeb(impls(\n    \"<U> Tupled<u32, U>\",\n    \"<U> Tupled<u64, U>\",\n    \"<U> Tupled<bool, U> where U: 'static,\",\n))]\nstruct Tupled<T, U>(\n    u32,\n    #[cdeb(ignore)]\n    #[allow(dead_code)]\n    Option<&'static str>,\n    T,\n    PhantomData<U>,\n);\n\n#[derive(ConstDebug)]\n#[cdeb(crate = \"::cfmt_b\")]\nstruct Unit;\n\n#[test]\nfn struct_formatting() {\n    const fn inner(f: &mut Formatter<'_>) -> Result<(), Error> {\n        let braced = Braced {\n            x: 100,\n            y: Some(\"hello\"),\n            z: (0, 1),\n            a: true,\n        };\n        try_!(writec!(f, \"{0:?}\\n{0:x?}\\n{0:X?}\\n\", braced));\n\n        let tupled_a: Tupled<u32, Dummy> = Tupled(13, Some(\"hello\"), 21, PhantomData);\n        let tupled_b: Tupled<u64, Dummy> = Tupled(32, Some(\"hello\"), 33, PhantomData);\n        let tupled_c: Tupled<bool, Dummy> = Tupled(48, Some(\"hello\"), false, PhantomData);\n        try_!(writec!(\n            f,\n            \"{0:?}\\n{0:x?}\\n{0:X?}\\n{1:?}\\n{1:x?}\\n{1:X?}\\n{2:?}\\n{2:x?}\\n{2:X?}\\n\",\n            tupled_a,\n            tupled_b,\n            tupled_c,\n        ));\n\n        try_!(writec!(f, \"{:?}\", Unit));\n\n        Ok(())\n    }\n\n    let writer: &mut StrWriter = &mut StrWriter::new([0; 1024]);\n\n    inner(&mut writer.make_formatter(FormattingFlags::NEW)).unwrap();\n\n    assert_eq!(\n        writer.as_str(),\n        \"\\\n            Braced { x: 100, y: Some(\\\"hello\\\"), a: true }\\n\\\n            Braced { x: 64, y: Some(\\\"hello\\\"), a: true }\\n\\\n            Braced { x: 64, y: Some(\\\"hello\\\"), a: true }\\n\\\n            Tupled(13, 21, PhantomData)\\n\\\n            Tupled(d, 15, PhantomData)\\n\\\n            Tupled(D, 15, PhantomData)\\n\\\n            Tupled(32, 33, PhantomData)\\n\\\n            Tupled(20, 21, PhantomData)\\n\\\n            Tupled(20, 21, PhantomData)\\n\\\n            Tupled(48, false, PhantomData)\\n\\\n            Tupled(30, false, PhantomData)\\n\\\n            Tupled(30, false, PhantomData)\\n\\\n            Unit\\\n        \",\n    );\n}\n\n///////////////////////////////////////////////////////////////////////////////\n\n#[derive(ConstDebug)]\n#[cdeb(crate = \"::cfmt_b\")]\nenum Enum {\n    Braced {\n        x: u32,\n        y: Option<&'static str>,\n        #[allow(dead_code)]\n        #[cdeb(ignore)]\n        z: (u32, u32),\n        a: bool,\n    },\n    Tupled(\n        u32,\n        #[cdeb(ignore)]\n        #[allow(dead_code)]\n        Option<&'static str>,\n        u32,\n        PhantomData<()>,\n    ),\n    Unit,\n}\n\n#[test]\nfn enum_formatting() {\n    const fn inner(f: &mut Formatter<'_>) -> Result<(), Error> {\n        let braced = Enum::Braced {\n            x: 100,\n            y: Some(\"hello\"),\n            z: (0, 1),\n            a: true,\n        };\n        try_!(writec!(f, \"{0:?}\\n{0:x?}\\n{0:X?}\\n\", braced));\n\n        let tupled_a = Enum::Tupled(13, Some(\"hello\"), 21, PhantomData);\n        let tupled_b = Enum::Tupled(32, Some(\"hello\"), 33, PhantomData);\n        try_!(writec!(\n            f,\n            \"{0:?}\\n{0:x?}\\n{0:X?}\\n{1:?}\\n{1:x?}\\n{1:X?}\\n\",\n            tupled_a,\n            tupled_b\n        ));\n\n        try_!(writec!(f, \"{:?}\", Enum::Unit));\n\n        Ok(())\n    }\n\n    let writer: &mut StrWriter = &mut StrWriter::new([0; 1024]);\n\n    inner(&mut writer.make_formatter(FormattingFlags::NEW)).unwrap();\n\n    assert_eq!(\n        writer.as_str(),\n        \"\\\n            Braced { x: 100, y: Some(\\\"hello\\\"), a: true }\\n\\\n            Braced { x: 64, y: Some(\\\"hello\\\"), a: true }\\n\\\n            Braced { x: 64, y: Some(\\\"hello\\\"), a: true }\\n\\\n            Tupled(13, 21, PhantomData)\\n\\\n            Tupled(d, 15, PhantomData)\\n\\\n            Tupled(D, 15, PhantomData)\\n\\\n            Tupled(32, 33, PhantomData)\\n\\\n            Tupled(20, 21, PhantomData)\\n\\\n            Tupled(20, 21, PhantomData)\\n\\\n            Unit\\\n        \",\n    );\n}\n"
  },
  {
    "path": "const_format/tests/misc_tests/equality_tests.rs",
    "content": "use cfmt_b::coerce_to_fmt;\n\nuse core::{\n    cmp::Ordering,\n    num::{NonZeroU128, NonZeroU8, NonZeroUsize},\n    sync::atomic::Ordering as AtomicOrdering,\n};\n\nmacro_rules! compare_array_case {\n    ( $first:expr, $second:expr, $third:expr; $foo:expr, $bar:expr ) => {{\n        assert!(!coerce_to_fmt!(&[$first, $second]).const_eq(&[$foo, $bar]));\n        assert!(!coerce_to_fmt!(&[$first, $second]).const_eq(&[$first, $foo]));\n        assert!(!coerce_to_fmt!(&[$first, $second]).const_eq(&[$first]));\n        assert!(!coerce_to_fmt!(&[$first, $second]).const_eq(&[$first, $second, $third]));\n        assert!(coerce_to_fmt!(&[$first, $second]).const_eq(&[$first, $second]));\n    }};\n}\n\n#[test]\nfn compare_arrays() {\n    compare_array_case!(\"hello\", \"world\", \"cool\"; \"foo\", \"bar\");\n    compare_array_case! {'a', 'A', 'Ñ'; '3', '2'}\n\n    compare_array_case!(3u8, 5u8, 8u8; 13u8, 21u8);\n    compare_array_case!(3u16, 5u16, 8u16; 13u16, 21u16);\n    compare_array_case!(3usize, 5usize, 8usize; 13usize, 21usize);\n\n    {\n        assert!(!coerce_to_fmt!(&[false, false]).const_eq(&[false, true]));\n        assert!(!coerce_to_fmt!(&[false, false]).const_eq(&[true, false]));\n        assert!(!coerce_to_fmt!(&[true, true]).const_eq(&[false, true]));\n        assert!(!coerce_to_fmt!(&[true, true]).const_eq(&[true, false]));\n        assert!(!coerce_to_fmt!(&[false]).const_eq(&[true]));\n\n        assert!(coerce_to_fmt!(&[true, true]).const_eq(&[true, true]));\n        assert!(coerce_to_fmt!(&[false, false]).const_eq(&[false, false]));\n        assert!(coerce_to_fmt!(&[false]).const_eq(&[false]));\n        assert!(coerce_to_fmt!(&[] as &[bool]).const_eq(&[]));\n    }\n}\n\nmacro_rules! compare_option_case {\n    ( $ty:ty ; $first:expr, $second:expr ) => {{\n        let first: $ty = $first;\n        let second: $ty = $second;\n        {\n            assert!(!coerce_to_fmt!(first).const_eq(&second));\n            assert!(!coerce_to_fmt!(second).const_eq(&first));\n\n            assert!(coerce_to_fmt!(first).const_eq(&first));\n            assert!(coerce_to_fmt!(second).const_eq(&second));\n        }\n        {\n            assert!(!coerce_to_fmt!(Some(first)).const_eq(&Some(second)));\n\n            assert!(!coerce_to_fmt!(Some(first)).const_eq(&Some(second)));\n            assert!(!coerce_to_fmt!(Some(first)).const_eq(&None));\n            assert!(!coerce_to_fmt!(None::<$ty>).const_eq(&Some(first)));\n\n            assert!(coerce_to_fmt!(Some(first)).const_eq(&Some(first)));\n            assert!(coerce_to_fmt!(None::<$ty>).const_eq(&None));\n        }\n    }};\n}\n\n#[test]\nfn compare_options() {\n    compare_option_case!(u8; 3, 5);\n    compare_option_case!(u128; 3, 5);\n    compare_option_case!(usize; 3, 5);\n\n    compare_option_case!(NonZeroU8; NonZeroU8::new(3).unwrap(), NonZeroU8::new(5).unwrap());\n\n    compare_option_case!(NonZeroU128; NonZeroU128::new(3).unwrap(), NonZeroU128::new(5).unwrap());\n\n    compare_option_case!(NonZeroUsize; NonZeroUsize::new(3).unwrap(), NonZeroUsize::new(5).unwrap());\n\n    compare_option_case!(bool; false, true);\n\n    compare_option_case!(&str; \"foo\", \"bar\");\n}\n\nmacro_rules! compare_cases {\n    ($($value:expr),* $(,)* ) => ({\n        let cases = [$($value,)*];\n\n        for left in cases.iter() {\n            for right in cases.iter() {\n                assert_eq!(coerce_to_fmt!(left).const_eq(&right), left==right);\n            }\n        }\n    })\n}\n\n#[test]\nfn enums() {\n    compare_cases! {Ordering::Less, Ordering::Equal, Ordering::Greater}\n    compare_cases! {\n        AtomicOrdering::Relaxed,\n        AtomicOrdering::Acquire,\n        AtomicOrdering::Release,\n        AtomicOrdering::AcqRel,\n        AtomicOrdering::SeqCst,\n    }\n}\n\n#[test]\nfn char_cases() {\n    compare_cases! {'a', 'A', 'Ñ', 'ñ'}\n}\n\n#[test]\nfn ranges() {\n    compare_cases! {0..10, 5..10, 5..15, 0..15}\n    compare_cases! {0..=10, 5..=10, 5..=15, 0..=15}\n    compare_cases! {0.., 5..}\n    compare_cases! {..}\n    compare_cases! {..0, ..5}\n    compare_cases! {..=0, ..=5}\n}\n"
  },
  {
    "path": "const_format/tests/misc_tests/formatc_macros.rs",
    "content": "use cfmt_b::formatcp;\nuse cfmt_b::test_utils::{ALL_ASCII, ALL_ASCII_ESCAPED};\n\n#[cfg(feature = \"fmt\")]\nuse cfmt_b::formatc;\n\nuse arrayvec::{ArrayString, ArrayVec};\n\nuse core::fmt::Write;\n\nmacro_rules! fmt_assert {\n    ( ($($arg:tt)*), $expected:expr $(,)? ) => ({\n        let expected = $expected;\n\n        assert_eq!(formatcp!($($arg)*), expected);\n\n        #[cfg(feature = \"fmt\")]\n        assert_eq!(formatc!($($arg)*), expected);\n    })\n}\n\n#[test]\nfn concat_fmt_strings() {\n    fmt_assert!((concat!()), \"\");\n\n    fmt_assert!((concat!(\"foo{}baz\"), \"bar\"), \"foobarbaz\");\n\n    fmt_assert!((concat!(r#\"foo{}\"#, \"{:?}\"), \"bar\", \"baz\"), \"foobar\\\"baz\\\"\");\n\n    fmt_assert!((concat!(concat!())), \"\");\n    fmt_assert!((concat!(\"foo\", concat!())), \"foo\");\n    fmt_assert!((concat!(concat!(), \"foo\")), \"foo\");\n    fmt_assert!((concat!(concat!(\"foo\"), \"bar\")), \"foobar\");\n    fmt_assert!((concat!(concat!(\"foo\"), concat!(\"bar\"))), \"foobar\");\n    fmt_assert!(\n        (\n            concat!(concat!(\"foo{}\", \"bar{}\"), concat!(r#\"baz{}\"#, \"qux{}\")),\n            3u8,\n            5u8,\n            13u8,\n            21u8\n        ),\n        \"foo3bar5baz13qux21\",\n    );\n\n    fmt_assert!((concat!(\"foo{}baz\"), \"bar\"), \"foobarbaz\");\n\n    fmt_assert!((concat!(r#\"foo{}\"#, \"{:?}\"), \"bar\", \"baz\"), \"foobar\\\"baz\\\"\");\n}\n\n#[test]\nfn positional_and_named_arguments() {\n    // Positional,implicit\n    assert_eq!(formatcp!(\"{}{}{}\", 3u8, 5u8, 8u8), \"358\");\n\n    // Positional explicit\n    assert_eq!(formatcp!(\"{0},{1},{2},{1},{0}\", 3u8, 5u8, 8u8), \"3,5,8,5,3\");\n\n    const A: u32 = 3;\n    const B: u32 = 5;\n\n    // Uses the named argument if it's provided,otherwise looks for constant from scope.\n    assert_eq!(formatcp!(\"{A},{B}\", B = 8u8), \"3,8\");\n    assert_eq!(formatcp!(\"{A},{B}\"), \"3,5\");\n\n    // implicit positional args aren't affected by explicit ones.\n    assert_eq!(\n        formatcp!(\"{2},{},{2},{},{P},{}\", 3u8, 5u8, 8u8, P = 89u8),\n        \"8,3,8,5,89,8\"\n    );\n}\n\n// Display formatting is already tested in the `shared_cp_macro_tests` module\n#[test]\nfn debug_formatting() {\n    let mut string = ArrayString::<64>::new();\n\n    macro_rules! same_as_display {\n        ($($expr:expr),* $(,)?) => (\n            $(\n                string.clear();\n                write!(string, \"{:?}\", $expr).unwrap();\n\n                assert_eq!(formatcp!(\"{:?}\", $expr), string.as_str());\n\n                #[cfg(feature = \"fmt\")]\n                assert_eq!(formatc!(\"{:?}\", $expr), string.as_str());\n            )*\n        )\n    }\n\n    same_as_display! {\n        i8::MIN, i8::MAX,\n        i16::MIN, i16::MAX,\n        i32::MIN, i32::MAX,\n        i64::MIN, i64::MAX,\n        i128::MIN, i128::MAX,\n        isize::MIN, isize::MAX,\n        u8::MIN, u8::MAX,\n        u16::MIN, u16::MAX,\n        u32::MIN, u32::MAX,\n        u64::MIN, u64::MAX,\n        u128::MIN, u128::MAX,\n        usize::MIN, usize::MAX,\n        false, true,\n    }\n\n    ////////////////////////////\n    //  Let's debug format all ascii characters!\n\n    let mut escapedes = ArrayVec::<&str, 16>::new();\n\n    escapedes.extend(\n        [\n            formatcp!(\"{:?}\", ALL_ASCII),\n            formatcp!(\"{:x}\", ALL_ASCII),\n            formatcp!(\"{:b}\", ALL_ASCII),\n            formatcp!(\"{:x?}\", ALL_ASCII),\n            formatcp!(\"{:X?}\", ALL_ASCII),\n            formatcp!(\"{:b?}\", ALL_ASCII),\n        ]\n        .iter()\n        .copied(),\n    );\n\n    #[cfg(feature = \"fmt\")]\n    escapedes.extend(\n        [\n            formatc!(\"{:?}\", ALL_ASCII),\n            formatc!(\"{:x}\", ALL_ASCII),\n            formatc!(\"{:b}\", ALL_ASCII),\n            formatc!(\"{:x?}\", ALL_ASCII),\n            formatc!(\"{:X?}\", ALL_ASCII),\n            formatc!(\"{:b?}\", ALL_ASCII),\n        ]\n        .iter()\n        .copied(),\n    );\n\n    for escaped in escapedes.iter().copied() {\n        assert_eq!(&escaped[..1], \"\\\"\");\n        assert_eq!(&escaped[1..escaped.len() - 1], ALL_ASCII_ESCAPED);\n        assert_eq!(&escaped[escaped.len() - 1..], \"\\\"\");\n    }\n}\n\nmacro_rules! binary_hex_test_case {\n    ($ty:ident, $buffer:ident) => {{\n        binary_hex_test_case! {@inner formatcp, $ty, $buffer};\n\n        #[cfg(feature = \"fmt\")]\n        binary_hex_test_case! {@inner formatc, $ty, $buffer};\n    }};\n    (@inner $themacro:ident, $ty:ident, $buffer:ident) => {{\n        const P: &[$ty] = &[\n            $ty::MIN,\n            $ty::MIN + 1,\n            $ty::MIN / 7,\n            $ty::MIN / 13,\n            0,\n            1,\n            4,\n            $ty::MAX - 1,\n            $ty::MAX,\n        ];\n\n        {\n            let cp_string = $themacro!(\n                \"{0:?}_{0:X?}_{0:b?}_{0:#X?}_{0:#b?}_\\\n                 {1:?}_{1:X?}_{1:b?}_{1:#X?}_{1:#b?}_\\\n                 {2:?}_{2:X?}_{2:b?}_{2:#X?}_{2:#b?}_\\\n                 {3:?}_{3:X?}_{3:b?}_{3:#X?}_{3:#b?}_\\\n                 {4:?}_{4:X}_{4:b}_{4:#X}_{4:#b}_\\\n                 {5:?}_{5:X?}_{5:b?}_{5:#X?}_{5:#b?}_\\\n                 {6:?}_{6:X?}_{6:b?}_{6:#X?}_{6:#b?}_\\\n                 {7:?}_{7:X?}_{7:b?}_{7:#X?}_{7:#b?}_\\\n                 {8:?}_{8:X?}_{8:b?}_{8:#X?}_{8:#b?}_\\\n                 \",\n                P[0],\n                P[1],\n                P[2],\n                P[3],\n                P[4],\n                P[5],\n                P[6],\n                P[7],\n                P[8]\n            );\n\n            $buffer.clear();\n            write!(\n                $buffer,\n                \"{0:?}_{0:X}_{0:b}_{0:#X}_{0:#b}_\\\n            {1:?}_{1:X}_{1:b}_{1:#X}_{1:#b}_\\\n            {2:?}_{2:X}_{2:b}_{2:#X}_{2:#b}_\\\n            {3:?}_{3:X}_{3:b}_{3:#X}_{3:#b}_\\\n            {4:?}_{4:X}_{4:b}_{4:#X}_{4:#b}_\\\n            {5:?}_{5:X}_{5:b}_{5:#X}_{5:#b}_\\\n            {6:?}_{6:X}_{6:b}_{6:#X}_{6:#b}_\\\n            {7:?}_{7:X}_{7:b}_{7:#X}_{7:#b}_\\\n            {8:?}_{8:X}_{8:b}_{8:#X}_{8:#b}_\\\n            \",\n                P[0], P[1], P[2], P[3], P[4], P[5], P[6], P[7], P[8]\n            )\n            .unwrap();\n\n            assert_eq!(cp_string, $buffer.as_str());\n        }\n        {\n            let cp_string = $themacro!(\n                \"{0:x?}_{0:#x?}_\\\n                 {1:x?}_{1:#x?}_\\\n                 {2:x?}_{2:#x?}_\\\n                 {3:x?}_{3:#x?}_\\\n                 {4:x}_{4:#x}_\\\n                 {5:x?}_{5:#x?}_\\\n                 {6:x?}_{6:#x?}_\\\n                 {7:x?}_{7:#x?}_\\\n                 {8:x?}_{8:#x?}_\\\n                 \",\n                P[0],\n                P[1],\n                P[2],\n                P[3],\n                P[4],\n                P[5],\n                P[6],\n                P[7],\n                P[8]\n            );\n\n            $buffer.clear();\n            write!(\n                $buffer,\n                \"{0:x?}_{0:#x?}_\\\n                 {1:x?}_{1:#x?}_\\\n                 {2:x?}_{2:#x?}_\\\n                 {3:x?}_{3:#x?}_\\\n                 {4:x}_{4:#x}_\\\n                 {5:x?}_{5:#x?}_\\\n                 {6:x?}_{6:#x?}_\\\n                 {7:x?}_{7:#x?}_\\\n                 {8:x?}_{8:#x?}_\\\n                 \",\n                P[0], P[1], P[2], P[3], P[4], P[5], P[6], P[7], P[8]\n            )\n            .unwrap();\n\n            assert_eq!(cp_string, $buffer.as_str());\n        }\n    }};\n}\n\n#[test]\nfn binary_and_hex_formatting() {\n    let mut s = ArrayString::<4096>::new();\n    binary_hex_test_case!(u8, s);\n    binary_hex_test_case!(u16, s);\n    binary_hex_test_case!(u32, s);\n    binary_hex_test_case!(u64, s);\n    binary_hex_test_case!(u128, s);\n    binary_hex_test_case!(i8, s);\n    binary_hex_test_case!(i16, s);\n    binary_hex_test_case!(i32, s);\n    binary_hex_test_case!(i64, s);\n    binary_hex_test_case!(i128, s);\n}\n\n#[test]\nfn other_tests() {\n    assert_eq!(formatcp!(\"{0:?}-{0:x?}-{0:b?}\", \"\"), r#\"\"\"-\"\"-\"\"\"#);\n\n    const EMPTY: &str = formatcp!(\"\");\n    assert_eq!(EMPTY, \"\");\n}\n\n#[test]\nfn escaped_format_string() {\n    {\n        let found = formatcp!(\n            \"\\\n             \\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\\n             \\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f \\\n             !\\\"#$%&\\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\]\\\n             ^_`abcdefghijklmnopqrstuvwxyz{{|}}~\\x7f\\u{80}\\u{81}\\u{90}\\u{91}\\\n            \"\n        );\n        assert_eq!(found, ALL_ASCII);\n    }\n    assert_eq!(formatcp!(\"\\\\\"), r#\"\\\"#);\n\n    assert_eq!(formatcp!(r#\"\\u\\u{}\"#, \"{}\"), r#\"\\u\\u{}\"#);\n    assert_eq!(formatcp!(r#\"\\u\\u{{}}\"#), r#\"\\u\\u{}\"#);\n}\n\n#[test]\nfn raw_literals() {\n    assert_eq!(formatcp!(r\"-{}_\", \"hello\"), r\"-hello_\");\n    assert_eq!(formatcp!(r\"-{{}}_\"), r\"-{}_\");\n\n    assert_eq!(formatcp!(r#\"r\"-{}_\"\"#, \"hello\"), r#\"r\"-hello_\"\"#);\n    assert_eq!(formatcp!(r#\"r\"-{{}}_\"\"#), r#\"r\"-{}_\"\"#);\n\n    assert_eq!(formatcp!(r##\"r#\"-{}_\"#\"##, \"hello\"), r##\"r#\"-hello_\"#\"##);\n    assert_eq!(formatcp!(r##\"r#\"-{{}}_\"#\"##), r##\"r#\"-{}_\"#\"##);\n}\n\n#[test]\n#[cfg(feature = \"fmt\")]\n#[expect(non_local_definitions)]\nfn access_formatter() {\n    use cfmt_b::call_debug_fmt;\n\n    struct FmtConst;\n\n    assert_eq!(\n        formatc!(\"{0}\", |fmt| {\n            impl FmtConst {\n                const A: u32 = 3;\n            }\n            call_debug_fmt!(array, [(), ()], fmt)\n        }),\n        \"[(), ()]\"\n    );\n\n    assert_eq!(FmtConst::A, 3);\n\n    assert_eq!(\n        formatc!(\"{0} ; {0}\", |fmt| { call_debug_fmt!(array, [(), ()], fmt) }),\n        \"[(), ()] ; [(), ()]\"\n    );\n\n    assert_eq!(\n        formatc!(\"{0}\", |fmt| call_debug_fmt!(array, [(), ()], fmt)),\n        \"[(), ()]\"\n    );\n\n    assert_eq!(\n        formatc!(\"{0} ; {0}\", |fmt| call_debug_fmt!(array, [(), ()], fmt)),\n        \"[(), ()] ; [(), ()]\"\n    );\n}\n"
  },
  {
    "path": "const_format/tests/misc_tests/impl_fmt_macro_tests.rs",
    "content": "#![allow(non_camel_case_types)]\n#![allow(non_local_definitions)]\n\nuse cfmt_b::{\n    fmt::{ComputeStrLength, Error, Formatter, FormattingFlags, StrWriter, StrWriterMut},\n    impl_fmt, try_,\n    wrapper_types::PWrapper,\n};\n\nuse arrayvec::ArrayString;\n\nuse core::{fmt::Write, marker::PhantomData};\n\n////////////////////////////////////////////////////////////////////////////////\n\nstruct Delegating<T>(T);\n\n////////////////////////////////////////////////////////////////////////////////\n\nstruct BracedStruct<T: 'static> {\n    a: T,\n    b: &'static [T],\n    c: TupleStruct<T>,\n    d: UnitStruct,\n}\nstruct TupleStruct<T>(T, u32);\n\nstruct UnitStruct;\n\nimpl_fmt! {\n    impl[] BracedStruct<u32>;\n\n    #[allow(dead_code)]\n    impl[] BracedStruct<u64>;\n\n    const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {\n        let mut f = f.debug_struct(\"BracedStruct\");\n        try_!(PWrapper(self.a).const_debug_fmt(f.field(\"a\")));\n        try_!(PWrapper(self.b).const_debug_fmt(f.field(\"b\")));\n        try_!(self.c.const_debug_fmt(f.field(\"c\")));\n        try_!(self.d.const_debug_fmt(f.field(\"d\")));\n        f.finish()\n    }\n}\n\nimpl_fmt! {\n    #[allow(dead_code)]\n    impl[] TupleStruct<u64>;\n\n    impl[] TupleStruct<u32>;\n\n    const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {\n        let mut f = f.debug_tuple(\"TupleStruct\");\n        try_!(PWrapper(self.0).const_debug_fmt(f.field()));\n        try_!(PWrapper(self.1).const_debug_fmt(f.field()));\n        f.finish()\n    }\n}\n\nimpl_fmt! {\n    impl[] UnitStruct;\n\n    const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {\n        f.debug_tuple(\"UnitStruct\").finish()\n    }\n}\n\nmacro_rules! declare_test_case_fns {\n    ( $Ty:ty ) => {\n        impl_fmt! {\n            impl[] Delegating<&$Ty>;\n\n            const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {\n                self.0.const_debug_fmt(f)\n            }\n        }\n\n        const fn inner_delegating(\n            this: Delegating<&$Ty>,\n            writer: &mut StrWriterMut<'_>,\n            flags: FormattingFlags,\n        ) -> Result<usize, Error> {\n            try_!(this.const_debug_fmt(&mut writer.make_formatter(flags)));\n\n            let mut str_len = ComputeStrLength::new();\n            try_!(this.const_debug_fmt(&mut str_len.make_formatter(flags)));\n\n            Ok(str_len.len())\n        }\n\n        const fn inner(\n            this: &$Ty,\n            writer: &mut StrWriterMut<'_>,\n            flags: FormattingFlags,\n        ) -> Result<usize, Error> {\n            try_!(this.const_debug_fmt(&mut writer.make_formatter(flags)));\n\n            let mut str_len = ComputeStrLength::new();\n            try_!(this.const_debug_fmt(&mut str_len.make_formatter(flags)));\n\n            Ok(str_len.len())\n        }\n\n        fn test_case(this: &$Ty, writer: &mut StrWriter, flags: FormattingFlags, expected: &str) {\n            let writer = &mut writer.as_mut();\n            {\n                writer.clear();\n                let len = inner(this, writer, flags).unwrap();\n\n                assert_eq!(writer.as_str(), expected);\n                assert_eq!(writer.len(), len, \"{}\", writer.as_str());\n            }\n            {\n                writer.clear();\n                let len = inner_delegating(Delegating(this), writer, flags).unwrap();\n\n                assert_eq!(writer.as_str(), expected);\n                assert_eq!(writer.len(), len, \"{}\", writer.as_str());\n            }\n        }\n    };\n}\n\n#[test]\nfn struct_debug_impl() {\n    declare_test_case_fns!(BracedStruct<u32>);\n\n    let foo = BracedStruct {\n        a: 10,\n        b: &[20, 30],\n        c: TupleStruct(40, 50),\n        d: UnitStruct,\n    };\n\n    let writer: &mut StrWriter = &mut StrWriter::new([0; 512]);\n\n    test_case(\n        &foo,\n        writer,\n        FormattingFlags::NEW.set_alternate(false),\n        \"BracedStruct { a: 10, b: [20, 30], c: TupleStruct(40, 50), d: UnitStruct }\",\n    );\n\n    const ALT: &str = \"\\\nBracedStruct {\n    a: 10,\n    b: [\n        20,\n        30,\n    ],\n    c: TupleStruct(\n        40,\n        50,\n    ),\n    d: UnitStruct,\n}\\\n    \";\n\n    test_case(&foo, writer, FormattingFlags::NEW.set_alternate(true), ALT);\n\n    const ALT_HEX: &str = \"\\\nBracedStruct {\n    a: 0xA,\n    b: [\n        0x14,\n        0x1E,\n    ],\n    c: TupleStruct(\n        0x28,\n        0x32,\n    ),\n    d: UnitStruct,\n}\\\n    \";\n\n    test_case(\n        &foo,\n        writer,\n        FormattingFlags::NEW.set_alternate(true).set_hexadecimal(),\n        ALT_HEX,\n    );\n}\n\n#[allow(dead_code)]\nstruct BracedStructNE<T: 'static> {\n    a: T,\n    b: &'static [T],\n    c: TupleStructNE<T, UnDebug>,\n    d: UnitStruct,\n    e: u8,\n    f: (),\n}\n\nstruct UnDebug;\n\nstruct TupleStructNE<T, U>(T, u32, PhantomData<U>);\n\nimpl_fmt! {\n    impl BracedStructNE<u32>;\n\n    #[allow(dead_code)]\n    impl[] BracedStructNE<u64>;\n\n    const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {\n        let mut f = f.debug_struct(\"BracedStructNE\");\n        try_!(PWrapper(self.a).const_debug_fmt(f.field(\"a\")));\n        try_!(PWrapper(self.b).const_debug_fmt(f.field(\"b\")));\n        try_!(self.c.const_debug_fmt(f.field(\"c\")));\n        try_!(self.d.const_debug_fmt(f.field(\"d\")));\n        f.finish()\n    }\n}\n\nimpl_fmt! {\n    #[allow(dead_code)]\n    impl[] TupleStructNE<u64, UnDebug>;\n\n    impl[T,] TupleStructNE<u32, T>\n    where[ T: 'static, ];\n\n    const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {\n        let mut f = f.debug_tuple(\"TupleStructNE\");\n        try_!(PWrapper(self.0).const_debug_fmt(f.field()));\n        try_!(PWrapper(self.1).const_debug_fmt(f.field()));\n        f.finish()\n    }\n}\n\n#[test]\nfn struct_nonexhaustive_debug_impl() {\n    declare_test_case_fns!(BracedStructNE<u32>);\n\n    let foo = BracedStructNE {\n        a: 10u32,\n        b: &[20, 30],\n        c: TupleStructNE(40, 50, PhantomData),\n        d: UnitStruct,\n        e: 0,\n        f: (),\n    };\n\n    let writer: &mut StrWriter = &mut StrWriter::new([0; 512]);\n\n    test_case(\n        &foo,\n        writer,\n        FormattingFlags::NEW.set_alternate(false),\n        \"BracedStructNE { a: 10, b: [20, 30], c: TupleStructNE(40, 50), d: UnitStruct }\",\n    );\n}\n\n////////////////////////////////////////////////////////////////////////////////\n\nenum EnumA<T> {\n    Tupled(T, u8),\n    Braced {\n        a: u16,\n        b: u16,\n        c: UnitStruct,\n        d: UnitStruct,\n    },\n    Unit,\n}\n\nimpl_fmt! {\n    impl[] EnumA<u32>;\n\n    #[allow(dead_code)]\n    impl[] EnumA<u64>;\n\n    const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {\n        match self {\n            Self::Tupled(f0, f1)=>{\n                let mut f = f.debug_tuple(\"Tupled\");\n                try_!(PWrapper(*f0).const_debug_fmt(f.field()));\n                try_!(PWrapper(*f1).const_debug_fmt(f.field()));\n                f.finish()\n            }\n            Self::Braced {a,b,c,d} => {\n                let mut f = f.debug_struct(\"Braced\");\n                try_!(PWrapper(*a).const_debug_fmt(f.field(\"a\")));\n                try_!(PWrapper(*b).const_debug_fmt(f.field(\"b\")));\n                try_!(c.const_debug_fmt(f.field(\"c\")));\n                try_!(d.const_debug_fmt(f.field(\"d\")));\n                f.finish()\n            }\n            Self::Unit => f.debug_struct(\"Unit\").finish()\n        }\n    }\n}\n\n#[test]\nfn enum_debug_impl() {\n    declare_test_case_fns!(EnumA<u32>);\n\n    let writer: &mut StrWriter = &mut StrWriter::new([0; 512]);\n\n    {\n        let tupled = EnumA::Tupled(3, 5);\n\n        test_case(\n            &tupled,\n            writer,\n            FormattingFlags::NEW.set_alternate(false),\n            \"Tupled(3, 5)\",\n        );\n\n        test_case(\n            &tupled,\n            writer,\n            FormattingFlags::NEW.set_alternate(true),\n            \"Tupled(\\n    3,\\n    5,\\n)\",\n        );\n    }\n    {\n        let braced = EnumA::Braced {\n            a: 8,\n            b: 13,\n            c: UnitStruct,\n            d: UnitStruct,\n        };\n\n        test_case(\n            &braced,\n            writer,\n            FormattingFlags::NEW.set_alternate(false),\n            \"Braced { a: 8, b: 13, c: UnitStruct, d: UnitStruct }\",\n        );\n\n        test_case(\n            &braced,\n            writer,\n            FormattingFlags::NEW.set_alternate(true),\n            \"Braced {\\n    a: 8,\\n    b: 13,\\n    c: UnitStruct,\\n    d: UnitStruct,\\n}\",\n        );\n    }\n    {\n        let unit = EnumA::Unit;\n\n        test_case(\n            &unit,\n            writer,\n            FormattingFlags::NEW.set_alternate(false),\n            \"Unit\",\n        );\n\n        test_case(\n            &unit,\n            writer,\n            FormattingFlags::NEW.set_alternate(true),\n            \"Unit\",\n        );\n    }\n}\n\n#[allow(dead_code)]\nenum EnumA_NE<T> {\n    Tupled(T, u8, ()),\n    Braced {\n        a: u16,\n        b: u16,\n        c: UnitStruct,\n        d: UnitStruct,\n        e: (),\n        f: (),\n    },\n    Unit,\n}\n\nimpl_fmt! {\n    impl[] EnumA_NE<u32>;\n\n    #[allow(dead_code)]\n    impl[] EnumA_NE<u64>;\n\n\n    const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {\n        match self {\n            Self::Tupled(f0, f1,..)=>{\n                let mut f = f.debug_tuple(\"Tupled\");\n                try_!(PWrapper(*f0).const_debug_fmt(f.field()));\n                try_!(PWrapper(*f1).const_debug_fmt(f.field()));\n                f.finish()\n            }\n            Self::Braced {a,b,c,d,..} => {\n                let mut f = f.debug_struct(\"Braced\");\n                try_!(PWrapper(*a).const_debug_fmt(f.field(\"a\")));\n                try_!(PWrapper(*b).const_debug_fmt(f.field(\"b\")));\n                try_!(c.const_debug_fmt(f.field(\"c\")));\n                try_!(d.const_debug_fmt(f.field(\"d\")));\n                f.finish()\n            }\n            Self::Unit => f.debug_struct(\"<unknown_variant>\").finish()\n        }\n    }\n}\n\n#[test]\nfn enum_nonexhaustive_debug_impl() {\n    declare_test_case_fns!(EnumA_NE<u32>);\n\n    let writer: &mut StrWriter = &mut StrWriter::new([0; 512]);\n\n    {\n        let tupled = EnumA_NE::Tupled(3, 5, ());\n\n        test_case(&tupled, writer, FormattingFlags::NEW, \"Tupled(3, 5)\");\n    }\n    {\n        let braced = EnumA_NE::Braced {\n            a: 8,\n            b: 13,\n            c: UnitStruct,\n            d: UnitStruct,\n            e: (),\n            f: (),\n        };\n\n        test_case(\n            &braced,\n            writer,\n            FormattingFlags::NEW,\n            \"Braced { a: 8, b: 13, c: UnitStruct, d: UnitStruct }\",\n        );\n    }\n    {\n        let braced = EnumA_NE::Unit;\n\n        test_case(&braced, writer, FormattingFlags::NEW, \"<unknown_variant>\");\n    }\n}\n\n////////////////////////////////////////////////////////////////////////////////\n\nstruct StructWE<T>(EnumA<T>);\n\nimpl_fmt! {\n    impl[] StructWE<u32>;\n\n    #[allow(dead_code)]\n    impl[] StructWE<u64>;\n\n    const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {\n        let mut f = f.debug_tuple(\"StructWE\");\n        try_!(self.0.const_debug_fmt(f.field()));\n        f.finish()\n    }\n}\n\n#[test]\nfn enum_inside_struct() {\n    declare_test_case_fns!(StructWE<u32>);\n\n    let writer: &mut StrWriter = &mut StrWriter::new([0; 512]);\n    let mut string = ArrayString::<512>::new();\n\n    {\n        let tupled = StructWE(EnumA::Tupled(3, 5));\n\n        test_case(\n            &tupled,\n            writer,\n            FormattingFlags::NEW.set_alternate(false),\n            \"StructWE(Tupled(3, 5))\",\n        );\n\n        string.clear();\n        write!(\n            string,\n            \"StructWE({NL4}Tupled({NL8}3,{NL8}5,{NL4}),\\n)\",\n            NL4 = \"\\n    \",\n            NL8 = \"\\n        \",\n        )\n        .unwrap();\n\n        test_case(\n            &tupled,\n            writer,\n            FormattingFlags::NEW.set_alternate(true),\n            string.as_str(),\n        );\n    }\n}\n"
  },
  {
    "path": "const_format/tests/misc_tests/inline_const_pattern_tests.rs",
    "content": "use crate::cfmt_b;\n\nuse crate::cfmt_b::{\n    concatc, concatcp, formatc, formatcp, map_ascii_case, str_get, str_index, str_repeat,\n    str_replace, str_splice_out, str_split_pat,\n};\n\n#[test]\nfn concatc_inline_pat_tests() {\n    assert!(matches!(\"foo\", concatc!(\"fo\", \"o\")));\n    assert!(!matches!(\"bar\", concatc!(\"bar\", \"r\")));\n}\n\n#[test]\nfn concatcp_inline_pat_tests() {\n    assert!(matches!(\"foo\", concatcp!(\"fo\", \"o\")));\n    assert!(!matches!(\"bar\", concatcp!(\"bar\", \"r\")));\n}\n\n#[test]\nfn formatc_inline_pat_tests() {\n    assert!(matches!(\"foo\", formatc!(\"f{0}{0}\", \"o\")));\n    assert!(!matches!(\"bar\", formatc!(\"bar{}\", \"r\")));\n}\n\n#[test]\nfn formatcp_inline_pat_tests() {\n    assert!(matches!(\"foo\", formatcp!(\"f{0}{0}\", \"o\")));\n    assert!(!matches!(\"bar\", formatcp!(\"bar{}\", \"r\")));\n}\n\n#[test]\nfn map_ascii_case_inline_pat_tests() {\n    assert!(matches!(\"foo\", map_ascii_case!(cfmt_b::Case::Lower, \"FOO\")));\n    assert!(!matches!(\n        \"bar\",\n        map_ascii_case!(cfmt_b::Case::Upper, \"bar\")\n    ));\n}\n\n#[test]\nfn str_get_inline_pat_tests() {\n    assert!(matches!(Some(\"foo\"), str_get!(\" foobar\", 1..4)));\n    assert!(matches!(None, str_get!(\" foobar\", 10)));\n}\n\n#[test]\nfn str_splice_out_inline_pat_tests() {\n    assert!(matches!(\"foo\", str_splice_out!(\"fbar\", 1.., \"oo\")));\n    assert!(!matches!(\"foo\", str_splice_out!(\"foo\", 1..3, \"bar\")));\n}\n\n#[test]\nfn str_index_inline_pat_tests() {\n    assert!(matches!(\"foo\", str_index!(\" foobar\", 1..4)));\n    assert!(!matches!(\"foo\", str_index!(\" foobar\", 1..5)));\n}\n\n#[test]\nfn str_repeat_inline_pat_tests() {\n    assert!(matches!(\"foofoofoo\", str_repeat!(\"foo\", 3)));\n    assert!(!matches!(\"foo\", str_repeat!(\"foo\", 0)));\n}\n\n#[test]\nfn str_replace_inline_pat_tests() {\n    assert!(matches!(\"fooo\", str_replace!(\"fo\", \"o\", \"ooo\")));\n    assert!(!matches!(\"foo\", str_replace!(\"fo\", \"o\", \"bar\")));\n}\n\n#[test]\nfn str_split_pat_inline_pat_tests() {\n    assert!(matches!(\n        &[\"foo\", \"bar\", \"baz\"][..],\n        str_split_pat!(\"foo bar baz\", \" \")\n    ));\n    assert!(!matches!(\n        &[\"foo\", \"bar\", \"baz\"][..],\n        str_split_pat!(\"foo bar\", \" \")\n    ));\n}\n"
  },
  {
    "path": "const_format/tests/misc_tests/shared_cp_macro_tests.rs",
    "content": "use cfmt_b::{__identity, concatcp, formatcp};\n\n#[cfg(feature = \"fmt\")]\nuse cfmt_b::{concatc, formatc};\n\nuse arrayvec::ArrayString;\n\nuse core::fmt::Write;\n\nmacro_rules! tests {\n    (\n        format_str = $format_str:literal,\n        $($expr:expr,)*\n    ) => (\n        const ALL_TYS_F: &'static str = formatcp!( $format_str, $($expr,)* );\n        const ALL_TYS: &'static str = concatcp!( $($expr,)* );\n\n        #[cfg(feature = \"fmt\")]\n        const ALL_TYS_C: &'static str = concatc!( $($expr,)* );\n\n        #[test]\n        fn all_types() {\n            let mut string = ArrayString::<1024>::new();\n            $(\n                write!(string, \"{}\", $expr).unwrap();\n            )*\n            assert_eq!(string.as_str(), ALL_TYS);\n\n            assert_eq!(string.as_str(), ALL_TYS_F);\n\n            #[cfg(feature = \"fmt\")]\n            assert_eq!(string.as_str(), ALL_TYS_C);\n        }\n\n        #[test]\n        fn each_type(){\n            $({\n                const VALUE_F: &'static str = formatcp!(\"{}\", $expr);\n                const VALUE: &'static str = concatcp!($expr);\n\n                let mut string = ArrayString::<64>::new();\n                write!(string, \"{}\", $expr).unwrap();\n\n                assert_eq!(string.as_str(), VALUE);\n                assert_eq!(string.as_str(), VALUE_F);\n            })*\n        }\n    )\n}\n\ntests! {\n    format_str = \"\\\n        {}{}{}{}{}{}{}{}\\\n        {}{}{}{}{}{}{}{}\\\n        {}{}{}{}{}{}{}{}\\\n        {}{}{}{}{}{}{}{}\\\n        {}{}{}{}{}{}{}{}\\\n        {}{}{}{}{}{}{}{}\\\n        {}{}{}{}{}{}{}{}\\\n    \",\n\n    i8::MIN, \" \", i8::MAX, \" \",\n    i16::MIN, \" \", i16::MAX, \" \",\n    i32::MIN, \" \", i32::MAX, \" \",\n    i64::MIN, \" \", i64::MAX, \" \",\n    i128::MIN, \" \", i128::MAX, \" \",\n    isize::MIN, \" \", isize::MAX, \" \",\n    \"!Aq¡🧡🧠₀₁\",\n    \"\",\n    u8::MIN, \" \", u8::MAX, \" \",\n    u16::MIN, \" \", u16::MAX, \" \",\n    u32::MIN, \" \", u32::MAX, \" \",\n    u64::MIN, \" \", u64::MAX, \" \",\n    u128::MIN, \" \", u128::MAX, \" \",\n    usize::MIN, \" \", usize::MAX, \" \",\n    false, true,\n    'o', 'ñ', '个', '\\u{100000}',\n}\n\n#[test]\nfn other_tests() {\n    {\n        const EMPTY: &str = concatcp!();\n        assert_eq!(EMPTY, \"\");\n    }\n\n    #[cfg(feature = \"fmt\")]\n    {\n        const EMPTY: &str = concatc!();\n        assert_eq!(EMPTY, \"\");\n    }\n}\n\n// test that this error doesn't happen:\n// https://github.com/rodrimati1992/const_format_crates/issues/36\n#[test]\nfn call_in_braced_macro() {\n    {\n        assert_eq!(\n            {\n                __identity! {concatcp!(\"a\", \"b\")}\n            },\n            \"ab\"\n        );\n        {\n            __identity! {concatcp!(\"a\", \"b\")}\n        };\n        __identity! {concatcp!(\"a\", \"b\")};\n    }\n\n    #[cfg(feature = \"fmt\")]\n    {\n        assert_eq!(\n            {\n                __identity! {concatc!(\"a\", \"b\")}\n            },\n            \"ab\"\n        );\n        {\n            __identity! {concatc!(\"a\", \"b\")}\n        };\n        __identity! {concatc!(\"a\", \"b\")};\n    }\n\n    {\n        assert_eq!(\n            {\n                __identity! {formatcp!(\"ab\")}\n            },\n            \"ab\"\n        );\n        {\n            __identity! {formatcp!(\"ab\")}\n        };\n        __identity! {formatcp!(\"ab\")};\n    }\n\n    #[cfg(feature = \"fmt\")]\n    {\n        assert_eq!(\n            {\n                __identity! {formatc!(\"ab\")}\n            },\n            \"ab\"\n        );\n        {\n            __identity! {formatc!(\"ab\")}\n        };\n        __identity! {formatc!(\"ab\")};\n    }\n}\n"
  },
  {
    "path": "const_format/tests/misc_tests/type_kind_coercion_macro_tests.rs",
    "content": "use cfmt_b::fmt::{Error, Formatter, FormattingFlags, StrWriter};\nuse cfmt_b::{coerce_to_fmt, impl_fmt};\n\n#[test]\nfn coercion() {\n    let writer: &mut StrWriter = &mut StrWriter::new([0; 512]);\n\n    let flags = FormattingFlags::NEW;\n\n    writer.clear();\n    coerce_to_fmt!(&100u8)\n        .const_debug_fmt(&mut writer.make_formatter(flags))\n        .unwrap();\n    assert_eq!(writer.as_str(), \"100\");\n\n    writer.clear();\n    coerce_to_fmt!(&UnitStruct)\n        .const_debug_fmt(&mut writer.make_formatter(flags))\n        .unwrap();\n    assert_eq!(writer.as_str(), \"UnitStruct\");\n\n    writer.clear();\n    let array = [0u8, 1, 2, 3];\n    coerce_to_fmt!(&&&&&array)\n        .const_debug_fmt(&mut writer.make_formatter(flags))\n        .unwrap();\n    assert_eq!(writer.as_str(), \"[0, 1, 2, 3]\");\n\n    writer.clear();\n    let array = [0u8, 1, 2, 3];\n    coerce_to_fmt!(&&&array[..])\n        .const_debug_fmt(&mut writer.make_formatter(flags))\n        .unwrap();\n    assert_eq!(writer.as_str(), \"[0, 1, 2, 3]\");\n}\n\nstruct UnitStruct;\n\nimpl_fmt! {\n    impl[] UnitStruct;\n\n    const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {\n        f.write_str(\"UnitStruct\")\n    }\n}\n"
  },
  {
    "path": "const_format/tests/misc_tests/writec_macro.rs",
    "content": "// Don't need the tests for this macro to be thorough,\n// since this uses a lot of the same machinery as `formatcp` and `formatc`\n\nuse cfmt_b::fmt::{Error, Formatter, FormattingFlags, StrWriter};\nuse cfmt_b::{try_, writec};\n\nstruct Foo {\n    x: u32,\n    y: &'static str,\n}\n\n#[test]\nfn basic() {\n    const fn inner_0(writer: &mut StrWriter) -> Result<(), Error> {\n        writer.clear();\n        try_!(writec!(writer, \"10\"));\n        try_!(writec!(writer, \"-\"));\n        try_!(writec!(writer, \"20\"));\n        Ok(())\n    }\n    const fn inner_1(writer: &mut StrWriter) -> Result<(), Error> {\n        writer.clear();\n        try_!(writec!(writer, \"\"));\n        Ok(())\n    }\n\n    let writer: &mut StrWriter = &mut StrWriter::new([0; 40]);\n    inner_0(writer).unwrap();\n    assert_eq!(writer.as_str(), \"10-20\");\n\n    inner_1(writer).unwrap();\n    assert_eq!(writer.as_str(), \"\");\n}\n\n#[test]\nfn repeated_positional_args() {\n    const fn inner(foo: &Foo, writer: &mut StrWriter) -> Result<(), Error> {\n        writer.clear();\n        try_!(writec!(\n            writer,\n            \"{0:},{0:?},{0:#x},{0:#X},{0:#b},{1},{1:?}\",\n            foo.x,\n            foo.y\n        ));\n        Ok(())\n    }\n\n    let foo = Foo {\n        x: 13,\n        y: \"foo\\nbar\\tbaz\\x00\",\n    };\n\n    let writer: &mut StrWriter = &mut StrWriter::new([0; 256]);\n    inner(&foo, writer).unwrap();\n    assert_eq!(\n        writer.as_str(),\n        \"13,13,0xd,0xD,0b1101,foo\\nbar\\tbaz\\x00,\\\"foo\\\\nbar\\\\tbaz\\\\x00\\\"\"\n    );\n}\n\n#[test]\nfn write_from_consts() {\n    const FOO: Foo = Foo {\n        x: 13,\n        y: \"foo\\nbar\\tbaz\\x00\",\n    };\n\n    const fn inner(f: &mut Formatter<'_>) -> Result<(), Error> {\n        const X: u32 = FOO.x;\n        const Y: &str = FOO.y;\n        try_!(writec!(f, \"{X:},{X:?},{X:#x},{X:#X},{X:#b},{Y},{Y:?}\"));\n        Ok(())\n    }\n\n    let writer: &mut StrWriter = &mut StrWriter::new([0; 256]);\n    inner(&mut writer.make_formatter(FormattingFlags::NEW)).unwrap();\n    assert_eq!(\n        writer.as_str(),\n        \"13,13,0xd,0xD,0b1101,foo\\nbar\\tbaz\\x00,\\\"foo\\\\nbar\\\\tbaz\\\\x00\\\"\"\n    );\n}\n\n#[test]\nfn named_parameters() {\n    const fn inner(f: &mut Formatter<'_>) -> Result<(), Error> {\n        try_!(writec!(\n            f,\n            \"{x},{y},{},{},{x:b},{y:x},{y:X},{:?}\",\n            21u8,\n            34u8,\n            55..89,\n            x = 8u8,\n            y = 13u8\n        ));\n        Ok(())\n    }\n\n    let writer: &mut StrWriter = &mut StrWriter::new([0; 256]);\n    inner(&mut writer.make_formatter(FormattingFlags::NEW)).unwrap();\n    assert_eq!(writer.as_str(), \"8,13,21,34,1000,d,D,55..89\");\n}\n\n#[test]\nfn write_from_locals() {\n    const fn inner(f: &mut Formatter<'_>) -> Result<(), Error> {\n        let foo = 13u8;\n        let bar = \"58\";\n\n        innerb(f, foo, bar)\n    }\n    const fn innerb(f: &mut Formatter<'_>, foo: u8, bar: &str) -> Result<(), Error> {\n        writec!(\n            f,\n            \"{foo},{bar},{foo:?},{bar:?},{foo:x},{bar:x},{foo:X},{bar:X},{foo:b},{bar:b}\"\n        )\n    }\n\n    let writer: &mut StrWriter = &mut StrWriter::new([0; 96]);\n    inner(&mut writer.make_formatter(FormattingFlags::NEW)).unwrap();\n    assert_eq!(writer.as_str(), r#\"13,58,13,\"58\",d,\"58\",D,\"58\",1101,\"58\"\"#);\n\n    writer.clear();\n    inner(&mut writer.make_formatter(FormattingFlags::NEW)).unwrap();\n    assert_eq!(writer.as_str(), r#\"13,58,13,\"58\",d,\"58\",D,\"58\",1101,\"58\"\"#);\n}\n\n#[test]\n#[cfg(feature = \"fmt\")]\nfn access_formatter() {\n    use cfmt_b::call_debug_fmt;\n\n    const fn inner(f: &mut Formatter<'_>) -> Result<(), Error> {\n        let mut n = 0u64;\n\n        try_!(writec!(f, \"{0};;;\", |fmt| {\n            n += 1;\n            call_debug_fmt!(array, [(), ()], fmt)\n        }));\n\n        try_!(writec!(f, \"{0}; {0}; {0};;;\", |fmt| {\n            n += 100;\n            call_debug_fmt!(array, [n, n], fmt)\n        }));\n\n        try_!(writec!(f, \"{0};;;\", |fmt| call_debug_fmt!(\n            array,\n            [(), ()],\n            fmt\n        )));\n\n        try_!(writec!(f, \"{0}; {0};;;\", |fmt| call_debug_fmt!(\n            array,\n            [(), ()],\n            fmt\n        )));\n\n        Ok(())\n    }\n\n    let writer: &mut StrWriter = &mut StrWriter::new([0; 256]);\n    inner(&mut writer.make_formatter(FormattingFlags::NEW)).unwrap();\n\n    assert_eq!(\n        writer.as_str(),\n        \"\\\n            [(), ()];;;\\\n            [101, 101]; [201, 201]; [301, 301];;;\\\n            [(), ()];;;\\\n            [(), ()]; [(), ()];;;\\\n        \"\n    );\n}\n"
  },
  {
    "path": "const_format/tests/misc_tests_modules.rs",
    "content": "#![cfg_attr(feature = \"__inline_const_pat_tests\", feature(inline_const_pat))]\n\nextern crate const_format as cfmt_b;\nextern crate self as const_format;\n\n// Making sure that `const_format` points at this test crate.\npub const NOT_CF: usize = 13;\npub const _ASSERT_NOT_CF: [(); 13] = [(); const_format::NOT_CF];\n\nmod misc_tests {\n    #[cfg(feature = \"assertc\")]\n    #[cfg(not(feature = \"__only_new_tests\"))]\n    mod assertc_tests;\n\n    mod clippy_warnings;\n\n    #[cfg(feature = \"assertcp\")]\n    mod assertcp_tests;\n\n    #[cfg(feature = \"fmt\")]\n    #[cfg(not(feature = \"__only_new_tests\"))]\n    mod call_debug_fmt_macro;\n\n    #[cfg(feature = \"fmt\")]\n    #[cfg(not(feature = \"__only_new_tests\"))]\n    mod concatc_macro_tests;\n\n    #[cfg(feature = \"derive\")]\n    #[cfg(not(feature = \"__only_new_tests\"))]\n    mod derive_tests;\n\n    #[cfg(feature = \"assertc\")]\n    #[cfg(not(feature = \"__only_new_tests\"))]\n    mod equality_tests;\n\n    #[cfg(not(feature = \"__only_new_tests\"))]\n    mod formatc_macros;\n\n    #[cfg(feature = \"fmt\")]\n    #[cfg(not(feature = \"__only_new_tests\"))]\n    mod impl_fmt_macro_tests;\n\n    #[cfg(not(feature = \"__only_new_tests\"))]\n    mod shared_cp_macro_tests;\n\n    #[cfg(feature = \"fmt\")]\n    #[cfg(not(feature = \"__only_new_tests\"))]\n    mod type_kind_coercion_macro_tests;\n\n    #[cfg(feature = \"fmt\")]\n    //#[cfg(not(feature = \"__only_new_tests\"))]\n    mod writec_macro;\n\n    #[cfg(feature = \"__inline_const_pat_tests\")]\n    mod inline_const_pattern_tests;\n}\n"
  },
  {
    "path": "const_format/tests/str_methods.rs",
    "content": "mod str_methods_modules {\n    mod conv_ascii_case;\n\n    mod str_replace;\n\n    mod str_splice;\n\n    mod str_split_tests;\n}\n"
  },
  {
    "path": "const_format/tests/str_methods_modules/conv_ascii_case.rs",
    "content": "use const_format::__ascii_case_conv::{convert_str, size_after_conversion};\nuse const_format::{map_ascii_case, Case};\n\nmacro_rules! assert_case {\n    ($case:expr, $input:expr, $output:expr $(,)?) => {{\n        const IN: &str = $input;\n        const OUT: &str = $output;\n        const CASE: Case = $case;\n\n        assert_eq!(size_after_conversion(CASE, IN), OUT.len());\n\n        assert_eq!(\n            std::str::from_utf8(&convert_str::<{ OUT.len() }>(CASE, IN)).unwrap(),\n            OUT,\n        );\n\n        assert_eq!(map_ascii_case!(CASE, IN), OUT);\n    }};\n}\n\n#[test]\nfn test_lowercase() {\n    assert_case!(\n        Case::Lower,\n        \"helloazWORLDAZ 効率 \\u{303}n\\u{303}Nñ\",\n        \"helloazworldaz 効率 \\u{303}n\\u{303}nñ\",\n    );\n}\n\n#[test]\nfn test_uppercase() {\n    assert_case!(\n        Case::Upper,\n        \"helloazWORLDAZ 効率 \\u{303}n\\u{303}Nñ\",\n        \"HELLOAZWORLDAZ 効率 \\u{303}N\\u{303}Nñ\",\n    );\n}\n\n#[test]\nfn test_snake_kebab_case() {\n    assert_case!(Case::Snake, \" __ 100 hello_nnWorld \", \"100_hello_nn_world\");\n    assert_case!(\n        Case::UpperSnake,\n        \" __ 100 hello_nnWorld \",\n        \"100_HELLO_NN_WORLD\"\n    );\n\n    // Kebab case\n    assert_case!(Case::Kebab, \" __ 100 hello_nnWorld \", \"100-hello-nn-world\");\n    assert_case!(\n        Case::UpperKebab,\n        \" __ 100 hello_nnWorld \",\n        \"100-HELLO-NN-WORLD\"\n    );\n}\n\n#[test]\nfn test_pascal_camel_case() {\n    assert_case!(\n        Case::Pascal,\n        \" _foo_ 100 hello_nnñWorld \",\n        \"Foo100HelloNnñWorld\"\n    );\n    assert_case!(Case::Pascal, \"一门 foo 一门\", \"一门Foo一门\");\n\n    assert_case!(Case::Pascal, \"一门foo 一门\", \"一门foo一门\");\n\n    // Camel case\n    assert_case!(\n        Case::Camel,\n        \" _bar_ 100一门 hello_nnñWorld \",\n        \"bar100一门HelloNnñWorld\",\n    );\n    assert_case!(Case::Camel, \"一门 foo 一门\", \"一门Foo一门\");\n\n    assert_case!(Case::Camel, \"一门foo 一门\", \"一门foo一门\");\n}\n"
  },
  {
    "path": "const_format/tests/str_methods_modules/str_replace.rs",
    "content": "use const_format::__str_methods::{ReplaceInput, ReplaceInputConv};\nuse const_format::str_replace;\n\nmacro_rules! assert_case {\n    ($input:expr, $patt:expr, $replace_with:expr, $output:expr $(,)*) => {{\n        const IN: &str = $input;\n        const ARGS: ReplaceInput = ReplaceInputConv(IN, $patt, REPLACE_WITH).conv();\n        const REPLACE_WITH: &str = $replace_with;\n        const OUT: &str = $output;\n\n        assert_eq!(ARGS.replace_length(), OUT.len());\n\n        assert_eq!(\n            std::str::from_utf8(&ARGS.replace::<{ OUT.len() }>()).unwrap(),\n            OUT,\n        );\n\n        assert_eq!(str_replace!(IN, $patt, REPLACE_WITH), OUT);\n    }};\n}\n\n#[test]\nfn test_small_pattern() {\n    assert_case! {\"hequ\", \"q\", \"XY\", \"heXYu\"}\n    assert_case! {\"hequx\", \"q\", \"XYZ\", \"heXYZux\"}\n    assert_case! {\"hequq\", \"q\", \"XY\", \"heXYuXY\"}\n    assert_case! {\"hequxq\", \"q\", \"XYZ\", \"heXYZuxXYZ\"}\n\n    assert_case! {\"hequ\", \"qu\", \"XY\", \"heXY\"}\n    assert_case! {\"hequ\", \"qu\", \"XYZ\", \"heXYZ\"}\n    assert_case! {\"hequx\", \"qu\", \"XYZ\", \"heXYZx\"}\n}\n\n#[test]\nfn test_char_pattern() {\n    {\n        const C: char = 'q';\n        assert_eq!(C.len_utf8(), 1);\n\n        assert_case! {\"hequ\", C, \"XY\", \"heXYu\"}\n        assert_case! {\"hequx\", C, \"XYZ\", \"heXYZux\"}\n        assert_case! {\"hequq\", C, \"XY\", \"heXYuXY\"}\n        assert_case! {\"hequxq\", C, \"XYZ\", \"heXYZuxXYZ\"}\n    }\n    {\n        const C: char = 'ñ';\n        assert_eq!(C.len_utf8(), 2);\n\n        assert_case! {\"heñu\", C, \"XY\", \"heXYu\"}\n        assert_case! {\"heñux\", C, \"XYZ\", \"heXYZux\"}\n        assert_case! {\"heñuñ\", C, \"XY\", \"heXYuXY\"}\n        assert_case! {\"heñuxñ\", C, \"XYZ\", \"heXYZuxXYZ\"}\n    }\n    {\n        const C: char = '₀';\n        assert_eq!(C.len_utf8(), 3);\n\n        assert_case! {\"he₀u\", C, \"XY\", \"heXYu\"}\n        assert_case! {\"he₀ux\", C, \"XYZ\", \"heXYZux\"}\n        assert_case! {\"he₀u₀\", C, \"XY\", \"heXYuXY\"}\n        assert_case! {\"he₀ux₀\", C, \"XYZ\", \"heXYZuxXYZ\"}\n    }\n    {\n        const C: char = '🧡';\n        assert_eq!(C.len_utf8(), 4);\n\n        assert_case! {\"he🧡u\", C, \"XY\", \"heXYu\"}\n        assert_case! {\"he🧡ux\", C, \"XYZ\", \"heXYZux\"}\n        assert_case! {\"he🧡u🧡\", C, \"XY\", \"heXYuXY\"}\n        assert_case! {\"he🧡ux🧡\", C, \"XYZ\", \"heXYZuxXYZ\"}\n    }\n}\n\n#[test]\nfn test_replace_overlapping() {\n    assert_case! {\"helololololol\", \"lol\", \"XY\", \"heXYoXYoXY\"}\n\n    assert_case! {\"hequ\", \"qux\", \"XY\", \"hequ\"}\n    assert_case! {\"hequx\", \"qux\", \"XYZA\", \"heXYZA\"}\n    assert_case! {\"heququx\", \"qux\", \"XYZAB\", \"hequXYZAB\"}\n    assert_case! {\"hequxqu\", \"qux\", \"XYZABC\", \"heXYZABCqu\"}\n}\n\n#[test]\nfn test_replace_empty() {\n    assert_case! {\"\", \"qux\", \"-------\", \"\"}\n\n    assert_case! {\"hequxqu\", \"\", \"-------------\", \"hequxqu\"}\n\n    assert_case! {\"hequxqu\", \"qux\", \"\", \"hequ\"}\n}\n"
  },
  {
    "path": "const_format/tests/str_methods_modules/str_splice.rs",
    "content": "use const_format::{str_splice, str_splice_out, SplicedStr};\n\nfn ss(output: &'static str, removed: &'static str) -> SplicedStr {\n    SplicedStr { output, removed }\n}\n\nconst IN: &str = \"abcdefghij\";\nconst RW: &str = \"_.-\";\n\n#[test]\nfn splice_ranges() {\n    assert_eq!(str_splice!(IN, 2, RW), ss(\"ab_.-defghij\", \"c\"));\n    assert_eq!(str_splice!(IN, 4, RW), ss(\"abcd_.-fghij\", \"e\"));\n\n    assert_eq!(str_splice!(IN, 2..4, RW), ss(\"ab_.-efghij\", \"cd\"));\n    assert_eq!(str_splice!(IN, 4..4, RW), ss(\"abcd_.-efghij\", \"\"));\n    assert_eq!(str_splice!(IN, 4..0, RW), ss(\"abcd_.-efghij\", \"\"));\n\n    assert_eq!(str_splice!(IN, 2..=4, RW), ss(\"ab_.-fghij\", \"cde\"));\n    assert_eq!(str_splice!(IN, 4..=4, RW), ss(\"abcd_.-fghij\", \"e\"));\n\n    assert_eq!(str_splice!(IN, ..2, RW), ss(\"_.-cdefghij\", \"ab\"));\n    assert_eq!(str_splice!(IN, ..4, RW), ss(\"_.-efghij\", \"abcd\"));\n\n    assert_eq!(str_splice!(IN, ..=1, RW), ss(\"_.-cdefghij\", \"ab\"));\n    assert_eq!(str_splice!(IN, ..=3, RW), ss(\"_.-efghij\", \"abcd\"));\n\n    assert_eq!(str_splice!(IN, 5.., RW), ss(\"abcde_.-\", \"fghij\"));\n    assert_eq!(str_splice!(IN, 5..IN.len(), RW), ss(\"abcde_.-\", \"fghij\"));\n    assert_eq!(str_splice!(IN, 7.., RW), ss(\"abcdefg_.-\", \"hij\"));\n\n    assert_eq!(str_splice!(IN, .., RW), ss(\"_.-\", \"abcdefghij\"));\n}\n\n#[test]\nfn replacements() {\n    assert_eq!(str_splice!(\"abcde\", 2..4, \"\"), ss(\"abe\", \"cd\"));\n    assert_eq!(str_splice!(\"abcde\", 2..4, \"h\"), ss(\"abhe\", \"cd\"));\n    assert_eq!(str_splice!(\"abcde\", 2..4, \"he\"), ss(\"abhee\", \"cd\"));\n    assert_eq!(str_splice!(\"abcde\", 2..4, \"hel\"), ss(\"abhele\", \"cd\"));\n    assert_eq!(str_splice!(\"abcde\", 2..4, \"hell\"), ss(\"abhelle\", \"cd\"));\n    assert_eq!(str_splice!(\"abcde\", 2..4, \"hello\"), ss(\"abhelloe\", \"cd\"));\n}\n\n#[test]\nfn splice_out_ranges() {\n    assert_eq!(str_splice_out!(IN, 2, RW), \"ab_.-defghij\");\n    assert_eq!(str_splice_out!(IN, 4, RW), \"abcd_.-fghij\");\n\n    assert_eq!(str_splice_out!(IN, 2..4, RW), \"ab_.-efghij\");\n    assert_eq!(str_splice_out!(IN, 4..4, RW), \"abcd_.-efghij\");\n    assert_eq!(str_splice_out!(IN, 4..0, RW), \"abcd_.-efghij\");\n\n    assert_eq!(str_splice_out!(IN, 2..=4, RW), \"ab_.-fghij\");\n    assert_eq!(str_splice_out!(IN, 4..=4, RW), \"abcd_.-fghij\");\n\n    assert_eq!(str_splice_out!(IN, ..2, RW), \"_.-cdefghij\");\n    assert_eq!(str_splice_out!(IN, ..4, RW), \"_.-efghij\");\n\n    assert_eq!(str_splice_out!(IN, ..=1, RW), \"_.-cdefghij\");\n    assert_eq!(str_splice_out!(IN, ..=3, RW), \"_.-efghij\");\n\n    assert_eq!(str_splice_out!(IN, 5.., RW), \"abcde_.-\");\n    assert_eq!(str_splice_out!(IN, 5..IN.len(), RW), \"abcde_.-\");\n    assert_eq!(str_splice_out!(IN, 7.., RW), \"abcdefg_.-\");\n\n    assert_eq!(str_splice_out!(IN, .., RW), \"_.-\");\n}\n\n#[test]\nfn splice_out_replacements() {\n    assert_eq!(str_splice_out!(\"abcde\", 2..4, \"\"), \"abe\");\n    assert_eq!(str_splice_out!(\"abcde\", 2..4, \"h\"), \"abhe\");\n    assert_eq!(str_splice_out!(\"abcde\", 2..4, \"he\"), \"abhee\");\n    assert_eq!(str_splice_out!(\"abcde\", 2..4, \"hel\"), \"abhele\");\n    assert_eq!(str_splice_out!(\"abcde\", 2..4, \"hell\"), \"abhelle\");\n    assert_eq!(str_splice_out!(\"abcde\", 2..4, \"hello\"), \"abhelloe\");\n}\n"
  },
  {
    "path": "const_format/tests/str_methods_modules/str_split_tests.rs",
    "content": "use const_format::{str_split, str_split_pat};\n\n#[test]\nfn test_str_split_pat_basic_equivalence() {\n    assert_eq!(str_split_pat!(\"fob\", \"XY\"), &[\"fob\"][..]);\n    assert_eq!(str_split_pat!(\"XYfob\", \"XY\"), &[\"\", \"fob\"][..]);\n    assert_eq!(str_split_pat!(\"XYfobXY\", \"XY\"), &[\"\", \"fob\", \"\"][..]);\n    assert_eq!(\n        str_split_pat!(\"fooXYbarXYbaz\", \"XY\"),\n        &[\"foo\", \"bar\", \"baz\"][..]\n    );\n    assert_eq!(\n        str_split_pat!(\"fooXY bar XYbaz\", \"XY\"),\n        &[\"foo\", \" bar \", \"baz\"][..]\n    );\n}\n\n#[test]\nfn test_str_split_with_empty_str_arg() {\n    assert_eq!(str_split!(\"\", \"\"), [\"\", \"\"]);\n    assert_eq!(str_split!(\"f\", \"\"), [\"\", \"f\", \"\"]);\n    assert_eq!(str_split!(\"fo\", \"\"), [\"\", \"f\", \"o\", \"\"]);\n    assert_eq!(str_split!(\"fob\", \"\"), [\"\", \"f\", \"o\", \"b\", \"\"]);\n\n    assert_eq!(\n        str_split!(\"!Aq¡🧡🧠₀₁oñ个\", \"\"),\n        [\"\", \"!\", \"A\", \"q\", \"¡\", \"\", \"\", \"🧡\", \"🧠\", \"₀\", \"₁\", \"o\", \"ñ\", \"个\", \"\"],\n    );\n}\n\n#[test]\nfn test_str_split_with_space_str_arg() {\n    assert_eq!(str_split!(\"fob\", \" \"), [\"fob\"]);\n    assert_eq!(str_split!(\" fob\", \" \"), [\"\", \"fob\"]);\n    assert_eq!(str_split!(\" fob \", \" \"), [\"\", \"fob\", \"\"]);\n    assert_eq!(str_split!(\"foo bar baz\", \" \"), [\"foo\", \"bar\", \"baz\"]);\n    assert_eq!(str_split!(\"foo  bar baz\", \" \"), [\"foo\", \"\", \"bar\", \"baz\"]);\n}\n\n#[test]\nfn test_str_split_with_dash_str_arg() {\n    assert_eq!(str_split!(\"fob\", \"-\"), [\"fob\"]);\n    assert_eq!(str_split!(\"-fob\", \"-\"), [\"\", \"fob\"]);\n    assert_eq!(str_split!(\"-fob-\", \"-\"), [\"\", \"fob\", \"\"]);\n    assert_eq!(str_split!(\"foo-bar-baz\", \"-\"), [\"foo\", \"bar\", \"baz\"]);\n    assert_eq!(str_split!(\"foo--bar-baz\", \"-\"), [\"foo\", \"\", \"bar\", \"baz\"]);\n}\n\n#[test]\nfn test_str_split_with_word_arg() {\n    assert_eq!(str_split!(\"fob\", \"XY\"), [\"fob\"]);\n    assert_eq!(str_split!(\"XYfob\", \"XY\"), [\"\", \"fob\"]);\n    assert_eq!(str_split!(\"XYfobXY\", \"XY\"), [\"\", \"fob\", \"\"]);\n    assert_eq!(str_split!(\"fooXYbarXYbaz\", \"XY\"), [\"foo\", \"bar\", \"baz\"]);\n    assert_eq!(str_split!(\"fooXY bar XYbaz\", \"XY\"), [\"foo\", \" bar \", \"baz\"]);\n}\n\n#[test]\nfn test_str_split_with_ascii_char_arg() {\n    assert_eq!(str_split!(\"fob\", '-'), [\"fob\"]);\n    assert_eq!(str_split!(\"-fob\", '-'), [\"\", \"fob\"]);\n    assert_eq!(str_split!(\"-fob-\", '-'), [\"\", \"fob\", \"\"]);\n    assert_eq!(str_split!(\"foo-bar-baz\", '-'), [\"foo\", \"bar\", \"baz\"]);\n    assert_eq!(str_split!(\"foo- bar -baz\", '-'), [\"foo\", \" bar \", \"baz\"]);\n}\n\n#[test]\nfn test_str_split_with_non_ascii_char_arg() {\n    {\n        assert_eq!(''.len_utf8(), 1);\n        assert_eq!(str_split!(\"fob\", ''), [\"fob\"]);\n        assert_eq!(str_split!(\"fob\", ''), [\"\", \"fob\"]);\n        assert_eq!(str_split!(\"fob\", ''), [\"\", \"fob\", \"\"]);\n        assert_eq!(str_split!(\"foobarbaz\", ''), [\"foo\", \"bar\", \"baz\"]);\n        assert_eq!(str_split!(\"foo bar baz\", ''), [\"foo\", \" bar \", \"baz\"]);\n    }\n    {\n        assert_eq!('ñ'.len_utf8(), 2);\n        assert_eq!(str_split!(\"fob\", 'ñ'), [\"fob\"]);\n        assert_eq!(str_split!(\"ñfob\", 'ñ'), [\"\", \"fob\"]);\n        assert_eq!(str_split!(\"ñfobñ\", 'ñ'), [\"\", \"fob\", \"\"]);\n        assert_eq!(str_split!(\"fooñbarñbaz\", 'ñ'), [\"foo\", \"bar\", \"baz\"]);\n        assert_eq!(str_split!(\"fooñ bar ñbaz\", 'ñ'), [\"foo\", \" bar \", \"baz\"]);\n    }\n    {\n        assert_eq!('₀'.len_utf8(), 3);\n        assert_eq!(str_split!(\"fob\", '₀'), [\"fob\"]);\n        assert_eq!(str_split!(\"₀fob\", '₀'), [\"\", \"fob\"]);\n        assert_eq!(str_split!(\"₀fob₀\", '₀'), [\"\", \"fob\", \"\"]);\n        assert_eq!(str_split!(\"foo₀bar₀baz\", '₀'), [\"foo\", \"bar\", \"baz\"]);\n        assert_eq!(str_split!(\"foo₀ bar ₀baz\", '₀'), [\"foo\", \" bar \", \"baz\"]);\n    }\n    {\n        assert_eq!('🧡'.len_utf8(), 4);\n        assert_eq!(str_split!(\"fob\", '🧡'), [\"fob\"]);\n        assert_eq!(str_split!(\"🧡fob\", '🧡'), [\"\", \"fob\"]);\n        assert_eq!(str_split!(\"🧡fob🧡\", '🧡'), [\"\", \"fob\", \"\"]);\n        assert_eq!(str_split!(\"foo🧡bar🧡baz\", '🧡'), [\"foo\", \"bar\", \"baz\"]);\n        assert_eq!(str_split!(\"foo🧡 bar 🧡baz\", '🧡'), [\"foo\", \" bar \", \"baz\"]);\n    }\n}\n"
  },
  {
    "path": "const_format_proc_macros/Cargo.toml",
    "content": "[package]\nname = \"const_format_proc_macros\"\nversion = \"0.2.34\"\nauthors = [\"rodrimati1992 <rodrimatt1985@gmail.com>\"]\nrust-version = \"1.57.0\"\nedition = \"2021\"\nlicense = \"Zlib\"\ndescription = \"Implementation detail of the `const_format` crate\"\nkeywords = [\"no-std\", \"format\", \"concat\"]\ncategories = [\"no-std\", \"text-processing\"]\nrepository = \"https://github.com/rodrimati1992/const_format_crates/\"\ninclude = [\n    \"Cargo.toml\", \n    \"src/**/*.rs\", \n    \"../README.md\",\n    \"LICENSE-ZLIB.md\", \n]\n\n[lib]\nproc-macro = true\n\n[features]\ndefault = []\nderive = [\"syn\", \"syn/derive\", \"syn/printing\"]\ndebug = [\"syn/extra-traits\"]\nall = [\"derive\"]\n\n[dependencies]\nquote = \"1.0.7\"\nproc-macro2 = \"1.0.19\"\nunicode-xid = \"0.2\"\n\n[dependencies.syn]\nversion = \"1.0.38\"\noptional = true\ndefault-features = false\nfeatures = [\"parsing\", \"proc-macro\"]\n\n[dev-dependencies]\nfastrand = \"1.3.4\"\n\n\n[package.metadata.docs.rs]\nrustc-args = [\"--cfg\", \"feature = \\\"all\\\"\"]\n"
  },
  {
    "path": "const_format_proc_macros/LICENSE-ZLIB.md",
    "content": "Copyright (c) 2020 Matias Rodriguez.\n\nThis software is provided 'as-is', without any express or implied\nwarranty. In no event will the authors be held liable for any damages\narising from the use of this software.\n\nPermission is granted to anyone to use this software for any purpose,\nincluding commercial applications, and to alter it and redistribute it\nfreely, subject to the following restrictions:\n\n1. The origin of this software must not be misrepresented; you must not\n   claim that you wrote the original software. If you use this software\n   in a product, an acknowledgment in the product documentation would be\n   appreciated but is not required.\n2. Altered source versions must be plainly marked as such, and must not be\n   misrepresented as being the original software.\n3. This notice may not be removed or altered from any source distribution."
  },
  {
    "path": "const_format_proc_macros/src/datastructure/field_map.rs",
    "content": "use super::*;\n\nuse std::ops::{Index, IndexMut};\n\n/**\nThis is a map from fields to some value.\n\nIf you put this in a type,and use Default to initialize it,\nyou must remember to replace the `FieldMap` using either `FieldMap::defaulted` or `FieldMap::with`\n\n*/\n#[derive(Debug)]\npub struct FieldMap<T> {\n    // The outer vec is the enum variant (if it's a struct/union it's a single element Vec),\n    // the inner one is the field within a variant/struct/union.\n    fields: Vec<Vec<T>>,\n}\n\nimpl<T> FieldMap<T> {\n    /// Constructs an FieldMap which maps each field in the DataStructure to a value\n    /// (obtained by mapping each individual field to `T` using a closure).\n    pub fn with<'a, F>(ds: &'a DataStructure<'a>, mut f: F) -> Self\n    where\n        F: FnMut(&'a Field<'a>) -> T,\n    {\n        Self {\n            fields: ds\n                .variants\n                .iter()\n                .map(|vari| vari.fields.iter().map(&mut f).collect::<Vec<_>>())\n                .collect::<Vec<_>>(),\n        }\n    }\n\n    #[allow(dead_code)]\n    pub fn iter(&self) -> impl Iterator<Item = (FieldIndex, &'_ T)> + Clone + '_ {\n        self.fields.iter().enumerate().flat_map(|(v_i, v)| {\n            v.iter().enumerate().map(move |(f_i, f)| {\n                let index = FieldIndex {\n                    variant: v_i as _,\n                    pos: f_i as _,\n                };\n                (index, f)\n            })\n        })\n    }\n\n    #[allow(dead_code)]\n    pub fn iter_mut(&mut self) -> impl Iterator<Item = (FieldIndex, &'_ mut T)> + '_ {\n        self.fields.iter_mut().enumerate().flat_map(|(v_i, v)| {\n            v.iter_mut().enumerate().map(move |(f_i, f)| {\n                let index = FieldIndex {\n                    variant: v_i as _,\n                    pos: f_i as _,\n                };\n                (index, f)\n            })\n        })\n    }\n}\n\nimpl<'a, T> Index<FieldIndex> for FieldMap<T> {\n    type Output = T;\n\n    fn index(&self, index: FieldIndex) -> &T {\n        &self.fields[index.variant][index.pos]\n    }\n}\n\nimpl<'a, T> IndexMut<FieldIndex> for FieldMap<T> {\n    fn index_mut(&mut self, index: FieldIndex) -> &mut T {\n        &mut self.fields[index.variant][index.pos]\n    }\n}\n\nimpl<'a, T> Index<&'a Field<'a>> for FieldMap<T> {\n    type Output = T;\n\n    fn index(&self, field: &'a Field<'a>) -> &T {\n        let index = field.index;\n        &self.fields[index.variant][index.pos]\n    }\n}\n\nimpl<'a, T> IndexMut<&'a Field<'a>> for FieldMap<T> {\n    fn index_mut(&mut self, field: &'a Field<'a>) -> &mut T {\n        let index = field.index;\n        &mut self.fields[index.variant][index.pos]\n    }\n}\n"
  },
  {
    "path": "const_format_proc_macros/src/datastructure.rs",
    "content": "use syn::{\n    self, Attribute, Data, DeriveInput, Field as SynField, Fields as SynFields, Generics, Ident,\n    Type, Visibility,\n};\n\nuse quote::ToTokens;\n\nuse proc_macro2::TokenStream;\n\nuse std::fmt::{self, Display};\n\nmod field_map;\n\npub use self::field_map::FieldMap;\n\n//////////////////////////////////////////////////////////////////////////////\n\n/// A type definition(enum,struct,union).\n#[derive(Clone)]\npub struct DataStructure<'a> {\n    pub vis: &'a Visibility,\n    pub name: &'a Ident,\n    pub generics: &'a Generics,\n    pub attrs: &'a [Attribute],\n\n    /// Whether this is a struct/union/enum.\n    pub data_variant: DataVariant,\n\n    /// The variants in the type definition.\n    ///\n    /// If it is a struct or a union this only has 1 element.\n    pub variants: Vec<Struct<'a>>,\n}\n\nimpl<'a> DataStructure<'a> {\n    pub fn new(ast: &'a DeriveInput) -> Self {\n        let name = &ast.ident;\n\n        let data_variant: DataVariant;\n\n        let mut variants = Vec::new();\n\n        match &ast.data {\n            Data::Enum(enum_) => {\n                for (variant, var) in enum_.variants.iter().enumerate() {\n                    variants.push(Struct::new(\n                        StructParams {\n                            variant: variant,\n                            name: &var.ident,\n                        },\n                        &var.fields,\n                    ));\n                }\n                data_variant = DataVariant::Enum;\n            }\n            Data::Struct(struct_) => {\n                variants.push(Struct::new(\n                    StructParams {\n                        variant: 0,\n                        name: name,\n                    },\n                    &struct_.fields,\n                ));\n                data_variant = DataVariant::Struct;\n            }\n\n            Data::Union(union_) => {\n                let fields = Some(&union_.fields.named);\n                let sk = StructKind::Braced;\n                let vari = Struct::with_fields(\n                    StructParams {\n                        variant: 0,\n                        name: name,\n                    },\n                    sk,\n                    fields,\n                );\n                variants.push(vari);\n                data_variant = DataVariant::Union;\n            }\n        }\n\n        Self {\n            vis: &ast.vis,\n            name,\n            attrs: &ast.attrs,\n            generics: &ast.generics,\n            data_variant,\n            variants,\n        }\n    }\n}\n\n//////////////////////////////////////////////////////////////////////////////\n\n/// Whether the struct is tupled or not.\n#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Ord, Eq, Hash)]\npub enum StructKind {\n    /// structs declared using the `struct Name( ... ) syntax.\n    Tupled,\n    /// structs declared using the `struct Name{ ... }` or `struct name;` syntaxes\n    Braced,\n}\n\n#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Ord, Eq, Hash)]\npub enum DataVariant {\n    Struct,\n    Enum,\n    Union,\n}\n\n#[derive(Copy, Clone)]\npub struct FieldIndex {\n    pub variant: usize,\n    pub pos: usize,\n}\n\n//////////////////////////////////////////////////////////////////////////////\n\n#[derive(Copy, Clone)]\nstruct StructParams<'a> {\n    variant: usize,\n    name: &'a Ident,\n}\n\n/// A struct/union or a variant of an enum.\n#[derive(Clone)]\npub struct Struct<'a> {\n    /// The name of this `Struct`.\n    ///\n    /// If this is a struct/union:these is the same as DataStructure.name.\n    ///\n    /// If this is an enum:this is the name of the variant.\n    pub name: &'a Ident,\n    pub kind: StructKind,\n    pub fields: Vec<Field<'a>>,\n    _priv: (),\n}\n\nimpl<'a> Struct<'a> {\n    fn new(p: StructParams<'a>, fields: &'a SynFields) -> Self {\n        let kind = match *fields {\n            SynFields::Named { .. } => StructKind::Braced,\n            SynFields::Unnamed { .. } => StructKind::Tupled,\n            SynFields::Unit { .. } => StructKind::Braced,\n        };\n        let fields = match fields {\n            SynFields::Named(f) => Some(&f.named),\n            SynFields::Unnamed(f) => Some(&f.unnamed),\n            SynFields::Unit => None,\n        };\n\n        Self::with_fields(p, kind, fields)\n    }\n\n    fn with_fields<I>(p: StructParams<'a>, kind: StructKind, fields: Option<I>) -> Self\n    where\n        I: IntoIterator<Item = &'a SynField>,\n    {\n        let fields = match fields {\n            Some(x) => Field::from_iter(p, x),\n            None => Vec::new(),\n        };\n\n        Self {\n            name: p.name,\n            kind,\n            fields,\n            _priv: (),\n        }\n    }\n}\n\n//////////////////////////////////////////////////////////////////////////////\n\n/// Represent a struct field\n///\n#[derive(Clone)]\npub struct Field<'a> {\n    pub index: FieldIndex,\n    pub attrs: &'a [Attribute],\n    /// identifier for the field,which is either an index(in a tuple struct) or a name.\n    pub ident: FieldIdent<'a>,\n    pub pattern_ident: Ident,\n    pub ty: &'a Type,\n}\n\nimpl<'a> Field<'a> {\n    fn new(index: FieldIndex, field: &'a SynField) -> Self {\n        let span;\n        let ident = match field.ident.as_ref() {\n            Some(ident) => {\n                span = ident.span();\n                FieldIdent::Named(ident)\n            }\n            None => {\n                span = syn::spanned::Spanned::span(&field.ty);\n                FieldIdent::new_index(index.pos)\n            }\n        };\n        let pattern_ident = Ident::new(&format!(\"f{}_7ac4rtizw8q\", ident), span);\n\n        Self {\n            index,\n            attrs: &field.attrs,\n            ident,\n            pattern_ident,\n            ty: &field.ty,\n        }\n    }\n\n    /// Gets the identifier of this field as an `&Ident`.\n    pub fn pattern_ident(&self) -> &Ident {\n        &self.pattern_ident\n    }\n\n    fn from_iter<I>(p: StructParams<'a>, fields: I) -> Vec<Self>\n    where\n        I: IntoIterator<Item = &'a SynField>,\n    {\n        fields\n            .into_iter()\n            .enumerate()\n            .map(|(pos, f)| {\n                let fi = FieldIndex {\n                    variant: p.variant,\n                    pos,\n                };\n                Field::new(fi, f)\n            })\n            .collect()\n    }\n}\n\n//////////////////////////////////////////////////////////////////////////////\n\n#[derive(Debug, Clone, PartialEq, Eq, Ord, PartialOrd, Hash)]\npub enum FieldIdent<'a> {\n    Index(usize),\n    Named(&'a Ident),\n}\n\nimpl<'a> Display for FieldIdent<'a> {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        match self {\n            FieldIdent::Index(x) => Display::fmt(x, f),\n            FieldIdent::Named(x) => Display::fmt(x, f),\n        }\n    }\n}\n\nimpl<'a> ToTokens for FieldIdent<'a> {\n    fn to_tokens(&self, tokens: &mut TokenStream) {\n        match *self {\n            FieldIdent::Index(ind) => syn::Index::from(ind).to_tokens(tokens),\n            FieldIdent::Named(name) => name.to_tokens(tokens),\n        }\n    }\n}\n\nimpl<'a> FieldIdent<'a> {\n    fn new_index(index: usize) -> Self {\n        FieldIdent::Index(index)\n    }\n}\n"
  },
  {
    "path": "const_format_proc_macros/src/derive_debug/attribute_parsing.rs",
    "content": "use crate::{\n    datastructure::{DataStructure, Field, FieldMap},\n    utils::LinearResult,\n};\n\nuse super::{syntax::ImplHeader, type_detection};\n\nuse quote::ToTokens;\n\nuse syn::{Attribute, Meta, MetaList, NestedMeta};\n\nuse std::marker::PhantomData;\n\npub(crate) struct ConstDebugConfig<'a> {\n    pub(crate) debug_print: bool,\n    pub(crate) crate_path: Option<syn::Path>,\n    pub(crate) impls: Vec<ImplHeader>,\n    pub(crate) field_map: FieldMap<FieldConfig<'a>>,\n    _marker: PhantomData<&'a ()>,\n}\n\nimpl<'a> ConstDebugConfig<'a> {\n    fn new(roa: ConstDebugAttrs<'a>) -> Result<Self, crate::Error> {\n        let ConstDebugAttrs {\n            debug_print,\n            crate_path,\n            impls,\n            field_map,\n            errors: _,\n            _marker: PhantomData,\n        } = roa;\n\n        Ok(Self {\n            debug_print,\n            crate_path,\n            impls,\n            field_map,\n            _marker: PhantomData,\n        })\n    }\n}\n\nstruct ConstDebugAttrs<'a> {\n    debug_print: bool,\n    crate_path: Option<syn::Path>,\n    impls: Vec<ImplHeader>,\n    field_map: FieldMap<FieldConfig<'a>>,\n    errors: LinearResult,\n    _marker: PhantomData<&'a ()>,\n}\n\n////////////////////////////////////////////////////////////////////////////////\n\npub(crate) struct FieldConfig<'a> {\n    pub(crate) how_to_fmt: HowToFmt<'a>,\n}\n\npub(crate) enum HowToFmt<'a> {\n    /// coerce_to_fmt!(&field).const_debug_fmt(f)`\n    Regular,\n    /// Doesn't print the field.\n    Ignore,\n    /// A slice or an array\n    Slice,\n    /// A single field tuple struct, èg: `struct Foo(u32);;`\n    Option_,\n    /// A single field tuple struct, èg: `struct Foo(u32);;`\n    /// The path of the field is parsed from the type, erroring if it's not a path.\n    Newtype(&'a syn::Ident),\n    /// The function used to format the field.\n    With(syn::Path),\n    //// The macro used to format the field,\n    //// it's expected to be callable as `themacro!(var, formatter);`.\n    WithMacro(syn::Path),\n    /// The newtype used to format the field, taking the field by reference.\n    /// eg: `struct Foo<'a>(&'a u32);`.\n    WithWrapper(syn::Path),\n}\n\n////////////////////////////////////////////////////////////////////////////////\n\n#[derive(Copy, Clone)]\nenum ParseContext<'a> {\n    TypeAttr,\n    Field { field: &'a Field<'a> },\n}\n\npub(crate) fn parse_attrs_for_derive<'a>(\n    ds: &'a DataStructure<'a>,\n) -> Result<ConstDebugConfig<'a>, crate::Error> {\n    let mut this = ConstDebugAttrs {\n        debug_print: false,\n        crate_path: None,\n        impls: Vec::new(),\n        field_map: FieldMap::with(ds, |f| FieldConfig {\n            how_to_fmt: type_detection::detect_type_formatting(f.ty),\n        }),\n        errors: LinearResult::ok(),\n        _marker: PhantomData,\n    };\n\n    let ty_ctx = ParseContext::TypeAttr;\n    parse_inner(&mut this, ds.attrs, ty_ctx)?;\n\n    for variant in &ds.variants {\n        for field in variant.fields.iter() {\n            parse_inner(&mut this, field.attrs, ParseContext::Field { field })?;\n        }\n    }\n\n    this.errors.take()?;\n\n    ConstDebugConfig::new(this)\n}\n\n/// Parses an individual attribute\nfn parse_inner<'a, I>(\n    this: &mut ConstDebugAttrs<'a>,\n    attrs: I,\n    pctx: ParseContext<'a>,\n) -> Result<(), crate::Error>\nwhere\n    I: IntoIterator<Item = &'a Attribute>,\n{\n    for attr in attrs {\n        match attr.parse_meta() {\n            Ok(Meta::List(list)) => {\n                let x = parse_attr_list(this, pctx, list);\n                this.errors.combine_err(x);\n            }\n            Err(e) => {\n                this.errors.push_err(e);\n            }\n            _ => {}\n        }\n    }\n    Ok(())\n}\n\n/// Parses an individual attribute list (A `#[attribute( .. )] attribute`).\nfn parse_attr_list<'a>(\n    this: &mut ConstDebugAttrs<'a>,\n    pctx: ParseContext<'a>,\n    list: MetaList,\n) -> Result<(), crate::Error> {\n    if list.path.is_ident(\"cdeb\") {\n        with_nested_meta(\"cdeb\", list.nested, |attr| {\n            let x = parse_sabi_attr(this, pctx, attr);\n            this.errors.combine_err(x);\n            Ok(())\n        })?;\n    }\n\n    Ok(())\n}\n\nfn make_err(tokens: &dyn ToTokens) -> crate::Error {\n    spanned_err!(tokens, \"unrecognized attribute\")\n}\n\n/// Parses the contents of a `#[sabi( .. )]` attribute.\nfn parse_sabi_attr<'a>(\n    this: &mut ConstDebugAttrs<'a>,\n    pctx: ParseContext<'a>,\n    attr: Meta,\n) -> Result<(), crate::Error> {\n    match (pctx, attr) {\n        (ParseContext::Field { field, .. }, Meta::Path(path)) => {\n            let f_config = &mut this.field_map[field.index];\n\n            if path.is_ident(\"ignore\") {\n                f_config.how_to_fmt = HowToFmt::Ignore;\n            } else {\n                return Err(make_err(&path));\n            }\n        }\n        (ParseContext::Field { field, .. }, Meta::NameValue(nv)) => {\n            let f_config = &mut this.field_map[field.index];\n\n            if nv.path.is_ident(\"with\") {\n                f_config.how_to_fmt = HowToFmt::With(parse_lit(&nv.lit)?);\n            } else if nv.path.is_ident(\"with_macro\") {\n                f_config.how_to_fmt = HowToFmt::WithMacro(parse_lit(&nv.lit)?);\n            } else if nv.path.is_ident(\"with_wrapper\") {\n                f_config.how_to_fmt = HowToFmt::WithWrapper(parse_lit(&nv.lit)?);\n            } else {\n                return Err(make_err(&nv));\n            }\n        }\n        (ParseContext::Field { field, .. }, Meta::List(list)) => {\n            let f_config = &mut this.field_map[field.index];\n\n            if list.path.is_ident(\"is_a\") {\n                match list.nested.len() {\n                    0 => return Err(make_err(&list)),\n                    1 => (),\n                    _ => return_spanned_err!(\n                        list,\n                        \"The `#[cdeb(is_a())` attribute must only specify one kind of type.\"\n                    ),\n                }\n                with_nested_meta(\"is_a\", list.nested, |attr| {\n                    f_config.how_to_fmt = parse_the_is_a_attribute(attr, field)?;\n                    Ok(())\n                })?;\n            } else {\n                return Err(make_err(&list));\n            }\n        }\n        (ParseContext::TypeAttr { .. }, Meta::Path(path)) => {\n            if path.is_ident(\"debug_print\") {\n                this.debug_print = true;\n            } else {\n                return Err(make_err(&path));\n            }\n        }\n        (ParseContext::TypeAttr { .. }, Meta::NameValue(nv)) => {\n            if nv.path.is_ident(\"crate\") {\n                this.crate_path = Some(parse_lit(&nv.lit)?);\n            } else {\n                return Err(make_err(&nv));\n            }\n        }\n        (ParseContext::TypeAttr { .. }, Meta::List(list)) => {\n            if list.path.is_ident(\"impls\") {\n                for x in list.nested {\n                    let lit = match x {\n                        NestedMeta::Meta(attr) => return Err(make_err(&attr)),\n                        NestedMeta::Lit(lit) => lit,\n                    };\n                    this.impls.push(parse_lit::<ImplHeader>(&lit)?);\n                }\n            } else {\n                return Err(make_err(&list));\n            }\n        }\n        #[allow(unreachable_patterns)]\n        (_, x) => return Err(make_err(&x)),\n    }\n    Ok(())\n}\n\n///////////////////////////////////////////////////////////////////////////////\n\nfn parse_the_is_a_attribute<'a>(\n    attr: syn::Meta,\n    f: &Field<'a>,\n) -> Result<HowToFmt<'a>, crate::Error> {\n    match attr {\n        Meta::Path(path) => {\n            if path.is_ident(\"array\") || path.is_ident(\"slice\") {\n                Ok(HowToFmt::Slice)\n            } else if path.is_ident(\"Option\") || path.is_ident(\"option\") {\n                Ok(HowToFmt::Option_)\n            } else if path.is_ident(\"newtype\") {\n                let newtype = type_detection::parse_type_as_ident(f.ty)?;\n                Ok(HowToFmt::Newtype(newtype))\n            } else if path.is_ident(\"non_std\") || path.is_ident(\"not_std\") {\n                Ok(HowToFmt::Regular)\n            } else {\n                Err(make_err(&path))\n            }\n        }\n        _ => Err(make_err(&attr)),\n    }\n}\n\n///////////////////////////////////////////////////////////////////////////////\n\nfn parse_lit<T>(lit: &syn::Lit) -> Result<T, crate::Error>\nwhere\n    T: syn::parse::Parse,\n{\n    match lit {\n        syn::Lit::Str(x) => x.parse().map_err(crate::Error::from),\n        _ => Err(spanned_err!(\n            lit,\n            \"Expected string literal containing identifier\"\n        )),\n    }\n}\n\n#[allow(dead_code)]\nfn parse_expr(lit: syn::Lit) -> Result<syn::Expr, crate::Error> {\n    match lit {\n        syn::Lit::Str(x) => x.parse(),\n        syn::Lit::Int(x) => syn::parse_str(x.base10_digits()),\n        _ => return_spanned_err!(lit, \"Expected string or integer literal\"),\n    }\n    .map_err(crate::Error::from)\n}\n\n///////////////////////////////////////////////////////////////////////////////\n\npub fn with_nested_meta<F>(\n    attr_name: &str,\n    iter: syn::punctuated::Punctuated<NestedMeta, syn::Token!(,)>,\n    mut f: F,\n) -> Result<(), crate::Error>\nwhere\n    F: FnMut(Meta) -> Result<(), crate::Error>,\n{\n    for repr in iter {\n        match repr {\n            NestedMeta::Meta(attr) => {\n                f(attr)?;\n            }\n            NestedMeta::Lit(lit) => {\n                return_spanned_err!(\n                    lit,\n                    \"the #[{}(...)] attribute does not allow literals in the attribute list\",\n                    attr_name,\n                );\n            }\n        }\n    }\n    Ok(())\n}\n"
  },
  {
    "path": "const_format_proc_macros/src/derive_debug/syntax.rs",
    "content": "use syn::{\n    parse::{Parse, ParseStream},\n    Generics,\n};\n\n////////////////////////////////////////////////////////////////////////////////\n\npub(crate) struct ImplHeader {\n    pub(crate) generics: Generics,\n    pub(crate) self_ty: syn::Path,\n}\n\nimpl Parse for ImplHeader {\n    fn parse(input: ParseStream) -> Result<Self, syn::Error> {\n        let mut generics = input.parse::<Generics>()?;\n\n        let self_ty = input.parse()?;\n\n        generics.where_clause = input.parse()?;\n\n        Ok(Self { generics, self_ty })\n    }\n}\n"
  },
  {
    "path": "const_format_proc_macros/src/derive_debug/type_detection.rs",
    "content": "use super::HowToFmt;\n\nuse syn::Type;\n\npub(super) fn detect_type_formatting(ty: &Type) -> HowToFmt {\n    let ty = unwrap_reference(ty);\n\n    // println!(\"{:?} {}\", ty, ty.to_token_stream());\n\n    match ty {\n        Type::Array { .. } | Type::Slice { .. } => HowToFmt::Slice,\n        Type::Path(ty) if ty.qself.is_none() && is_path_an_option(&ty.path) => HowToFmt::Option_,\n        _ => HowToFmt::Regular,\n    }\n}\n\nfn unwrap_reference(mut ty: &Type) -> &Type {\n    loop {\n        match ty {\n            Type::Reference(next) => ty = &*next.elem,\n            Type::Group(next) => ty = &*next.elem,\n            Type::Paren(next) => ty = &*next.elem,\n            _ => break,\n        }\n    }\n    ty\n}\n\nfn is_path_an_option(path: &syn::Path) -> bool {\n    let segments = &path.segments;\n\n    if segments[0].ident == \"Option\" {\n        return true;\n    }\n\n    if segments.len() < 3 {\n        return false;\n    }\n\n    let thecrate = &segments[0].ident;\n\n    (thecrate == \"core\" || thecrate == \"alloc\" || thecrate == \"std\")\n        && segments[1].ident == \"option\"\n        && segments[2].ident == \"Option\"\n}\n\n/// Parses the type as an identifier, or the last identifier of a path.\npub(super) fn parse_type_as_ident(ty: &Type) -> Result<&syn::Ident, crate::Error> {\n    let ty = unwrap_reference(ty);\n    match ty {\n        Type::Path(typath) if typath.qself.is_none() && !typath.path.segments.is_empty() => {\n            Ok(&typath.path.segments.last().unwrap().ident)\n        }\n        _ => Err(spanned_err!(ty, \"expected a struct or enum\")),\n    }\n}\n"
  },
  {
    "path": "const_format_proc_macros/src/derive_debug.rs",
    "content": "use crate::datastructure::{DataStructure, DataVariant, Field, StructKind};\n\nuse proc_macro2::{Span, TokenStream as TokenStream2};\n\nuse quote::{quote, quote_spanned, quote_spanned as quote_s, ToTokens, TokenStreamExt};\n\nuse syn::{DeriveInput, Ident};\n\nmod attribute_parsing;\nmod syntax;\nmod type_detection;\n\nuse self::attribute_parsing::HowToFmt;\n\npub(crate) fn derive_constdebug_impl(input: DeriveInput) -> Result<TokenStream2, crate::Error> {\n    let ds = &DataStructure::new(&input);\n    let config = attribute_parsing::parse_attrs_for_derive(ds)?;\n    let cratep = match &config.crate_path {\n        Some(p) => p.to_token_stream(),\n        None => quote!(::const_format),\n    };\n\n    let vis = ds.vis;\n\n    let name = ds.name;\n\n    let mut impl_headers;\n\n    if config.impls.is_empty() {\n        let impl_params = ds.generics.params.iter();\n        let (_, tygen, _) = ds.generics.split_for_impl();\n        let where_clause = get_where_clause_tokens(&ds.generics.where_clause);\n\n        impl_headers = quote!(\n            impl[#( #impl_params ,)*] #name #tygen\n            #where_clause;\n        );\n    } else {\n        impl_headers = TokenStream2::new();\n\n        for imp in config.impls.iter() {\n            let params = imp.generics.params.iter();\n            let self_ty = &imp.self_ty;\n            let where_clause = get_where_clause_tokens(&imp.generics.where_clause);\n\n            impl_headers.append_all(quote!(\n                impl[#(#params)*] #self_ty\n                #where_clause;\n            ));\n        }\n    };\n\n    let enum_prefix = match ds.data_variant {\n        DataVariant::Enum => quote!(#name::),\n        DataVariant::Struct => TokenStream2::new(),\n        DataVariant::Union => panic!(\"Cannot derive ConstDebug on unions\"),\n    };\n\n    let variant_branches = ds.variants.iter().map(|variant| {\n        let vname = variant.name;\n\n        let debug_method = match variant.kind {\n            StructKind::Braced => Ident::new(\"debug_struct\", Span::call_site()),\n            StructKind::Tupled => Ident::new(\"debug_tuple\", Span::call_site()),\n        };\n\n        let patt = variant\n            .fields\n            .iter()\n            .filter_map(|f| -> Option<TokenStream2> {\n                if let HowToFmt::Ignore = config.field_map[f].how_to_fmt {\n                    return None;\n                }\n\n                let pat = &f.ident;\n                let variable = f.pattern_ident();\n\n                Some(quote!(#pat : #variable,))\n            });\n\n        let fmt_call = variant\n            .fields\n            .iter()\n            .filter_map(|f| -> Option<TokenStream2> {\n                let how_to_fmt = &config.field_map[f].how_to_fmt;\n                if let HowToFmt::Ignore = how_to_fmt {\n                    return None;\n                }\n\n                let fspan = f.pattern_ident().span();\n\n                let field_name_str = match variant.kind {\n                    StructKind::Braced => Some(f.ident.to_string()),\n                    StructKind::Tupled => None,\n                }\n                .into_iter();\n\n                let mut field_ts = quote_spanned!(fspan=>\n                    let mut field_formatter = formatter.field(#(#field_name_str)*);\n                );\n\n                field_ts.append_all(match &how_to_fmt {\n                    HowToFmt::Regular => coerce_and_fmt(&cratep, f),\n                    HowToFmt::Ignore => unreachable!(),\n                    HowToFmt::Slice => fmt_slice(&cratep, f),\n                    HowToFmt::Option_ => fmt_option(&cratep, f),\n                    HowToFmt::Newtype(newtype) => fmt_newtype(&cratep, newtype, f),\n                    HowToFmt::With(with) => call_with_function(&cratep, f, with),\n                    HowToFmt::WithMacro(with) => call_with_macro(&cratep, f, with),\n                    HowToFmt::WithWrapper(with) => call_with_wrapper(&cratep, f, with),\n                });\n\n                Some(field_ts)\n            });\n\n        quote!(\n            #enum_prefix #vname { #(#patt)* .. } => {\n                let mut formatter = formatter.#debug_method(stringify!(#vname));\n                #(#fmt_call)*\n                formatter.finish()\n            }\n        )\n    });\n\n    let ret = quote!(\n        #cratep::impl_fmt!{\n            #impl_headers\n\n            #vis const fn const_debug_fmt(\n                &self,\n                formatter: &mut #cratep::pmr::Formatter<'_>,\n            ) -> #cratep::pmr::Result<(), #cratep::pmr::Error> {\n                match self {\n                    #(\n                        #variant_branches\n                    )*\n                }\n            }\n        }\n    );\n\n    if config.debug_print {\n        panic!(\"\\n\\n\\n{}\\n\\n\\n\", ret);\n    }\n    Ok(ret)\n}\n\n// Copying the definitino of the `const_format::coerce_to_fn` macro here\n// because the compiler points inside the coerce_to_fn macro otherwise\nfn coerce_and_fmt(cratep: &TokenStream2, field: &Field<'_>) -> TokenStream2 {\n    let var = field.pattern_ident();\n    let fspan = var.span();\n\n    quote_spanned!(fspan=>\n        let mut marker = #cratep::pmr::IsAFormatMarker::NEW;\n        if false {\n            marker = marker.infer_type(#var);\n        }\n        #cratep::try_!(\n            marker.coerce(marker.unreference(#var))\n                .const_debug_fmt(field_formatter)\n        );\n    )\n}\n\nfn fmt_slice(cratep: &TokenStream2, field: &Field<'_>) -> TokenStream2 {\n    let var = field.pattern_ident();\n    let fspan = var.span();\n\n    let call = call_debug_fmt(\n        cratep,\n        quote_s!(fspan=> &#var[n]),\n        quote_s!(fspan=> slice_fmt.entry()),\n        fspan,\n    );\n\n    quote_spanned!(fspan=>{\n        let mut slice_fmt = field_formatter.debug_list();\n        let mut n = 0;\n        let len = #var.len();\n        while n != len {\n            #call\n            n += 1;\n        }\n        #cratep::try_!(slice_fmt.finish());\n    })\n}\n\nfn fmt_option(cratep: &TokenStream2, field: &Field<'_>) -> TokenStream2 {\n    let var = field.pattern_ident();\n    let fspan = var.span();\n\n    let call = call_debug_fmt(\n        cratep,\n        quote_s!(fspan=>val),\n        quote_s!(fspan=>f.field()),\n        fspan,\n    );\n\n    quote_spanned!(fspan=>\n        #cratep::try_!(match #var {\n            #cratep::pmr::Some(val) => {\n                let mut f = field_formatter.debug_tuple(\"Some\");\n                #call\n                f.finish()\n            }\n            #cratep::pmr::None => field_formatter.write_str(\"None\"),\n        });\n    )\n}\n\nfn fmt_newtype(cratep: &TokenStream2, newtype: &syn::Ident, field: &Field<'_>) -> TokenStream2 {\n    let var = field.pattern_ident();\n    let fspan = var.span();\n    let ty_str = newtype.to_token_stream().to_string();\n\n    let call = call_debug_fmt(\n        cratep,\n        quote_s!(fspan=> &#var.0 ),\n        quote_s!(fspan=> f.field() ),\n        fspan,\n    );\n\n    quote_spanned!(fspan=>{\n        #cratep::try_!({\n            let mut f = field_formatter.debug_tuple(#ty_str);\n            #call\n            f.finish()\n        });\n    })\n}\n\nfn call_with_function(cratep: &TokenStream2, field: &Field<'_>, func: &syn::Path) -> TokenStream2 {\n    let var = field.pattern_ident();\n    let fspan = var.span();\n\n    quote_spanned!(fspan=> #cratep::try_!(#func(#var, field_formatter)); )\n}\n\nfn call_with_macro(cratep: &TokenStream2, field: &Field<'_>, macr: &syn::Path) -> TokenStream2 {\n    let var = field.pattern_ident();\n    let fspan = var.span();\n\n    quote_spanned!(fspan=> #cratep::try_!(#macr!(#var, field_formatter)); )\n}\n\nfn call_with_wrapper(\n    cratep: &TokenStream2,\n    field: &Field<'_>,\n    newtype: &syn::Path,\n) -> TokenStream2 {\n    let var = field.pattern_ident();\n    let fspan = var.span();\n\n    quote_spanned!(fspan=>\n        #cratep::try_!(#newtype(#var).const_debug_fmt(field_formatter));\n    )\n}\n\n// Helper of the other `call_` functions\nfn call_debug_fmt(\n    cratep: &TokenStream2,\n    field: impl ToTokens,\n    formatter: impl ToTokens,\n    span: Span,\n) -> TokenStream2 {\n    quote_spanned!(span=>{\n        // Importing it like this because the error span is wrong otherwise\n        use #cratep::pmr::IsAFormatMarker as __IsAFormatMarker;\n\n        let mut marker = __IsAFormatMarker::NEW;\n        if false {\n            marker = marker.infer_type(#field);\n        }\n        #cratep::try_!(\n            marker.coerce(marker.unreference(#field)).const_debug_fmt(#formatter)\n        );\n    })\n}\n\nfn get_where_clause_tokens(where_clause: &Option<syn::WhereClause>) -> TokenStream2 {\n    match where_clause {\n        Some(x) => {\n            let preds = x.predicates.iter();\n            quote!(where[ #(#preds,)* ])\n        }\n        None => TokenStream2::new(),\n    }\n}\n"
  },
  {
    "path": "const_format_proc_macros/src/error.rs",
    "content": "use crate::spanned::Spans;\n\nuse proc_macro2::{\n    Delimiter, Group, Ident, Literal, Punct, Spacing, Span, TokenStream as TokenStream2,\n    TokenTree as TokenTree2,\n};\n\nuse std::fmt::Display;\n\n#[derive(Debug, Clone)]\npub struct Error {\n    messages: Vec<CompileError>,\n}\n\n#[derive(Debug, Clone)]\nenum CompileError {\n    Basic {\n        start_span: Span,\n        end_span: Span,\n        msg: String,\n    },\n    #[cfg(feature = \"derive\")]\n    Syn(TokenStream2),\n}\n\nimpl Error {\n    pub fn new<T: Display>(span: Span, msg: T) -> Self {\n        Error {\n            messages: vec![CompileError::Basic {\n                start_span: span,\n                end_span: span,\n                msg: msg.to_string(),\n            }],\n        }\n    }\n\n    pub fn spanned<T: Display>(spans: Spans, msg: T) -> Self {\n        Error {\n            messages: vec![CompileError::Basic {\n                start_span: spans.start,\n                end_span: spans.end,\n                msg: msg.to_string(),\n            }],\n        }\n    }\n\n    pub fn to_compile_error(&self) -> TokenStream2 {\n        macro_rules!  tokenstream{\n            ($($tt:expr),* $(,)*) => ({\n                let list: Vec<TokenTree2> = vec![\n                    $($tt.into(),)*\n                ];\n                list.into_iter().collect::<TokenStream2>()\n            })\n        }\n\n        self.messages\n            .iter()\n            .map(|em| match em {\n                CompileError::Basic {\n                    start_span,\n                    end_span,\n                    msg,\n                } => {\n                    let ts = tokenstream![\n                        Ident::new(\"compile_error\", *start_span),\n                        {\n                            let mut this = Punct::new('!', Spacing::Alone);\n                            this.set_span(*start_span);\n                            this\n                        },\n                        {\n                            let mut group = Group::new(\n                                Delimiter::Parenthesis,\n                                tokenstream![{\n                                    let mut lit = Literal::string(msg);\n                                    lit.set_span(*end_span);\n                                    TokenTree2::Literal(lit)\n                                }],\n                            );\n                            group.set_span(*end_span);\n                            group\n                        },\n                    ];\n\n                    // Still have no idea why the compile_error has to be wrapped in parentheses\n                    // so that the spans point at the stuff between start_span and end_span.\n                    let mut this = Group::new(Delimiter::Parenthesis, ts);\n                    this.set_span(*end_span);\n                    tokenstream![this]\n                }\n                #[cfg(feature = \"derive\")]\n                CompileError::Syn(x) => x.clone(),\n            })\n            .collect()\n    }\n\n    pub fn combine(&mut self, another: Error) {\n        self.messages.extend(another.messages)\n    }\n}\n\n#[cfg(feature = \"derive\")]\nimpl From<syn::Error> for Error {\n    fn from(err: syn::Error) -> Self {\n        Self {\n            messages: vec![CompileError::Syn(err.to_compile_error())],\n        }\n    }\n}\n"
  },
  {
    "path": "const_format_proc_macros/src/format_args/parsing.rs",
    "content": "use super::{\n    ExpandFormatted, ExpandInto, ExpandWithFormatter, FormatArg, FormatArgs, FormatIfArgs,\n    LocalVariable, UncheckedFormatArg, UncheckedFormatArgs, WriteArgs,\n};\n\nuse crate::{\n    format_str::{FmtArg, FmtStrComponent, FormatStr, WhichArg},\n    parse_utils::{LitStr, MyParse, ParseBuffer, ParseStream, TokenTreeExt},\n    shared_arg_parsing::ExprArg,\n    spanned::Spans,\n    utils::{dummy_ident, LinearResult},\n};\n\nuse proc_macro2::{Ident, Span, TokenTree};\n\n////////////////////////////////////////////////\n\nimpl MyParse for UncheckedFormatArg {\n    fn parse(input: ParseStream<'_>) -> Result<Self, crate::Error> {\n        // the compile wraps `:expr` in macro_rules macros in a TokenStream::Group\n        // with no delimiters.\n        input.parse_unwrap_group(|content| {\n            let mut ident = None;\n            if matches!(content.peek2(), Some(x) if x.is_punct('=')) {\n                ident = Some(content.parse_ident()?);\n                content.next();\n            }\n\n            // For some reason,\n            // the compile wraps closures in parentheses when passing them as\n            // expressions to proc macros.\n            content.parse_unwrap_paren(|content| {\n                let mut fmt_ident = None;\n\n                if matches!(content.peek(), Some(x) if x.is_punct('|'))\n                    && matches!(content.peek2(), Some(TokenTree::Ident(_)))\n                {\n                    content.next();\n                    fmt_ident = Some(content.parse_ident()?);\n                    content.parse_punct('|')?;\n                }\n\n                let (expr, spans) = if content.peek2().is_some() {\n                    content.parse_token_stream_and_span()\n                } else {\n                    content.parse_unwrap_tt(|content| Ok(content.parse_token_stream_and_span()))?\n                };\n\n                Ok(Self {\n                    spans,\n                    ident,\n                    fmt_ident,\n                    expr,\n                })\n            })\n        })\n    }\n}\n\n////////////////////////////////////////////////\n\nfn lit_str_to_fmt_lit(lit: &LitStr) -> Result<FormatStr, crate::Error> {\n    let lit_str = lit.value();\n    let format_str_span = lit.span;\n    FormatStr::parse(lit.value(), lit.rawness)\n        .map_err(|e| e.into_crate_err(format_str_span, lit_str))\n}\n\nfn parse_fmt_lit(this: &mut FormatStr, input: ParseStream<'_>) -> Result<(), crate::Error> {\n    input.parse_unwrap_tt(|input| {\n        let tt = input.next();\n\n        match tt {\n            Some(TokenTree::Literal(lit)) => {\n                let mut lit = lit_str_to_fmt_lit(&LitStr::parse_from_literal(&lit)?)?;\n\n                this.list.append(&mut lit.list);\n\n                Ok(())\n            }\n            Some(TokenTree::Ident(ident)) if ident == \"concat\" => {\n                input.next(); // skipping the `!`\n                let paren = input.parse_paren()?;\n                let mut input = ParseBuffer::new(paren.contents);\n\n                while !input.is_empty() {\n                    parse_fmt_lit(this, &mut input)?;\n                    input.parse_opt_punct(',')?;\n                }\n                Ok(())\n            }\n            _ => Ok(()),\n        }\n    })\n}\n\nimpl MyParse for UncheckedFormatArgs {\n    fn parse(input: ParseStream<'_>) -> Result<Self, crate::Error> {\n        let mut literal = FormatStr { list: Vec::new() };\n\n        // Have to parse `concat!()` because it's not expanded before the proc macro is called.\n        {\n            let paren = input.parse_paren()?;\n            let mut input = ParseBuffer::new(paren.contents);\n\n            parse_fmt_lit(&mut literal, &mut input)?;\n        }\n\n        input.parse_opt_punct(',')?;\n\n        let mut args = Vec::new();\n\n        while !input.is_empty() {\n            args.push(UncheckedFormatArg::parse(input)?);\n\n            input.parse_opt_punct(',')?;\n        }\n\n        Ok(Self { literal, args })\n    }\n}\n\n////////////////////////////////////////////////\n\nimpl MyParse for FormatArgs {\n    fn parse(input: ParseStream<'_>) -> Result<Self, crate::Error> {\n        let prefix = Ident::new(\"__const_fmt_local_\", Span::call_site());\n        FormatArgs::parse_with(input, prefix)\n    }\n}\n\nimpl FormatArgs {\n    pub fn parse_with(input: ParseStream<'_>, prefix: Ident) -> Result<FormatArgs, crate::Error> {\n        let mut res = LinearResult::ok();\n\n        let unchecked_fargs = UncheckedFormatArgs::parse(input)?;\n\n        let mut first_named_arg = unchecked_fargs.args.len();\n\n        let mut named_arg_names = Vec::<Ident>::new();\n        let mut args = Vec::<FormatArg>::with_capacity(unchecked_fargs.args.len());\n        let mut local_variables = Vec::<LocalVariable>::with_capacity(unchecked_fargs.args.len());\n\n        let arg_span_idents: Vec<(Spans, Option<Ident>)> = unchecked_fargs\n            .args\n            .iter()\n            .map(|x| (x.spans, x.ident.clone()))\n            .collect();\n\n        {\n            let mut prev_is_named_arg = false;\n            for (i, arg) in unchecked_fargs.args.into_iter().enumerate() {\n                let expr_span = arg.spans;\n\n                let make_ident = |s: String| Ident::new(&s, expr_span.start);\n\n                let is_named_arg = arg.ident.is_some();\n\n                let var_name = if let Some(ident) = arg.ident {\n                    if !prev_is_named_arg {\n                        first_named_arg = i;\n                    }\n\n                    let name = make_ident(format!(\"{}{}\", prefix, ident));\n                    named_arg_names.push(ident);\n                    name\n                } else {\n                    if prev_is_named_arg {\n                        return Err(crate::Error::spanned(\n                            arg.spans,\n                            \"expected a named argument, \\\n                             named arguments cannot be followed by positional arguments.\",\n                        ));\n                    }\n\n                    make_ident(format!(\"{}{}\", prefix, i))\n                };\n\n                let format_arg = if let Some(fmt_ident) = &arg.fmt_ident {\n                    FormatArg::WithFormatter {\n                        fmt_ident: fmt_ident.clone(),\n                        expr: arg.expr.clone(),\n                    }\n                } else {\n                    local_variables.push(LocalVariable {\n                        ident: var_name.clone(),\n                        expr: arg.expr.clone(),\n                    });\n\n                    FormatArg::WithLocal(var_name)\n                };\n\n                args.push(format_arg);\n\n                prev_is_named_arg = is_named_arg;\n            }\n        }\n\n        let mut unused_args = vec![true; args.len()];\n\n        let first_named_arg = first_named_arg;\n        let named_arg_names = named_arg_names;\n        let args = args;\n\n        let positional_args = &args[..first_named_arg];\n        let named_args = &args[first_named_arg..];\n\n        let fmt_str_components = unchecked_fargs.literal.list;\n\n        let expanded_into: Vec<ExpandInto> = {\n            let mut current_pos_arg = 0;\n            let mut get_variable_name = |param: FmtArg| -> ExpandInto {\n                let FmtArg {\n                    which_arg,\n                    formatting,\n                    rawness,\n                } = param;\n\n                let arg = match which_arg {\n                    WhichArg::Ident(ident) => {\n                        if let Some(pos) = named_arg_names.iter().position(|x| *x == ident) {\n                            unused_args[pos + first_named_arg] = false;\n                            &named_args[pos]\n                        } else {\n                            // `formatcp!(\"{FOO}\")` assumes that FOO is a constant in scope\n                            return ExpandInto::Formatted(ExpandFormatted {\n                                local_variable: Ident::new(&ident, rawness.span()),\n                                format: formatting,\n                            });\n                        }\n                    }\n                    WhichArg::Positional(opt_pos) => {\n                        let pos = opt_pos.unwrap_or_else(|| {\n                            let pos = current_pos_arg;\n                            current_pos_arg += 1;\n                            pos\n                        });\n\n                        match positional_args.get(pos) {\n                            Some(arg) => {\n                                unused_args[pos] = false;\n                                arg\n                            }\n                            None => {\n                                res.push_err(crate::Error::new(\n                                    rawness.span(),\n                                    format!(\n                                        \"attempting to use nonexistent  positional argument `{}`\",\n                                        pos,\n                                    ),\n                                ));\n                                return ExpandInto::Formatted(ExpandFormatted {\n                                    local_variable: dummy_ident(),\n                                    format: formatting,\n                                });\n                            }\n                        }\n                    }\n                };\n\n                match arg {\n                    FormatArg::WithFormatter { fmt_ident, expr } => {\n                        ExpandInto::WithFormatter(ExpandWithFormatter {\n                            format: formatting,\n                            fmt_ident: fmt_ident.clone(),\n                            expr: expr.clone(),\n                        })\n                    }\n                    FormatArg::WithLocal(local_variable) => {\n                        ExpandInto::Formatted(ExpandFormatted {\n                            format: formatting,\n                            local_variable: local_variable.clone(),\n                        })\n                    }\n                }\n            };\n\n            fmt_str_components\n                .into_iter()\n                .map(|fmt_str_comp| match fmt_str_comp {\n                    FmtStrComponent::Str(str, str_rawness) => ExpandInto::Str(str, str_rawness),\n                    FmtStrComponent::Arg(arg) => get_variable_name(arg),\n                })\n                .collect()\n        };\n\n        for (i, (is_it_unused, (spans, ident))) in\n            unused_args.iter().zip(&arg_span_idents).enumerate()\n        {\n            if *is_it_unused {\n                let msg = if let Some(ident) = ident {\n                    format!(\"the '{}' argument is unused\", ident)\n                } else {\n                    format!(\"argument number {} is unused\", i)\n                };\n                res.push_err(crate::Error::spanned(*spans, msg));\n            }\n        }\n        res.take()?;\n\n        Ok(FormatArgs {\n            condition: None,\n            local_variables,\n            expanded_into,\n        })\n    }\n}\n\n////////////////////////////////////////////////\n\nimpl MyParse for FormatIfArgs {\n    fn parse(input: ParseStream) -> Result<Self, crate::Error> {\n        let condition = ExprArg::parse(input)?;\n\n        let mut inner = FormatArgs::parse(input)?;\n        inner.condition = Some(condition);\n\n        Ok(Self { inner })\n    }\n}\n\n////////////////////////////////////////////////\n\nimpl MyParse for WriteArgs {\n    fn parse(input: ParseStream) -> Result<Self, crate::Error> {\n        let prefix = Ident::new(\"__const_fmt_local_\", Span::call_site());\n\n        let paren = input.parse_paren()?;\n\n        let mut content = ParseBuffer::new(paren.contents);\n\n        let (writer_expr, spans) =\n            content.parse_unwrap_tt(|content| Ok(content.parse_token_stream_and_span()))?;\n\n        let format_args = FormatArgs::parse_with(input, prefix)?;\n\n        Ok(Self {\n            writer_expr,\n            writer_span: spans.joined(),\n            format_args,\n        })\n    }\n}\n"
  },
  {
    "path": "const_format_proc_macros/src/format_args.rs",
    "content": "use crate::{\n    format_str::FormatStr, formatting::FormattingFlags, parse_utils::StrRawness,\n    parse_utils::TokenStream2Ext, shared_arg_parsing::ExprArg, spanned::Spans,\n};\n\nuse proc_macro2::{Ident, Span, TokenStream as TokenStream2};\n\nuse quote::{quote_spanned, TokenStreamExt};\n\n////////////////////////////////////////////////\n\nmod parsing;\n\n////////////////////////////////////////////////\n\nstruct UncheckedFormatArgs {\n    literal: FormatStr,\n    args: Vec<UncheckedFormatArg>,\n}\n\nstruct UncheckedFormatArg {\n    pub(crate) spans: Spans,\n    pub(crate) ident: Option<Ident>,\n    // The identifier for the Formatter passed to format the argument.\n    // If this is Some, then `expr` is expanded directly,\n    pub(crate) fmt_ident: Option<Ident>,\n    /// Using a TokenStream2 because it is validated to be a valid expression in\n    /// the macro_rules! macros that call these proc macros.\n    pub(crate) expr: TokenStream2,\n}\n\npub(crate) struct FormatArgs {\n    pub(crate) condition: Option<ExprArg>,\n    pub(crate) local_variables: Vec<LocalVariable>,\n    pub(crate) expanded_into: Vec<ExpandInto>,\n}\n\npub(crate) struct FormatIfArgs {\n    pub(crate) inner: FormatArgs,\n}\n\n/// The arguments of `writec`\npub(crate) struct WriteArgs {\n    pub(crate) writer_expr: TokenStream2,\n    pub(crate) writer_span: Span,\n    pub(crate) format_args: FormatArgs,\n}\n\npub(crate) enum ExpandInto {\n    Str(String, StrRawness),\n    Formatted(ExpandFormatted),\n    WithFormatter(ExpandWithFormatter),\n}\n\npub(crate) struct ExpandFormatted {\n    pub(crate) format: FormattingFlags,\n    pub(crate) local_variable: Ident,\n}\n\npub(crate) struct ExpandWithFormatter {\n    pub(crate) format: FormattingFlags,\n    pub(crate) fmt_ident: Ident,\n    pub(crate) expr: TokenStream2,\n}\n\npub(crate) struct LocalVariable {\n    // The local variable that the macro will output for this argument,\n    // so that it is not evaluated multiple times when it's used multiple times\n    // in the format string.\n    pub(crate) ident: Ident,\n    /// Using a TokenStream2 because it is validated to be a valid expression in\n    /// the macro_rules! macros that call these proc macros.\n    pub(crate) expr: TokenStream2,\n}\n\npub(crate) enum FormatArg {\n    WithFormatter {\n        // The identifier for the Formatter passed to format the argument.\n        // If this is Some, then `expr` is expanded directly,\n        fmt_ident: Ident,\n        /// Using a TokenStream2 because it is validated to be a valid expression in\n        /// the macro_rules! macros that call these proc macros.\n        expr: TokenStream2,\n    },\n    WithLocal(Ident),\n}\n\n////////////////////////////////////////////////\n\nimpl ExpandInto {\n    pub(crate) fn fmt_call(&self, formatter: &Ident) -> TokenStream2 {\n        match self {\n            ExpandInto::Str(str, rawness) => {\n                let str_tokens = rawness.tokenize_sub(str);\n\n                quote_spanned!(rawness.span()=> #formatter.write_str(#str_tokens) )\n            }\n            ExpandInto::Formatted(fmted) => {\n                let flags = fmted.format;\n                let fmt_method = fmted.format.fmt_method_name();\n                let local_variable = &fmted.local_variable;\n                let span = local_variable.span();\n\n                let mut tokens = quote::quote!(\n                    __cf_osRcTFl4A::coerce_to_fmt!(&#local_variable)\n                        .#fmt_method\n                )\n                .set_span_recursive(span);\n\n                tokens.append_all(quote::quote!( (&mut #formatter.make_formatter(#flags)) ));\n\n                tokens\n            }\n            ExpandInto::WithFormatter(ExpandWithFormatter {\n                format,\n                fmt_ident,\n                expr,\n            }) => quote::quote!({\n                let #fmt_ident = &mut #formatter.make_formatter(#format);\n                __cf_osRcTFl4A::pmr::ToResult( #expr ).to_result()\n            }),\n        }\n    }\n}\n"
  },
  {
    "path": "const_format_proc_macros/src/format_macro/tests.rs",
    "content": "use crate::{parse_utils::MyParse, test_utils::StrExt};\n\nfn process_str(s: &str) -> Result<String, String> {\n    MyParse::parse_token_stream_2(s.parse().unwrap())\n        .and_then(crate::format_macro::formatcp_impl)\n        .map(|x| x.to_string())\n        .map_err(|e| e.to_compile_error().to_string())\n}\n\nmacro_rules! assert_ret {\n    ($call:expr, |$res:ident| $predicate:expr $(,)*) => {\n        let $res = $call;\n        let $res = $res.as_ref();\n        assert!($predicate, \"\\nreturned:\\n{:?}\\n\\n\", $res);\n    };\n}\n\n#[test]\nfn named_argument_followed_by_positional() {\n    assert_ret!(process_str(r#\"(\"\"), (a=()), () \"#), |s| {\n        s.unwrap_err()\n            .consecutive_in_self(&[\"named arguments\", \"cannot\", \"positional arguments\"])\n    });\n}\n\n#[test]\nfn access_formatter_error() {\n    let cases = [\n        r#\"(\"{}\"), (|f| 100u8) \"#,\n        r#\"(\"{}\"), (|_| 100u8) \"#,\n        r#\"(\"{foo}\"), (foo = |f| 100u8) \"#,\n        r#\"(\"{foo}\"), (foo = |_| 100u8) \"#,\n        r#\"(\"{foo}\"), (foo = (|f| 100u8)) \"#,\n        r#\"(\"{foo}\"), (foo = (|_| 100u8)) \"#,\n    ];\n\n    for case in cases.iter().copied() {\n        assert_ret!(process_str(case), |s| {\n            s.unwrap_err().consecutive_in_self(&[\"custom formatting\"])\n        });\n    }\n}\n\n#[test]\nfn nonexistent_argument() {\n    assert_ret!(process_str(r#\"(\"{1}\"), () \"#), |s| {\n        s.unwrap_err()\n            .consecutive_in_self(&[\"positional argument\", \"1\"])\n    });\n\n    assert_ret!(process_str(r#\"(\"{}{}\"), () \"#), |s| {\n        s.unwrap_err()\n            .consecutive_in_self(&[\"positional argument\", \"1\"])\n    });\n    process_str(r#\"(\"{}\"), () \"#).unwrap();\n}\n\n#[test]\nfn unused_arguments() {\n    assert_ret!(process_str(r#\"(\"{}\"), (), () \"#), |s| {\n        let e = s.unwrap_err();\n        e.consecutive_in_self(&[\"argument\", \"1\", \"unused\"])\n    });\n    assert_ret!(process_str(r#\"(\"{}\"), (), () , () \"#), |s| {\n        let e = s.unwrap_err();\n        e.consecutive_in_self(&[\"argument\", \"1\", \"unused\"])\n            && e.consecutive_in_self(&[\"argument\", \"2\", \"unused\"])\n    });\n\n    assert_ret!(process_str(r#\"(\"{}\"), (), (foooo = \"\") \"#), |s| {\n        s.unwrap_err()\n            .consecutive_in_self(&[\"foooo\", \"argument\", \"unused\"])\n    });\n\n    assert_ret!(\n        process_str(r#\"(\"{}\"), (), (), (foooo = \"\"), (bar = \"\") \"#),\n        |s| {\n            let e = s.unwrap_err();\n            e.consecutive_in_self(&[\"argument\", \"1\", \"unused\"])\n                && e.consecutive_in_self(&[\"foooo\", \"argument\", \"unused\"])\n                && e.consecutive_in_self(&[\"bar\", \"argument\", \"unused\"])\n        }\n    );\n}\n"
  },
  {
    "path": "const_format_proc_macros/src/format_macro.rs",
    "content": "use crate::{\n    format_args::{ExpandInto, FormatArgs, FormatIfArgs, LocalVariable, WriteArgs},\n    parse_utils::TokenStream2Ext,\n    shared_arg_parsing::{ExprArg, ExprArgs},\n    Error,\n};\n\nuse proc_macro2::{Ident, Span, TokenStream as TokenStream2};\n\nuse quote::{quote, quote_spanned};\n\n#[cfg(test)]\nmod tests;\n\n////////////////////////////////////////////////////////////////////////////////\n\npub(crate) fn concatcp_impl(value: ExprArgs) -> Result<TokenStream2, crate::Error> {\n    let fmt_var = Ident::new(\"fmt\", Span::mixed_site());\n\n    let concat_args = value.args.iter().map(|ExprArg { expr, span }| {\n        quote_spanned!(span.start=>\n            __cf_osRcTFl4A::pmr::PConvWrapper(#expr).to_pargument_display(#fmt_var)\n        )\n    });\n\n    Ok(quote!(({\n        // The suffix is to avoid name collisions with identifiers in the passed-in expression.\n        #[doc(hidden)]\n        #[allow(unused_mut, non_snake_case)]\n        const CONCATP_NHPMWYD3NJA : &[__cf_osRcTFl4A::pmr::PArgument] = {\n            let #fmt_var = __cf_osRcTFl4A::pmr::FormattingFlags::NEW;\n\n            &[\n                #( #concat_args ),*\n            ]\n        };\n\n        __cf_osRcTFl4A::__concatcp_inner!(CONCATP_NHPMWYD3NJA)\n    })))\n}\n\n////////////////////////////////////////////////////////////////////////////////\n\npub(crate) fn formatcp_if_macro_impl(value: FormatIfArgs) -> Result<TokenStream2, crate::Error> {\n    formatcp_impl(value.inner)\n}\n\npub(crate) fn formatcp_impl(fmt_args: FormatArgs) -> Result<TokenStream2, crate::Error> {\n    let locals = fmt_args\n        .local_variables\n        .iter()\n        .map(|LocalVariable { ident, expr }| {\n            let span = ident.span();\n            quote_spanned!(span=> let #ident = #expr;)\n        });\n\n    for ei in fmt_args.expanded_into.iter() {\n        if let ExpandInto::WithFormatter(wf) = ei {\n            return Err(crate::Error::new(\n                wf.fmt_ident.span(),\n                \"Can't do custom formatting in the `formatcp` macro\",\n            ));\n        }\n    }\n\n    let parg_constructor = fmt_args.expanded_into.iter().map(|ei| match ei {\n        ExpandInto::Str(str, rawness) => {\n            let str_tokens = rawness.tokenize_sub(str);\n            quote!(\n                __cf_osRcTFl4A::pmr::PConvWrapper(#str_tokens)\n                    .to_pargument_display(__cf_osRcTFl4A::pmr::FormattingFlags::NEW)\n            )\n        }\n        ExpandInto::Formatted(fmted) => {\n            let to_pargument_m = fmted.format.to_pargument_method_name();\n            let formatting = fmted.format;\n            let local_variable = &fmted.local_variable;\n            let span = local_variable.span();\n            // I had to use `set_span_recursive` to set the span to that of the argument,\n            // quote_span doesn't work for that somehow.\n            quote!(\n                __cf_osRcTFl4A::pmr::PConvWrapper(#local_variable).#to_pargument_m(#formatting)\n            )\n            .set_span_recursive(span)\n        }\n        ExpandInto::WithFormatter { .. } => unreachable!(),\n    });\n\n    let fmt_if_true = quote!({\n        let mut len = 0usize;\n\n        #( #locals )*\n\n        &[\n            #( #parg_constructor ),*\n        ]\n    });\n\n    if let Some(cond) = fmt_args.condition {\n        Ok(quote!(({\n            enum __Fooosrctfl4a {}\n\n            // This is generic so that the constant is only evaluated when it's needed.\n            impl<T> __cf_osRcTFl4A::pmr::ConcatArgsIf<T, true> for __Fooosrctfl4a {\n                #[doc(hidden)]\n                const PARGUMENTS : &'static [__cf_osRcTFl4A::pmr::PArgument] = #fmt_if_true;\n            }\n\n            __cf_osRcTFl4A::__concatcp_inner!(\n                <__Fooosrctfl4a as __cf_osRcTFl4A::pmr::ConcatArgsIf<(), #cond>>::PARGUMENTS\n            )\n        })))\n    } else {\n        Ok(quote!(({\n            // The suffix is to avoid name collisions with identifiers in the passed-in expression.\n            #[doc(hidden)]\n            #[allow(unused_mut, non_snake_case)]\n            const CONCATP_NHPMWYD3NJA : &[__cf_osRcTFl4A::pmr::PArgument] = #fmt_if_true;\n\n            __cf_osRcTFl4A::__concatcp_inner!(CONCATP_NHPMWYD3NJA)\n        })))\n    }\n}\n\n////////////////////////////////////////////////////////////////////////////////\n\npub(crate) fn formatc_if_macro_impl(value: FormatIfArgs) -> Result<TokenStream2, crate::Error> {\n    formatc_macro_impl(value.inner)\n}\n\n////////////////////////////////////////////////////////////////////////////////\n\npub(crate) fn formatc_macro_impl(fmt_args: FormatArgs) -> Result<TokenStream2, crate::Error> {\n    let locals = fmt_args.local_variables.iter().map(|arg| &arg.ident);\n    let expr = fmt_args.local_variables.iter().map(|arg| &arg.expr);\n\n    let strwriter = Ident::new(\"strwriter\", Span::mixed_site());\n\n    let writing_formatted = fmt_args\n        .expanded_into\n        .iter()\n        .map(|ei| ei.fmt_call(&strwriter));\n\n    let cond_a = fmt_args.condition.iter();\n\n    Ok(quote!(({\n        #[doc(hidden)]\n        #[allow(non_snake_case)]\n        const fn fmt_NHPMWYD3NJA(\n            mut #strwriter: __cf_osRcTFl4A::fmt::Formatter<'_>,\n        ) -> __cf_osRcTFl4A::Result {\n            match (#(&(#expr),)*) {\n                (#(#locals,)*) => {\n                    #(\n                        __cf_osRcTFl4A::try_!(#writing_formatted);\n                    )*\n                },\n            }\n            __cf_osRcTFl4A::pmr::Ok(())\n        }\n\n        __cf_osRcTFl4A::__concatc_inner!(\n            fmt_NHPMWYD3NJA,\n            #((#cond_a) && )* true,\n            ____\n        )\n    })))\n}\n\npub(crate) fn writec_macro_impl(value: WriteArgs) -> Result<TokenStream2, Error> {\n    let writer_expr = value.writer_expr;\n    let writer_span = value.writer_span;\n    let FormatArgs {\n        condition: _,\n        expanded_into,\n        local_variables,\n    } = value.format_args;\n\n    let locals = local_variables.iter().map(|arg| &arg.ident);\n    let expr = local_variables.iter().map(|arg| &arg.expr);\n\n    let strwriter = Ident::new(\"strwriter\", Span::mixed_site());\n\n    let writing_formatted = expanded_into.iter().map(|ei| ei.fmt_call(&strwriter));\n\n    let borrow_mutably = quote_spanned!(writer_span=> ((#writer_expr).borrow_mutably()));\n\n    let make_formatter = quote_spanned!(writer_span =>\n        let mut marker = __cf_osRcTFl4A::pmr::IsAWriteMarker::NEW;\n        if false {\n            marker = marker.infer_type(&#strwriter);\n        }\n        let mut #strwriter = marker.coerce(#strwriter);\n        let mut #strwriter =\n            #strwriter.make_formatter(__cf_osRcTFl4A::FormattingFlags::NEW);\n    );\n\n    Ok(quote! {({\n\n        #[allow(non_snake_case)]\n        match (#borrow_mutably, #(&(#expr),)*) {\n            (#strwriter, #(#locals,)*) => {\n                #make_formatter\n\n                loop {\n                    #(\n                        __cf_osRcTFl4A::unwrap_or_else!(\n                            #writing_formatted,\n                            |e| break __cf_osRcTFl4A::pmr::Err(e)\n                        );\n                    )*\n                    break __cf_osRcTFl4A::pmr::Ok(());\n                }\n            }\n        }\n    })})\n}\n"
  },
  {
    "path": "const_format_proc_macros/src/format_str/errors.rs",
    "content": "use proc_macro2::Span;\n\nuse std::{\n    fmt::{self, Display},\n    ops::Range,\n};\n\n#[derive(Debug, PartialEq)]\npub(crate) struct ParseError {\n    pub(crate) pos: usize,\n    pub(crate) kind: ParseErrorKind,\n}\n\n#[derive(Debug, PartialEq)]\npub(crate) enum ParseErrorKind {\n    /// A `{` that wasn't closed.\n    UnclosedArg,\n    /// A `}` that doesn't close an argument.\n    InvalidClosedArg,\n    /// When parsing the number of a positional arguments\n    NotANumber {\n        what: String,\n    },\n    /// When parsing the identifier of a named argument\n    NotAnIdent {\n        what: String,\n    },\n    UnknownFormatting {\n        what: String,\n    },\n}\n\n#[allow(dead_code)]\nimpl ParseErrorKind {\n    pub fn not_a_number(what: &str) -> Self {\n        Self::NotANumber {\n            what: what.to_string(),\n        }\n    }\n    pub fn not_an_ident(what: &str) -> Self {\n        Self::NotAnIdent {\n            what: what.to_string(),\n        }\n    }\n    pub fn unknown_formatting(what: &str) -> Self {\n        Self::UnknownFormatting {\n            what: what.to_string(),\n        }\n    }\n}\n\n////////////////////////////////////////////////////////////////////////////////\n\n#[derive(Debug, PartialEq)]\npub(crate) struct DisplayParseError<'a> {\n    pub(crate) str: &'a str,\n    pub(crate) error_span: Range<usize>,\n    pub(crate) kind: ParseErrorKind,\n}\nimpl ParseError {\n    fn error_span(&self) -> Range<usize> {\n        let len = match &self.kind {\n            ParseErrorKind::UnclosedArg => 0,\n            ParseErrorKind::InvalidClosedArg => 0,\n            ParseErrorKind::NotANumber { what } => what.len(),\n            ParseErrorKind::NotAnIdent { what } => what.len(),\n            ParseErrorKind::UnknownFormatting { what } => what.len(),\n        };\n\n        self.pos..self.pos + len\n    }\n\n    pub(crate) fn into_crate_err(self, span: Span, original_str: &str) -> crate::Error {\n        let display = DisplayParseError {\n            str: original_str,\n            error_span: self.error_span(),\n            kind: self.kind,\n        };\n\n        crate::Error::new(span, display)\n    }\n}\n\nimpl Display for ParseErrorKind {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        match self {\n            ParseErrorKind::UnclosedArg => f.write_str(\"unclosed argument\"),\n            ParseErrorKind::InvalidClosedArg => f.write_str(\"`}` closing a nonexistent argument\"),\n            ParseErrorKind::NotANumber { what } => writeln!(f, \"not a number: \\\"{}\\\"\", what),\n            ParseErrorKind::NotAnIdent { what } => {\n                writeln!(f, \"not a valid identifier: \\\"{}\\\"\", what)\n            }\n            ParseErrorKind::UnknownFormatting { what } => {\n                writeln!(f, \"unknown formatting: \\\"{}\\\"\", what)\n            }\n        }\n    }\n}\n\nimpl Display for DisplayParseError<'_> {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        f.write_str(\"failed to parse the format string \")?;\n\n        // Gets the amount of chars up to the error,\n        // this is good enough for most cases,\n        // but doesn't acount for multi-char characters.\n        let chars = self.str[..self.error_span.start].chars().count();\n        writeln!(f, \"at the character number {}, \", chars)?;\n\n        Display::fmt(&self.kind, f)?;\n\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "const_format_proc_macros/src/format_str/parsing.rs",
    "content": "use super::{FmtArg, FmtStrComponent, FormatStr, ParseError, ParseErrorKind, WhichArg};\n\nuse crate::{\n    formatting::{FormattingFlags, IsAlternate, NumberFormatting},\n    parse_utils::StrRawness,\n};\n\n#[cfg(test)]\nimpl FmtStrComponent {\n    pub(super) fn str(s: &str) -> Self {\n        Self::Str(s.to_string(), StrRawness::dummy())\n    }\n    pub(super) fn arg(which_arg: WhichArg, formatting: FormattingFlags) -> Self {\n        Self::Arg(FmtArg {\n            which_arg,\n            formatting,\n            rawness: StrRawness::dummy(),\n        })\n    }\n}\n\nimpl FmtArg {\n    fn new(which_arg: WhichArg, formatting: FormattingFlags, rawness: StrRawness) -> Self {\n        Self {\n            which_arg,\n            formatting,\n            rawness,\n        }\n    }\n}\n\n#[allow(dead_code)]\nimpl WhichArg {\n    pub(super) fn ident(s: &str) -> Self {\n        Self::Ident(s.to_string())\n    }\n}\n\n/////////////////////////////////////\n\n#[cfg(test)]\nimpl std::str::FromStr for FormatStr {\n    type Err = ParseError;\n\n    fn from_str(input: &str) -> Result<FormatStr, ParseError> {\n        parse_format_str(input, StrRawness::dummy())\n    }\n}\n\nimpl FormatStr {\n    pub fn parse(input: &str, rawness: StrRawness) -> Result<FormatStr, ParseError> {\n        parse_format_str(input, rawness)\n    }\n}\n\nfn parse_format_str(input: &str, rawness: StrRawness) -> Result<FormatStr, ParseError> {\n    let mut components = Vec::<FmtStrComponent>::new();\n\n    let mut arg_start = 0;\n\n    loop {\n        let open_pos = input.find_from('{', arg_start);\n\n        let str = &input[arg_start..open_pos.unwrap_or(input.len())];\n        components.push_arg_str(parse_mid_str(str, arg_start)?, rawness);\n\n        if let Some(open_pos) = open_pos {\n            let after_open = open_pos + 1;\n            if input[after_open..].starts_with('{') {\n                components.push_arg_str(\"{\".to_string(), rawness);\n\n                arg_start = open_pos + 2;\n            } else if let Some(close_pos) = input.find_from('}', after_open) {\n                let after_close = close_pos + 1;\n\n                let arg = parse_fmt_arg(&input[after_open..close_pos], after_open, rawness)?;\n                components.push(FmtStrComponent::Arg(arg));\n\n                arg_start = after_close;\n            } else {\n                return Err(ParseError {\n                    pos: open_pos,\n                    kind: ParseErrorKind::UnclosedArg,\n                });\n            }\n        } else {\n            break;\n        }\n    }\n\n    Ok(FormatStr { list: components })\n}\n\n/// Parses the text between arguments, to unescape `}}` into `}`\nfn parse_mid_str(str: &str, starts_at: usize) -> Result<String, ParseError> {\n    let mut buffer = String::with_capacity(str.len());\n\n    let mut starts_pos = 0;\n    let bytes = str.as_bytes();\n\n    while let Some(close_pos) = str.find_from('}', starts_pos) {\n        let after_close = close_pos + 1;\n        if bytes.get(after_close) == Some(&b'}') {\n            buffer.push_str(&str[starts_pos..after_close]);\n            starts_pos = after_close + 1;\n        } else {\n            return Err(ParseError {\n                pos: starts_at + close_pos,\n                kind: ParseErrorKind::InvalidClosedArg,\n            });\n        }\n    }\n    buffer.push_str(&str[starts_pos..]);\n\n    Ok(buffer)\n}\n\n/// Parses the format arguments (`{:?}`, `{foo:}`, `{0}`, etc).\n///\n/// `starts_at` is the offset of `input` in the formatting string.\nfn parse_fmt_arg(input: &str, starts_at: usize, rawness: StrRawness) -> Result<FmtArg, ParseError> {\n    let colon = input.find(':');\n\n    let which_arg_str = &input[..colon.unwrap_or(input.len())];\n    let formatting_str = colon.map_or(\"\", |x| &input[x + 1..]);\n    let formatting_starts_at = colon.map_or(input.len(), |x| starts_at + x + 1);\n\n    Ok(FmtArg::new(\n        parse_which_arg(which_arg_str, starts_at)?,\n        parse_formatting(formatting_str, formatting_starts_at)?,\n        rawness,\n    ))\n}\n\n/// Parses the name of the argument in `{foo}`, `{}`, `{bar:?}`\n///\n/// `starts_at` is the offset of `input` in the formatting string.\nfn parse_which_arg(input: &str, starts_at: usize) -> Result<WhichArg, ParseError> {\n    if input.is_empty() {\n        Ok(WhichArg::Positional(None))\n    } else if input.as_bytes()[0].is_ascii_digit() {\n        match input.parse::<usize>() {\n            Ok(number) => Ok(WhichArg::Positional(Some(number))),\n            Err(_) => Err(ParseError {\n                pos: starts_at,\n                kind: ParseErrorKind::NotANumber {\n                    what: input.to_string(),\n                },\n            }),\n        }\n    } else {\n        parse_ident(input, starts_at)\n    }\n}\n\n/// Parses the `?` and other formatters inside formatting arguments (`{}`).\n///\n/// `starts_at` is the offset of `input` in the formatting string.\nfn parse_formatting(input: &str, starts_at: usize) -> Result<FormattingFlags, ParseError> {\n    match input {\n        \"#\" => return Ok(FormattingFlags::display(IsAlternate::Yes)),\n        \"\" => return Ok(FormattingFlags::display(IsAlternate::No)),\n        _ => {}\n    }\n\n    let mut bytes = input.as_bytes();\n\n    let make_error = || ParseError {\n        pos: starts_at,\n        kind: ParseErrorKind::UnknownFormatting {\n            what: input.to_string(),\n        },\n    };\n\n    if let [before @ .., b'?'] = bytes {\n        bytes = before;\n    }\n\n    let mut num_fmt = NumberFormatting::Decimal;\n    let mut is_alternate = IsAlternate::No;\n\n    for byte in bytes {\n        match byte {\n            b'b' if num_fmt.is_regular() => num_fmt = NumberFormatting::Binary,\n            b'x' if num_fmt.is_regular() => num_fmt = NumberFormatting::LowerHexadecimal,\n            b'X' if num_fmt.is_regular() => num_fmt = NumberFormatting::Hexadecimal,\n            b'#' => is_alternate = IsAlternate::Yes,\n            _ => return Err(make_error()),\n        }\n    }\n    Ok(FormattingFlags::debug(num_fmt, is_alternate))\n}\n\n/// Parses an identifier in a formatting argument.\n///\n/// `starts_at` is the offset of `input` in the formatting string.\nfn parse_ident(ident_str: &str, starts_at: usize) -> Result<WhichArg, ParseError> {\n    if is_ident(ident_str) {\n        Ok(WhichArg::Ident(ident_str.to_string()))\n    } else {\n        Err(ParseError {\n            pos: starts_at,\n            kind: ParseErrorKind::NotAnIdent {\n                what: ident_str.to_string(),\n            },\n        })\n    }\n}\n\n////////////////////////////////////////////////////////////////////////////////\n\nfn is_ident(s: &str) -> bool {\n    use unicode_xid::UnicodeXID;\n\n    if s.is_empty() || s == \"_\" {\n        return false;\n    }\n\n    let mut chars = s.chars();\n    let first = chars.next().unwrap();\n\n    // For some reason '_' is not considered a valid character for the stard of an ident\n    (first.is_xid_start() || first == '_') && chars.all(|c| c.is_xid_continue())\n}\n\n////////////////////////////////////////////////////////////////////////////////\n\ntrait VecExt {\n    fn push_arg_str(&mut self, str: String, rawness: StrRawness);\n}\n\nimpl VecExt for Vec<FmtStrComponent> {\n    fn push_arg_str(&mut self, str: String, rawness: StrRawness) {\n        if !str.is_empty() {\n            self.push(FmtStrComponent::Str(str, rawness));\n        }\n    }\n}\n\ntrait StrExt {\n    fn find_from(&self, c: char, from: usize) -> Option<usize>;\n}\n\nimpl StrExt for str {\n    fn find_from(&self, c: char, from: usize) -> Option<usize> {\n        self[from..].find(c).map(|p| p + from)\n    }\n}\n"
  },
  {
    "path": "const_format_proc_macros/src/format_str/tests.rs",
    "content": "use super::*;\n\nuse super::{ParseError as PE, ParseErrorKind as PEK};\n\nuse crate::formatting::{FormattingFlags as FF, IsAlternate, NumberFormatting};\n\nuse fastrand::Rng;\n\nuse std::ops::RangeInclusive;\n\nfn err(s: &'static str) -> ParseError {\n    FormatStr::parse(s, StrRawness::dummy()).unwrap_err()\n}\n\nfn ok(s: &'static str) -> FormatStr {\n    FormatStr::parse(s, StrRawness::dummy()).unwrap()\n}\n\nconst NOALT: IsAlternate = IsAlternate::No;\nconst NFDEC: NumberFormatting = NumberFormatting::Decimal;\n\n#[test]\nfn unclosed_arg() {\n    assert_eq!(\n        err(\"_{\"),\n        PE {\n            pos: 1,\n            kind: PEK::UnclosedArg\n        }\n    );\n    assert_eq!(\n        err(\"___{\"),\n        PE {\n            pos: 3,\n            kind: PEK::UnclosedArg\n        }\n    );\n    assert_eq!(\n        err(\"___{__\"),\n        PE {\n            pos: 3,\n            kind: PEK::UnclosedArg\n        }\n    );\n}\n\n#[test]\nfn invalid_closed_arg() {\n    assert_eq!(\n        err(\"_}\"),\n        PE {\n            pos: 1,\n            kind: PEK::InvalidClosedArg\n        }\n    );\n    assert_eq!(\n        err(\"___}\"),\n        PE {\n            pos: 3,\n            kind: PEK::InvalidClosedArg\n        }\n    );\n    assert_eq!(\n        err(\"___}__\"),\n        PE {\n            pos: 3,\n            kind: PEK::InvalidClosedArg\n        }\n    );\n}\n\n#[test]\nfn not_a_number() {\n    assert_eq!(\n        err(\"  {0a} \"),\n        PE {\n            pos: 3,\n            kind: PEK::not_a_number(\"0a\")\n        }\n    );\n    assert_eq!(\n        err(\"   {4B:?} \"),\n        PE {\n            pos: 4,\n            kind: PEK::not_a_number(\"4B\")\n        }\n    );\n    assert_eq!(\n        err(\"    {6_:} \"),\n        PE {\n            pos: 5,\n            kind: PEK::not_a_number(\"6_\")\n        }\n    );\n}\n\n#[test]\nfn not_an_ident() {\n    assert_eq!(\n        err(\"  {?} \"),\n        PE {\n            pos: 3,\n            kind: PEK::not_an_ident(\"?\")\n        }\n    );\n    assert_eq!(\n        err(\"  {_} \"),\n        PE {\n            pos: 3,\n            kind: PEK::not_an_ident(\"_\")\n        }\n    );\n    assert_eq!(\n        err(\"   {a?} \"),\n        PE {\n            pos: 4,\n            kind: PEK::not_an_ident(\"a?\")\n        }\n    );\n    assert_eq!(\n        err(\"    {_?:} \"),\n        PE {\n            pos: 5,\n            kind: PEK::not_an_ident(\"_?\")\n        }\n    );\n}\n\n#[test]\nfn unknown_formatting() {\n    assert_eq!(\n        err(\"   {:!} \"),\n        PE {\n            pos: 5,\n            kind: PEK::unknown_formatting(\"!\")\n        }\n    );\n    assert_eq!(\n        err(\"    {:????} \"),\n        PE {\n            pos: 6,\n            kind: PEK::unknown_formatting(\"????\")\n        }\n    );\n}\n\n#[test]\nfn ok_cases() {\n    assert_eq!(\n        ok(\"{{{100}}}{200:}{300:?}\").list,\n        vec![\n            FmtStrComponent::str(\"{\"),\n            FmtStrComponent::arg(WhichArg::Positional(Some(100)), FF::display(NOALT)),\n            FmtStrComponent::str(\"}\"),\n            FmtStrComponent::arg(WhichArg::Positional(Some(200)), FF::display(NOALT)),\n            FmtStrComponent::arg(WhichArg::Positional(Some(300)), FF::debug(NFDEC, NOALT)),\n        ]\n    );\n\n    assert_eq!(\n        ok(\"{{{}}}{:}{:?}\").list,\n        vec![\n            FmtStrComponent::str(\"{\"),\n            FmtStrComponent::arg(WhichArg::Positional(None), FF::display(NOALT)),\n            FmtStrComponent::str(\"}\"),\n            FmtStrComponent::arg(WhichArg::Positional(None), FF::display(NOALT)),\n            FmtStrComponent::arg(WhichArg::Positional(None), FF::debug(NFDEC, NOALT)),\n        ]\n    );\n\n    assert_eq!(\n        ok(\"{{{AA}}}{BB:}{CC:?}\").list,\n        vec![\n            FmtStrComponent::str(\"{\"),\n            FmtStrComponent::arg(WhichArg::ident(\"AA\"), FF::display(NOALT)),\n            FmtStrComponent::str(\"}\"),\n            FmtStrComponent::arg(WhichArg::ident(\"BB\"), FF::display(NOALT)),\n            FmtStrComponent::arg(WhichArg::ident(\"CC\"), FF::debug(NFDEC, NOALT)),\n        ]\n    );\n\n    assert_eq!(\n        ok(\"AA {BB} CC {__:}{_aA0ñÑóö:}{FF:?} EE\").list,\n        vec![\n            FmtStrComponent::str(\"AA \"),\n            FmtStrComponent::arg(WhichArg::ident(\"BB\"), FF::display(NOALT)),\n            FmtStrComponent::str(\" CC \"),\n            FmtStrComponent::arg(WhichArg::ident(\"__\"), FF::display(NOALT)),\n            FmtStrComponent::arg(WhichArg::ident(\"_aA0ñÑóö\"), FF::display(NOALT)),\n            FmtStrComponent::arg(WhichArg::ident(\"FF\"), FF::debug(NFDEC, NOALT)),\n            FmtStrComponent::str(\" EE\"),\n        ]\n    );\n}\n\n////////////////////////////////////////////////////////////////////////////////\n\ntrait RngExt {\n    /// # Panic\n    ///\n    /// Panics if the input slice is empty\n    fn pick<'a, T>(&self, slice: &'a [T]) -> &'a T;\n\n    /// # Panic\n    ///\n    /// Panics if there are no `chars` in the `bounds`\n    fn char_(&self, bounds: RangeInclusive<char>) -> char;\n}\n\nimpl RngExt for Rng {\n    fn pick<'a, T>(&self, slice: &'a [T]) -> &'a T {\n        &slice[self.usize(0..slice.len())]\n    }\n\n    fn char_(&self, bounds: RangeInclusive<char>) -> char {\n        if let None = bounds.clone().next() {\n            panic!(\"There are no chars in the {:?} bounds\", bounds);\n        }\n\n        let u32_bounds = u32::from(*bounds.start())..=u32::from(*bounds.end());\n\n        loop {\n            if let Some(x) = std::char::from_u32(self.u32(u32_bounds.clone())) {\n                break x;\n            }\n        }\n    }\n}\n\nfn generate_input() -> String {\n    let rng = Rng::new();\n    let len = rng.usize(0..40);\n    let mut string = String::with_capacity(len * 2);\n\n    for _ in 0..len {\n        match rng.u8(0..100) {\n            0..=10 => string.push(*rng.pick(&['{', '}'])),\n            _ => {\n                let range = rng\n                    .pick(&[\n                        'A'..='Z',\n                        'a'..='z',\n                        '0'..='9',\n                        '\\u{0000}'..='\\u{007F}',\n                        '\\u{007F}'..='\\u{07FF}',\n                        '\\u{07FF}'..='\\u{FFFF}',\n                        '\\u{10000}'..='\\u{10FFFF}',\n                    ])\n                    .clone();\n\n                for _ in 0..rng.u32(0..4) {\n                    string.push(rng.char_(range.clone()));\n                }\n            }\n        };\n    }\n\n    string\n}\n\n#[test]\nfn never_panics() {\n    let iters = 200;\n    loop {\n        let mut ok_count = 0u64;\n        for _ in 0..iters {\n            let input = generate_input();\n            // println!(\"input: {}\\n\\n\", input);\n            if input.parse::<FormatStr>().is_ok() {\n                ok_count += 1;\n            }\n        }\n        if ok_count * 100 / iters > 30 {\n            break;\n        } else {\n            println!(\"retrying never_panics\");\n        }\n    }\n}\n"
  },
  {
    "path": "const_format_proc_macros/src/format_str.rs",
    "content": "use crate::{formatting::FormattingFlags, parse_utils::StrRawness};\n\nmod errors;\n\nmod parsing;\n\n#[cfg(test)]\nmod tests;\n\npub(crate) use self::errors::{ParseError, ParseErrorKind};\n\n#[derive(Debug, PartialEq)]\npub(crate) struct FormatStr {\n    pub(crate) list: Vec<FmtStrComponent>,\n}\n\n#[derive(Debug, PartialEq)]\npub(crate) enum FmtStrComponent {\n    Str(String, StrRawness),\n    Arg(FmtArg),\n}\n\n/// An argument in the format string eg: `\"{foo:?}\"`\n#[derive(Debug, PartialEq)]\npub(crate) struct FmtArg {\n    pub(crate) which_arg: WhichArg,\n    pub(crate) formatting: FormattingFlags,\n    pub(crate) rawness: StrRawness,\n}\n\n#[derive(Debug, PartialEq)]\npub(crate) enum WhichArg {\n    Ident(String),\n    Positional(Option<usize>),\n}\n"
  },
  {
    "path": "const_format_proc_macros/src/formatting.rs",
    "content": "use proc_macro2::{Ident, Span, TokenStream as TokenStream2};\n\nuse quote::{quote, ToTokens, TokenStreamExt};\n\n#[derive(Debug, Copy, Clone, PartialEq)]\npub(crate) enum Formatting {\n    Debug(NumberFormatting),\n    Display,\n}\n\n#[derive(Debug, Copy, Clone, PartialEq)]\npub(crate) enum NumberFormatting {\n    Decimal,\n    Hexadecimal,\n    LowerHexadecimal,\n    Binary,\n}\n\nimpl NumberFormatting {\n    pub(crate) fn is_regular(self) -> bool {\n        matches!(self, NumberFormatting::Decimal)\n    }\n}\n\nimpl ToTokens for NumberFormatting {\n    fn to_tokens(&self, ts: &mut TokenStream2) {\n        ts.append_all(match self {\n            Self::Decimal => return,\n            Self::Hexadecimal => quote!(.set_hexadecimal()),\n            Self::LowerHexadecimal => quote!(.set_lower_hexadecimal()),\n            Self::Binary => quote!(.set_binary()),\n        });\n    }\n}\n\n////////////////////////////////////////////////////////////////////////////////\n\n#[derive(Debug, Copy, Clone, PartialEq)]\npub(crate) enum IsAlternate {\n    Yes,\n    No,\n}\n\n////////////////////////////////////////////////////////////////////////////////\n\n#[derive(Debug, Copy, Clone, PartialEq)]\npub(crate) struct FormattingFlags {\n    pub(crate) formatting: Formatting,\n    pub(crate) is_alternate: IsAlternate,\n}\n\nimpl FormattingFlags {\n    #[inline]\n    pub(crate) const fn display(is_alternate: IsAlternate) -> Self {\n        Self {\n            formatting: Formatting::Display,\n            is_alternate,\n        }\n    }\n\n    #[inline]\n    pub(crate) const fn debug(num_fmt: NumberFormatting, is_alternate: IsAlternate) -> Self {\n        Self {\n            formatting: Formatting::Debug(num_fmt),\n            is_alternate,\n        }\n    }\n}\n\nimpl FormattingFlags {\n    pub(crate) fn to_pargument_method_name(self) -> Ident {\n        let name = match self.formatting {\n            Formatting::Display => \"to_pargument_display\",\n            Formatting::Debug { .. } => \"to_pargument_debug\",\n        };\n\n        Ident::new(name, Span::mixed_site())\n    }\n\n    #[allow(dead_code)]\n    pub(crate) fn fmt_method_name(self) -> Ident {\n        let name = match self.formatting {\n            Formatting::Display => \"const_display_fmt\",\n            Formatting::Debug { .. } => \"const_debug_fmt\",\n        };\n\n        Ident::new(name, Span::mixed_site())\n    }\n\n    #[allow(dead_code)]\n    pub(crate) fn len_method_name(self) -> Ident {\n        let name = match self.formatting {\n            Formatting::Display => \"const_display_fmt\",\n            Formatting::Debug { .. } => \"const_debug_fmt\",\n        };\n\n        Ident::new(name, Span::mixed_site())\n    }\n}\n\nimpl ToTokens for FormattingFlags {\n    fn to_tokens(&self, ts: &mut TokenStream2) {\n        use self::{IsAlternate as IA, NumberFormatting as FM};\n\n        let formatting = match self.formatting {\n            Formatting::Display => NumberFormatting::Decimal,\n            Formatting::Debug(num_fmt) => num_fmt,\n        };\n\n        ts.append_all(match (self.is_alternate, formatting) {\n            (IA::No, FM::Decimal) => quote!(__cf_osRcTFl4A::pmr::FormattingFlags::__REG),\n            (IA::No, FM::Hexadecimal) => quote!(__cf_osRcTFl4A::pmr::FormattingFlags::__HEX),\n            (IA::No, FM::LowerHexadecimal) => {\n                quote!(__cf_osRcTFl4A::pmr::FormattingFlags::__LOWHEX)\n            }\n            (IA::No, FM::Binary) => quote!(__cf_osRcTFl4A::pmr::FormattingFlags::__BIN),\n            (IA::Yes, FM::Decimal) => quote!(__cf_osRcTFl4A::pmr::FormattingFlags::__A_REG),\n            (IA::Yes, FM::Hexadecimal) => quote!(__cf_osRcTFl4A::pmr::FormattingFlags::__A_HEX),\n            (IA::Yes, FM::LowerHexadecimal) => {\n                quote!(__cf_osRcTFl4A::pmr::FormattingFlags::__A_LOWHEX)\n            }\n            (IA::Yes, FM::Binary) => quote!(__cf_osRcTFl4A::pmr::FormattingFlags::__A_BIN),\n        });\n    }\n}\n"
  },
  {
    "path": "const_format_proc_macros/src/lib.rs",
    "content": "#![allow(clippy::or_fun_call)]\n#![allow(clippy::derive_partial_eq_without_eq)]\n\nuse proc_macro::TokenStream as TokenStream1;\n\nuse proc_macro2::TokenStream as TokenStream2;\n\n#[cfg(feature = \"derive\")]\n#[macro_use]\nmod macros;\n\n#[cfg(feature = \"derive\")]\nmod datastructure;\n\nmod error;\n\n#[cfg(feature = \"derive\")]\nmod derive_debug;\n\nmod format_args;\n\nmod format_str;\n\nmod format_macro;\n\nmod formatting;\n\nmod parse_utils;\n\nmod respan_to_macro;\n\nmod shared_arg_parsing;\n\nmod spanned;\n\nmod utils;\n\n#[cfg(test)]\nmod test_utils;\n\nuse crate::error::Error;\nuse crate::parse_utils::MyParse;\n\nfn compile_err_empty_str(e: crate::Error) -> TokenStream2 {\n    let e = e.to_compile_error();\n    quote::quote!({\n        #e;\n        \"\"\n    })\n}\n\n#[doc(hidden)]\n#[proc_macro]\npub fn __concatcp_impl(input: TokenStream1) -> TokenStream1 {\n    MyParse::parse_token_stream_1(input)\n        .and_then(format_macro::concatcp_impl)\n        .unwrap_or_else(compile_err_empty_str)\n        .into()\n}\n\n/// Input syntax: `\"format string\", (arg0), (name = arg1)` (with optional trailing comma).\n///\n/// The arguments are parenthesized to not require syn to parse `arg0` and `arg1` as syn::Expr,\n/// they're just parsed as a `TokenStream2`.\n///\n/// They're guaranteed to be expressions when this macro is invoked by `const_format` macros,\n/// which should be the only ones to do so.\n#[doc(hidden)]\n#[proc_macro]\npub fn __formatcp_impl(input: TokenStream1) -> TokenStream1 {\n    MyParse::parse_token_stream_1(input)\n        .and_then(format_macro::formatcp_impl)\n        .unwrap_or_else(compile_err_empty_str)\n        .into()\n}\n\n#[doc(hidden)]\n#[proc_macro]\npub fn __formatc_impl(input: TokenStream1) -> TokenStream1 {\n    MyParse::parse_token_stream_1(input)\n        .and_then(format_macro::formatc_macro_impl)\n        .unwrap_or_else(compile_err_empty_str)\n        .into()\n}\n\n#[doc(hidden)]\n#[proc_macro]\npub fn __formatc_if_impl(input: TokenStream1) -> TokenStream1 {\n    MyParse::parse_token_stream_1(input)\n        .and_then(format_macro::formatc_if_macro_impl)\n        .unwrap_or_else(compile_err_empty_str)\n        .into()\n}\n\n#[doc(hidden)]\n#[proc_macro]\npub fn __formatcp_if_impl(input: TokenStream1) -> TokenStream1 {\n    MyParse::parse_token_stream_1(input)\n        .and_then(format_macro::formatcp_if_macro_impl)\n        .unwrap_or_else(compile_err_empty_str)\n        .into()\n}\n\n#[doc(hidden)]\n#[proc_macro]\npub fn __writec_impl(input: TokenStream1) -> TokenStream1 {\n    MyParse::parse_token_stream_1(input)\n        .and_then(format_macro::writec_macro_impl)\n        .unwrap_or_else(|e| {\n            let e = e.to_compile_error();\n            quote::quote!({\n                #e;\n                ::core::result::Result::Ok(())\n            })\n        })\n        .into()\n}\n\n#[cfg(feature = \"derive\")]\n#[proc_macro_derive(ConstDebug, attributes(cdeb))]\npub fn derive_const_debug(input: TokenStream1) -> TokenStream1 {\n    syn::parse(input)\n        .map_err(crate::Error::from)\n        .and_then(derive_debug::derive_constdebug_impl)\n        .unwrap_or_else(|e| e.to_compile_error())\n        .into()\n}\n\n/// `__respan_to!(( foo tokens )  bar tokens )`\n/// Respan all the bar tokens to the span of the foo tokens\n#[proc_macro]\npub fn respan_to(input: TokenStream1) -> TokenStream1 {\n    crate::respan_to_macro::implementation(input.into()).into()\n}\n"
  },
  {
    "path": "const_format_proc_macros/src/macros.rs",
    "content": "#![allow(unused_macros)]\n\n#[doc(hidden)]\nmacro_rules! to_stream {\n    ( $stream:ident ; $($expr:expr),* $(,)* ) => {{\n        // use quote::TokenStreamExt;\n\n        $( $expr.to_tokens($stream); )*\n    }}\n}\n\n#[doc(hidden)]\nmacro_rules! spanned_err {\n    ( $e:expr, $($fmt:tt)* ) => ({\n        $crate::utils::spanned_err(\n            &$e,\n            &format!($($fmt)*),\n        )\n    })\n}\n\n#[doc(hidden)]\nmacro_rules! return_spanned_err {\n    ( $e:expr, $($fmt:tt)* ) => ({\n        return Err($crate::utils::spanned_err(\n            &$e,\n            &format!($($fmt)*),\n        ))\n    })\n}\n\n#[doc(hidden)]\nmacro_rules! syn_err {\n    ( $span:expr, $($fmt:tt)* ) => ({\n        $crate::utils::syn_err(\n            $span,\n            &format!($($fmt)*),\n        )\n    })\n}\n\n#[doc(hidden)]\nmacro_rules! return_syn_err {\n    ( $span:expr, $($fmt:tt)* ) => ({\n        return Err($crate::utils::syn_err(\n            $span,\n            &format!($($fmt)*),\n        ))\n    })\n}\n"
  },
  {
    "path": "const_format_proc_macros/src/parse_utils.rs",
    "content": "use crate::{spanned::Spans, utils::Peekable2, Error};\n\nuse proc_macro2::{\n    token_stream::IntoIter, Delimiter, Group, Ident, Punct, Span, TokenStream as TokenStream2,\n    TokenTree as TokenTree2,\n};\n\nuse std::{cmp::PartialEq, ops::Range};\n\npub type ParseStream<'a> = &'a mut ParseBuffer;\n\npub struct ParseBuffer {\n    iter: Peekable2<IntoIter>,\n}\n\nimpl ParseBuffer {\n    pub fn new(ts: TokenStream2) -> Self {\n        let iter = Peekable2::new(ts);\n        Self { iter }\n    }\n\n    pub fn is_empty(&mut self) -> bool {\n        self.iter.is_empty()\n    }\n\n    pub fn peek(&mut self) -> Option<&TokenTree2> {\n        self.iter.peek()\n    }\n    pub fn peek2(&mut self) -> Option<&TokenTree2> {\n        self.iter.peek2()\n    }\n\n    pub fn parse_punct(&mut self, c: char) -> Result<Punct, crate::Error> {\n        match self.next() {\n            Some(TokenTree2::Punct(x)) if x.as_char() == c => Ok(x),\n            Some(x) => Err(Error::new(x.span(), &format!(\"Expected a '{}' token\", c))),\n            None => Err(Error::new(\n                Span::mixed_site(),\n                &format!(\"Expected a '{}' token\", c),\n            )),\n        }\n    }\n    pub fn parse_opt_punct(&mut self, c: char) -> Result<Option<Punct>, crate::Error> {\n        match self.next() {\n            Some(TokenTree2::Punct(x)) if x.as_char() == c => Ok(Some(x)),\n            Some(x) => Err(Error::new(x.span(), &format!(\"Expected a '{}' token\", c))),\n            None => Ok(None),\n        }\n    }\n\n    pub fn parse_ident(&mut self) -> Result<Ident, crate::Error> {\n        match self.next() {\n            Some(TokenTree2::Ident(x)) => Ok(x),\n            Some(x) => Err(Error::new(x.span(), \"Expected an identifier\")),\n            None => Err(Error::new(Span::mixed_site(), \"Expected an identifier\")),\n        }\n    }\n\n    pub fn parse_paren(&mut self) -> Result<Parentheses, crate::Error> {\n        match self.next() {\n            Some(TokenTree2::Group(group)) if group.delimiter() == Delimiter::Parenthesis => {\n                Ok(Parentheses {\n                    paren_span: group.span(),\n                    contents: group.stream(),\n                })\n            }\n            Some(x) => Err(Error::new(\n                x.span(),\n                &format!(\"Expected parentheses: found {}\", x),\n            )),\n            None => Err(Error::new(\n                Span::mixed_site(),\n                \"Expected parentheses, found nothing\",\n            )),\n        }\n    }\n\n    pub fn parse_unwrap_paren<F, T>(&mut self, f: F) -> Result<T, crate::Error>\n    where\n        F: FnOnce(ParseStream<'_>) -> Result<T, crate::Error>,\n    {\n        if matches!(self.peek(), Some(TokenTree2::Group(x)) if x.delimiter() == Delimiter::Parenthesis )\n        {\n            if let Some(TokenTree2::Group(group)) = self.next() {\n                ParseBuffer::new(group.stream()).parse_unwrap_tt(f)\n            } else {\n                unreachable!(\"But I peeked for a Parenthesis delimited TokenTree::Group!!\")\n            }\n        } else {\n            f(self)\n        }\n    }\n\n    pub fn parse_unwrap_group<F, T>(&mut self, f: F) -> Result<T, crate::Error>\n    where\n        F: FnOnce(ParseStream<'_>) -> Result<T, crate::Error>,\n    {\n        if let Some(TokenTree2::Group(group)) = self.next() {\n            ParseBuffer::new(group.stream()).parse_unwrap_tt(f)\n        } else {\n            f(self)\n        }\n    }\n\n    pub fn parse_token_stream_and_span(&mut self) -> (TokenStream2, Spans) {\n        let mut start = match self.peek() {\n            Some(x) => x.span(),\n            None => Span::call_site(),\n        };\n\n        let mut end = start;\n\n        let ts = self\n            .inspect(|tt| {\n                end = tt.span();\n                if let Some(next) = start.join(end) {\n                    start = next;\n                }\n            })\n            .collect::<TokenStream2>();\n\n        (ts, Spans { start, end })\n    }\n\n    /// Unwraps a none-delimited token tree to parse a type,\n    /// if the first token is not a none-delimited token tree it parses the type in\n    /// the passed in ParseStream.\n    pub fn parse_unwrap_tt<F, T>(&mut self, f: F) -> Result<T, crate::Error>\n    where\n        F: FnOnce(ParseStream<'_>) -> Result<T, crate::Error>,\n    {\n        if matches!(self.peek(), Some(TokenTree2::Group(x)) if x.delimiter() == Delimiter::None ) {\n            if let Some(TokenTree2::Group(group)) = self.next() {\n                ParseBuffer::new(group.stream()).parse_unwrap_tt(f)\n            } else {\n                unreachable!(\"But I peeked for a None delimited TokenTree::Group!!\")\n            }\n        } else {\n            f(self)\n        }\n    }\n}\n\nimpl Iterator for ParseBuffer {\n    type Item = TokenTree2;\n\n    fn next(&mut self) -> Option<TokenTree2> {\n        self.iter.next()\n    }\n\n    fn size_hint(&self) -> (usize, Option<usize>) {\n        self.iter.size_hint()\n    }\n}\n\n///////////////////////////////////////////////////////////////////////////////\n\npub struct Parentheses {\n    #[allow(dead_code)]\n    pub paren_span: Span,\n    pub contents: TokenStream2,\n}\n\n///////////////////////////////////////////////////////////////////////////////\n\npub struct LitStr {\n    value: String,\n    pub rawness: StrRawness,\n    pub inside_lit: Range<usize>,\n    pub span: Span,\n}\n\nimpl LitStr {\n    pub fn value(&self) -> &str {\n        &self.value[self.inside_lit.clone()]\n    }\n    pub(crate) fn parse_from_literal(literal: &proc_macro2::Literal) -> Result<Self, Error> {\n        let mut value = literal.to_string();\n        // Ignoring the quote characters\n        let mut range = 1..value.len() - 1;\n        let span = literal.span();\n\n        let is_raw = if let Some(suffix) = value.strip_prefix('r') {\n            let hashes = suffix.bytes().take_while(|x| *x == b'#').count();\n\n            if value.as_bytes()[1 + hashes] != b'\"' {\n                return Err(Error::new(\n                    span,\n                    &format!(\"Expected a string literal, found: {}\", literal),\n                ));\n            }\n\n            // Ignoring the r and hashes\n            range.start += 1 + hashes;\n            range.end -= hashes;\n            Some(hashes as u32)\n        } else {\n            let mut matches = value.match_indices(r#\"\\u\"#).peekable();\n            if matches.peek().is_some() {\n                let mut prev_end = 0;\n                let mut new = String::with_capacity(value.len());\n\n                for (pos, _) in matches {\n                    new.push_str(&value[prev_end..pos]);\n\n                    let past_open = pos + 3;\n\n                    let off_close = value[pos..].find('}').unwrap();\n\n                    let c = &value[past_open..pos + off_close];\n                    let c = u32::from_str_radix(c, 16).unwrap();\n                    let c = std::char::from_u32(c).unwrap();\n\n                    // if matches!(c, '\\\\' | '\"') {\n                    //     new.push('\\\\');\n                    // }\n                    new.push(c);\n\n                    prev_end = pos + off_close + 1;\n                }\n                new.push_str(&value[prev_end..]);\n                value = new;\n            }\n\n            range = 1..value.len() - 1;\n\n            None\n        };\n\n        Ok(Self {\n            value,\n            rawness: StrRawness { is_raw, span },\n            inside_lit: range,\n            span,\n        })\n    }\n}\n\n#[derive(Debug, Copy, Clone)]\npub struct StrRawness {\n    is_raw: Option<u32>,\n    span: Span,\n}\n\nimpl PartialEq for StrRawness {\n    fn eq(&self, other: &Self) -> bool {\n        self.is_raw == other.is_raw\n    }\n}\n\nimpl StrRawness {\n    #[cfg(test)]\n    pub fn dummy() -> Self {\n        Self {\n            is_raw: Some(4),\n            span: Span::mixed_site(),\n        }\n    }\n\n    pub fn span(&self) -> Span {\n        self.span\n    }\n\n    /// Tokenizes a slice of the parsed string literal.\n    pub fn tokenize_sub(&self, str: &str) -> TokenStream2 {\n        let mut buffer = String::new();\n        match self.is_raw {\n            Some(hashes) => {\n                let hashes = hashes as usize;\n                buffer.reserve(3 + hashes + str.len() + hashes);\n                buffer.push('r');\n                let hashes = (0..hashes).map(|_| '#');\n                buffer.extend(hashes.clone());\n                buffer.push('\"');\n                buffer.push_str(str);\n                buffer.push('\"');\n                buffer.extend(hashes);\n            }\n            None => {\n                buffer.reserve(2 + str.len());\n                buffer.push('\"');\n                buffer.push_str(str);\n                buffer.push('\"');\n            }\n        }\n\n        buffer\n            .parse::<TokenStream2>()\n            .unwrap()\n            .set_span_recursive(self.span)\n    }\n}\n\n///////////////////////////////////////////////////////////////////////////////\n\npub trait TokenTreeExt: Sized {\n    fn as_token_tree(&self) -> &TokenTree2;\n    fn into_token_tree(self) -> TokenTree2;\n\n    fn is_punct(&self, c: char) -> bool {\n        matches!(self.as_token_tree(), TokenTree2::Punct(p)  if p.as_char() == c)\n    }\n\n    #[allow(dead_code)]\n    fn is_paren(&self) -> bool {\n        matches!(\n            self.as_token_tree(),\n            TokenTree2::Group(g) if g.delimiter() == Delimiter::Parenthesis\n        )\n    }\n\n    #[allow(dead_code)]\n    fn is_ident(&self, ident: &str) -> bool {\n        matches!(self.as_token_tree(), TokenTree2::Ident(x)  if x == ident)\n    }\n\n    fn set_span_recursive(self, span: Span) -> TokenTree2 {\n        let mut tt = self.into_token_tree();\n\n        tt.set_span(span);\n        if let TokenTree2::Group(group) = tt {\n            let delim = group.delimiter();\n            let stream = group.stream().set_span_recursive(span);\n            tt = TokenTree2::Group(Group::new(delim, stream));\n        }\n        tt.set_span(span);\n        tt\n    }\n}\n\nimpl TokenTreeExt for TokenTree2 {\n    fn as_token_tree(&self) -> &TokenTree2 {\n        self\n    }\n\n    fn into_token_tree(self) -> TokenTree2 {\n        self\n    }\n}\n\n///////////////////////////////////////////////////////////////////////////////\n\npub trait TokenStream2Ext: Sized {\n    fn into_token_stream(self) -> TokenStream2;\n\n    fn set_span_recursive(self, span: Span) -> TokenStream2 {\n        self.into_token_stream()\n            .into_iter()\n            .map(|tt| tt.set_span_recursive(span))\n            .collect()\n    }\n}\n\nimpl TokenStream2Ext for TokenStream2 {\n    fn into_token_stream(self) -> TokenStream2 {\n        self\n    }\n}\n\n///////////////////////////////////////////////////////////////////////////////\n\npub trait MyParse: Sized {\n    fn parse(input: ParseStream<'_>) -> Result<Self, crate::Error>;\n\n    fn parse_token_stream_1(input: proc_macro::TokenStream) -> Result<Self, crate::Error> {\n        Self::parse(&mut ParseBuffer::new(TokenStream2::from(input)))\n    }\n\n    #[allow(dead_code)]\n    fn parse_token_stream_2(input: TokenStream2) -> Result<Self, crate::Error> {\n        Self::parse(&mut ParseBuffer::new(input))\n    }\n}\n\n///////////////////////////////////////////////////////////////////////////////\n"
  },
  {
    "path": "const_format_proc_macros/src/respan_to_macro.rs",
    "content": "use crate::parse_utils::TokenTreeExt;\n\nuse proc_macro2::{Delimiter, Span, TokenStream as TokenStream2, TokenTree as TokenTree2};\n\nconst MSG: &str = \"Expected the macro to be called as `respan_to!((tokens) more tokens)`\";\n\nfn parse_paren(tt: TokenTree2) -> TokenStream2 {\n    match tt {\n        TokenTree2::Group(group) if group.delimiter() == Delimiter::Parenthesis => group.stream(),\n        _ => panic!(\"{}\", MSG),\n    }\n}\n\nfn get_span(ts: TokenStream2) -> Span {\n    let mut iter = ts.into_iter();\n\n    match iter.next() {\n        Some(TokenTree2::Group(group)) if group.delimiter() == Delimiter::None => {\n            get_span(group.stream())\n        }\n        Some(first_tt) => {\n            let mut span = first_tt.span();\n\n            for tt in iter {\n                span = span.join(tt.span()).unwrap_or(span);\n            }\n            span\n        }\n        None => Span::mixed_site(),\n    }\n}\n\npub(crate) fn implementation(ts: TokenStream2) -> TokenStream2 {\n    let mut iter = ts.into_iter();\n\n    let span_to = get_span(parse_paren(iter.next().expect(MSG)));\n\n    iter.map(|tt| tt.set_span_recursive(span_to)).collect()\n}\n"
  },
  {
    "path": "const_format_proc_macros/src/shared_arg_parsing.rs",
    "content": "//! Types for parsing arguments, shared by many of the macros\n\nuse crate::{\n    parse_utils::{MyParse, ParseBuffer, ParseStream},\n    spanned::Spans,\n};\n\nuse proc_macro2::TokenStream as TokenStream2;\n\nuse quote::ToTokens;\n\n////////////////////////////////////////////////\n\n// An expression inside `(...)`\npub(crate) struct ExprArg {\n    pub(crate) span: Spans,\n    /// Using a TokenStream2 because it is validated to be a valid expression in\n    /// the macro_rules! macros that call these proc macros.\n    pub(crate) expr: TokenStream2,\n}\n\nimpl ToTokens for ExprArg {\n    fn to_tokens(&self, ts: &mut TokenStream2) {\n        self.expr.to_tokens(ts);\n    }\n}\n\n/// A sequence of comma separated expressions wrapped in parentheses (with a trailing comma)\npub(crate) struct ExprArgs {\n    pub(crate) args: Vec<ExprArg>,\n}\n\n////////////////////////////////////////////////\n\nimpl MyParse for ExprArg {\n    fn parse(input: ParseStream<'_>) -> Result<Self, crate::Error> {\n        let paren = input.parse_paren()?;\n\n        let mut content = ParseBuffer::new(paren.contents);\n\n        content.parse_unwrap_tt(|content| {\n            let (expr, span) = content.parse_token_stream_and_span();\n\n            Ok(Self { span, expr })\n        })\n    }\n}\n\n////////////////////////////////////////////////\n\nimpl MyParse for ExprArgs {\n    fn parse(input: ParseStream<'_>) -> Result<Self, crate::Error> {\n        let mut args = Vec::new();\n\n        while !input.is_empty() {\n            args.push(ExprArg::parse(input)?);\n\n            if !input.is_empty() {\n                input.parse_punct(',')?;\n            }\n        }\n\n        Ok(Self { args })\n    }\n}\n"
  },
  {
    "path": "const_format_proc_macros/src/spanned.rs",
    "content": "use proc_macro2::Span;\n\n#[derive(Copy, Clone)]\npub struct Spans {\n    pub start: Span,\n    pub end: Span,\n}\n\nimpl Spans {\n    pub fn joined(self) -> Span {\n        self.start.join(self.end).unwrap_or(self.start)\n    }\n}\n"
  },
  {
    "path": "const_format_proc_macros/src/test_utils.rs",
    "content": "pub trait StrExt {\n    fn as_str(&self) -> &str;\n\n    /// Checks that these needles exist consequtively in self.\n    ///\n    /// Example: `\"hello world\".consecutive_in_set(&[\"he\", \"wor\"])` returns `true`.\n    /// Example: `\"hello world\".consecutive_in_set(&[\"wor\", \"he\"])` returns `false`.\n    fn consecutive_in_self(&self, needles: &[&str]) -> bool {\n        let mut rem = self.as_str();\n        for needle in needles {\n            rem = match rem.find(needle) {\n                Some(next) => &rem[next + needle.len()..],\n                None => return false,\n            };\n        }\n        true\n    }\n}\n\nimpl StrExt for str {\n    #[inline(always)]\n    fn as_str(&self) -> &str {\n        self\n    }\n}\n\nimpl StrExt for String {\n    #[inline(always)]\n    fn as_str(&self) -> &str {\n        self\n    }\n}\n"
  },
  {
    "path": "const_format_proc_macros/src/utils.rs",
    "content": "use proc_macro2::Span;\n\n#[cfg(feature = \"derive\")]\nuse quote::ToTokens;\n\nuse std::{\n    collections::VecDeque,\n    iter::Fuse,\n    mem,\n    ops::{Deref, DerefMut},\n};\n\npub(crate) fn dummy_ident() -> proc_macro2::Ident {\n    proc_macro2::Ident::new(\"__dummy__\", Span::mixed_site())\n}\n\n////////////////////////////////////////////////////////////////////////////////////\n\n#[cfg(feature = \"derive\")]\npub fn spanned_err(tokens: &dyn ToTokens, display: &dyn std::fmt::Display) -> crate::Error {\n    use syn::spanned::Spanned;\n    crate::Error::new(tokens.span(), display)\n}\n\n////////////////////////////////////////////////////////////////////////////////////\n\n#[derive(Clone, Debug)]\npub struct Peekable2<I: Iterator> {\n    iter: Fuse<I>,\n    queue: VecDeque<I::Item>,\n}\n\nimpl Peekable2<std::ops::Range<u8>> {\n    #[allow(clippy::new_ret_no_self)]\n    pub fn new<I: IntoIterator>(iter: I) -> Peekable2<I::IntoIter> {\n        Peekable2 {\n            iter: iter.into_iter().fuse(),\n            queue: VecDeque::new(),\n        }\n    }\n}\n\nimpl<I: Iterator> Peekable2<I> {\n    pub fn is_empty(&mut self) -> bool {\n        self.peek().is_none()\n    }\n\n    pub fn peek(&mut self) -> Option<&I::Item> {\n        if self.queue.is_empty() {\n            self.queue.push_back(self.iter.next()?);\n        }\n        Some(&self.queue[0])\n    }\n    pub fn peek2(&mut self) -> Option<&I::Item> {\n        while self.queue.len() < 2 {\n            self.queue.push_back(self.iter.next()?);\n        }\n        Some(&self.queue[1])\n    }\n}\n\nimpl<I> Iterator for Peekable2<I>\nwhere\n    I: Iterator,\n{\n    type Item = I::Item;\n\n    fn next(&mut self) -> Option<I::Item> {\n        if let opt @ Some(_) = self.queue.pop_front() {\n            opt\n        } else {\n            self.iter.next()\n        }\n    }\n\n    fn size_hint(&self) -> (usize, Option<usize>) {\n        let (low, high) = self.iter.size_hint();\n        let len = self.queue.len();\n        (low + len, high.map(|x| x.saturating_add(len)))\n    }\n}\n\n////////////////////////////////////////////////////////////////////////////////////\n\n/// A result wrapper which panics if it's the error variant is not handled,\n/// by calling `.into_result()`.\n#[derive(Debug, Clone)]\npub struct LinearResult {\n    errors: Result<(), crate::Error>,\n}\n\nimpl Drop for LinearResult {\n    fn drop(&mut self) {\n        mem::replace(&mut self.errors, Ok(())).expect(\"Expected LinearResult to be handled\");\n    }\n}\n\nimpl LinearResult {\n    #[inline]\n    pub fn new(res: Result<(), crate::Error>) -> Self {\n        Self { errors: res }\n    }\n\n    #[inline]\n    pub fn ok() -> Self {\n        Self::new(Ok(()))\n    }\n}\n\nimpl From<Result<(), crate::Error>> for LinearResult {\n    #[inline]\n    fn from(res: Result<(), crate::Error>) -> Self {\n        Self::new(res)\n    }\n}\n\nimpl Deref for LinearResult {\n    type Target = Result<(), crate::Error>;\n\n    fn deref(&self) -> &Result<(), crate::Error> {\n        &self.errors\n    }\n}\n\nimpl DerefMut for LinearResult {\n    fn deref_mut(&mut self) -> &mut Result<(), crate::Error> {\n        &mut self.errors\n    }\n}\n\n#[allow(dead_code)]\nimpl LinearResult {\n    #[inline]\n    pub fn into_result(mut self) -> Result<(), crate::Error> {\n        mem::replace(&mut self.errors, Ok(()))\n    }\n\n    #[inline]\n    pub fn take(&mut self) -> Result<(), crate::Error> {\n        self.replace(Ok(()))\n    }\n\n    #[inline]\n    pub fn replace(&mut self, other: Result<(), crate::Error>) -> Result<(), crate::Error> {\n        mem::replace(&mut self.errors, other)\n    }\n\n    #[inline]\n    pub fn push_err<E>(&mut self, err: E)\n    where\n        E: Into<crate::Error>,\n    {\n        let err = err.into();\n        match &mut self.errors {\n            this @ Ok(_) => *this = Err(err),\n            Err(e) => e.combine(err),\n        }\n    }\n\n    #[inline]\n    pub fn combine_err<E>(&mut self, res: Result<(), E>)\n    where\n        E: Into<crate::Error>,\n    {\n        if let Err(err) = res {\n            let err = err.into();\n            self.push_err(err);\n        }\n    }\n}\n"
  },
  {
    "path": "print_errors/Cargo.toml",
    "content": "[package]\nname = \"print_errors\"\nversion = \"0.1.0\"\nauthors = [\"rodrimati1992 <rodrimatt1985@gmail.com>\"]\nedition = \"2018\"\n\n[dependencies.cfmt]\npath = \"../const_format/\"\npackage = \"const_format\"\nfeatures = [\"assertc\"]"
  },
  {
    "path": "print_errors/src/formatc_macros.rs",
    "content": "use cfmt::formatcp;\n\nuse cfmt::formatc;\n\nconst _: &str = formatcp!(\"{}\");\n\nconst _: &str = formatcp!(\"{}\", foo = \"\", 100u8 + 0);\n\nconst _: &str = formatcp!(\"{}\", 0 + 0);\n\nconst _: &str = formatcp!(\"{}\", 0u8, 0u8 + 1);\n\nconst _: &str = formatcp!(\"{}\", |fmt| 0 + 0);\n\nconst _: () = {\n    const _: &str = formatc!(\"{}\");\n\n    const _: &str = formatc!(\"{}\", foo = \"\", 100u8 + 0);\n\n    const _: &str = formatc!(\"{}\", 0 + 0);\n\n    const _: &str = formatc!(\"{}\", {\n        let a = 0;\n        let b = 0;\n        a + b\n    });\n};\n"
  },
  {
    "path": "print_errors/src/lib.rs",
    "content": "#![allow(unused_imports)]\n\nmod formatc_macros;\n\nconst _: &str = cfmt::concatcp!(0, 1, ());\n\nconst _: &str = cfmt::concatc!(0, 1, ());\n\nmod using_assertc_macros;\n\nmod using_writec_macro;\n"
  },
  {
    "path": "print_errors/src/using_assertc_macros.rs",
    "content": "use cfmt::{assertc, assertc_eq, assertc_ne};\n\n// uninferred argument\nassertc!(false, \"{}\", 0);\n\nassertc!(true, \"{}\");\n\nassertc!(true, \"{}\", foo = \"\", 100u8);\n\nassertc_eq!(0u8, [0u8][10]);\n\nassertc_eq!(0, 0, \"{}\", 0u8);\n\nassertc_eq!((), (), \"{}\");\n\nassertc_eq!((), (), \"{}\", foo = \"\", 100u8);\n\nassertc_eq!(0u8, 1u8, \"{}\", 0);\n\nassertc_eq!(0u8, 1u8, \"{}\", 0u8);\n\nassertc!(2 + 2 == 5, \"{}\", 0u8);\n"
  },
  {
    "path": "print_errors/src/using_writec_macro.rs",
    "content": "use cfmt::{writec, StrWriter};\n\nfn using_writec(writer: &mut StrWriter) -> cfmt::Result {\n    // Trying to write to a non-writer\n    writec!((), \"\")?;\n\n    writec!(writer, \"{}\")?;\n\n    writec!(writer, \"{}\", foo = \"\", 100u8)?;\n\n    // trying to write an uninferred integer type\n    writec!(writer, \"{}\", 0)?;\n\n    let a = 0;\n    writec!(writer, \"{}\", a)?;\n    writec!(writer, \"{b}\", b = a)?;\n    writec!(writer, \"{a}\")?;\n    writec!(writer, \"{a:?}\")?;\n\n    Ok(())\n}\n"
  },
  {
    "path": "print_warnings/Cargo.toml",
    "content": "[package]\nname = \"print_warnings\"\nversion = \"0.1.0\"\nauthors = [\"rodrimati1992 <rodrimatt1985@gmail.com>\"]\nedition = \"2018\"\n\n[dependencies.const_format]\npath = \"../const_format/\"\nfeatures = [\"assertc\", \"assertcp\", \"rust_1_64\"]"
  },
  {
    "path": "print_warnings/src/main.rs",
    "content": "#![deny(non_camel_case_types)]\n\nuse const_format::{assertcp, concatcp, formatcp};\n\npub mod rust_1_83 {\n    use const_format::{\n        assertc, assertc_eq, assertc_ne, concatc, for_examples::Unit, formatc, writec, StrWriter,\n        StrWriterMut,\n    };\n\n    pub const TWO: u32 = 2;\n    pub const TEN: u32 = 10;\n\n    assertc!(TWO != TEN, \"{} != {}\", TWO, TEN);\n    assertc_eq!(TWO, TWO);\n    assertc_ne!(TWO, TEN);\n\n    pub const CONCATC_A: &str = concatc!(\"hello\", \"world\");\n    pub const CONCATC_B: &str = concatc!(10u8, TWO);\n\n    pub const FORMATC_A: &str = formatc!(\"{}hello{}{:?}\", \"foo\", 100u8, Unit);\n\n    const fn as_str_ctor() -> StrWriter<[u8; 100]> {\n        let mut writer = StrWriter::new([0; 100]);\n\n        let _ = writec!(writer, \"{:#?}\", Unit);\n        {\n            let mut writer = StrWriterMut::new(&mut writer);\n\n            let _ = writec!(writer, \"{0}{0:?}\", 100u8);\n        }\n        writer\n    }\n\n    pub const __AS_STR: &StrWriter = &as_str_ctor();\n    pub const AS_STR: &str = __AS_STR.as_str();\n}\n\npub const CONCATCP_A: &str = concatcp!(\"hello\", \"world\");\npub const CONCATCP_B: &str = concatcp!(10u8, 20u8);\n\npub const FORMATCP_A: &str = formatcp!(\"{}hello{:x?}\", \"foo\", 100u8);\n\nassertcp! {1 == 1, \"what the {}\", \"F\"}\n\nfn main() {}\n"
  }
]