master 6bcde171f0a9 cached
121 files
611.2 KB
167.5k tokens
837 symbols
1 requests
Download .txt
Showing preview only (650K chars total). Download the full file or copy to clipboard to get everything.
Repository: rodrimati1992/const_format_crates
Branch: master
Commit: 6bcde171f0a9
Files: 121
Total size: 611.2 KB

Directory structure:
gitextract_3exoboco/

├── .github/
│   └── workflows/
│       └── rust.yml
├── .gitignore
├── Cargo.toml
├── Changelog.md
├── LICENSE-ZLIB.md
├── README.md
├── commit.sh
├── const_format/
│   ├── Cargo.toml
│   ├── LICENSE-ZLIB.md
│   ├── src/
│   │   ├── __ascii_case_conv/
│   │   │   └── word_iterator.rs
│   │   ├── __ascii_case_conv.rs
│   │   ├── __hidden_utils.rs
│   │   ├── __str_methods/
│   │   │   ├── pattern.rs
│   │   │   ├── str_indexing.rs
│   │   │   ├── str_repeat.rs
│   │   │   ├── str_replace.rs
│   │   │   ├── str_splice.rs
│   │   │   └── str_split.rs
│   │   ├── __str_methods.rs
│   │   ├── char_encoding/
│   │   │   └── tests.rs
│   │   ├── char_encoding.rs
│   │   ├── const_debug_derive.rs
│   │   ├── const_generic_concatcp.rs
│   │   ├── doctests.rs
│   │   ├── equality.rs
│   │   ├── fmt/
│   │   │   ├── error.rs
│   │   │   ├── formatter.rs
│   │   │   ├── std_type_impls/
│   │   │   │   └── ranges.rs
│   │   │   ├── std_type_impls.rs
│   │   │   ├── str_writer.rs
│   │   │   └── str_writer_mut.rs
│   │   ├── fmt.rs
│   │   ├── for_assert_macros.rs
│   │   ├── for_examples.rs
│   │   ├── formatting.rs
│   │   ├── lib.rs
│   │   ├── macros/
│   │   │   ├── assertions/
│   │   │   │   ├── assertc_macros.rs
│   │   │   │   └── assertcp_macros.rs
│   │   │   ├── assertions.rs
│   │   │   ├── call_debug_fmt.rs
│   │   │   ├── constructors.rs
│   │   │   ├── fmt_macros.rs
│   │   │   ├── helper_macros.rs
│   │   │   ├── impl_fmt.rs
│   │   │   ├── map_ascii_case.rs
│   │   │   └── str_methods.rs
│   │   ├── macros.rs
│   │   ├── marker_traits/
│   │   │   ├── format_marker.rs
│   │   │   └── write_marker.rs
│   │   ├── marker_traits.rs
│   │   ├── msg.rs
│   │   ├── pargument.rs
│   │   ├── slice_cmp.rs
│   │   ├── test_utils.rs
│   │   ├── utils.rs
│   │   ├── wrapper_types/
│   │   │   ├── ascii_str.rs
│   │   │   ├── pwrapper/
│   │   │   │   └── tests.rs
│   │   │   ├── pwrapper.rs
│   │   │   └── sliced.rs
│   │   └── wrapper_types.rs
│   └── tests/
│       ├── fmt_tests/
│       │   ├── display_formatting.rs
│       │   ├── formatted_writing.rs
│       │   ├── formatter_methods/
│       │   │   └── debug_methods.rs
│       │   ├── formatter_methods.rs
│       │   ├── std_impl_tests.rs
│       │   ├── str_writer_methods.rs
│       │   └── str_writer_mut.rs
│       ├── fmt_tests_modules.rs
│       ├── misc_tests/
│       │   ├── assertc_tests.rs
│       │   ├── assertcp_tests.rs
│       │   ├── call_debug_fmt_macro.rs
│       │   ├── clippy_warnings.rs
│       │   ├── concatc_macro_tests.rs
│       │   ├── derive_tests/
│       │   │   └── is_a_attributes.rs
│       │   ├── derive_tests.rs
│       │   ├── equality_tests.rs
│       │   ├── formatc_macros.rs
│       │   ├── impl_fmt_macro_tests.rs
│       │   ├── inline_const_pattern_tests.rs
│       │   ├── shared_cp_macro_tests.rs
│       │   ├── type_kind_coercion_macro_tests.rs
│       │   └── writec_macro.rs
│       ├── misc_tests_modules.rs
│       ├── str_methods.rs
│       └── str_methods_modules/
│           ├── conv_ascii_case.rs
│           ├── str_replace.rs
│           ├── str_splice.rs
│           └── str_split_tests.rs
├── const_format_proc_macros/
│   ├── Cargo.toml
│   ├── LICENSE-ZLIB.md
│   └── src/
│       ├── datastructure/
│       │   └── field_map.rs
│       ├── datastructure.rs
│       ├── derive_debug/
│       │   ├── attribute_parsing.rs
│       │   ├── syntax.rs
│       │   └── type_detection.rs
│       ├── derive_debug.rs
│       ├── error.rs
│       ├── format_args/
│       │   └── parsing.rs
│       ├── format_args.rs
│       ├── format_macro/
│       │   └── tests.rs
│       ├── format_macro.rs
│       ├── format_str/
│       │   ├── errors.rs
│       │   ├── parsing.rs
│       │   └── tests.rs
│       ├── format_str.rs
│       ├── formatting.rs
│       ├── lib.rs
│       ├── macros.rs
│       ├── parse_utils.rs
│       ├── respan_to_macro.rs
│       ├── shared_arg_parsing.rs
│       ├── spanned.rs
│       ├── test_utils.rs
│       └── utils.rs
├── print_errors/
│   ├── Cargo.toml
│   └── src/
│       ├── formatc_macros.rs
│       ├── lib.rs
│       ├── using_assertc_macros.rs
│       └── using_writec_macro.rs
└── print_warnings/
    ├── Cargo.toml
    └── src/
        └── main.rs

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/workflows/rust.yml
================================================
name: Rust

on: 
  push:
  pull_request:
  schedule:
    - cron: '0 0 1 * *'

env:
  CARGO_TERM_COLOR: always

jobs:
  build:
    runs-on: ubuntu-latest

    strategy:
      max-parallel: 2
      matrix:
        rust: [stable, beta, nightly, 1.71.0, 1.83.0]

    steps:
    - uses: actions/checkout@v2
    - name: ci-all-versions
      run: |
        rustup override set ${{ matrix.rust }}
        cargo update
          
        cd "${{github.workspace}}/const_format_proc_macros/"
        cargo test

        cd "${{github.workspace}}/const_format/"
        cargo test --features "__test"

        cargo test --features "__test assertcp"

    - uses: actions/checkout@v2
    - name: ci-non-msrv
      if: ${{ matrix.rust != '1.71.0' }}
      run: |
        rustup override set ${{ matrix.rust }}

        cargo update

        cd "${{github.workspace}}/const_format/"
        
        cargo test --features "__test"
        cargo test --features "__test more_str_macros"
        cargo test --features "__test assertcp"
        cargo test --features "__test fmt"
        cargo test --features "__test assertc"
        cargo test --features "__test derive"
        cargo test --features "__test constant_time_as_str"
        cargo test --features "__test rust_1_83"
        cargo test --features "__test derive constant_time_as_str"
        cargo test --features "__test derive constant_time_as_str assertc"
        cargo test --features "__test derive constant_time_as_str assertc more_str_macros rust_1_83"

    - uses: actions/checkout@v2
    - name: ci-nighly
      if: ${{ matrix.rust == 'nightly' && runner.os == 'Linux' }}
      run: |
        rustup override set ${{ matrix.rust }}

        cargo update -Z minimal-versions
        
        cd "${{github.workspace}}/const_format_proc_macros/"
        cargo test

        cd "${{github.workspace}}/const_format/"

        # enable `__inline_const_pat_tests` feature if `const {...}` pats are allowed
        cargo test --features "__test derive constant_time_as_str assertc more_str_macros rust_1_83"

        MIRI_NIGHTLY=nightly-$(curl -s https://rust-lang.github.io/rustup-components-history/x86_64-unknown-linux-gnu/miri)
        MIRIFLAGS="-Zmiri-strict-provenance -Zmiri-check-number-validity -Zmiri-symbolic-alignment-check"
        echo "Installing latest nightly with Miri"
        echo "$MIRI_NIGHTLY"
        rustup set profile minimal
        rustup default "$MIRI_NIGHTLY"
        rustup override set "$MIRI_NIGHTLY"
        rustup component add miri
        cargo miri setup

        cargo clean 

        # tests the crate without the constant_time_as_str feature 
        # (and also without any feature that implies it)
        cargo miri test --tests --features "__test derive fmt assertc"
        
        # tests the crate with every feature, including constant_time_as_str 
        # enable `__inline_const_pat_tests` feature if `const {...}` pats are allowed
        cargo miri test \
        --features "__test derive constant_time_as_str assertc more_str_macros rust_1_83"


================================================
FILE: .gitignore
================================================
/target
**/*.rs.bk
**/*.7z
Cargo.lock
__ignored__*

================================================
FILE: Cargo.toml
================================================
[workspace]
members=[
    "const_format",
    "const_format_proc_macros",
    "print_errors",
    "print_warnings",
]
resolver = "2"

================================================
FILE: Changelog.md
================================================
This is the changelog,summarising changes in each version(some minor changes may be ommited).

# 0.2 

### 0.2.36

Breaking change: bumped Minimum Supported Rust Version to Rust 1.71. This change is motivated by `quote` increasing its MSRV to 1.71.

Now the `"rust_1_64"` feature is effectively always enabled, so these items are always enabled:
- `const_format::str_split`

Deprecated these items because their replacements now take constant time to run:
- `const_format::fmt::StrWriter::as_bytes_alt`: superceeded by `as_bytes`
- `const_format::fmt::StrWriter::as_str_alt`: superceeded by `as_str`
- `const_format::fmt::StrWriterMut::as_bytes_alt`: superceeded by `as_bytes`
- `const_format::fmt::StrWriterMut::as_str_alt`: superceeded by `as_str`
- `const_format::utils::slice_up_to_len_alt`: superceeded by `slice_up_to_len`

Changed these methods from being conditionally const (by requiring the `"rust_1_64"` feature to be const) to being unconditionally const:
- `const_format::fmt::StrWriter::as_bytes`
- `const_format::fmt::StrWriter::as_str`
- `const_format::fmt::StrWriterMut::as_bytes`
- `const_format::fmt::StrWriterMut::as_str`

Changed this method to be `const`:
- `const_format::AsciiStr::as_str`

Fixed nightly 2026-04-09 compatibility when `cargo update -Z minimal-versions` is used by bumping `konst` internal dependency to `"0.2.20"` version

### 0.2.35

Breaking change: bumped Minimum Supported Rust Version to Rust 1.60. This change is motivated by `quote` increasing its MSRV to 1.60.

### 0.2.34

Now all features that used to require nightly only require Rust 1.83.0

Added `"rust_1_83"` feature that enables `"rust_1_64"` feature

Changed `"fmt"` feature to enable `"rust_1_83"` feature

Made many macros forward compatible with inline const patterns(when the `"rust_1_83"` feature is enabled):
- `concatc`
- `concatcp`
- `formatc`
- `formatcp`
- `map_ascii_case`
- `str_get`
- `str_index`
- `str_repeat`
- `str_replace`

Added these macros:
- `str_splice_out`
- `str_split_alt`

### 0.2.33

Fixed Rust Analyzer style warning for assertion macros.

### 0.2.32

Breaking 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.

Changed these items that needed the `"rust_1_51"` feature into always being enabled:
- `map_ascii_case`
- `str_replace`

### 0.2.31

Added a workaround for rustdoc bug (https://github.com/rust-lang/rust/issues/112085).

### 0.2.29

Added lowercase hexadecimal formatting support.
    
Breaking: to add lowercase hexadecimal formatting, this crate changed the uppercase hexadecimal formatter from `{:x}` to `{:X}`


### 0.2.27

Replacing existing features with these:
- `"rust_1_64"`: superceeding the soft-deprecated `"more_str_macros"` feature.
- `"rust_1_51"`: superceeding the soft-deprecated `"const_generics"` feature.
The new features are enabled by the feature they superceede.

Now the `"fmt"` feature enables the `"rust_1_64"` feature.

### 0.2.26 

Added `"more_str_macros"` crate feature.

Added `str_split` macro, conditional on the `"more_str_macros"` feature.

Added `char` pattern support to `str_replace`.

### 0.2.25

Fixed the `clippy::double_parens` (false positive) warning by 
encoding the `&'static str` type annotation some other way.

Made `SplicedStr`, `Formatting`, and `NumberFormatting` derive `Eq` .

### 0.2.24

Fixed error that caused formatting macros not to be usable in statement position.

### 0.2.23

Added type annotations to `concatp`, `concatcp`, `formatc` and `formatcp` macros to help IDEs infer the type.

### 0.2.22


Added the `assertcp`, `assertcp_ne`, and `assertcp_eq` macros under the "assertcp"  feature.

Added `const_eq` methods for `PWrapper<&[char]>` and `PWrapper<Option<char>>`

Added the "assertcp" feature, which enables the `assertcp*` macros.

Aliased "assert" crate feature to "assertc", and removed old name from docs to reduce confusion.

### 0.2.21

Rewrote assertion macros to:
- Have more concise error messages
- Point to all their arguments when the assertion fails
- Resemble std error messages more

### 0.2.19

Added `char` support to all formatting macros.

Added `char`, `&[char]`, and `Option<char>` impls of FormatMarker trait, with debug formatting methods.

Added `Formatter::{write_char, write_char_debug}` methods.

Added `StrWriterMut::{as_str_alt, write_char, write_char_debug}` methods.

Added `StrWriter::{as_str_alt, unsize}` methods.

Deprecated `strwriter_as_str` macro, superceded by `StrWriter::as_str_alt`.

Bumped the minimum required nightly version to 2021-07-05 due to use of const-stabilized `core::str::from_utf8_unchecked`.

### 0.2.18

Fixed potential soundness bug where unions used to do pointer casts were not `#[repr(C)]`

### 0.2.16

Added these macros that act like `str` methods:
- `str_get`
- `str_index`
- `str_repeat`
- `str_replace`
- `str_splice`

Added the `SplicedStr` struct.

### 0.2.15

Added `map_ascii_case` macro to convert the casing style of a `&'static str`.

Added the `Case` enum.

Fixed "constant_time_as_str" crate feature in newer nightlies,
this will break code that uses the feature and hasn't updated the nightly compiler
to a release post mid-july 2021.

### 0.2.14

Fixed a few documentation issues.

Made 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.

Repurposed the "const_generics" feature to generate less code in the `concatcp` and `formatcp` macros,
by moving some of their implementation to a function that uses const generics.

### 0.2.13

Fixed 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.

### 0.2.11

Fixed the documentation in case that the https://github.com/rust-lang/rust/pull/80243 
rustc pull request is merged.

### 0.2.8

Added minimal const generic support, for use in the added methods.

Added these methods to `StrWriter<[u8; N]>`:
- `r`: for casting it to a `StrWriter<[u8]>`
- `as_mut`: for casting it to a `StrWriterMut`.

Added "const_generics" and "nightly_const_generics" features.

Fixed hygiene bug in assertion macros.

Bumped version number to 0.2.8 .

### 0.2.6

Made the macros in `const_format` usable when the crate is renamed.

Added a `#[cdeb(crate = "foo")]` helper attribute to
pass the path to `const_format` to `ConstDebug`, useful when reexporting the derive macro.

Documented that `writec!(buff, "{foo}")` (where `foo` is a local variable) works,
and is equivelent to `writec!(buff, "{}", foo)`.

### 0.2.5

Added the "assert" cargo feature,
defining the `assertc`/`assertc_eq`/`assertc_ne` macros for 
compile-time assertions with formatting.

Added custom formatting support in the `const_format::fmt`-based formatting macros,
by prefixing any argument with `|identifier|`,
accessing a `Formatter` to format that argument however one wants.

Added `concatc` macro for concatenating std/user-defined types into a `&'static str` constant.

Added `const_format::Result` alias for `std::result::Result<(), const_format::Error>`.

Added `const_format::fmt::ToResult` type for converting  
`()` and `const_format::Result` to `const_format::Result`.

Added `Pwrapper::const_eq` methods for comparing many std types in 
the `assertc_eq`/`assertc_ne` macros.

Added `Pwrapper::const_display_fmt` methods for `NonZero*` types.

Added support for passing `concat!(....)` as the format string.

### 0.2.0

Every single new item added requires Rust nightly to use, with at least the "fmt" cargo feature enabled.

Defined a `core::fmt`-like API with these these types:
`ComputeStrLength`, `DebugList`, `DebugSet`, `DebugStruct`, `DebugTuple`, `Error`, `Formatter`, `FormattingFlags`, `NumberFormatting`, `StrWriter`, `StrWriterMut`, `NoEncoding`, `Utf8Encoding`.

Added `formatc` macro, for formatting std and user-defined types into a `&'static str` constant.

Added `writec` macro, for writing formatted std and user-defined types, 
into a type that implements `WriteMarker`.

Added `marker_traits::FormatMarker` trait, for types that implement const formatting,
with either the `const_debug_fmt`, or `const_display_fmt` inherent methods.

Added `ConstDebug` derive macro, for implementing `FormatMarker`,
and implement the `const_debug_fmt` inherent method.

Added `marker_traits::WriteMarker` trait, for types that can be written into,
defining the `borrow_mutably` and `make_formatter` methods.

Added these type in `marker_traits` module: `IsAFormatMarker`, `IsAStrWriter`, `IsAWriteMarker`, 
`IsArrayKind`, `IsNotAStrWriter`, `IsNotStdKind`, `IsStdKind`

Added hexadecimal and binary formatting to the `formatcp` macro
(also usable in `formatc`, and `writec`)

Defined the `AsciiStr` type, a wrapper type for `&[u8]` slices which are valid ascii,
with an `ascii_str` macro for constructing it at compile-time,
and `wrapper_types::NotAsciiError` returned by the fallible constructor.

Exposed the `PWrapper` type, wrapper for std types to call some methods on them.

Defined the `Sliced` type, to output a slice from a `&str`.

Defined these macros for implementing/doing compile-time formatting:
`call_debug_fmt`, `coerce_to_fmt`, `impl_fmt`

Defined the `strwriter_as_str` macro to cast a `&'static StrWriter` to a `&'static str`

Defined these error handling macros: `try_`, `unwrap`, `unwrap_or_else`

Defined the `for_examples` module with examples of types that implement const formatting.

Defined these utility functions in the `utils` module: 
`slice_up_to_len`, `slice_up_to_len_alt`, `str_eq u8`, `slice_eq `

Fixed error reporting in `formatcp` and `concatcp` macros,
now compiler errors point at the argument that caused an error rather than the whole macro invocation.

Added the "fmt" cargo feature, to enable the `fmt`-like API, and every other thing that depends on it.

Added the "derive" cargo feature, to enable the `ConstDebug` macro.

Added the "constant_time_as_str", to optimize some methods, requires additional nightly features.

Made `syn` an optional dependency, only enabled when the "derive" feature is used.

Added `unicode-xid` dependency.

# 0.1

Created `const_format` crate,
`const_format_proc_macros` crate(implementation detail of `const_format`)

Defined the concatcp macro,
for concatenating constants of primitive types into a `&'static str` constant.

Defined the formatcp macro,
for formatting constants of primitive types into a `&'static str` constant.

Added dependencies: syn with none of the expensive features, quote, proc_macro2



================================================
FILE: LICENSE-ZLIB.md
================================================
Copyright (c) 2020 Matias Rodriguez.

This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.

Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:

1. The origin of this software must not be misrepresented; you must not
   claim that you wrote the original software. If you use this software
   in a product, an acknowledgment in the product documentation would be
   appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
   misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.

================================================
FILE: README.md
================================================


[![Rust](https://github.com/rodrimati1992/const_format_crates/workflows/Rust/badge.svg)](https://github.com/rodrimati1992/const_format_crates/actions)
[![crates-io](https://img.shields.io/crates/v/const_format.svg)](https://crates.io/crates/const_format)
[![api-docs](https://docs.rs/const_format/badge.svg)](https://docs.rs/const_format/*)


Compile-time string formatting.

This crate provides types and macros for formatting strings at compile-time.

# Rust versions

There are some features that require a variety of Rust versions,
the sections below describe the features that are available for each version.

### Rust 1.71.0

These macros are available in Rust 1.71.0:

- [`concatcp`]:
Concatenates `integers`, `bool`, `char`, and `&str` constants into a `&'static str` constant.

- [`formatcp`]:
[`format`]-like formatting which takes `integers`, `bool`, `char`, and `&str` constants,
and emits a `&'static str` constant.

- [`str_get`]:
Indexes a `&'static str` constant, returning `None` when the index is out of bounds.

- [`str_index`]:
Indexes a `&'static str` constant.

- [`str_repeat`]:
Creates a `&'static str` by repeating a `&'static str` constant `times` times.

- [`str_splice`]:
Replaces a substring in a `&'static str` constant.

- [`map_ascii_case`]:
Converts a `&'static str` constant to a different casing style,
determined by a [`Case`] argument.

- [`str_replace`]:
Replaces all the instances of a pattern in a `&'static str` constant with
another `&'static str` constant.

-  [`str_split`]: 
Splits a string constant


The `"assertcp"` feature enables the [`assertcp`], [`assertcp_eq`],
and [`assertcp_ne`] macros.
These macros are like the standard library assert macros,
but evaluated at compile-time,
with the limitation that they can only have primitive types as arguments
(just like [`concatcp`] and [`formatcp`]).

### Rust 1.83.0

By enabling the "fmt" feature, you can use a [`std::fmt`]-like API.

This requires Rust 1.83.0, because it uses mutable references in const fn.

All the other features of this crate are implemented on top of the [`const_format::fmt`] API:

- [`concatc`]:
Concatenates many standard library and user defined types into a `&'static str` constant.

- [`formatc`]:
[`format`]-like macro that can format many standard library and user defined types into
a `&'static str` constant.

- [`writec`]:
[`write`]-like macro that can format many standard library and user defined types
into a type that implements [`WriteMarker`].

The `"derive"` feature enables the [`ConstDebug`] macro,
and the `"fmt"` feature.<br>
[`ConstDebug`] derives the [`FormatMarker`] trait,
and implements an inherent `const_debug_fmt` method for compile-time debug formatting.

The `"assertc"` feature enables the [`assertc`], [`assertc_eq`], [`assertc_ne`] macros,
and the `"fmt"` feature.<br>
These macros are like the standard library assert macros, but evaluated at compile-time.

# Examples

### Concatenation of primitive types

```rust
use const_format::concatcp;

const NAME: &str = "Bob";
const FOO: &str = concatcp!(NAME, ", age ", 21u8,"!");

assert_eq!(FOO, "Bob, age 21!");
```

### Formatting primitive types

```rust
use const_format::formatcp;

const NAME: &str = "John";

const FOO: &str = formatcp!("{NAME}, age {}!", compute_age(NAME));

assert_eq!(FOO, "John, age 24!");

const fn compute_age(s: &str) -> usize { s.len() * 6 }
```

### Formatting custom types

This example demonstrates how you can use the [`ConstDebug`] derive macro,
and then format the type into a `&'static str` constant.

This example requires Rust 1.83.0, and the `"derive"` feature.

```rust
use const_format::{ConstDebug, formatc};

#[derive(ConstDebug)]
struct Message{
    ip: [Octet; 4],
    value: &'static str,
}

#[derive(ConstDebug)]
struct Octet(u8);

const MSG: Message = Message{
    ip: [Octet(127), Octet(0), Octet(0), Octet(1)],
    value: "Hello, World!",
};

const FOO: &str = formatc!("{:?}", MSG);

assert_eq!(
    FOO,
    "Message { ip: [Octet(127), Octet(0), Octet(0), Octet(1)], value: \"Hello, World!\" }"
);

```

### Formatted const assertions

This example demonstrates how you can use the [`assertcp_ne`] macro to
do compile-time inequality assertions with formatted error messages.

This requires the `"assertcp"` feature.

```rust, compile_fail
use const_format::assertcp_ne;

macro_rules! check_valid_pizza{
    ($user:expr, $topping:expr) => {
        assertcp_ne!(
            $topping,
            "pineapple",
            "You can't put pineapple on pizza, {}",
            $user,
        );
    }
}

check_valid_pizza!("John", "salami");
check_valid_pizza!("Dave", "sausage");
check_valid_pizza!("Bob", "pineapple");

```

This is the compiler output:

```text
error[E0080]: evaluation of constant value failed
  --> src/lib.rs:178:27
   |
20 | check_valid_pizza!("Bob", "pineapple");
   |                           ^^^^^^^^^^^ the evaluated program panicked at '
assertion failed: `(left != right)`
 left: `"pineapple"`
right: `"pineapple"`
You can't put pineapple on pizza, Bob
', src/lib.rs:20:27


```

<div id="macro-limitations"></div>

# Limitations

All of the macros from `const_format` have these limitations:

- The formatting macros that expand to
`&'static str`s can only use constants from concrete types,
so while a `Type::<u8>::FOO` argument would be fine,
`Type::<T>::FOO` would not be (`T` being a type parameter).

- Integer arguments must have a type inferrable from context,
[more details in the Integer arguments section](#integer-args).

- They cannot be used places that take string literals.
So `#[doc = "foobar"]` cannot be replaced with `#[doc = concatcp!("foo", "bar") ]`.

<span id="integer-args"></span>

### Integer arguments

Integer arguments must have a type inferrable from context.
so if you only pass an integer literal it must have a suffix.

Example of what does compile:

```rust
const N: u32 = 1;
assert_eq!(const_format::concatcp!(N + 1, 2 + N), "23");

assert_eq!(const_format::concatcp!(2u32, 2 + 1u8, 3u8 + 1), "234");
```

Example of what does not compile:
```rust,compile_fail
assert_eq!(const_format::concatcp!(1 + 1, 2 + 1), "23");
```
# Plans

None right now.

# Renaming crate

All function-like macros from `const_format` can be used when the crate is renamed.

The [`ConstDebug`] derive macro has the `#[cdeb(crate = "foo::bar")]` attribute to
tell it where to find the `const_format` crate.

Example of renaming the `const_format` crate in the Cargo.toml file:
```toml
[dependencies]
cfmt = {version = "0.*", package = "const_format"}
```

# Cargo features

- `"fmt"`: Enables the [`std::fmt`]-like API and `"rust_1_83"` feature,
requires Rust 1.83.0 because it uses mutable references in const fn.<br>
This feature includes the [`formatc`]/[`writec`] formatting macros.

- `"derive"`: requires Rust 1.83.0, implies the `"fmt"` feature,
provides the [`ConstDebug`] derive macro to format user-defined types at compile-time.<br>
This implicitly uses the `syn` crate, so clean compiles take a bit longer than without the feature.

- `"assertc"`: requires Rust 1.83.0, implies the `"fmt"` feature,
enables the [`assertc`], [`assertc_eq`], and [`assertc_ne`] assertion macros.<br>
This feature was previously named `"assert"`,
but it was renamed to avoid confusion with the `"assertcp"` feature.

- `"assertcp"`:
Enables the [`assertcp`], [`assertcp_eq`], and [`assertcp_ne`] assertion macros.

- `"rust_1_83"`: 
Makes macros that evaluate to a value become compatible with [inline const patterns].

# No-std support

`const_format` is unconditionally `#![no_std]`, it can be used anywhere Rust can be used.

# Minimum Supported Rust Version

`const_format` requires Rust 1.71.0.

Features that require newer versions of Rust, or the nightly compiler,
need to be explicitly enabled with cargo features.

[`assertc`]: https://docs.rs/const_format/0.2.*/const_format/macro.assertc.html

[`assertc_eq`]: https://docs.rs/const_format/0.2.*/const_format/macro.assertc_eq.html

[`assertc_ne`]: https://docs.rs/const_format/0.2.*/const_format/macro.assertc_ne.html

[`assertcp`]: https://docs.rs/const_format/0.2.*/const_format/macro.assertcp.html

[`assertcp_eq`]: https://docs.rs/const_format/0.2.*/const_format/macro.assertcp_eq.html

[`assertcp_ne`]: https://docs.rs/const_format/0.2.*/const_format/macro.assertcp_ne.html

[`concatcp`]: https://docs.rs/const_format/0.2.*/const_format/macro.concatcp.html

[`formatcp`]: https://docs.rs/const_format/0.2.*/const_format/macro.formatcp.html

[`format`]: https://doc.rust-lang.org/std/macro.format.html

[`std::fmt`]: https://doc.rust-lang.org/std/fmt/index.html

[`const_format::fmt`]: https://docs.rs/const_format/0.2.*/const_format/fmt/index.html

[`concatc`]: https://docs.rs/const_format/0.2.*/const_format/macro.concatc.html

[`formatc`]: https://docs.rs/const_format/0.2.*/const_format/macro.formatc.html

[`writec`]: https://docs.rs/const_format/0.2.*/const_format/macro.writec.html

[`write`]: https://doc.rust-lang.org/std/macro.write.html

[`Formatter`]: https://docs.rs/const_format/0.2.*/const_format/fmt/struct.Formatter.html

[`StrWriter`]: https://docs.rs/const_format/0.2.*/const_format/fmt/struct.StrWriter.html

[`ConstDebug`]: https://docs.rs/const_format/0.2.*/const_format/derive.ConstDebug.html

[`FormatMarker`]: https://docs.rs/const_format/0.2.*/const_format/marker_traits/trait.FormatMarker.html

[`WriteMarker`]: https://docs.rs/const_format/0.2.*/const_format/marker_traits/trait.WriteMarker.html

[`map_ascii_case`]: https://docs.rs/const_format/0.2.*/const_format/macro.map_ascii_case.html

[`Case`]: https://docs.rs/const_format/0.2.*/const_format/enum.Case.html

[`str_get`]: https://docs.rs/const_format/0.2.*/const_format/macro.str_get.html

[`str_index`]: https://docs.rs/const_format/0.2.*/const_format/macro.str_index.html

[`str_repeat`]: https://docs.rs/const_format/0.2.*/const_format/macro.str_repeat.html

[`str_splice`]: https://docs.rs/const_format/0.2.*/const_format/macro.str_splice.html

[`str_replace`]: https://docs.rs/const_format/0.2.*/const_format/macro.str_replace.html

[`str_split`]: https://docs.rs/const_format/0.2.*/const_format/macro.str_split.html

[`str::replace`]: https://doc.rust-lang.org/std/primitive.str.html#method.replace

[inline const patterns]: https://doc.rust-lang.org/1.83.0/unstable-book/language-features/inline-const-pat.html


================================================
FILE: commit.sh
================================================
#!/bin/sh

#
# You can use this script to format and commit the code all at once
#
#

cargo fmt

if [ $? -eq 0 ]
then
    echo "ran cargo fmt!!!!"
else
    exit 1
fi


git update-index --again

git commit

================================================
FILE: const_format/Cargo.toml
================================================
[package]
name = "const_format"
version = "0.2.36"
authors = ["rodrimati1992 <rodrimatt1985@gmail.com>"]
rust-version = "1.71.0"
edition = "2021"
license = "Zlib"
description = "Compile-time string formatting"
documentation = "https://docs.rs/const_format/"
readme="../README.md"
keywords = ["no-std", "format", "concat"]
categories = ["no-std", "text-processing"]
repository = "https://github.com/rodrimati1992/const_format_crates/"
include = [
    "Cargo.toml", 
    "src/**/*.rs", 
    "../README.md",
    "LICENSE-ZLIB.md", 
]

[features]
default = []
const_generics = ["rust_1_51"]
nightly_const_generics = ["const_generics"]
rust_1_51 = []
rust_1_64 = ["rust_1_51"]
rust_1_83 = ["rust_1_64"]
fmt = ["rust_1_83"]
derive = ["fmt", "const_format_proc_macros/derive"]

# soft-deprecated, use assertc instead.
assert = ["assertc"]

assertc = ["fmt", "assertcp"]
assertcp = ["rust_1_51"]
constant_time_as_str = ["fmt"]
more_str_macros = ["rust_1_64"]

# enables all the features, requires (potentially) the latest nightly
all = [
    "fmt",
    "derive",
    "rust_1_64",
    "assert",
]

##############
### "private" features

# 
__debug = ["const_format_proc_macros/debug"]
__test = []
__only_new_tests = ["__test"]
__inline_const_pat_tests = ["__test", "fmt"]
__docsrs = []

[dependencies.const_format_proc_macros]
version = "=0.2.34"
path = "../const_format_proc_macros"

[dependencies.konst]
version = "0.2.20"
default-features = false
features = ["rust_1_64"]

[dev-dependencies]
fastrand = {version = "1.3.5", default-features = false}
arrayvec = {version = "0.7.0", default-features = false}

[package.metadata.docs.rs]
features = ["all", "__docsrs"]



================================================
FILE: const_format/LICENSE-ZLIB.md
================================================
Copyright (c) 2020 Matias Rodriguez.

This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.

Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:

1. The origin of this software must not be misrepresented; you must not
   claim that you wrote the original software. If you use this software
   in a product, an acknowledgment in the product documentation would be
   appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
   misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.

================================================
FILE: const_format/src/__ascii_case_conv/word_iterator.rs
================================================
use core::fmt::{self, Debug};

macro_rules! for_range_inc {
    ($current:ident in $start:expr, $end:expr => $($code:tt)*) => {
        let mut $current = $start;
        let end = $end;

        while $current <= end {
            $($code)*

            $current+=1;
        }
    };
}

use core::ops::Range;

#[derive(Copy, Clone)]
struct ByteKind(u8);

impl Debug for ByteKind {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.write_str(match () {
            _ if self.0 == Self::Other.0 => "Other",
            _ if self.0 == Self::Number.0 => "Number",
            _ if self.0 == Self::LowerCase.0 => "LowerCase",
            _ if self.0 == Self::UpperCase.0 => "UpperCase",
            _ if self.0 == Self::NonAscii.0 => "NonAscii",
            _ => unreachable!(),
        })
    }
}

#[allow(non_upper_case_globals)]
impl ByteKind {
    const Other: Self = Self(0b0001);
    const Number: Self = Self(0b0010);
    const LowerCase: Self = Self(0b0100);
    const UpperCase: Self = Self(0b1000);
    const Alphabetic: Self = Self(Self::LowerCase.0 | Self::UpperCase.0);
    // Assumes that non-ascii chars are mostly alphabetic,
    // this should work out fine most of the time.
    const NonAscii: Self = Self(0b1100);
}

impl ByteKind {
    #[allow(dead_code)]
    #[inline(always)]
    pub const fn eq(self, other: Self) -> bool {
        (self.0 & other.0) != 0
    }

    #[inline(always)]
    pub const fn ne(self, other: Self) -> bool {
        (self.0 & other.0) == 0
    }

    #[inline(always)]
    pub const fn is_alphabetic(self) -> bool {
        self.0 == Self::LowerCase.0 || self.0 == Self::UpperCase.0
    }

    pub const fn is_end_of_word(mut self, prev: Self, other: Self) -> bool {
        if self.0 == Self::NonAscii.0 {
            self = prev;
        }

        if self.0 == Self::UpperCase.0 {
            other.ne(Self::Alphabetic)
        } else {
            self.ne(other)
        }
    }
}

#[derive(Debug, Copy, Clone)]
pub(crate) struct WordIterator<'a> {
    bytes: &'a [u8],
    start: usize,
}

const BYTE_KIND: &[ByteKind; 256] = &{
    let mut out = [ByteKind::NonAscii; 256];

    // Make sure that this goes first
    for_range_inc! {i in 0, 127 => out[i as usize] = ByteKind::Other; }
    for_range_inc! {i in b'A', b'Z' => out[i as usize] = ByteKind::UpperCase; }
    for_range_inc! {i in b'a', b'z' => out[i as usize] = ByteKind::LowerCase; }
    for_range_inc! {i in b'0', b'9' => out[i as usize] = ByteKind::Number; }

    out
};

impl<'a> WordIterator<'a> {
    pub(crate) const fn new(bytes: &'a [u8]) -> Self {
        Self { bytes, start: 0 }
    }

    const fn skip_same_kind(mut self, mut kind: ByteKind) -> (Self, ByteKind) {
        let orig_bytes_len = self.bytes.len();

        let mut prev_kind = kind;
        while let [b, rem @ ..] = self.bytes {
            let next_kind = BYTE_KIND[*b as usize];
            let cmp = kind.is_end_of_word(prev_kind, next_kind);
            if kind.is_alphabetic() {
                prev_kind = kind;
            }
            kind = next_kind;
            if cmp {
                break;
            }
            self.bytes = rem;
        }

        // Advance until a char boundary is found
        while let [b, rem @ ..] = self.bytes {
            if (*b as i8) >= -0x40 {
                break;
            }
            self.bytes = rem;
        }

        // Remember not to add return statements to the function
        self.start += orig_bytes_len - self.bytes.len();

        (self, kind)
    }

    pub(crate) const fn next(self) -> Option<(Self, Range<usize>)> {
        let (this, fkind) = self.skip_same_kind(ByteKind::Other);
        if let [] = this.bytes {
            None
        } else {
            let (next, _) = this.skip_same_kind(fkind);
            let range = this.start..next.start;
            Some((next, range))
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    use arrayvec::ArrayVec;

    fn get_words(text: &str) -> ArrayVec<&str, 20> {
        let mut list = <ArrayVec<&str, 20>>::new();
        let mut word_iter = WordIterator::new(text.as_bytes());

        while let Some((niter, word_range)) = word_iter.next() {
            word_iter = niter;
            list.push(&text[word_range]);
        }

        list
    }

    #[test]
    fn test_word_iter() {
        assert_eq!(
            get_words("01934324ñmaniÑNnFooBar")[..],
            ["01934324", "ñmaniÑ", "Nn", "Foo", "Bar"],
        );

        assert_eq!(
            get_words("01934 324  ñmani-嶲Nn____FOOOBar")[..],
            ["01934", "324", "ñmani", "嶲Nn", "FOOOBar"],
        );

        assert_eq!(get_words("    01934 1111 ")[..], ["01934", "1111"],);

        assert_eq!(get_words("    嶲01934 ")[..], ["嶲", "01934"],);

        assert_eq!(get_words("    嶲A01934 ")[..], ["嶲A", "01934"],);

        assert_eq!(get_words("    嶲a01934 ")[..], ["嶲a", "01934"],);

        assert_eq!(get_words("    ñA01934 ")[..], ["ñA", "01934"],);

        assert_eq!(get_words("    ña01934 ")[..], ["ña", "01934"],);
    }
}


================================================
FILE: const_format/src/__ascii_case_conv.rs
================================================
mod word_iterator;

use word_iterator::WordIterator;

/// The casing style of a string.
///
/// You can pass this to [`map_ascii_case`] to determine the casing style of the
/// returned `&'static str`.
///
///
/// [`map_ascii_case`]: ./macro.map_ascii_case.html
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum Case {
    /// Lowercase
    Lower,
    /// Uppercase
    Upper,
    /// Pascal case, eg: `FooBarBaz`. The first character is always uppercase.
    Pascal,
    /// Camel case, eg: `fooBarBaz`. The first character is always lowercase.
    Camel,
    /// Snake case, eg: `foo_bar_baz`. Also turns the string lowercase.
    Snake,
    /// Snake case, eg: `FOO_BAR_BAZ`. Also turns the string uppercase.
    UpperSnake,
    /// Kebab case, eg: `foo-bar-baz`. Also turns the string lowercase.
    Kebab,
    /// Kebab case, eg: `FOO-BAR-BAZ`. Also turns the string uppercase.
    UpperKebab,
}

macro_rules! if_next_word {
    ($word_iterator:ident, $word_range:ident => $then:block $(else $else:block)? ) => {
        #[allow(unused_mut)]
        if let Some((niter, mut $word_range)) = $word_iterator.next() {
            $word_iterator = niter;

            $then
        } $(else $else)?
    };
}

macro_rules! while_next_word {
    ($word_iterator:ident, $word_range:ident => $then:block) => {
        #[allow(unused_mut)]
        while let Some((niter, mut $word_range)) = $word_iterator.next() {
            $word_iterator = niter;

            $then
        }
    };
}

struct WordCountAndLength {
    /// The amount of words
    count: usize,
    /// The length of all words added up
    length: usize,
}

const fn words_count_and_length(bytes: &[u8]) -> WordCountAndLength {
    let mut count = 0;
    let mut length = 0;
    let mut word_iter = WordIterator::new(bytes);
    while_next_word! {word_iter, word_range => {
        count += 1;
        length += word_range.end - word_range.start;
    }}
    WordCountAndLength { count, length }
}

pub const fn size_after_conversion(case: Case, s: &str) -> usize {
    match case {
        Case::Upper | Case::Lower => s.len(),
        Case::Pascal | Case::Camel => {
            let wcl = words_count_and_length(s.as_bytes());
            wcl.length
        }
        Case::Snake | Case::Kebab | Case::UpperSnake | Case::UpperKebab => {
            let wcl = words_count_and_length(s.as_bytes());
            wcl.length + wcl.count.saturating_sub(1)
        }
    }
}

pub const fn convert_str<const N: usize>(case: Case, s: &str) -> [u8; N] {
    let mut arr = [0; N];
    let mut inp = s.as_bytes();
    let mut o = 0;

    macro_rules! map_bytes {
        ($byte:ident => $e:expr) => {
            while let [$byte, rem @ ..] = inp {
                let $byte = *$byte;
                inp = rem;
                arr[o] = $e;
                o += 1;
            }
        };
    }

    macro_rules! write_byte {
        ($byte:expr) => {
            arr[o] = $byte;
            o += 1;
        };
    }

    macro_rules! write_range_from {
        ($range:expr, $from:expr, $byte:ident => $mapper:expr) => {{
            let mut range = $range;
            while range.start < range.end {
                let $byte = $from[range.start];
                arr[o] = $mapper;

                range.start += 1;
                o += 1;
            }
        }};
    }

    macro_rules! write_snake_kebab_case {
        ($separator:expr, $byte_conversion:expr) => {{
            let mut word_iter = WordIterator::new(inp);

            if_next_word! {word_iter, word_range => {
                write_range_from!(word_range, inp, byte => $byte_conversion(byte));

                while_next_word!{word_iter, word_range => {
                    write_byte!($separator);
                    write_range_from!(word_range, inp, byte => $byte_conversion(byte));
                }}
            }}
        }};
    }

    macro_rules! write_pascal_camel_case {
        ($first_word_conv:expr) => {{
            let mut word_iter = WordIterator::new(inp);

            if_next_word! {word_iter, word_range => {
                write_byte!($first_word_conv(inp[word_range.start]));
                word_range.start += 1;
                write_range_from!(word_range, inp, byte => lowercase_u8(byte));

                while_next_word!{word_iter, word_range => {
                    write_byte!(uppercase_u8(inp[word_range.start]));
                    word_range.start += 1;
                    write_range_from!(word_range, inp, byte => lowercase_u8(byte));
                }}
            }}
        }};
    }

    match case {
        Case::Upper => map_bytes!(b => uppercase_u8(b)),
        Case::Lower => map_bytes!(b => lowercase_u8(b)),
        Case::Snake => write_snake_kebab_case!(b'_', lowercase_u8),
        Case::UpperSnake => write_snake_kebab_case!(b'_', uppercase_u8),
        Case::Kebab => write_snake_kebab_case!(b'-', lowercase_u8),
        Case::UpperKebab => write_snake_kebab_case!(b'-', uppercase_u8),
        Case::Pascal => write_pascal_camel_case!(uppercase_u8),
        Case::Camel => write_pascal_camel_case!(lowercase_u8),
    }

    arr
}

const CASE_DIFF: u8 = b'a' - b'A';

const fn uppercase_u8(b: u8) -> u8 {
    if let b'a'..=b'z' = b {
        b - CASE_DIFF
    } else {
        b
    }
}

const fn lowercase_u8(b: u8) -> u8 {
    if let b'A'..=b'Z' = b {
        b + CASE_DIFF
    } else {
        b
    }
}


================================================
FILE: const_format/src/__hidden_utils.rs
================================================
pub(crate) const fn max_usize(l: usize, r: usize) -> usize {
    if l > r {
        l
    } else {
        r
    }
}
pub(crate) const fn saturating_add(l: usize, r: usize) -> usize {
    let (sum, overflowed) = l.overflowing_add(r);
    if overflowed {
        usize::MAX
    } else {
        sum
    }
}

pub(crate) const fn is_char_boundary_no_len_check(str: &[u8], index: usize) -> bool {
    index == str.len() || (str[index] as i8) >= -0x40
}

#[repr(C)]
pub union PtrToRef<'a, T: ?Sized> {
    pub ptr: *const T,
    pub reff: &'a T,
}


================================================
FILE: const_format/src/__str_methods/pattern.rs
================================================
use super::AsciiByte;

pub(crate) struct PatternCtor<T>(pub(crate) T);

impl PatternCtor<u8> {
    pub(crate) const fn conv(self) -> Pattern {
        Pattern::AsciiByte(AsciiByte::new(self.0))
    }
}

impl PatternCtor<&'static str> {
    pub(crate) const fn conv(self) -> Pattern {
        if let [b @ 0..=127] = *self.0.as_bytes() {
            Pattern::AsciiByte(AsciiByte::new(b))
        } else {
            Pattern::Str(self.0)
        }
    }
}

impl PatternCtor<char> {
    pub(crate) const fn conv(self) -> Pattern {
        let code = self.0 as u32;
        if let c @ 0..=127 = code {
            Pattern::AsciiByte(AsciiByte::new(c as u8))
        } else {
            Pattern::Char(crate::char_encoding::char_to_display(self.0))
        }
    }
}

#[derive(Copy, Clone)]
pub(crate) enum Pattern {
    AsciiByte(AsciiByte),
    Str(&'static str),
    Char(crate::char_encoding::FmtChar),
}

pub(crate) enum PatternNorm<'a> {
    AsciiByte(AsciiByte),
    Str(&'a [u8]),
}

impl Pattern {
    pub(crate) const fn normalize(&self) -> PatternNorm<'_> {
        match self {
            Pattern::AsciiByte(ab) => PatternNorm::AsciiByte(*ab),
            Pattern::Str(str) => PatternNorm::Str(str.as_bytes()),
            Pattern::Char(char) => PatternNorm::Str(char.as_bytes()),
        }
    }
}


================================================
FILE: const_format/src/__str_methods/str_indexing.rs
================================================
pub struct StrIndexArgsConv<T> {
    pub str: &'static str,
    pub arg: T,
}

#[allow(non_snake_case)]
pub const fn StrIndexArgsConv<T>(str: &'static str, arg: T) -> StrIndexArgsConv<T> {
    StrIndexArgsConv { str, arg }
}

pub struct StrIndexArgs {
    pub str: &'static str,
    pub index_validity: IndexValidity,
    pub used_rstart: usize,
    pub used_rlen: usize,
    pub used_rend: usize,
}

#[derive(Copy, Clone)]
#[cfg_attr(test, derive(Debug, PartialEq))]
pub enum IndexValidity {
    Valid,
    StartOob(usize),
    StartInsideChar(usize),
    EndOob(usize),
    EndInsideChar(usize),
}

impl IndexValidity {
    pub const fn is_valid(self) -> bool {
        matches!(self, Self::Valid)
    }

    pub const fn assert_valid(self) {
        match self {
            Self::Valid => (),
            Self::StartOob(index) => [/*start index is out of bounds*/][index],
            Self::StartInsideChar(index) => [/*start index is not on a char boundary*/][index],
            Self::EndOob(index) => [/*end index is out of bounds*/][index],
            Self::EndInsideChar(index) => [/*end index is not on a char boundary*/][index],
        }
    }
}

macro_rules! pass_range_types {
    ($macro:ident) => {
        const _: () = {
            use core::ops;

            #[allow(unused_imports)]
            use crate::__hidden_utils::{is_char_boundary_no_len_check, max_usize, saturating_add};

            $macro! {
                fn(self, usize) {
                    let mut end = saturating_add(self.arg, 1);
                    let bytes = self.str.as_bytes();

                    if end < self.str.len() {
                        while !is_char_boundary_no_len_check(bytes, end) {
                            end = saturating_add(end, 1);
                        }
                    }

                    self.arg .. end
                }

                fn(self, ops::Range<usize>) {
                    let ops::Range{start, end} = self.arg;
                    start .. max_usize(start, end)
                }

                fn(self, ops::RangeTo<usize>) {
                    0..self.arg.end
                }

                fn(self, ops::RangeFrom<usize>) {
                    self.arg.start..self.str.len()
                }

                fn(self, ops::RangeInclusive<usize>) {
                    let start = *self.arg.start();
                    start .. max_usize(saturating_add(*self.arg.end(), 1), start)
                }

                fn(self, ops::RangeToInclusive<usize>) {
                    0 .. saturating_add(self.arg.end, 1)
                }

                fn(self, ops::RangeFull) {
                    0 .. self.str.len()
                }
            }
        };
    };
}
pub(super) use pass_range_types;

macro_rules! define_conversions {
    (
        $( fn($self:ident, $ty:ty) $block:block )*
    ) => {

        $(
            impl StrIndexArgsConv<$ty> {
                pub const fn conv($self) -> StrIndexArgs {
                    use crate::__hidden_utils::is_char_boundary_no_len_check;

                    let range = $block;

                    let str_len = $self.str.len();

                    let mut used_rstart = 0;
                    let mut used_rend = str_len;

                    let mut index_validity = IndexValidity::Valid;
                    let bytes = $self.str.as_bytes();

                    if range.end > str_len {
                        index_validity = IndexValidity::EndOob(range.end);
                    } else if is_char_boundary_no_len_check(bytes, range.end) {
                        used_rend = range.end;
                    } else {
                        index_validity = IndexValidity::EndInsideChar(range.end);
                    };

                    if range.start > str_len {
                        index_validity = IndexValidity::StartOob(range.start);
                    } else if is_char_boundary_no_len_check(bytes, range.start) {
                        used_rstart = range.start;
                    } else {
                        index_validity = IndexValidity::StartInsideChar(range.start);
                    };

                    StrIndexArgs {
                        str: $self.str,
                        index_validity,
                        used_rstart,
                        used_rend,
                        used_rlen: used_rend - used_rstart,
                    }
                }
            }
        )*
    };
}

pass_range_types! {define_conversions}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn index_validity_test() {
        macro_rules! miv {
            ($str:expr, $range:expr) => {
                StrIndexArgsConv($str, $range).conv().index_validity
            };
        }

        assert_eq!(miv!("効率的", 3), IndexValidity::Valid);
        assert_eq!(miv!("効率的", 6), IndexValidity::Valid);
        assert_eq!(miv!("効率的", 3..6), IndexValidity::Valid);

        assert_eq!(miv!("効率的", 4..6), IndexValidity::StartInsideChar(4));
        assert_eq!(miv!("効率的", 3..5), IndexValidity::EndInsideChar(5));
        assert_eq!(miv!("効率的", 7..9), IndexValidity::StartInsideChar(7));

        assert_eq!(miv!("効率的", 100..9), IndexValidity::StartOob(100));
        assert_eq!(miv!("効率的", 3..10), IndexValidity::EndOob(10));
        assert_eq!(miv!("効率的", 9), IndexValidity::EndOob(10));
        assert_eq!(miv!("効率的", 10), IndexValidity::StartOob(10));
        assert_eq!(miv!("効率的", 100..900), IndexValidity::StartOob(100));
    }
}


================================================
FILE: const_format/src/__str_methods/str_repeat.rs
================================================
pub struct StrRepeatArgs {
    pub str: &'static str,
    pub str_len: usize,
    pub out_len: usize,
    pub overflowed_len: Option<usize>,
    pub repeat: usize,
}

#[allow(non_snake_case)]
pub const fn StrRepeatArgs(str: &'static str, repeat: usize) -> StrRepeatArgs {
    let str_len = str.len();
    let (mul, overflowed) = str_len.overflowing_mul(repeat);

    let (out_len, overflowed_len, repeat) = if overflowed {
        (str_len, Some(mul), 1)
    } else {
        (mul, None, repeat)
    };

    StrRepeatArgs {
        str,
        str_len,
        out_len,
        overflowed_len,
        repeat,
    }
}

impl StrRepeatArgs {
    pub const fn assert_valid(&self) {
        if let Some(overflowed_len) = self.overflowed_len {
            [/* the returned string is too large */][overflowed_len]
        }
    }
}


================================================
FILE: const_format/src/__str_methods/str_replace.rs
================================================
use super::{bytes_find, Pattern, PatternCtor, PatternNorm};

pub struct ReplaceInputConv<T>(pub &'static str, pub T, pub &'static str);

macro_rules! ctor {
    ($ty:ty) => {
        impl ReplaceInputConv<$ty> {
            pub const fn conv(self) -> ReplaceInput {
                ReplaceInput {
                    str: self.0,
                    pattern: PatternCtor(self.1).conv(),
                    replaced_with: self.2,
                }
            }
        }
    };
}

ctor! {u8}
ctor! {&'static str}
ctor! {char}

pub struct ReplaceInput {
    str: &'static str,
    pattern: Pattern,
    replaced_with: &'static str,
}

impl ReplaceInput {
    pub const fn replace_length(&self) -> usize {
        str_replace_length(self.str, self.pattern, self.replaced_with)
    }
    pub const fn replace<const L: usize>(&self) -> [u8; L] {
        str_replace(self.str, self.pattern, self.replaced_with)
    }
}

const fn str_replace_length(inp: &str, r: Pattern, replaced_with: &str) -> usize {
    let inp = inp.as_bytes();

    let replaced_len = replaced_with.len();
    let mut out_len = 0;

    match r.normalize() {
        PatternNorm::AsciiByte(byte) => {
            let byte = byte.get();
            iter_copy_slice! {b in inp =>
                out_len += if b == byte { replaced_len } else { 1 };
            }
        }
        PatternNorm::Str(str) => {
            if str.is_empty() {
                return inp.len();
            }
            let str_len = str.len();
            let mut i = 0;
            while let Some(next_match) = bytes_find(inp, str, i) {
                out_len += (next_match - i) + replaced_len;
                i = next_match + str_len;
            }
            out_len += inp.len() - i;
        }
    }

    out_len
}

const fn str_replace<const L: usize>(inp: &str, r: Pattern, replaced_with: &str) -> [u8; L] {
    let inp = inp.as_bytes();

    let replaced_with_bytes = replaced_with.as_bytes();
    let mut out = [0u8; L];
    let mut out_i = 0;

    macro_rules! write_replaced {
        () => {
            iter_copy_slice! {b in replaced_with_bytes =>
                out[out_i] = b;
                out_i += 1;
            }
        };
    }
    macro_rules! write_byte {
        ($byte:expr) => {
            out[out_i] = $byte;
            out_i += 1;
        };
    }

    match r.normalize() {
        PatternNorm::AsciiByte(byte) => {
            let byte = byte.get();
            iter_copy_slice! {b in inp =>
                if b == byte {
                    write_replaced!{}
                } else {
                    write_byte!{b}
                }
            }
        }
        PatternNorm::Str(str) => {
            if str.is_empty() {
                iter_copy_slice! {b in inp =>
                    write_byte!(b);
                }
                return out;
            }
            let str_len = str.len();
            let mut i = 0;
            while let Some(next_match) = bytes_find(inp, str, i) {
                __for_range! {j in i..next_match =>
                    write_byte!(inp[j]);
                }
                write_replaced! {}

                i = next_match + str_len;
            }
            __for_range! {j in i..inp.len() =>
                write_byte!(inp[j]);
            }
        }
    }
    out
}


================================================
FILE: const_format/src/__str_methods/str_splice.rs
================================================
use super::str_indexing::{pass_range_types, IndexValidity, StrIndexArgs, StrIndexArgsConv};

pub struct StrSplceArgsConv<T> {
    pub arg: T,
    pub str: &'static str,
    pub insert: &'static str,
}

#[allow(non_snake_case)]
pub const fn StrSplceArgsConv<T>(
    str: &'static str,
    arg: T,
    insert: &'static str,
) -> StrSplceArgsConv<T> {
    StrSplceArgsConv { str, arg, insert }
}

pub struct StrSpliceArgs {
    pub str: &'static str,
    pub insert: &'static str,
    pub index_validity: IndexValidity,
    pub used_rstart: usize,
    pub used_rlen: usize,
    pub insert_len: usize,
    pub suffix_len: usize,
    pub out_len: usize,
}

/// The return value of [`str_splice`](./macro.str_splice.html)
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct SplicedStr {
    /// A string that had `removed` replaced with some other string.
    pub output: &'static str,
    /// The part of the string that was removed.
    pub removed: &'static str,
}

#[repr(C, packed)]
pub struct DecomposedString<P, M, S> {
    pub prefix: P,
    pub middle: M,
    pub suffix: S,
}

macro_rules! define_conversions {
    (
        $( fn($self:ident, $ty:ty) $block:block )*
    ) => {
        $(
            impl StrSplceArgsConv<$ty> {
                pub const fn conv(self) -> StrSpliceArgs {
                    let StrIndexArgs{
                        str,
                        index_validity,
                        used_rstart,
                        used_rend,
                        used_rlen,
                    } = StrIndexArgsConv{
                        arg: self.arg,
                        str: self.str,
                    }.conv();

                    StrSpliceArgs{
                        str,
                        index_validity,
                        used_rstart,
                        used_rlen,
                        insert: self.insert,
                        insert_len: self.insert.len(),
                        suffix_len: str.len() - used_rend,
                        out_len: str.len() - used_rlen + self.insert.len(),
                    }
                }
            }
        )*
    };
}

pass_range_types! {define_conversions}


================================================
FILE: const_format/src/__str_methods/str_split.rs
================================================
use super::{Pattern, PatternCtor, PatternNorm};

use konst::slice::{bytes_find, bytes_find_skip};

pub struct SplitInputConv<T>(pub &'static str, pub T);

macro_rules! ctor {
    ($ty:ty) => {
        impl SplitInputConv<$ty> {
            pub const fn conv(self) -> SplitInput {
                SplitInput {
                    str: self.0,
                    pattern: PatternCtor(self.1).conv(),
                    length: usize::MAX,
                }
                .compute_length()
            }
        }
    };
}

ctor! {u8}
ctor! {&'static str}
ctor! {char}

#[derive(Copy, Clone)]
pub struct SplitInput {
    str: &'static str,
    pattern: Pattern,
    length: usize,
}

impl SplitInput {
    const fn compute_length(mut self) -> Self {
        self.length = count_splits(self);
        self
    }

    pub const fn split_it<const LEN: usize>(self) -> [&'static str; LEN] {
        split_it(self)
    }

    pub const fn length(&self) -> usize {
        self.length
    }
}

pub const fn count_splits(SplitInput { str, pattern, .. }: SplitInput) -> usize {
    let mut count = 1;

    match pattern.normalize() {
        PatternNorm::AsciiByte(ascii_c) => {
            let mut bytes = str.as_bytes();
            let ascii_c = ascii_c.get();

            while let [byte, rem @ ..] = bytes {
                bytes = rem;

                if *byte == ascii_c {
                    count += 1;
                }
            }
        }
        PatternNorm::Str(str_pat) => {
            if str_pat.is_empty() {
                let mut char_i = 0;
                count += 1;
                while let Some(next) = find_next_char_boundary(str, char_i) {
                    char_i = next;
                    count += 1;
                }
            } else {
                let mut str = str.as_bytes();
                while let Some(next) = bytes_find_skip(str, str_pat) {
                    str = next;
                    count += 1;
                }
            }
        }
    }

    count
}

const fn find_u8(mut slice: &[u8], byte: u8) -> Option<usize> {
    let mut i = 0;

    while let [b, ref rem @ ..] = *slice {
        if byte == b {
            return Some(i);
        }
        slice = rem;
        i += 1;
    }
    None
}

const fn find_next_char_boundary(str: &str, mut index: usize) -> Option<usize> {
    if index == str.len() {
        None
    } else {
        loop {
            index += 1;
            if index == str.len() || (str.as_bytes()[index] as i8) >= -0x40 {
                break Some(index);
            }
        }
    }
}

pub const fn split_it<const LEN: usize>(args: SplitInput) -> [&'static str; LEN] {
    let SplitInput {
        mut str,
        pattern,
        length: _,
    } = args;

    let mut out = [""; LEN];
    let mut out_i = 0;

    macro_rules! write_out {
        ($string:expr) => {
            out[out_i] = $string;
            out_i += 1;
        };
    }

    match pattern.normalize() {
        PatternNorm::AsciiByte(ascii_c) => {
            let ascii_c = ascii_c.get();

            while let Some(found_at) = find_u8(str.as_bytes(), ascii_c) {
                write_out! {konst::string::str_up_to(str, found_at)}
                str = konst::string::str_from(str, found_at + 1);
            }
        }
        PatternNorm::Str(str_pat) => {
            if str_pat.is_empty() {
                out_i += 1;
                while let Some(next) = find_next_char_boundary(str, 0) {
                    write_out! {konst::string::str_up_to(str, next)}
                    str = konst::string::str_from(str, next);
                }
            } else {
                while let Some(found_at) = bytes_find(str.as_bytes(), str_pat, 0) {
                    write_out! {konst::string::str_up_to(str, found_at)}
                    str = konst::string::str_from(str, found_at + str_pat.len());
                }
            }
        }
    }

    write_out! {str}

    assert!(out_i == LEN);
    out
}


================================================
FILE: const_format/src/__str_methods.rs
================================================
mod str_replace;

pub use self::str_replace::{ReplaceInput, ReplaceInputConv};

mod str_repeat;
pub use str_repeat::StrRepeatArgs;

mod str_splice;
pub use str_splice::{DecomposedString, SplicedStr, StrSplceArgsConv, StrSpliceArgs};

mod str_indexing;
pub use str_indexing::{IndexValidity, StrIndexArgs, StrIndexArgsConv};

mod str_split;

pub use str_split::{SplitInput, SplitInputConv};

mod pattern;

use pattern::{Pattern, PatternCtor, PatternNorm};

mod ascii_byte {
    #[derive(Copy, Clone)]
    pub struct AsciiByte(u8);

    impl AsciiByte {
        #[inline(always)]
        pub const fn new(byte: u8) -> Self {
            if byte > 127 {
                let byte = byte as usize;
                let _: () = [/* byte isn't valid ascii */][byte];
                loop {}
            }
            Self(byte)
        }
        #[inline(always)]
        pub const fn get(self) -> u8 {
            self.0
        }
    }
}
pub use ascii_byte::AsciiByte;

// copied from the konst crate, if that implementation is wrong, this needs to be fixed
const fn bytes_find(left: &[u8], right: &[u8], from: usize) -> Option<usize> {
    let mut matching = right;

    __for_range! {i in from..left.len() =>
        match matching {
            [mb, m_rem @ ..] => {
                let b = left[i];

                matching = if b == *mb {
                    m_rem
                } else {
                    match right {
                        // For when the string is "lawlawn" and we are trying to find "lawn"
                        [mb2, m_rem2 @ ..] if b == *mb2 => m_rem2,
                        _ => right,
                    }
                };
            }
            [] => {
                return Some(i - right.len())
            }
        }
    }

    if matching.is_empty() {
        Some(left.len() - right.len())
    } else {
        None
    }
}


================================================
FILE: const_format/src/char_encoding/tests.rs
================================================
use super::{char_debug_len, char_display_len, char_to_debug, char_to_display};

#[test]
fn char_to_utf8_encoding_test() {
    for c in '\0'..=core::char::MAX {
        let mut utf8_std = [0u8; 4];
        let utf8_std = c.encode_utf8(&mut utf8_std);

        let utf8_here = char_to_display(c);
        assert_eq!(utf8_here.len(), char_display_len(c));

        assert_eq!(utf8_std.as_bytes(), utf8_here.as_bytes());
    }
}

#[test]
fn char_to_utf8_display_test() {
    for c in '\0'..=core::char::MAX {
        let mut utf8_std = [0u8; 4];
        let utf8_std = c.encode_utf8(&mut utf8_std);

        let utf8_here = char_to_display(c);
        assert_eq!(utf8_here.len(), char_display_len(c));

        assert_eq!(utf8_std.as_bytes(), utf8_here.as_bytes());
    }
}

#[test]
fn char_to_utf8_debug_test() {
    let first_escapes = [
        ('\x00', r#"'\x00'"#),
        ('\x01', r#"'\x01'"#),
        ('\x02', r#"'\x02'"#),
        ('\x03', r#"'\x03'"#),
        ('\x04', r#"'\x04'"#),
        ('\x05', r#"'\x05'"#),
        ('\x06', r#"'\x06'"#),
        ('\x07', r#"'\x07'"#),
        ('\x08', r#"'\x08'"#),
        ('\t', r#"'\t'"#),
        ('\n', r#"'\n'"#),
        ('\x0B', r#"'\x0B'"#),
        ('\x0C', r#"'\x0C'"#),
        ('\r', r#"'\r'"#),
        ('\x0E', r#"'\x0E'"#),
        ('\x0F', r#"'\x0F'"#),
        ('\x10', r#"'\x10'"#),
        ('\x11', r#"'\x11'"#),
        ('\x12', r#"'\x12'"#),
        ('\x13', r#"'\x13'"#),
        ('\x14', r#"'\x14'"#),
        ('\x15', r#"'\x15'"#),
        ('\x16', r#"'\x16'"#),
        ('\x17', r#"'\x17'"#),
        ('\x18', r#"'\x18'"#),
        ('\x19', r#"'\x19'"#),
        ('\x1A', r#"'\x1A'"#),
        ('\x1B', r#"'\x1B'"#),
        ('\x1C', r#"'\x1C'"#),
        ('\x1D', r#"'\x1D'"#),
        ('\x1E', r#"'\x1E'"#),
        ('\x1F', r#"'\x1F'"#),
    ];

    for (c, expected) in first_escapes.iter().copied() {
        let utf8_here = char_to_debug(c);
        assert_eq!(expected.as_bytes(), utf8_here.as_bytes(), "{:?}", c);
        assert_eq!(expected.len(), char_debug_len(c), "{:?}", c);
    }

    let other_escapes = [('\'', r#"'\''"#), ('\"', r#"'\"'"#), ('\\', r#"'\\'"#)];

    let mut buffer = arrayvec::ArrayString::<12>::new();
    for c in '\x20'..=core::char::MAX {
        let utf8_here = char_to_debug(c);

        if let Some((_, expected)) = Some(c)
            .filter(|c| *c <= '\x7F')
            .and_then(|c| other_escapes.iter().copied().find(|x| x.0 == c))
        {
            assert_eq!(expected.as_bytes(), utf8_here.as_bytes(), "{:?}", c);
            assert_eq!(expected.len(), char_debug_len(c), "{:?}", c);
        } else {
            buffer.clear();
            buffer.push('\'');
            buffer.push(c);
            buffer.push('\'');
            assert_eq!(buffer.as_bytes(), utf8_here.as_bytes(), "{:?}", c);
            assert_eq!(buffer.len(), char_debug_len(c), "{:?}", c);
        }
    }
}


================================================
FILE: const_format/src/char_encoding.rs
================================================
use crate::formatting::{hex_as_ascii, HexFormatting};

#[cfg(any(test, feature = "fmt"))]
pub(crate) const fn char_display_len(c: char) -> usize {
    match c as u32 {
        0..=127 => 1,
        0x80..=0x7FF => 2,
        0x800..=0xFFFF => 3,
        0x10000..=u32::MAX => 4,
    }
}

#[cfg(any(test, feature = "fmt"))]
pub(crate) const fn char_debug_len(c: char) -> usize {
    let inner = match c {
        '\t' | '\r' | '\n' | '\\' | '\'' | '\"' => 2,
        '\x00'..='\x1F' => 4,
        _ => char_display_len(c),
    };
    inner + 2
}

const fn char_to_utf8(char: char) -> ([u8; 4], usize) {
    let u32 = char as u32;
    match u32 {
        0..=127 => ([u32 as u8, 0, 0, 0], 1),
        0x80..=0x7FF => {
            let b0 = 0b1100_0000 | (u32 >> 6) as u8;
            let b1 = 0b1000_0000 | (u32 & 0b0011_1111) as u8;
            ([b0, b1, 0, 0], 2)
        }
        0x800..=0xFFFF => {
            let b0 = 0b1110_0000 | (u32 >> 12) as u8;
            let b1 = 0b1000_0000 | ((u32 >> 6) & 0b0011_1111) as u8;
            let b2 = 0b1000_0000 | (u32 & 0b0011_1111) as u8;
            ([b0, b1, b2, 0], 3)
        }
        0x10000..=u32::MAX => {
            let b0 = 0b1111_0000 | (u32 >> 18) as u8;
            let b1 = 0b1000_0000 | ((u32 >> 12) & 0b0011_1111) as u8;
            let b2 = 0b1000_0000 | ((u32 >> 6) & 0b0011_1111) as u8;
            let b3 = 0b1000_0000 | (u32 & 0b0011_1111) as u8;
            ([b0, b1, b2, b3], 4)
        }
    }
}

pub(crate) const fn char_to_display(char: char) -> FmtChar {
    let ([b0, b1, b2, b3], len) = char_to_utf8(char);
    FmtChar {
        encoded: [b0, b1, b2, b3, 0, 0],
        len: len as u8,
    }
}

pub(crate) const fn char_to_debug(c: char) -> FmtChar {
    let ([b0, b1, b2, b3], len) = match c {
        '\t' => (*br#"\t  "#, 2),
        '\r' => (*br#"\r  "#, 2),
        '\n' => (*br#"\n  "#, 2),
        '\\' => (*br#"\\  "#, 2),
        '\'' => (*br#"\'  "#, 2),
        '\"' => (*br#"\"  "#, 2),
        '\x00'..='\x1F' => {
            let n = c as u8;
            (
                [
                    b'\\',
                    b'x',
                    hex_as_ascii(n >> 4, HexFormatting::Upper),
                    hex_as_ascii(n & 0b1111, HexFormatting::Upper),
                ],
                4,
            )
        }
        _ => char_to_utf8(c),
    };

    let mut encoded = [b'\'', b0, b1, b2, b3, 0];
    encoded[len + 1] = b'\'';

    FmtChar {
        encoded,
        len: (len as u8) + 2,
    }
}

#[derive(Copy, Clone)]
pub struct FmtChar {
    encoded: [u8; 6],
    len: u8,
}

impl FmtChar {
    /// Array which contains the pre-len display/debug-formatted  `char`,
    /// only `&self.encoded[][..self.len()]` should be copied.
    pub const fn encoded(&self) -> &[u8; 6] {
        &self.encoded
    }

    pub const fn len(&self) -> usize {
        self.len as usize
    }

    pub(crate) const fn as_bytes(&self) -> &[u8] {
        self.encoded.split_at(self.len()).0
    }
}

#[cfg(all(test, not(miri)))]
mod tests;


================================================
FILE: const_format/src/const_debug_derive.rs
================================================
/// Derives const debug formatting for a type.
///
/// Derives the [`FormatMarker`] trait, and defines an `const_debug_fmt` inherent
/// method to format a type at compile-time.
/// 
/// # Features 
/// 
/// This derive macro is only available with the "derive" feature,
/// and Rust 1.83.0, because is uses mutable references in const.
///
/// # Limitations
///
/// Compile-time formatting currently imposes these limitations on users,
/// this derive macro has some mitigations for some of them.
///
/// ### Generic impls
///
/// Because the formatting of custom types is implemented with duck typing,
/// it's not possible to format generic types, instead you must do either of these:
///
/// - Provide all the implementations ahead of time, what the [`impls attribute`] is for.
///
/// - Provide a macro that formats the type.
/// The `call_debug_fmt` macro is a version of this that formats generic std types,
/// then it can be used to format fields of the type with the 
/// [`#[cdeb(with_macro = "....")]`](#cdeb_with_macro) attribute.
///
/// These are the things that this macro does to mitigate the limitations:
///
/// - Allows users to provide a function/macro/wrapper to format a field.
///
/// - Automatically detect some builtin/standard library types that are generic.
///
/// - Allow users to ignore a field.
///
/// # Container Attributes 
///
/// These attributes go on the type itself, rather than the fields.
///
/// ### `#[cdeb(debug_print)]`
///
/// Panics with the output of the expanded derive.
///
/// ### `#[cdeb(impls(....))]`
///
/// Allows users to implement const debug formatting for multiple different
/// concrete instances of the type.
/// 
/// When this attribute is used it disables the default implementation
/// that uses the type parameters generically.
///
/// Example:
/// 
/// ```rust
/// #[derive(const_format::ConstDebug)]
/// #[cdeb(impls(
///     "Foo<u8, u64>",
///     "<T> Foo<u16, T>",
///     "<T> Foo<u32, T> where T: 'static",
/// ))]
/// struct Foo<A, B>(A, *const B);
/// ```
///
/// In this example, there's exactly three impls of 
/// the `const_debug_fmt` method and [`FormatMarker`] trait.
///
/// ### `#[cdeb(crate = "foo::bar")]`
///
/// The path to the `const_format` crate, useful if you want to reexport the ConstDebug macro,
/// or rename the `const_format` crate in the Cargo.toml .
///
/// Example of renaming the `const_format` crate in the Cargo.toml file:
/// ```toml
/// cfmt = {version = "0.*", package = "const_format"}
/// ```
///
/// # Field attributes
///
/// ### `#[cdeb(ignore)]`
///
/// Ignores the field, pretending that it doesn't exist.
///
/// ### `#[cdeb(with = "module::function")]`
///
/// Uses the function at the passed-in path to format the field.
///
/// The function is expected to have this signature:
/// ```ignored
/// const fn(&FieldType, &mut const_format::Formatter<'_>) -> Result<(), const_format::Error>
/// ```
///
/// <span id = "cdeb_with_macro"> </span>
///
/// ### `#[cdeb(with_macro = "module::the_macro")]`
///
/// Uses the macro at the passed-in path to format the field.
///
/// The macro is expected to be callable like a function with this signature: 
/// ```ignored
/// const fn(&FieldType, &mut const_format::Formatter<'_>) -> Result<(), const_format::Error>
/// ```
/// 
/// ### `#[cdeb(with_wrapper = "module::Wrapper")]`
/// 
/// Uses the wrapper type to print the field.
///
/// The wrapper is expected to wrap a reference to the field type,
/// to have an implementation of the [`FormatMarker`] trait,
/// and have a method with this signature:
/// ```ignored
/// const fn const_debug_fmt(
///     self,
///     &mut const_format::Formatter<'_>,
/// ) -> Result<(), const_format::Error>
/// ```
/// (`self` can be taken by reference or by value)
///
/// ### `#[cdeb(is_a(....))]`
/// 
/// Gives the derive macro a hint of what the type is.
///
/// For standard library types,
/// this is necessary if you're using a type alias, since the derive macro detects 
/// those types syntactically.
///
/// These are the valid ways to use this attribute:
///
/// - `#[cdeb(is_a(array))]`/`#[cdeb(is_a(slice))]`:
/// Treats the field as being a slice/array,
/// printing the elements of std or user-defined type with const debug formatting.
///
/// - `#[cdeb(is_a(Option))]`/`#[cdeb(is_a(option))]`:
/// Treats the field as being an Option, 
/// printing the contents of std or user-defined type with const debug formatting.
///
/// - `#[cdeb(is_a(newtype))]`:
/// Treats the field as being being a single field tuple struct, 
/// using the identifier of the field type as the name of the struct,
/// then printing the single field of std or user-defined type with const debug formatting.
///
/// - `#[cdeb(is_a(non_std))]`/`#[cdeb(is_a(not_std))]`:
/// This acts as an opt-out for the automatic detection of std types,
/// most likely needed for types named `Option`.
/// 
/// # Examples
/// 
/// ### Basic
/// 
/// This example demonstrates using the derive without using any helper attributes.
/// 
/// ```rust
/// 
/// use const_format::{ConstDebug, formatc};
/// 
/// use std::cmp::Ordering;
/// 
/// const E_FOO: &str = formatc!("{:?}", Enum::Foo);
/// const E_BAR: &str = formatc!("{:?}", Enum::Bar(10));
/// const E_BAZ: &str = formatc!("{:?}", Enum::Baz{order: Ordering::Less});
/// 
/// const S_UNIT: &str = formatc!("{:?}", Unit);
/// const S_BRACED: &str = formatc!("{:?}", Braced{is_true: false, optional: Some(Unit)});
/// 
/// assert_eq!(E_FOO, "Foo");
/// assert_eq!(E_BAR, "Bar(10)");
/// assert_eq!(E_BAZ, "Baz { order: Less }");
/// 
/// assert_eq!(S_UNIT, "Unit");
/// assert_eq!(S_BRACED, "Braced { is_true: false, optional: Some(Unit) }");
/// 
/// 
/// #[derive(ConstDebug)]
/// enum Enum {
///     Foo,
///     Bar(u32),
///     Baz{
///         order: Ordering,
///     },
/// }
/// 
/// #[derive(ConstDebug)]
/// struct Unit;
/// 
/// #[derive(ConstDebug)]
/// struct Braced {
///     is_true: bool,
///     optional: Option<Unit>,
/// }
/// 
/// ```
/// 
/// ### Generic type
/// 
/// This example demonstrates the `#[cdeb(impls)]` attribute,
/// a workaround for deriving this trait for generic types,
/// specifying a list of impls of types that unconditionally implement const debug formatting
/// 
/// ```rust
/// 
/// use const_format::{ConstDebug, formatc};
/// 
/// use std::marker::PhantomData;
/// 
/// 
/// const S_U32: &str = formatc!("{:?}", Foo(10));
///
/// const S_STR: &str = formatc!("{:?}", Foo("hello"));
/// 
/// const S_PHANTOM: &str = formatc!("{:?}", Foo(PhantomData::<()>));
/// 
/// assert_eq!(S_U32, r#"Foo(10)"#);
/// assert_eq!(S_STR, r#"Foo("hello")"#);
/// assert_eq!(S_PHANTOM, r#"Foo(PhantomData)"#);
/// 
/// 
/// // This type implements const debug formatting three times:
/// // - `Foo<u32>`
/// // - `Foo<&str>`
/// // - `Foo<PhantomData<T>>`: with a generic `T`
/// #[derive(ConstDebug)]
/// #[cdeb(impls(
///     "Foo<u32>",
///     "Foo<&str>",
///     "<T> Foo<PhantomData<T>>",
/// ))]
/// struct Foo<T>(T);
/// 
/// ```
/// 
/// ### `is_a` attributes
/// 
/// This example demonstrates when you would use the `is_a` attributes.
/// 
/// ```rust
/// 
/// use const_format::{ConstDebug, formatc};
/// 
/// use std::{
///     cmp::Ordering,
///     marker::PhantomData,
///     num::Wrapping,
/// };
/// 
/// const STRUCT: &Struct = &Struct {
///     arr: [Ordering::Less, Ordering::Equal, Ordering::Greater, Ordering::Less],
///     opt: Some(Unit),
///     wrap: Wrapping(21),
///     not_option: Option(PhantomData), // This is not the standard library `Option`
/// };
/// 
/// const S_STRUCT: &str = formatc!("{STRUCT:#?}");
/// 
/// const EXPECTED: &str = "\
/// Struct {
///     arr: [
///         Less,
///         Equal,
///         Greater,
///         Less,
///     ],
///     opt: Some(
///         Unit,
///     ),
///     wrap: Wrapping(
///         21,
///     ),
///     not_option: Option(
///         PhantomData,
///     ),
/// }";
/// 
/// fn main(){
///     assert_eq!(S_STRUCT, EXPECTED);
/// }
/// 
/// #[derive(ConstDebug)]
/// struct Struct {
///     // `Ordering` implements const debug formatting,
///     // but `[Ordering; 4]` does not, so this attribute is required for the 
///     // derive macro to generate code to format this array field.
///     #[cdeb(is_a(array))]
///     arr: Array,
///     
///     // Attribute is required to tell the derive macro that this is an
///     // `Option` wrapping a user-defined type,
///     // since `Option<Unit>` doesn't implement const debug formatting.
///     #[cdeb(is_a(option))]
///     opt: Opt,
///     
///     // Attribute is required because `Wrapping<usize>` is a newtype struct
///     // that doesn't implement const debug formatting,
///     // so the derive generates code to format it.
///     #[cdeb(is_a(newtype))]
///     wrap: Wrapping<usize>,
///
///     // Attribute is required for the field to be treated as a user-defined type,
///     // otherwise it'd be assumed to be `Option` from the standard library.
///     #[cdeb(is_a(not_std))]
///     not_option: Option<u32>, 
///     
/// }
/// 
/// type Array = [Ordering; 4];
/// 
/// type Opt = std::option::Option<Unit>;
/// 
/// #[derive(ConstDebug)]
/// struct Unit;
/// 
/// #[derive(ConstDebug)]
/// struct Option<T>(PhantomData<T>);
/// 
/// ```
///
/// [`FormatMarker`]: ./marker_traits/trait.FormatMarker.html
/// [`impls attribute`]: #cdebimpls
///
///
///
/// 
/// ### Renamed import
/// 
/// This example demonstrates that you can use all the macros when the `const_format`
/// crate is renamed.
/// 
/// ```rust
/// # extern crate self as const_format;
/// # extern crate const_format as cfmt;
/// # fn main() {
/// use cfmt::{
///     for_examples::Unit,
///     ConstDebug, formatc,
/// };
/// 
/// #[derive(ConstDebug)]
/// #[cdeb(crate = "cfmt")]
/// struct Foo {
///     bar: &'static str,
///     baz: Unit
/// }
/// 
/// const TEXT: &str = formatc!("{:?}", Foo{ bar: "hello", baz: Unit });
/// 
/// assert_eq!(TEXT, r#"Foo { bar: "hello", baz: Unit }"#);
/// 
/// # }
/// ```
///
#[cfg_attr(feature = "__docsrs", doc(cfg(feature = "derive")))]
#[cfg(feature = "derive")]
pub use const_format_proc_macros::ConstDebug;


================================================
FILE: const_format/src/const_generic_concatcp.rs
================================================
//! Reimplements some stuff from concatcp to be const generic instead of macro generated

use crate::pmr::{LenAndArray, PArgument, PVariant};

#[doc(hidden)]
pub const fn __priv_concatenate<const LEN: usize>(input: &[PArgument]) -> LenAndArray<[u8; LEN]> {
    let mut out = LenAndArray {
        len: 0,
        array: [0u8; LEN],
    };

    crate::__for_range! { outer_i in 0..input.len() =>
        let current = &input[outer_i];

        match current.elem {
            PVariant::Str(s) => crate::__write_pvariant!(str, current, s => out),
            PVariant::Int(int) => crate::__write_pvariant!(int, current, int => out),
            PVariant::Char(c) => crate::__write_pvariant!(char, current, c => out),
        }
    }

    out
}


================================================
FILE: const_format/src/doctests.rs
================================================
//! This module tests for errors that happen in the expanded code,
//! errors detectable by the macro itself are tested in the proc macro crate.

#![allow(non_camel_case_types)]

///
/// ```rust
///
/// struct Foo<T>(T);
///
/// const_format::impl_fmt!{
///     impl[T,] Foo<T>
///     where[T: 'static,];
///
///     fn foo(){}
///
/// }
/// ```
///
/// ```compile_fail
///
/// struct Foo<T>(T);
///
/// const_format::impl_fmt!{
///     impl[T,] Foo<T>
///     where[asodkaspodaoskd,];
///
///     fn foo(){}
/// }
/// ```
///
/// ```compile_fail
///
/// struct Foo<T>(T);
///
/// const_format::impl_fmt!{
///     impl[T,] Foo<T>
///     where[T: T];
///
///     fn foo(){}
/// }
/// ```
///
#[cfg(feature = "fmt")]
pub struct ImplFmtWhereClause;

///
/// ```rust
///
/// #[derive(const_format::ConstDebug)]
/// struct Foo<T>(*const T)
/// where T: 'static;
///
/// fn main(){}
/// ```
///
/// ```compile_fail
///
/// #[derive(const_format::ConstDebug)]
/// struct Foo<T>(*const T)
/// where AAAA: AAAA;
///
/// fn main(){}
/// ```
///
#[cfg(feature = "derive")]
pub struct ConstDebugWhereClause;

/// ```rust
///
/// use const_format::StrWriterMut;
///
/// let mut len = 0;
/// let mut buffer = [0; 128];
///
/// let mut writer = StrWriterMut::from_custom(&mut buffer, &mut len);
///
/// writer.write_str("hello").unwrap();
///
/// assert_eq!(writer.as_bytes(), b"hello")
///
/// ```
///
/// ```compile_fail
///
/// use const_format::StrWriterMut;
///
/// let mut len = 0;
/// let mut buffer = [0; 128];
///
/// let mut writer = StrWriterMut::from_custom(&mut buffer, &mut len);
///
/// writer.write_str("hello").unwrap();
///
/// assert_eq!(writer.as_str(), "hello")
///
/// ```
///
#[cfg(feature = "fmt")]
pub struct AsStr_For_StrWriterMut_NoEncoding;

/// ```rust
///
/// const_format::assertc!(true, "foo");
///
/// ```
///
/// ```compile_fail
///
/// const_format::assertc!(false, "foo");
///
/// ```
///
/// # With a Formatting argument
///
/// ```rust
///
/// const_format::assertc!(
///     true,
///     "{foo}\n{foo:#?}\n{}",
///     |fmt| { const_format::call_debug_fmt!(array, [100u8], fmt ) },
///     foo = |fmt| { const_format::call_debug_fmt!(array, [(), ()], fmt ) },
/// );
///
/// const_format::assertc!(
///     true,
///     "{foo}\n{foo:#?}\n{}",
///     |fmt| const_format::call_debug_fmt!(array, [100u8], fmt ),
///     foo = |fmt| const_format::call_debug_fmt!(array, [(), ()], fmt ),
/// );
///
/// ```
///
/// ```compile_fail
///
/// const_format::assertc!(
///     false,
///     "{foo}\n{foo:#?}\n{}",
///     |fmt| { const_format::call_debug_fmt!(array, [100u8], fmt ) },
///     foo = |fmt| { const_format::call_debug_fmt!(array, [(), ()], fmt ) },
/// );
///
/// const_format::assertc!(
///     false,
///     "{foo}\n{foo:#?}\n{}",
///     |fmt| const_format::call_debug_fmt!(array, [100u8], fmt ),
///     foo = |fmt| const_format::call_debug_fmt!(array, [(), ()], fmt ),
/// );
///
/// ```
///
#[cfg(feature = "assertc")]
pub struct Assert;

/// # assert_eq
///
/// ```rust
///
/// const_format::assertc_eq!(0u8, 0u8, "foo");
///
/// ```
///
/// ```compile_fail
///
/// const_format::assertc_eq!(0u8, 10u8, "foo");
///
/// ```
///
/// # assert_ne
///
/// ```rust
///
/// const_format::assertc_ne!(0u8, 10u8, "foo");
///
/// ```
///
/// ```compile_fail
///
/// const_format::assertc_ne!(0u8, 0u8, "foo");
///
/// ```
///
#[cfg(feature = "assertc")]
pub struct AssertCmp;

/// ```rust
/// const_format::assertcp!(true, "foo");
/// ```
///
/// ```compile_fail
/// const_format::assertcp!(false, "foo");
/// ```
///
#[cfg(feature = "assertcp")]
pub struct AssertCP;

/// # assert_eq
///
/// ```rust
/// const_format::assertcp_eq!(0u8, 0u8, "foo");
/// ```
///
/// ```compile_fail
/// const_format::assertcp_eq!(0u8, 10u8, "foo");
/// ```
///
/// # assert_ne
///
/// ```rust
/// const_format::assertcp_ne!(0u8, 10u8, "foo");
/// ```
///
/// ```compile_fail
/// const_format::assertcp_ne!(0u8, 0u8, "foo");
/// ```
///
#[cfg(feature = "assertcp")]
pub struct AssertCPCmp;


================================================
FILE: const_format/src/equality.rs
================================================
#![allow(missing_docs, unused_variables)]

use crate::wrapper_types::PWrapper;

use core::{
    cmp::Ordering,
    marker::{PhantomData, PhantomPinned},
    num::{
        NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize, NonZeroU128,
        NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize,
    },
    ops::{Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive},
    sync::atomic::Ordering as AtomicOrdering,
};

////////////////////////////////////////////////////////////////////////////////

macro_rules! slice_of_const_eq {($($elem:ty),* $(,)?) => (
    $(
        impl PWrapper<&[$elem]> {
            /// This method is only available with the "assert" feature.
            pub const fn const_eq(&self, other: &[$elem]) -> bool {
                if self.0.len() != other.len() {
                    return false;
                }

                __for_range!{i in 0..self.0.len() =>
                    if !PWrapper(self.0[i]).const_eq(&other[i]) {
                        return false
                    }
                }
                true
            }
        }
    )*
)}

slice_of_const_eq! {
    &str,
}

macro_rules! slice_of_equal_op_impl {($($elem:ty),* $(,)?) => (
    $(
        impl PWrapper<&[$elem]> {
            /// This method is only available with the "assert" feature.
            pub const fn const_eq(&self, other: &[$elem]) -> bool {
                if self.0.len() != other.len() {
                    return false;
                }

                __for_range!{i in 0..self.0.len() =>
                    if self.0[i] != other[i] {
                        return false
                    }
                }
                true
            }
        }
    )*
)}

slice_of_equal_op_impl! {
    bool,
    char,
    u8, i8,
    u16, i16,
    u32, i32,
    u64, i64,
    u128, i128,
    usize, isize,
}

////////////////////////////////////////////////////////////////////////////////

macro_rules! impl_eq_for_option_prim {
    (
        (l=$l:ident, r=$r:ident)
        $( impl[$($impl_:tt)*] $type:ty = $comparison:expr; )*
    ) => (
        $(
            impl<$($impl_)*> PWrapper<Option<$type>> {
                /// This method is only available with the "assert" feature.
                pub const fn const_eq(&self, other:&Option<$type>) -> bool {
                    match (self.0, other) {
                        (Some($l), Some($r)) => $comparison,
                        (None, None) => true,
                        _ => false,
                    }
                }
            }
        )*
    )
}

impl_eq_for_option_prim! {
    (l=l, r=r)
    impl[] u8 = l == *r;
    impl[] i8 = l == *r;
    impl[] u16 = l == *r;
    impl[] i16 = l == *r;
    impl[] u32 = l == *r;
    impl[] i32 = l == *r;
    impl[] u64 = l == *r;
    impl[] i64 = l == *r;
    impl[] u128 = l == *r;
    impl[] i128 = l == *r;
    impl[] usize = l == *r;
    impl[] isize = l == *r;
    impl[] bool = l == *r;
    impl[] char = l == *r;
    impl[] &str = crate::slice_cmp::str_eq(l, r);
}

macro_rules! impl_eq_for_option {
    (
        (l=$l:ident, r=$r:ident)
        $( impl[$($impl_:tt)*] $type:ty = $comparison:expr; )*
    ) => (
        $(
            impl<$($impl_)*> PWrapper<$type> {
                /// This method is only available with the "assert" feature.
                pub const fn const_eq(&self, $r:&$type) -> bool {
                    let $l = self.0;
                    $comparison
                }
            }
        )*

        impl_eq_for_option_prim! {
            (l=$l, r=$r)
            $( impl[$($impl_)*] $type = $comparison; )*
        }
    )
}

impl_eq_for_option! {
    (l=l, r=r)

    impl[] NonZeroU8 = l.get() == r.get();
    impl[] NonZeroI8 = l.get() == r.get();
    impl[] NonZeroU16 = l.get() == r.get();
    impl[] NonZeroI16 = l.get() == r.get();
    impl[] NonZeroU32 = l.get() == r.get();
    impl[] NonZeroI32 = l.get() == r.get();
    impl[] NonZeroU64 = l.get() == r.get();
    impl[] NonZeroI64 = l.get() == r.get();
    impl[] NonZeroU128 = l.get() == r.get();
    impl[] NonZeroI128 = l.get() == r.get();
    impl[] NonZeroUsize = l.get() == r.get();
    impl[] NonZeroIsize = l.get() == r.get();
}

macro_rules! impl_equality {
    (
        (l=$l:ident, r=$r:ident)

        $( impl[$($impl_:tt)*] $type:ty = $comparison:expr ;)*
    ) => (
        $(
            impl<$($impl_)*> PWrapper<$type> {
                /// This method is only available with the "assert" feature.
                #[inline(always)]
                pub const fn const_eq(&self, $r: &$type) -> bool {
                    let $l = &self.0;
                    $comparison
                }
            }
        )*
    )
}

impl_equality! {
    (l=l, r=r)

    impl[T: ?Sized,] PhantomData<T> = true;
    impl[] PhantomPinned = true;
    impl[] () = true;

    impl[] Ordering = *l as u8 == *r as u8;
    impl[] AtomicOrdering = *l as u8 == *r as u8;

    impl[] Range<usize>            = l.start == r.start && l.end == r.end;
    impl[] RangeInclusive<usize>   = *l.start() == *r.start() && *l.end() == *r.end();
    impl[] RangeFrom<usize>        = l.start == r.start;
    impl[] RangeFull               = true;
    impl[] RangeTo<usize>          = l.end == r.end;
    impl[] RangeToInclusive<usize> = l.end == r.end;
}


================================================
FILE: const_format/src/fmt/error.rs
================================================
// <_< clippy you silly
#![allow(clippy::enum_variant_names)]

use core::fmt::{self, Display};

/// An error while trying to write into a StrWriter.
#[non_exhaustive]
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum Error {
    /// Attempted to write something into the buffer when there isn't enough space to write it.
    NotEnoughSpace,
    /// For compatibility with [`NotAsciiError`](../wrapper_types/struct.NotAsciiError.html)
    NotAscii,
    /// Attempted to index a string arguent by an range where one of the bounds
    /// was not on a char boundary.
    NotOnCharBoundary,
}

impl Display for Error {
    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
        match self {
            Self::NotEnoughSpace => {
                fmt.write_str("The was not enough space to write the formatted output")
            }
            Self::NotAscii => fmt.write_str("Attempted to write non-ascii text"),
            Self::NotOnCharBoundary => {
                fmt.write_str("Attempted to index a byte that's not on a char boundary.")
            }
        }
    }
}

macro_rules! index_vars{
    ($self:ident, $index:ident; $($variant:ident),* $(,)? ) => (
        enum Index{
            $($variant,)*
        }

        let $index = match &$self {
            $(Error::$variant{..} => 3300 + Index::$variant as usize,)*
        };
    )
}

impl Error {
    /// For panicking at compile-time, with a compile-time error that says what the error is.
    #[track_caller]
    pub const fn unwrap<T>(&self) -> T {
        index_vars! {
            self,i;
            NotEnoughSpace,
            NotAscii,
            NotOnCharBoundary,
        };

        match self {
            Error::NotEnoughSpace => ["The was not enough space to write the formatted output"][i],
            Error::NotAscii => ["Attempted to write non-ascii text"][i],
            Error::NotOnCharBoundary => {
                ["Attempted to index a byte that's not on a char boundary."][i]
            }
        };
        loop {}
    }
}

////////////////////////////////////////////////////////////////////////////////

/// The return type of most formatting functions
pub type Result<T = (), E = Error> = core::result::Result<T, E>;

////////////////////////////////////////////////////////////////////////////////

/// For converting types to [`const_format::Result`]
///
/// [`const_format::Result`]: ./type.Result.html
pub struct ToResult<T>(pub T);

impl ToResult<()> {
    ///
    #[inline(always)]
    pub const fn to_result(self) -> Result {
        Ok(())
    }
}

impl ToResult<Result> {
    ///
    #[inline(always)]
    pub const fn to_result(self) -> Result {
        self.0
    }
}


================================================
FILE: const_format/src/fmt/formatter.rs
================================================
use crate::{
    fmt::{Error, FormattingFlags, NoEncoding, StrWriter, StrWriterMut},
    utils::saturate_range,
    wrapper_types::{AsciiStr, PWrapper},
};

use core::ops::Range;

////////////////////////////////////////////////////////////////////////////////

/// For computing how long a formatted string would be.
///
/// This is what the [`formatc`] macro uses to precalculate the length of its returned `&str`.
///
/// # Example
///
/// ```rust
///
/// use const_format::fmt::{ComputeStrLength, Error, Formatter, FormattingFlags, StrWriter};
/// use const_format::{try_, writec, unwrap};
///
/// const fn write_sum(mut f: Formatter<'_>) -> Result<(), Error> {
///     let l = 7u8;
///     let r = 8u8;
///     writec!(f, "{} + {} = {}", l, r, l + r)
/// }
///
/// const LEN: usize = {
///     let mut computer = ComputeStrLength::new();
///     unwrap!(write_sum(computer.make_formatter(FormattingFlags::NEW)));
///     computer.len()
/// };
///
/// // The type annotation coerces a `&mut StrWriter<[u8; LEN]>`
/// // to a `&mut StrWriter<[u8]>` (the type parameter defaults to `[u8]`)
/// let writer: &mut StrWriter = &mut StrWriter::new([0; LEN]);
///
/// write_sum(writer.make_formatter(FormattingFlags::NEW)).unwrap();
///
/// assert_eq!(writer.as_str(), "7 + 8 = 15");
/// assert_eq!(writer.len(), LEN);
/// assert_eq!(writer.capacity(), LEN);
///
/// ```
///
/// [`formatc`]: ../macro.formatc.html
///
///
pub struct ComputeStrLength {
    len: usize,
}

impl ComputeStrLength {
    /// Constructs a ComputeStrLength of length 0.
    pub const fn new() -> Self {
        Self { len: 0 }
    }

    /// Constructs a `Formatter`,
    /// which instead of writing to a buffer it adds the computed length into this.
    pub const fn make_formatter(&mut self, flags: FormattingFlags) -> Formatter<'_> {
        Formatter {
            margin: 0,
            flags,
            writer: WriterBackend::Length(self),
        }
    }

    /// Adds `len` to the calculated length.
    pub const fn add_len(&mut self, len: usize) {
        self.len += len;
    }

    /// The length of the string when formatted.
    pub const fn len(&self) -> usize {
        self.len
    }

    /// Whether the length of the computed string is zero.
    pub const fn is_empty(&self) -> bool {
        self.len == 0
    }

    /// For borrowing this mutably in macros,just takes and returns a `&mut Self`.
    #[inline(always)]
    pub const fn borrow_mutably(&mut self) -> &mut Self {
        self
    }
}

////////////////////////////////////////////////////////////////////////////////

enum WriterBackend<'w> {
    Str(StrWriterMut<'w, NoEncoding>),
    Length(&'w mut ComputeStrLength),
}

////////////////////////////////////////////////////////////////////////////////

/// A handle for writing formatted output.
///
/// `Formatter` writes utf8 encoded text, it can't be used to write arbitrary bytes.
///
/// # FormattingFlags
///
/// Types can change how they're formatted based on the value returned by `.flags()`,
/// for more details on that you can read the documentation for [`FormattingFlags`].
///
/// # Construction
///
/// This type can be constructed in these ways:
///
/// - From a pair of mutable reference to a [`StrWriter`] and a [`FormattingFlags`],
/// with the [`from_sw`] constructor.
///
/// - From a pair of [`StrWriterMut`] and [`FormattingFlags`],
/// with the [`from_sw_mut`] constructor.
///
/// - From a [`ComputeStrLength`], by calling its
/// [`make_formatter`](./struct.ComputeStrLength.html#method.make_formatter) method.
/// This allows computing the length of formatted output without writing to anything.
///
/// - From a triple of `[u8]` and `usize` mutable references, and a [`FormattingFlags`],
/// with the [`from_custom_cleared`] constructor,
/// or the [`from_custom`] constructor.
///
/// # Errors
///
/// The `write_*` methods can only return an `Error::NotEnoughSpace`,
/// when they do, the formatter was not written to, so you can try again with a shorter input.
///
/// In the case of the `debug_*` methods / the `Debug*` structs,
/// they can return a `Error::NotEnoughSpace` when their `finish` method is called,
/// not as soon as it happens.
///
/// # Examples
///
/// ### Display formatting
///
/// This example demonstrates how you can do display formatting with a Formatter.
///
/// If you want to write a braced struct/variant you can use [`DebugStruct`],
/// or [`DebugTuple`] for tuple structs/variants.
///
/// ```rust
///
/// use const_format::{Error, Formatter, FormattingFlags, StrWriter};
/// use const_format::{impl_fmt, try_};
///
/// struct Foo;
///
/// impl_fmt!{
///     impl[] Foo;
///     
///     const fn const_display_fmt(&self, mut f: Formatter<'_>) -> Result<(), Error> {
///         let string = "foo bar baz";
///         try_!(f.write_u8_display(100));
///         try_!(f.write_str(" "));
///         try_!(f.write_str_range(string, 4..7));
///         try_!(f.write_str("\n\n\n...figters"));
///         Ok(())
///     }
/// }
///
/// // We have to coerce `&mut StrWriter<[u8; 256]>` to `&mut StrWriter` to call the
/// // `make_formatter` method.
/// let writer: &mut StrWriter = &mut StrWriter::new([0; 256]);
///
/// let flags = FormattingFlags::NEW.set_binary();
///
/// // The Display formatters from this crate don't care which NumberFormatting you pass,
/// // they'll just write integers as decimal.
/// Foo.const_display_fmt(writer.make_formatter(flags));
///
/// assert_eq!(writer.as_str(), "100 bar\n\n\n...figters");
/// ```
///
/// <span id = "write_array_example"></span>
/// ### Writing to an array
///
/// This example demonstrates how you can use a Formatter to write to a byte slice.
///
/// You can use the [`from_custom`] constructor if you need to start writing from
/// anywhere other than 0.
///
/// ```rust
///
/// use const_format::{Error, Formatter, FormattingFlags, StrWriter};
/// use const_format::{impl_fmt, try_, writec};
///
/// const fn write_int(int: u32, buffer: &mut [u8]) -> Result<usize, Error> {
///     let mut len = 0;
///     let mut f = Formatter::from_custom_cleared(buffer, &mut len, FormattingFlags::NEW);
///     try_!(writec!(f, "{0},{0:x},{0:b}", int));
///     Ok(len)
/// }
///
/// let mut buffer = [0;64];
///
/// let written = write_int(17, &mut buffer).unwrap();
///
/// let string = std::str::from_utf8(&buffer[..written])
///     .expect("Formatter only writes valid UTF8");
///
/// assert_eq!(string, "17,11,10001");
///
/// ```
///
///
/// [`DebugStruct`]: crate::fmt::DebugStruct
/// [`DebugTuple`]: crate::fmt::DebugTuple
/// [`StrWriter`]: crate::fmt::StrWriter
/// [`StrWriterMut`]: crate::fmt::StrWriterMut
/// [`ComputeStrLength`]: crate::fmt::ComputeStrLength
/// [`from_sw`]: #method.from_sw
/// [`from_sw_mut`]: #method.from_sw_mut
/// [`from_custom_cleared`]: #method.from_custom_cleared
/// [`from_custom`]:  #method.from_custom
/// [`NumberFormatting`]: crate::fmt::NumberFormatting
/// [`FormattingFlags`]: crate::fmt::FormattingFlags
///
pub struct Formatter<'w> {
    margin: u16,
    flags: FormattingFlags,
    writer: WriterBackend<'w>,
}

const MARGIN_STEP: u16 = 4;

impl<'w> Formatter<'w> {
    /// Constructs a `Formatter`.
    ///
    /// # Example
    ///
    /// ```rust
    ///
    /// use const_format::{Error, Formatter, FormattingFlags, StrWriter};
    /// use const_format::try_;
    ///
    /// const fn inner(mut f: Formatter<'_>) -> Result<(), Error> {
    ///     try_!(f.write_str_range("ABCDEF", 2..4));
    ///     try_!(f.write_str(" N"));
    ///     try_!(f.write_ascii_repeated(b'o', 10));
    ///     Ok(())
    /// }
    ///
    /// // We have to coerce `&mut StrWriter<[u8; 128]>` to `&mut StrWriter` to call the
    /// // `as_str` method.
    /// let writer: &mut StrWriter = &mut StrWriter::new([0; 128]);
    /// inner(Formatter::from_sw(writer, FormattingFlags::NEW)).unwrap();
    ///
    /// assert_eq!(writer.as_str(), "CD Noooooooooo");
    ///
    /// ```
    #[inline]
    pub const fn from_sw(writer: &'w mut StrWriter, flags: FormattingFlags) -> Self {
        Self {
            margin: 0,
            flags,
            // safety:
            // Formatter only writes valid utf8, which is valid for both
            // encoding type parameters that StrWriterMut can have(Utf8Encoding / NoEncoding).
            writer: WriterBackend::Str(unsafe { writer.as_mut().into_byte_encoding() }),
        }
    }

    /// Constructs a `Formatter`.
    ///
    /// # Example
    ///
    /// ```rust
    ///
    /// use const_format::{Error, Formatter, FormattingFlags, StrWriterMut};
    /// use const_format::try_;
    ///
    /// const fn inner(mut f: Formatter<'_>) -> Result<(), Error> {
    ///     try_!(f.write_str_range("DVDVDVD", 2..5));
    ///     try_!(f.write_str(" N"));
    ///     try_!(f.write_ascii_repeated(b'o', 10));
    ///     Ok(())
    /// }
    ///
    /// let mut len = 0;
    /// let mut buffer = [0; 128];
    ///
    /// let mut writer = StrWriterMut::from_custom_cleared(&mut buffer, &mut len);
    ///
    /// // We need to call `.reborrow()`, because otherwise the `StrWriterMut` is moved.
    /// inner(Formatter::from_sw_mut(writer.reborrow(), FormattingFlags::NEW)).unwrap();
    ///
    /// assert_eq!(writer.as_str(), "DVD Noooooooooo");
    ///
    /// ```
    #[inline]
    pub const fn from_sw_mut<E: 'static>(
        writer: StrWriterMut<'w, E>,
        flags: FormattingFlags,
    ) -> Self {
        Self {
            margin: 0,
            flags,
            // safety:
            // Formatter only writes valid utf8, which is valid for both
            // encoding type parameters that StrWriterMut can have(Utf8Encoding / NoEncoding).
            writer: WriterBackend::Str(unsafe { writer.into_byte_encoding() }),
        }
    }

    /// Construct a `Formatter` from a byte slice.
    ///
    /// `Formatter` only writes utf8, which means that if `&buffer[..length]` is valid utf8,
    /// then `buffer` will continue to be `utf8` after being written by the `Formatter`.
    ///
    /// # Example
    ///
    /// This example demonstrates how you can use a Formatter to write to a byte slice
    /// that had some text written to it already.
    ///
    /// ```rust
    ///
    /// use const_format::{Error, Formatter, FormattingFlags, StrWriter};
    /// use const_format::{impl_fmt, try_, writec};
    ///
    /// ///
    /// /// # Safety
    /// ///
    /// /// `&buffer[..start]` must be valid utf8.
    /// const fn write_int(
    ///     int: u32,
    ///     buffer: &mut [u8],
    ///     start: usize,
    /// ) -> Result<usize, Error> {
    ///     let mut len = start;
    ///     let mut f = Formatter::from_custom(buffer, &mut len, FormattingFlags::NEW);
    ///     try_!(writec!(f, "{0},{0:x},{0:b}", int));
    ///     Ok(len)
    /// }
    ///
    /// let start_str = "The number is ";
    /// let mut buffer = [0;64];
    /// buffer[..start_str.len()].copy_from_slice(start_str.as_bytes());
    ///
    /// let new_len = write_int(20, &mut buffer, start_str.len()).unwrap();
    ///
    /// let string = std::str::from_utf8(&buffer[..new_len])
    ///     .expect("Formatter only writes valid UTF8");
    ///
    /// assert_eq!(string, "The number is 20,14,10100");
    ///
    /// ```
    #[inline]
    pub const fn from_custom(
        buffer: &'w mut [u8],
        length: &'w mut usize,
        flags: FormattingFlags,
    ) -> Self {
        Self {
            margin: 0,
            flags,
            writer: WriterBackend::Str(StrWriterMut::from_custom(buffer, length)),
        }
    }

    /// Construct a `Formatter`from a byte slice.
    ///
    /// # Example
    ///
    /// For an example of using this method you can look at
    /// [the type level docs](#write_array_example)
    ///
    #[inline]
    pub const fn from_custom_cleared(
        buffer: &'w mut [u8],
        length: &'w mut usize,
        flags: FormattingFlags,
    ) -> Self {
        *length = 0;
        Self {
            margin: 0,
            flags,
            writer: WriterBackend::Str(StrWriterMut::from_custom(buffer, length)),
        }
    }

    /// Gets the formatting flags associated with this `Formatter`.
    #[inline(always)]
    pub const fn flags(&self) -> FormattingFlags {
        self.flags
    }

    /// Gets how much indentation a data structure is printed with.
    pub const fn margin(&self) -> usize {
        self.margin as usize
    }

    #[inline(always)]
    const fn increment_margin(&mut self) -> &mut Self {
        self.margin += 4;
        self
    }

    #[inline(always)]
    const fn decrement_margin(&mut self) {
        self.margin -= 4;
    }
}

impl<'w> Formatter<'w> {
    /// For borrowing this mutably in macros,just takes and returns a `&mut Self`.
    #[inline(always)]
    pub const fn borrow_mutably(&mut self) -> &mut Self {
        self
    }

    /// Constructs a reborrow of this formatter, using `flags` as the formatting flags.
    ///
    /// The return value inherits the margin from this Formatter.
    ///
    /// This method exists because the [`writec`] macro gets a formatter from any writer
    /// by calling a `make_formatter` method.
    ///
    /// # Example
    ///
    /// This example demonstrates how you can change the flags when writing a field.
    ///
    /// ```rust
    ///
    /// use const_format::{Error, Formatter, PWrapper};
    /// use const_format::{coerce_to_fmt, formatc, impl_fmt, try_};
    ///
    /// use std::ops::RangeInclusive;
    ///
    /// struct Foo{
    ///     x: u32,
    ///     y: RangeInclusive<usize>,
    ///     z: u32,
    /// }
    ///
    /// impl_fmt!{
    ///     impl Foo;
    ///
    ///     pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
    ///         let mut f = f.debug_struct("Foo");
    ///         try_!(PWrapper(self.x).const_debug_fmt(f.field("x")));
    ///         
    ///         let mut fmt_y = f.field("y");
    ///         let flags = fmt_y.flags().set_binary();
    ///         try_!(coerce_to_fmt!(&self.y).const_debug_fmt(&mut fmt_y.make_formatter(flags)));
    ///
    ///         try_!(PWrapper(self.z).const_debug_fmt(f.field("z")));
    ///         f.finish()
    ///     }
    /// }
    ///
    /// const FOO: Foo = Foo {
    ///     x: 15,
    ///     y: 16..=31,
    ///     z: 32,
    /// };
    /// const S: &str = formatc!("{FOO:#?}");
    ///
    /// const EXPECTED: &str = "\
    /// Foo {
    ///     x: 15,
    ///     y: 0b10000..=0b11111,
    ///     z: 32,
    /// }\
    /// ";
    ///
    /// assert_eq!(S, EXPECTED);
    /// ```
    ///
    /// [`writec`]: ../macro.writec.html
    ///
    pub const fn make_formatter(&mut self, flags: FormattingFlags) -> Formatter<'_> {
        Formatter {
            margin: self.margin,
            flags,
            writer: match &mut self.writer {
                WriterBackend::Str(x) => WriterBackend::Str(x.reborrow()),
                WriterBackend::Length(x) => WriterBackend::Length(x),
            },
        }
    }

    /// For debug writing a braced struct, or braced variant,
    /// taking its name as a parameter
    ///
    /// # Examples
    ///
    /// For examples of using this method, you can look at the docs for [`DebugStruct`]
    ///
    /// [`DebugStruct`]: ./struct.DebugStruct.html
    ///
    #[inline]
    pub const fn debug_struct(&mut self, name: &str) -> DebugStruct<'_, 'w> {
        let err = self.write_str(name);
        DebugStruct {
            fmt: self.increment_margin(),
            wrote_field: false,
            err,
        }
    }

    /// For debug writing a tuple struct, or tuple variant,taking its name as a parameter
    ///
    /// # Examples
    ///
    /// For examples of using this method, you can look at the docs for [`DebugTuple`]
    ///
    /// [`DebugTuple`]: ./struct.DebugTuple.html
    ///
    #[inline]
    pub const fn debug_tuple(&mut self, name: &str) -> DebugTuple<'_, 'w> {
        let err = self.write_str(name);
        DebugTuple {
            fmt: self.increment_margin(),
            wrote_field: false,
            err,
        }
    }

    /// For debug writing a list/array.
    ///
    /// # Examples
    ///
    /// For examples of using this method, you can look at the docs for [`DebugList`]
    ///
    /// [`DebugList`]: ./struct.DebugList.html
    ///
    #[inline]
    pub const fn debug_list(&mut self) -> DebugList<'_, 'w> {
        DebugList {
            fmt: self.increment_margin(),
            wrote_field: false,
            err: Ok(()),
        }
    }

    /// For debug writing a set.
    ///
    /// # Examples
    ///
    /// For examples of using this method, you can look at the docs for [`DebugSet`]
    ///
    /// [`DebugSet`]: ./struct.DebugSet.html
    ///
    #[inline]
    pub const fn debug_set(&mut self) -> DebugSet<'_, 'w> {
        DebugSet {
            fmt: self.increment_margin(),
            wrote_field: false,
            err: Ok(()),
        }
    }
}

////////////////////////////////////////////////////////////////////////////////

macro_rules! trys {
    ($e:expr,$self:ident) => {
        if let result @ Err(_) = $e {
            $self.err = result;
        }
    };
}

const COLON_SPACE_LEN: usize = ": ".len();
const COMMA_SPACE_LEN: usize = ", ".len();
const COMMA_NL_LEN: usize = ",\n".len();

macro_rules! field_method_impl {
    ($
        self: ident, $open_space:expr, $open_newline:expr;
        len(|$fmt_len:ident| $($write_name_len:tt)*)
        fmt(|$writer:ident| $($write_name_fmt:tt)*)
    ) => ({
        match &mut $self.fmt.writer {
            WriterBackend::Length($fmt_len)=>{
                let $fmt_len = &mut **$fmt_len;

                const OPEN_SPACE: usize = $open_space.len();
                const OPEN_NEWLINE: usize = $open_newline.len();

                let is_alternate = $self.fmt.flags.is_alternate();
                $fmt_len.add_len(match ($self.wrote_field, is_alternate) {
                    (false, false) => OPEN_SPACE,
                    (false, true) => OPEN_NEWLINE + $self.fmt.margin as usize,
                    (true , false) => COMMA_SPACE_LEN,
                    (true , true) => COMMA_NL_LEN + $self.fmt.margin as usize,
                });
                $($write_name_len)*
            }
            WriterBackend::Str($writer)=>{
                let $writer = &mut *$writer;

                let is_alternate = $self.fmt.flags.is_alternate();
                let sep = match ($self.wrote_field, is_alternate) {
                    (false, false)=>$open_space,
                    (false, true)=>$open_newline,
                    (true, false)=>", ",
                    (true, true)=>",\n",
                };
                trys!($writer.write_str(sep), $self);
                if is_alternate {
                    trys!($writer.write_ascii_repeated(b' ', $self.fmt.margin as usize), $self);
                }
                $($write_name_fmt)*
            }
        }
        $self.wrote_field = true;

        $self.fmt
    })
}

macro_rules! finish_method_impl {
    ($self: ident, $close_token:expr, $space_close:expr) => {{
        if let result @ Err(_) = $self.err {
            return result;
        }

        $self.fmt.decrement_margin();
        if $self.wrote_field {
            match &mut $self.fmt.writer {
                WriterBackend::Length(fmt_len) => {
                    let fmt_len = &mut **fmt_len;

                    const CLOSE_TOKEN: usize = $close_token.len();
                    const SPACE_CLOSE: usize = $space_close.len();

                    if $self.fmt.flags.is_alternate() {
                        fmt_len.add_len(COMMA_NL_LEN + $self.fmt.margin as usize + CLOSE_TOKEN);
                    } else {
                        fmt_len.add_len(SPACE_CLOSE);
                    }
                    Ok(())
                }
                WriterBackend::Str(writer) => {
                    let writer = &mut *writer;

                    if $self.fmt.flags.is_alternate() {
                        try_!(writer.write_str(",\n"));
                        try_!(writer.write_ascii_repeated(b' ', $self.fmt.margin as usize));
                        writer.write_str($close_token)
                    } else {
                        writer.write_str($space_close)
                    }
                }
            }
        } else {
            Ok(())
        }
    }};
}

////////////////////////////////////////////////////////////////////////////////

/// A helper struct for debug formatting a braced struct, or braced variant.
///
/// # Example
///
/// This example demonstrates how you can debug format a struct,
/// and a braced variant.
///
/// ```rust
///
/// use const_format::{Error, Formatter};
/// use const_format::{call_debug_fmt, coerce_to_fmt, formatc, impl_fmt, try_};
///
/// fn main() {
///     const STRUC: &str = formatc!("{:?}", Foo { a: 5, b: [8, 13, 21], c: "34" });
///     const ENUM_: &str = formatc!("{:?}", Bar::Baz { d: false, e: None });
///     
///     assert_eq!(STRUC, "Foo { a: 5, b: [8, 13, 21], c: \"34\" }");
///     assert_eq!(ENUM_, "Baz { d: false, e: None }");
/// }
///
/// struct Foo{
///     a: u32,
///     b: [u32; 3],
///     c: &'static str,
/// }
///
/// enum Bar {
///     Baz{
///         d: bool,
///         e: Option<bool>,
///     }
/// }
///
/// impl_fmt!{
///     impl Foo;
///     
///     const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
///         let mut f = f.debug_struct("Foo");
///         try_!(coerce_to_fmt!(&self.a).const_debug_fmt(f.field("a")));
///         try_!(coerce_to_fmt!(&self.b).const_debug_fmt(f.field("b")));
///         try_!(coerce_to_fmt!(&self.c).const_debug_fmt(f.field("c")));
///         f.finish()
///     }
/// }
///
/// impl_fmt!{
///     impl Bar;
///     
///     const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
///         match self {
///             Bar::Baz{d, e} => {
///                 let mut f = f.debug_struct("Baz");
///                 
///                 // This macro allows debug formatting some generic types that
///                 // don't have a const_debug_fmt fn, like Options which wrap non-std types.
///                 call_debug_fmt!(std, d, f.field("d"));
///                 call_debug_fmt!(Option, e, f.field("e"));
///                 
///                 f.finish()
///             }
///         }
///     }
/// }
///
///
///
/// ```
pub struct DebugStruct<'f, 'w> {
    fmt: &'f mut Formatter<'w>,
    wrote_field: bool,
    err: Result<(), Error>,
}

impl<'f, 'w> DebugStruct<'f, 'w> {
    /// Adds a field to the formatted output.
    pub const fn field(&mut self, name: &str) -> &mut Formatter<'w> {
        field_method_impl!(
            self, " { ", " {\n";
            len(|fmt_len|
                fmt_len.add_len(name.len() + COLON_SPACE_LEN);
            )
            fmt(|writer|
                trys!(writer.write_str(name), self);
                trys!(writer.write_str(": "), self);
            )
        )
    }

    /// Finishes writing the struct/variant,
    /// and if anything went wrong in the `field` method,returns an error.
    pub const fn finish(self) -> Result<(), Error> {
        finish_method_impl!(self, "}", " }")
    }
}

////////////////////////////////////////////////////////////////////////////////

/// For debug formatting a tuple struct, or tuple variant.
///
/// # Example
///
/// This example demonstrates how you can debug format a tuple struct,
/// and an enum of tuple variants.
///
/// ```rust
///
/// use const_format::{Error, Formatter};
/// use const_format::{call_debug_fmt, coerce_to_fmt, formatc, impl_fmt, try_};
///
/// fn main() {
///     const STRUC: &str = formatc!("{:?}", Foo(5, [8, 13, 21], "34"));
///     const ENUM_: &str = formatc!("{:?}", Bar::Baz(false, None));
///     
///     assert_eq!(STRUC, "Foo(5, [8, 13, 21], \"34\")");
///     assert_eq!(ENUM_, "Baz(false, None)");
/// }
///
/// struct Foo(u32, [u32; 3], &'static str);
///
/// enum Bar {
///     Baz(bool, Option<bool>),
/// }
///
/// impl_fmt!{
///     impl Foo;
///     
///     const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
///         let mut f = f.debug_tuple("Foo");
///         try_!(coerce_to_fmt!(&self.0).const_debug_fmt(f.field()));
///         try_!(coerce_to_fmt!(&self.1).const_debug_fmt(f.field()));
///         try_!(coerce_to_fmt!(&self.2).const_debug_fmt(f.field()));
///         f.finish()
///     }
/// }
///
/// impl_fmt!{
///     impl Bar;
///     
///     const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
///         match self {
///             Bar::Baz(f0, f1) => {
///                 let mut f = f.debug_tuple("Baz");
///                 
///                 // This macro allows debug formatting some generic types that
///                 // don't have a const_debug_fmt fn, like Options which wrap non-std types.
///                 call_debug_fmt!(std, f0, f.field());
///                 call_debug_fmt!(Option, f1, f.field());
///                 
///                 f.finish()
///             }
///         }
///     }
/// }
///
///
///
/// ```
pub struct DebugTuple<'f, 'w> {
    fmt: &'f mut Formatter<'w>,
    wrote_field: bool,
    err: Result<(), Error>,
}

impl<'f, 'w> DebugTuple<'f, 'w> {
    /// Adds a field to the formatted output.
    pub const fn field(&mut self) -> &mut Formatter<'w> {
        field_method_impl!(self, "(", "(\n"; len(|fmt_len|) fmt(|writer|) )
    }

    /// Finishes writing the tuple struct/variant,
    /// and if anything went wrong in the `field` method,returns an error.
    pub const fn finish(self) -> Result<(), Error> {
        finish_method_impl!(self, ")", ")")
    }
}

////////////////////////////////////////////////////////////////////////////////

macro_rules! finish_listset_method_impl {
    ($self: ident, $close_token:expr, $open_close:expr) => {{
        if let result @ Err(_) = $self.err {
            return result;
        }

        match &mut $self.fmt.writer {
            WriterBackend::Length(fmt_len) => {
                let fmt_len = &mut **fmt_len;
                const CLOSE_TOKEN: usize = $close_token.len();
                const OPEN_CLOSE: usize = $open_close.len();

                $self.fmt.margin -= MARGIN_STEP;
                if $self.wrote_field {
                    if $self.fmt.flags.is_alternate() {
                        fmt_len.add_len(COMMA_NL_LEN + $self.fmt.margin as usize);
                    }
                    fmt_len.add_len(CLOSE_TOKEN);
                } else {
                    fmt_len.add_len(OPEN_CLOSE);
                }
                Ok(())
            }
            WriterBackend::Str(writer) => {
                let writer = &mut *writer;

                $self.fmt.margin -= MARGIN_STEP;
                let margin = $self.fmt.margin as usize;
                if $self.wrote_field {
                    if $self.fmt.flags.is_alternate() {
                        try_!(writer.write_str(",\n"));
                        try_!(writer.write_ascii_repeated(b' ', margin));
                    }
                    writer.write_str($close_token)
                } else {
                    writer.write_str($open_close)
                }
            }
        }
    }};
}

////////////////////////////////////////////////////////////////////////////////

/// For debug formatting a list/array.
///
/// # Example
///
/// This example demonstrates how you can debug format a custom type as a list.
///
/// ```rust
///
/// use const_format::{Error, Formatter};
/// use const_format::{formatc, impl_fmt, try_};
///
/// use std::ops::Range;
///
/// fn main() {
///     const LIST: &str = formatc!("{:?}", RangeList(0..5));
///     
///     assert_eq!(LIST, "[0, 1, 2, 3, 4]");
/// }
///
/// struct RangeList(Range<usize>);
///
/// impl_fmt!{
///     impl RangeList;
///     
///     const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
///         let mut f = f.debug_list();
///         let mut i = self.0.start;
///         while i < self.0.end {
///             try_!(f.entry().write_usize_display(i));
///             i+=1;
///         }
///         f.finish()
///     }
/// }
///
/// ```
///
pub struct DebugList<'f, 'w> {
    fmt: &'f mut Formatter<'w>,
    wrote_field: bool,
    err: Result<(), Error>,
}

impl<'f, 'w> DebugList<'f, 'w> {
    /// Adds a list entry to the formatted output
    pub const fn entry(&mut self) -> &mut Formatter<'w> {
        field_method_impl!(self, "[", "[\n"; len(|fmt_len|) fmt(|writer|) )
    }

    /// Finishes writing the list,
    /// and if anything went wrong in the `entry` method,returns an error.
    pub const fn finish(self) -> Result<(), Error> {
        finish_listset_method_impl!(self, "]", "[]")
    }
}

////////////////////////////////////////////////////////////////////////////////

/// For debug formatting a set.
///
/// # Example
///
/// This example demonstrates how you can debug format a custom type as a set.
///
/// ```rust
///
/// use const_format::{Error, Formatter};
/// use const_format::{formatc, impl_fmt, try_};
///
/// use std::ops::Range;
///
/// fn main() {
///     const SET: &str = formatc!("{:?}", StrSet(&["foo", "bar", "baz"]));
///     
///     assert_eq!(SET, r#"{"foo", "bar", "baz"}"#);
/// }
///
/// struct StrSet(&'static [&'static str]);
///
/// impl_fmt!{
///     impl StrSet;
///     
///     const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
///         let mut f = f.debug_set();
///         let mut i = 0;
///         while i < self.0.len() {
///             try_!(f.entry().write_str_debug(self.0[i]));
///             i+=1;
///         }
///         f.finish()
///     }
/// }
///
/// ```
///
pub struct DebugSet<'f, 'w> {
    fmt: &'f mut Formatter<'w>,
    wrote_field: bool,
    err: Result<(), Error>,
}

impl<'f, 'w> DebugSet<'f, 'w> {
    /// Adds a set entry to the formatted output
    pub const fn entry(&mut self) -> &mut Formatter<'w> {
        field_method_impl!(self, "{", "{\n"; len(|fmt_len|) fmt(|writer|) )
    }

    /// Finishes writing the set,
    /// and if anything went wrong in the `entry` method,returns an error.
    pub const fn finish(self) -> Result<(), Error> {
        finish_listset_method_impl!(self, "}", "{}")
    }
}

////////////////////////////////////////////////////////////////////////////////

macro_rules! delegate_write_methods {
    (
        shared_attrs $shared_attrs:tt
        $(
            $(#[$attrs:meta])*
            fn $method:ident($($arg:ident: $arg_ty:ty ),* $(,)* )
            length = $len:expr;
        )*
    ) => (
        impl Formatter<'_>{
            $(
                delegate_write_methods!{
                    @inner
                    shared_attrs $shared_attrs
                    $(#[$attrs])*
                    fn $method($($arg: $arg_ty ),* )
                    length = $len;
                }
            )*
        }
    );
    (
        @inner
        shared_attrs (
            $( #[$shared_attrs:meta] )*
        )
        $(#[$attrs:meta])*
        fn $method:ident($($arg:ident: $arg_ty:ty ),* $(,)* )
        length = $len:expr;
    ) => (
        $( #[$shared_attrs] )*
        $(#[$attrs])*
        pub const fn $method(&mut self, $($arg: $arg_ty ),*  ) -> Result<(), Error> {
            match &mut self.writer {
                WriterBackend::Length(fmt_len)=>{
                    fmt_len.add_len($len);
                    Ok(())
                }
                WriterBackend::Str(writer)=>{
                    writer.$method($($arg,)*)
                }
            }
        }
    )
}

delegate_write_methods! {
    shared_attrs()

    /// Writes `&string[range]` into this Formatter.
    ///
    /// This is a workaround for being unable to do `&foo[start..end]` at compile time.
    ///
    /// # Example
    ///
    /// ```rust
    ///
    /// use const_format::{Formatter, FormattingFlags, StrWriter};
    ///
    /// let writer: &mut StrWriter = &mut StrWriter::new([0; 16]);
    /// let mut fmt = writer.make_formatter(FormattingFlags::NEW);
    ///
    /// let _ = fmt.write_str_range("FOO BAR BAZ", 4..7);
    ///
    /// assert_eq!(writer.as_str(), "BAR");
    ///
    /// ```
    ///
    fn write_str_range(string: &str, range: Range<usize>)
    length = calculate_display_len(string.as_bytes(), &range);

    /// Writes `string` into this Formatter.
    ///
    /// # Example
    ///
    /// ```rust
    ///
    /// use const_format::{Formatter, FormattingFlags, StrWriter};
    ///
    /// let writer: &mut StrWriter = &mut StrWriter::new([0; 16]);
    /// let mut fmt = writer.make_formatter(FormattingFlags::NEW);
    ///
    /// let _ = fmt.write_str("FOO BAR BAZ");
    ///
    /// assert_eq!(writer.as_str(), "FOO BAR BAZ");
    ///
    /// ```
    ///
    fn write_str(string: &str)
    length = string.len();

    /// Writes `character` into this Formatter.
    ///
    /// # Example
    ///
    /// ```rust
    ///
    /// use const_format::{Formatter, FormattingFlags, StrWriter};
    ///
    /// let writer: &mut StrWriter = &mut StrWriter::new([0; 4]);
    /// let mut fmt = writer.make_formatter(FormattingFlags::NEW);
    ///
    /// let _ = fmt.write_char('a');
    /// let _ = fmt.write_char('b');
    /// let _ = fmt.write_char('c');
    ///
    /// assert_eq!(writer.as_str(), "abc");
    ///
    /// ```
    ///
    fn write_char(character: char)
    length = crate::char_encoding::char_display_len(character);

    /// Writes `&ascii[range]` into this formatter.
    ///
    /// This is a workaround for being unable to do `&foo[start..end]` at compile time.
    ///
    /// # Example
    ///
    /// ```rust
    ///
    /// use const_format::{Formatter, FormattingFlags, StrWriter, ascii_str};
    ///
    /// let writer: &mut StrWriter = &mut StrWriter::new([0; 16]);
    /// let mut fmt = writer.make_formatter(FormattingFlags::NEW);
    ///
    /// let _ = fmt.write_ascii_range(ascii_str!("FOO BAR BAZ"), 4..7);
    ///
    /// assert_eq!(writer.as_str(), "BAR");
    ///
    /// ```
    ///
    fn write_ascii_range(ascii: AsciiStr<'_>, range: Range<usize>)
    length = calculate_display_len(ascii.as_bytes(), &range);

    /// Writes `ascii` into this formatter.
    ///
    /// # Example
    ///
    /// ```rust
    ///
    /// use const_format::{Formatter, FormattingFlags, StrWriter, ascii_str};
    ///
    /// let writer: &mut StrWriter = &mut StrWriter::new([0; 16]);
    /// let mut fmt = writer.make_formatter(FormattingFlags::NEW);
    ///
    /// let _ = fmt.write_ascii(ascii_str!("FOO BAR BAZ"));
    ///
    /// assert_eq!(writer.as_str(), "FOO BAR BAZ");
    ///
    /// ```
    ///
    fn write_ascii(ascii: AsciiStr<'_>)
    length = ascii.len();

    /// Writes the ascii `character` into this formatter `repeated` times.
    ///
    /// If `character` is greater than 127,
    /// this writes `character - 128` as an ascii character.
    ///
    /// # Example
    ///
    /// ```rust
    ///
    /// use const_format::{Formatter, FormattingFlags, StrWriter};
    ///
    /// let writer: &mut StrWriter = &mut StrWriter::new([0; 16]);
    /// let mut fmt = writer.make_formatter(FormattingFlags::NEW);
    ///
    /// let _ = fmt.write_ascii_repeated(b'A', 10);
    ///
    /// assert_eq!(writer.as_str(), "AAAAAAAAAA");
    ///
    /// ```
    ///
    fn write_ascii_repeated(character: u8,repeated: usize)
    length = repeated;

    /// Writes `string` into this formatter, with debug formatting.
    ///
    /// This is a workaround for being unable to do `&foo[start..end]` at compile time.
    ///
    /// # Example
    ///
    /// ```rust
    ///
    /// use const_format::{Formatter, FormattingFlags, StrWriter};
    ///
    /// let writer: &mut StrWriter = &mut StrWriter::new([0; 16]);
    /// let mut fmt = writer.make_formatter(FormattingFlags::NEW);
    ///
    /// let _ = fmt.write_str_range_debug("FOO\nBAR\tBAZ", 3..8);
    ///
    /// assert_eq!(writer.as_str(), r#""\nBAR\t""#);
    ///
    /// ```
    ///
    fn write_str_range_debug(string: &str, range: Range<usize>)
    length = calculate_display_len_debug_range(string.as_bytes(), &range);

    /// Writes `string` into this formatter, with debug formatting.
    ///
    /// # Example
    ///
    /// ```rust
    ///
    /// use const_format::{Formatter, FormattingFlags, StrWriter};
    ///
    /// let writer: &mut StrWriter = &mut StrWriter::new([0; 16]);
    /// let mut fmt = writer.make_formatter(FormattingFlags::NEW);
    ///
    /// let _ = fmt.write_str_debug("FOO\nBAR\tBAZ");
    ///
    /// assert_eq!(writer.as_str(), r#""FOO\nBAR\tBAZ""#);
    ///
    /// ```
    ///
    fn write_str_debug(string: &str)
    length = PWrapper(string.as_bytes()).compute_utf8_debug_len();

    /// Writes `character` into this Formatter, with debug formatting.
    ///
    /// # Example
    ///
    /// ```rust
    ///
    /// use const_format::{Formatter, FormattingFlags, StrWriter};
    ///
    /// let writer: &mut StrWriter = &mut StrWriter::new([0; 64]);
    /// let mut fmt = writer.make_formatter(FormattingFlags::NEW);
    ///
    /// let _ = fmt.write_str(" ");
    /// let _ = fmt.write_char_debug('\\');
    /// let _ = fmt.write_str(" ");
    /// let _ = fmt.write_char_debug('A');
    /// let _ = fmt.write_str(" ");
    /// let _ = fmt.write_char_debug('0');
    /// let _ = fmt.write_str(" ");
    /// let _ = fmt.write_char_debug('\'');
    /// let _ = fmt.write_str(" ");
    ///
    /// assert_eq!(writer.as_str(), r#" '\\' 'A' '0' '\'' "#);
    ///
    /// ```
    ///
    fn write_char_debug(character: char)
    length = crate::char_encoding::char_debug_len(character);

    /// Writes `&ascii[range]` into this formatter, with debug formatting.
    ///
    /// This is a workaround for being unable to do `&foo[start..end]` at compile time.
    ///
    /// # Example
    ///
    /// ```rust
    ///
    /// use const_format::{Formatter, FormattingFlags, StrWriter, ascii_str};
    ///
    /// let writer: &mut StrWriter = &mut StrWriter::new([0; 16]);
    /// let mut fmt = writer.make_formatter(FormattingFlags::NEW);
    ///
    /// let _ = fmt.write_ascii_range_debug(ascii_str!("FOO\nBAR\tBAZ"), 3..8);
    ///
    /// assert_eq!(writer.as_str(), r#""\nBAR\t""#);
    ///
    /// ```
    ///
    fn write_ascii_range_debug(ascii: AsciiStr<'_>,range: Range<usize>)
    length = calculate_display_len_debug_range(ascii.as_bytes(), &range);

    /// Writes `ascii` into this formatter, with debug formatting.
    ///
    /// # Example
    ///
    /// ```rust
    ///
    /// use const_format::{Formatter, FormattingFlags, StrWriter, ascii_str};
    ///
    /// let writer: &mut StrWriter = &mut StrWriter::new([0; 16]);
    /// let mut fmt = writer.make_formatter(FormattingFlags::NEW);
    ///
    /// let _ = fmt.write_ascii_debug(ascii_str!("FOO\nBAR\tBAZ"));
    ///
    /// assert_eq!(writer.as_str(), r#""FOO\nBAR\tBAZ""#);
    ///
    /// ```
    ///
    fn write_ascii_debug(ascii: AsciiStr<'_>)
    length = PWrapper(ascii.as_bytes()).compute_utf8_debug_len();


    /// Write `n` with display formatting.
    ///
    /// # Example
    ///
    /// ```rust
    ///
    /// use const_format::{Formatter, FormattingFlags, StrWriter, ascii_str};
    ///
    /// let writer: &mut StrWriter = &mut StrWriter::new([0; 16]);
    /// let mut fmt = writer.make_formatter(FormattingFlags::NEW);
    ///
    /// let _ = fmt.write_u8_display(13);
    /// let _ = fmt.write_u8_display(21);
    /// let _ = fmt.write_u8_display(34);
    ///
    /// assert_eq!(writer.as_str(), "132134");
    ///
    /// ```
    ///
    fn write_u8_display(n: u8)
    length = PWrapper(n).compute_display_len(FormattingFlags::NEW);
}

delegate_write_methods! {
    shared_attrs(
        /// Writes `n` with display formatting
        ///
        /// For an example,
        /// you can look at the one for the [`write_u8_display`] method.
        ///
        /// [`write_u8_display`]: #method.write_u8_display
    )

    fn write_u16_display(n: u16)
    length = PWrapper(n).compute_display_len(FormattingFlags::NEW);

    fn write_u32_display(n: u32)
    length = PWrapper(n).compute_display_len(FormattingFlags::NEW);

    fn write_u64_display(n: u64)
    length = PWrapper(n).compute_display_len(FormattingFlags::NEW);

    fn write_u128_display(n: u128)
    length = PWrapper(n).compute_display_len(FormattingFlags::NEW);

    fn write_usize_display(n: usize)
    length = PWrapper(n).compute_display_len(FormattingFlags::NEW);

    fn write_i8_display(n: i8)
    length = PWrapper(n).compute_display_len(FormattingFlags::NEW);

    fn write_i16_display(n: i16)
    length = PWrapper(n).compute_display_len(FormattingFlags::NEW);

    fn write_i32_display(n: i32)
    length = PWrapper(n).compute_display_len(FormattingFlags::NEW);

    fn write_i64_display(n: i64)
    length = PWrapper(n).compute_display_len(FormattingFlags::NEW);

    fn write_i128_display(n: i128)
    length = PWrapper(n).compute_display_len(FormattingFlags::NEW);

    fn write_isize_display(n: isize)
    length = PWrapper(n).compute_display_len(FormattingFlags::NEW);
}

macro_rules! delegate_integer_debug_methods {
    (
        shared_attrs $shared_attrs:tt
        $(
            $(#[$attrs:meta])*
            fn $method:ident($($arg:ident: $arg_ty:ty ),* $(,)* )
            length = |$flags:ident| $len:expr;
        )*
    ) => (
        impl Formatter<'_>{
            $(
                delegate_integer_debug_methods!{
                    @inner
                    shared_attrs $shared_attrs
                    $(#[$attrs])*
                    fn $method($($arg: $arg_ty ),*)
                    length = |$flags| $len;
                }
            )*
        }
    );
    (
        @inner
        shared_attrs (
            $( #[$shared_attrs:meta] )*
        )
        $(#[$attrs:meta])*
        fn $method:ident($($arg:ident: $arg_ty:ty ),* $(,)* )
        length = |$flags:ident| $len:expr;
    ) => (
        $( #[$shared_attrs] )*
        $(#[$attrs])*
        pub const fn $method(&mut self, $($arg: $arg_ty ),*  ) -> Result<(), Error> {
            let $flags = self.flags;

            match &mut self.writer {
                WriterBackend::Length(fmt_len)=>{
                    fmt_len.add_len($len);
                    Ok(())
                }
                WriterBackend::Str(writer)=>{
                    writer.$method($($arg,)* $flags)
                }
            }
        }
    )
}

delegate_integer_debug_methods! {
    shared_attrs()

    /// Writes `n` with debug formatting.
    ///
    /// # Example
    ///
    /// ```rust
    ///
    /// use const_format::{Formatter, FormattingFlags, StrWriter};
    ///
    /// fn debug_fmt(writer: &mut StrWriter, flag: FormattingFlags) -> &str {
    ///     writer.clear();
    ///     let mut fmt = Formatter::from_sw(writer, flag);
    ///     let _ = fmt.write_u8_debug(63);
    ///     writer.as_str()
    /// }
    ///
    /// let reg_flag = FormattingFlags::NEW.set_alternate(false);
    /// let alt_flag = FormattingFlags::NEW.set_alternate(true);
    ///
    /// let writer: &mut StrWriter = &mut StrWriter::new([0; 64]);
    ///
    /// assert_eq!(debug_fmt(writer, reg_flag),                   "63"     );
    /// assert_eq!(debug_fmt(writer, reg_flag.set_hexadecimal()), "3F"     );
    /// assert_eq!(debug_fmt(writer, reg_flag.set_lower_hexadecimal()), "3f"     );
    /// assert_eq!(debug_fmt(writer, reg_flag.set_binary()),      "111111" );
    /// assert_eq!(debug_fmt(writer, alt_flag),                   "63"     );
    /// assert_eq!(debug_fmt(writer, alt_flag.set_hexadecimal()), "0x3F"   );
    /// assert_eq!(debug_fmt(writer, alt_flag.set_lower_hexadecimal()), "0x3f"   );
    /// assert_eq!(debug_fmt(writer, alt_flag.set_binary()),      "0b111111");
    ///
    /// ```
    ///
    fn write_u8_debug(n: u8)
    length = |flags| PWrapper(n).compute_debug_len(flags);
}

delegate_integer_debug_methods! {
    shared_attrs(
        /// Writes `n` with debug formatting.
        ///
        /// For an example,
        /// you can look at the one for the [`write_u8_debug`] method.
        ///
        /// [`write_u8_debug`]: #method.write_u8_debug
    )

    fn write_u16_debug(n: u16)
    length = |flags| PWrapper(n).compute_debug_len(flags);

    fn write_u32_debug(n: u32)
    length = |flags| PWrapper(n).compute_debug_len(flags);

    fn write_u64_debug(n: u64)
    length = |flags| PWrapper(n).compute_debug_len(flags);

    fn write_u128_debug(n: u128)
    length = |flags| PWrapper(n).compute_debug_len(flags);

    fn write_usize_debug(n: usize)
    length = |flags| PWrapper(n).compute_debug_len(flags);

    fn write_i8_debug(n: i8)
    length = |flags| PWrapper(n).compute_debug_len(flags);

    fn write_i16_debug(n: i16)
    length = |flags| PWrapper(n).compute_debug_len(flags);

    fn write_i32_debug(n: i32)
    length = |flags| PWrapper(n).compute_debug_len(flags);

    fn write_i64_debug(n: i64)
    length = |flags| PWrapper(n).compute_debug_len(flags);

    fn write_i128_debug(n: i128)
    length = |flags| PWrapper(n).compute_debug_len(flags);

    fn write_isize_debug(n: isize)
    length = |flags| PWrapper(n).compute_debug_len(flags);
}

#[inline(always)]
const fn calculate_display_len(b: &[u8], range: &Range<usize>) -> usize {
    let Range { start, end } = saturate_range(b, range);
    end - start
}

#[inline(always)]
const fn calculate_display_len_debug_range(b: &[u8], range: &Range<usize>) -> usize {
    let Range { start, end } = saturate_range(b, range);
    PWrapper(b).compute_utf8_debug_len_in_range(start..end)
}


================================================
FILE: const_format/src/fmt/std_type_impls/ranges.rs
================================================
use crate::{
    fmt::{Error, Formatter},
    marker_traits::{FormatMarker, IsAFormatMarker, IsStdKind},
    wrapper_types::PWrapper,
};

use core::ops::{Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive};

////////////////////////////////////////////////////////////////////////////////

impl FormatMarker for Range<usize> {
    type Kind = IsStdKind;
    type This = Self;
}

impl<T> IsAFormatMarker<IsStdKind, Range<usize>, T> {
    #[inline(always)]
    pub const fn coerce(self, range: &Range<usize>) -> PWrapper<Range<usize>> {
        PWrapper(Range {
            start: range.start,
            end: range.end,
        })
    }
}

impl PWrapper<Range<usize>> {
    const RANGE: &'static str = "..";

    #[inline(always)]
    pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
        try_!(PWrapper(self.0.start).const_debug_fmt(f));
        try_!(PWrapper(Self::RANGE).const_display_fmt(f));
        try_!(PWrapper(self.0.end).const_debug_fmt(f));
        Ok(())
    }
}

///////////////////////////////////////////////////////////////////////////////

impl FormatMarker for RangeFrom<usize> {
    type Kind = IsStdKind;
    type This = Self;
}

impl<T> IsAFormatMarker<IsStdKind, RangeFrom<usize>, T> {
    #[inline(always)]
    pub const fn coerce(self, range: &RangeFrom<usize>) -> PWrapper<RangeFrom<usize>> {
        PWrapper(RangeFrom { start: range.start })
    }
}

impl PWrapper<RangeFrom<usize>> {
    const RANGE: &'static str = "..";

    #[inline(always)]
    pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
        try_!(PWrapper(self.0.start).const_debug_fmt(f));
        try_!(PWrapper(Self::RANGE).const_display_fmt(f));
        Ok(())
    }
}

///////////////////////////////////////////////////////////////////////////////

impl FormatMarker for RangeTo<usize> {
    type Kind = IsStdKind;
    type This = Self;
}

impl<T> IsAFormatMarker<IsStdKind, RangeTo<usize>, T> {
    #[inline(always)]
    pub const fn coerce(self, range: &RangeTo<usize>) -> PWrapper<RangeTo<usize>> {
        PWrapper(RangeTo { end: range.end })
    }
}

impl PWrapper<RangeTo<usize>> {
    const RANGE: &'static str = "..";

    #[inline(always)]
    pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
        try_!(PWrapper(Self::RANGE).const_display_fmt(f));
        try_!(PWrapper(self.0.end).const_debug_fmt(f));
        Ok(())
    }
}

///////////////////////////////////////////////////////////////////////////////

impl FormatMarker for RangeToInclusive<usize> {
    type Kind = IsStdKind;
    type This = Self;
}

impl<T> IsAFormatMarker<IsStdKind, RangeToInclusive<usize>, T> {
    #[inline(always)]
    pub const fn coerce(
        self,
        range: &RangeToInclusive<usize>,
    ) -> PWrapper<RangeToInclusive<usize>> {
        PWrapper(RangeToInclusive { end: range.end })
    }
}

impl PWrapper<RangeToInclusive<usize>> {
    const RANGE: &'static str = "..=";

    #[inline(always)]
    pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
        try_!(PWrapper(Self::RANGE).const_display_fmt(f));
        try_!(PWrapper(self.0.end).const_debug_fmt(f));
        Ok(())
    }
}

///////////////////////////////////////////////////////////////////////////////

impl FormatMarker for RangeInclusive<usize> {
    type Kind = IsStdKind;
    type This = Self;
}

impl<T> IsAFormatMarker<IsStdKind, RangeInclusive<usize>, T> {
    #[inline(always)]
    pub const fn coerce(self, range: &RangeInclusive<usize>) -> PWrapper<RangeInclusive<usize>> {
        PWrapper(RangeInclusive::new(*range.start(), *range.end()))
    }
}

impl PWrapper<RangeInclusive<usize>> {
    const RANGE: &'static str = "..=";

    #[inline(always)]
    pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
        try_!(PWrapper(*self.0.start()).const_debug_fmt(f));
        try_!(PWrapper(Self::RANGE).const_display_fmt(f));
        try_!(PWrapper(*self.0.end()).const_debug_fmt(f));
        Ok(())
    }
}

///////////////////////////////////////////////////////////////////////////////

impl FormatMarker for RangeFull {
    type Kind = IsStdKind;
    type This = Self;
}

impl<T> IsAFormatMarker<IsStdKind, RangeFull, T> {
    #[inline(always)]
    pub const fn coerce(self, _: &RangeFull) -> PWrapper<RangeFull> {
        PWrapper(..)
    }
}

impl PWrapper<RangeFull> {
    const RANGE: &'static str = "..";

    #[inline(always)]
    pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
        PWrapper(Self::RANGE).const_display_fmt(f)
    }
}


================================================
FILE: const_format/src/fmt/std_type_impls.rs
================================================
#![allow(missing_docs)]

use crate::{
    fmt::{Error, Formatter},
    marker_traits::IsStdKind,
    wrapper_types::PWrapper,
};

mod ranges;

////////////////////////////////////////////////////////////////////////////////

impl PWrapper<&str> {
    pub const fn const_display_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
        f.write_str(self.0)
    }

    pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
        f.write_str_debug(self.0)
    }
}

impl PWrapper<bool> {
    pub const fn const_display_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
        f.write_str(if self.0 { "true" } else { "false" })
    }

    #[inline(always)]
    pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
        self.const_display_fmt(f)
    }
}

impl PWrapper<char> {
    pub const fn const_display_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
        f.write_char(self.0)
    }

    #[inline(always)]
    pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
        f.write_char_debug(self.0)
    }
}

macro_rules! slice_of_std_impl {($($elem:ty),* $(,)?) => (
    $(

        impl PWrapper<&[$elem]> {
            pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
                let mut f = f.debug_list();
                __for_range!{i in 0..self.0.len() =>
                    try_!(PWrapper(self.0[i]).const_debug_fmt(f.entry()));
                }
                f.finish()
            }
        }
    )*
)}

slice_of_std_impl! {
    &str,
    bool,
    char,
    u8, i8,
    u16, i16,
    u32, i32,
    u64, i64,
    u128, i128,
    usize, isize,
}

////////////////////////////////////////////////////////////////////////////////

use core::{
    marker::{PhantomData, PhantomPinned},
    num::{
        NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize, NonZeroU128,
        NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize,
    },
    ptr::NonNull,
};

impl_fmt! {
    is_std_type;

    impl[T,] Option<NonNull<T>>;
    impl[] Option<NonZeroU8>;
    impl[] Option<NonZeroI8>;
    impl[] Option<NonZeroU16>;
    impl[] Option<NonZeroI16>;
    impl[] Option<NonZeroU32>;
    impl[] Option<NonZeroI32>;
    impl[] Option<NonZeroU64>;
    impl[] Option<NonZeroI64>;
    impl[] Option<NonZeroU128>;
    impl[] Option<NonZeroI128>;
    impl[] Option<NonZeroUsize>;
    impl[] Option<NonZeroIsize>;
    impl[] Option<u8>;
    impl[] Option<i8>;
    impl[] Option<u16>;
    impl[] Option<i16>;
    impl[] Option<u32>;
    impl[] Option<i32>;
    impl[] Option<u64>;
    impl[] Option<i64>;
    impl[] Option<u128>;
    impl[] Option<i128>;
    impl[] Option<usize>;
    impl[] Option<isize>;
    impl[] Option<bool>;
    impl[] Option<char>;
    impl['a,] Option<&'a str>;

    pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
        match self.0 {
            Some(x) => {
                let mut f = f.debug_tuple("Some");
                try_!(PWrapper(x).const_debug_fmt(f.field()));
                f.finish()
            },
            None => f.write_str("None"),
        }
    }
}

macro_rules! non_zero_impls {
    ($($ty:ident,)*) => (
        $(
            std_kind_impl!{ impl[] $ty }

            impl PWrapper<$ty> {
                #[inline(always)]
                pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
                    PWrapper(self.0.get()).const_debug_fmt(f)
                }

                #[inline(always)]
                pub const fn const_display_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
                    PWrapper(self.0.get()).const_display_fmt(f)
                }
            }
        )*
    )
}

non_zero_impls! {
    NonZeroU8, NonZeroI8, NonZeroU16, NonZeroI16,
    NonZeroU32, NonZeroI32, NonZeroU64, NonZeroI64,
    NonZeroU128, NonZeroI128, NonZeroUsize, NonZeroIsize,
}

std_kind_impl! { impl[T,] *mut T }
// Unfortunately, can't print pointer addresses at compile-time.
impl<T> PWrapper<*mut T> {
    const PTR: &'static str = "<pointer>";

    #[inline(always)]
    pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
        f.write_str(Self::PTR)
    }
}

std_kind_impl! { impl[T,] *const T }
impl<T> PWrapper<*const T> {
    #[inline(always)]
    pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
        PWrapper(self.0 as *mut T).const_debug_fmt(f)
    }
}

std_kind_impl! { impl[T,] NonNull<T> }
impl<T> PWrapper<NonNull<T>> {
    #[inline(always)]
    pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
        PWrapper(self.0.as_ptr()).const_debug_fmt(f)
    }
}

macro_rules! impl_std_marker_type {
    (
        $( impl[$($impl_:tt)*] $type:ty = $tyname:expr ;)*
    ) => (
        $(
            std_kind_impl!{ impl[$($impl_)*] $type }

            impl<$($impl_)*> PWrapper<$type> {
                const NAME: &'static str = $tyname;

                #[inline(always)]
                pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
                    PWrapper(Self::NAME).const_display_fmt(f)
                }
            }
        )*
    )
}

impl_std_marker_type! {
    impl[T: ?Sized,] PhantomData<T> = "PhantomData";
    impl[] PhantomPinned = "PhantomPinned";
    impl[] () = "()";
}

////////////////////////////////////////////////////////////////////////////////

use core::{cmp::Ordering, sync::atomic::Ordering as AtomicOrdering};

impl_fmt! {
    is_std_type;

    impl AtomicOrdering;

    pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
        match self.0 {
            AtomicOrdering::Relaxed => f.write_str("Relaxed"),
            AtomicOrdering::Release => f.write_str("Release"),
            AtomicOrdering::Acquire => f.write_str("Acquire"),
            AtomicOrdering::AcqRel => f.write_str("AcqRel"),
            AtomicOrdering::SeqCst => f.write_str("SeqCst"),
            _ => f.write_str("<core::atomic::Ordering>"),
        }
    }
}

impl_fmt! {
    is_std_type;

    impl Ordering;

    pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
        match self.0 {
            Ordering::Less => f.write_str("Less"),
            Ordering::Equal => f.write_str("Equal"),
            Ordering::Greater => f.write_str("Greater"),
        }
    }
}


================================================
FILE: const_format/src/fmt/str_writer.rs
================================================
use super::{Error, Formatter, FormattingFlags, StrWriterMut, Utf8Encoding};

use core::marker::PhantomData;

////////////////////////////////////////////////////////////////////////////////

/// A wrapper over an array usable to build up a `&str` at compile-time.
///
/// # Calling methods
///
/// [Certain `StrWriter` methods](#certain-methods) require
/// a `StrWriter<[u8]>` to be called,
/// and since constructing `StrWriter` from an array produces a `StrWriter<[u8; N]>`,
/// it must be cast to call them.
///
/// `StrWriter`'s type parameter defaults to `[u8]`,
/// so every instance of a `StrWriter` as a *type* is a `StrWriter<[u8]>`.
///
/// Example of casting it:
///
/// ```rust
/// # use const_format::StrWriter;
/// let writer: &mut StrWriter<[u8; 8]> = &mut StrWriter::new([0; 8]);
///
/// // Casts `&StrWriter<[u8; 8]>` to `&StrWriter`
/// writer.unsize();
///
/// // Casts `&StrWriter<[u8; 8]>` to `&StrWriter`
/// writer.r();
///
/// // Coerces the `&mut StrWriter<[u8; 8]>` to `&mut StrWriter`
/// let _writer: &mut StrWriter = writer;
///
/// // Casts `&mut StrWriter<[u8; 8]>` to `StrWriterMut<'_>`,
/// // which defines methods for mutating `StrWriter`
/// let _writer = writer.as_mut();
///
/// # drop(writer);
/// ```
///
/// # StrWriterMut
///
/// `StrWriter` can be borrowed into a [`StrWriterMut`],
/// which provides methods for writing a formatted string.
///
/// Example:
///
/// ```rust
/// use const_format::StrWriter;
///
/// let mut buffer: &mut StrWriter = &mut StrWriter::new([0; 100]);
///
/// let mut writer = buffer.as_mut();
/// writer.write_str("Your password is: ");
/// writer.write_str_debug("PASSWORD");
///
/// assert_eq!(writer.as_str(), r#"Your password is: "PASSWORD""#);
///
/// ```
///
/// # Examples
///
/// ### Formatting into associated constant
///
/// This example shows how you can construct a formatted `&'static str` from associated constants.
///
/// ```rust
///
/// use const_format::{StrWriter, writec, unwrap};
///
/// trait Num {
///     const V: u32;
/// }
///
/// struct Two;
///
/// impl Num for Two {
///     const V: u32 = 2;
/// }
///
/// struct Three;
///
/// impl Num for Three {
///     const V: u32 = 3;
/// }
///
/// struct Mul<L, R>(L, R);
///
/// const fn compute_str(l: u32, r: u32) -> StrWriter<[u8; 128]> {
///     let mut writer = StrWriter::new([0; 128]);
///     unwrap!(writec!(writer, "{} * {} == {}", l, r, l * r ));
///     writer
/// }
///
/// impl<L: Num, R: Num> Mul<L, R> {
///     const __STR: &'static StrWriter<[u8]> = &compute_str(L::V, R::V);
///     const STR: &'static str = Self::__STR.as_str();
/// }
///
/// assert_eq!(Mul::<Two,Three>::STR, "2 * 3 == 6");
/// assert_eq!(Mul::<Three,Three>::STR, "3 * 3 == 9");
///
/// ```
///
/// [`StrWriterMut`]: ./struct.StrWriterMut.html
///
#[derive(Debug, Copy, Clone)]
pub struct StrWriter<A: ?Sized = [u8]> {
    pub(super) len: usize,
    pub(super) buffer: A,
}

impl<A> StrWriter<A> {
    /// Constructs a `StrWriter` from a `u8` array
    pub const fn new(array: A) -> Self {
        Self {
            len: 0,
            buffer: array,
        }
    }
}

impl<A: ?Sized> StrWriter<A> {
    /// Accesses the underlying buffer immutably.
    ///
    /// # Example
    ///
    /// ```rust
    /// use const_format::StrWriter;
    ///
    /// let buffer: &mut StrWriter = &mut StrWriter::new([0; 7]);
    /// assert_eq!(buffer.buffer(), &[0; 7]);
    ///
    /// buffer.as_mut().write_str("foo")?;
    /// assert_eq!(buffer.buffer(), b"foo\0\0\0\0");
    ///
    /// buffer.as_mut().write_str("bar")?;
    /// assert_eq!(buffer.buffer(), b"foobar\0");
    ///
    /// # Ok::<(), const_format::Error>(())
    /// ```
    #[inline(always)]
    pub const fn buffer(&self) -> &A {
        &self.buffer
    }

    /// How long the string this wrote is.
    ///
    /// # Example
    ///
    /// ```rust
    /// use const_format::StrWriter;
    ///
    /// let buffer: &mut StrWriter = &mut StrWriter::new([0; 64]);
    /// assert_eq!(buffer.len(), 0);
    ///
    /// buffer.as_mut().write_str("foo")?;
    /// assert_eq!(buffer.len(), 3);
    ///
    /// buffer.as_mut().write_str("bar")?;
    /// assert_eq!(buffer.len(), 6);
    ///
    /// # Ok::<(), const_format::Error>(())
    /// ```
    #[inline(always)]
    pub const fn len(&self) -> usize {
        self.len
    }

    /// Checks whether the string this wrote is empty.
    ///
    /// # Example
    ///
    /// ```rust
    /// use const_format::StrWriter;
    ///
    /// let buffer: &mut StrWriter = &mut StrWriter::new([0; 64]);
    /// assert!( buffer.is_empty() );
    ///
    /// buffer.as_mut().write_str("foo")?;
    /// assert!( !buffer.is_empty() );
    ///
    /// # Ok::<(), const_format::Error>(())
    /// ```
    #[inline]
    pub const fn is_empty(&self) -> bool {
        self.len == 0
    }
}

/// <span id="certain-methods"></span>
impl StrWriter {
    /// Gets the maximum length for a string written into this.
    ///
    /// Trying to write more that the capacity causes an error,
    /// returning back an `Err(Error::NotEnoughSpace)`
    ///
    /// # Example
    ///
    /// ```rust
    /// use const_format::{Error, StrWriter};
    ///
    /// let buffer: &mut StrWriter = &mut StrWriter::new([0; 64]);
    /// assert_eq!(buffer.capacity(), 64);
    ///
    /// buffer.as_mut().write_ascii_repeated(b'A', 64)?;
    /// assert_eq!(buffer.capacity(), 64);
    ///
    /// assert_eq!(buffer.as_mut().write_str("-").unwrap_err(), Error::NotEnoughSpace);
    /// assert_eq!(buffer.capacity(), 64);
    ///
    /// # Ok::<(), const_format::Error>(())
    /// ```
    #[inline(always)]
    pub const fn capacity(&self) -> usize {
        self.buffer.len()
    }

    /// Checks how many more bytes can be written.
    ///
    /// # Example
    ///
    /// ```rust
    /// use const_format::{Error, StrWriter};
    ///
    /// let buffer: &mut StrWriter = &mut StrWriter::new([0; 64]);
    /// assert_eq!(buffer.remaining_capacity(), 64);
    ///
    /// buffer.as_mut().write_str("foo")?;
    /// assert_eq!(buffer.remaining_capacity(), 61);
    ///
    /// buffer.as_mut().write_ascii_repeated(b'a', 61)?;
    /// assert_eq!(buffer.remaining_capacity(), 0);
    ///
    /// assert_eq!(buffer.as_mut().write_str(" ").unwrap_err(), Error::NotEnoughSpace);
    ///
    /// # Ok::<(), const_format::Error>(())
    /// ```
    #[inline]
    pub const fn remaining_capacity(&self) -> usize {
        self.buffer.len() - self.len
    }

    /// Truncates this `StrWriter` to `length`.
    ///
    /// If `length` is greater than the current length, this does nothing.
    ///
    /// # Errors
    ///
    /// Returns an `Error::NotOnCharBoundary` if `length` is not on a char boundary.
    ///
    /// # Example
    ///
    /// ```rust
    /// use const_format::{Error, StrWriter};
    ///
    /// let buffer: &mut StrWriter = &mut StrWriter::new([0; 64]);
    ///
    /// buffer.as_mut().write_str("foo bâr baz");
    /// assert_eq!(buffer.as_str(), "foo bâr baz");
    ///
    /// assert_eq!(buffer.truncate(6).unwrap_err(), Error::NotOnCharBoundary);
    ///
    /// buffer.truncate(3)?;
    /// assert_eq!(buffer.as_str(), "foo");
    ///
    /// buffer.as_mut().write_str("ooooooo");
    /// assert_eq!(buffer.as_str(), "fooooooooo");
    ///
    /// # Ok::<(), const_format::Error>(())
    /// ```
    #[inline]
    pub const fn truncate(&mut self, length: usize) -> Result<(), Error> {
        self.as_mut().truncate(length)
    }

    /// Truncates this `StrWriter` to length 0.
    ///
    /// # Example
    ///
    /// ```rust
    /// use const_format::{Error, StrWriter};
    ///
    /// let buffer: &mut StrWriter = &mut StrWriter::new([0; 64]);
    ///
    /// buffer.as_mut().write_str("foo")?;
    /// assert_eq!(buffer.as_str(), "foo");
    ///
    /// buffer.clear();
    /// assert_eq!(buffer.as_str(), "");
    /// assert!(buffer.is_empty());
    ///
    /// buffer.as_mut().write_str("bar");
    /// assert_eq!(buffer.as_str(), "bar");
    ///
    /// # Ok::<(), const_format::Error>(())
    /// ```
    #[inline]
    pub const fn clear(&mut self) {
        self.len = 0;
    }

    /// This is the same as `as_bytes`
    ///
    /// (this method only exists for backwards compatibility)
    #[inline(always)]
    #[deprecated(since = "0.2.36", note = "redundant, same as `as_bytes`")]
    pub const fn as_bytes_alt(&self) -> &[u8] {
        crate::utils::slice_up_to_len(&self.buffer, self.len)
    }

    /// This is the same as `as_str`
    ///
    /// (this method only exists for backwards compatibility)
    #[inline(always)]
    #[deprecated(since = "0.2.36", note = "redundant, same as `as_str`")]
    pub const fn as_str_alt(&self) -> &str {
        self.as_str()
    }

    /// Gets the written part of this `StrWriter` as a `&str`
    ///
    /// # Example
    ///
    /// ```rust
    ///
    /// use const_format::StrWriter;
    /// use const_format::{unwrap, writec};
    ///
    ///
    /// const CAP: usize = 128;
    ///
    /// const __STR: &StrWriter = &{
    ///     let mut writer =  StrWriter::new([0; CAP]);
    ///
    ///     // Writing the array with debug formatting, and the integers with hexadecimal formatting.
    ///     unwrap!(writec!(writer, "{:X}", [3u32, 5, 8, 13, 21, 34]));
    ///
    ///     writer
    /// };
    ///
    /// const STR: &str = __STR.as_str();
    ///
    /// fn main() {
    ///     assert_eq!(STR, "[3, 5, 8, D, 15, 22]");
    /// }
    /// ```
    #[inline(always)]
    pub const fn as_str(&self) -> &str {
        // All the methods that modify the buffer must ensure utf8 validity,
        // only methods from this module need to ensure this.
        unsafe { core::str::from_utf8_unchecked(self.as_bytes()) }
    }

    /// Gets the written part of this `StrWriter` as a `&[u8]`
    ///
    /// The slice is guaranteed to be valid utf8, so this is mostly for convenience.
    ///
    /// # Example
    ///
    /// ```rust
    /// use const_format::StrWriter;
    ///
    /// let buffer: &mut StrWriter = &mut StrWriter::new([0; 64]);
    ///
    /// buffer.as_mut().write_str("Hello, World!");
    ///
    /// assert_eq!(buffer.as_bytes(), "Hello, World!".as_bytes());
    ///
    /// ```
    #[inline(always)]
    pub const fn as_bytes(&self) -> &[u8] {
        crate::utils::slice_up_to_len(&self.buffer, self.len)
    }

    /// Borrows this `StrWriter<[u8]>` into a `StrWriterMut`,
    /// most useful for calling the `write_*` methods.
    ///
    /// ```rust
    /// use const_format::StrWriter;
    ///
    /// let buffer: &mut StrWriter = &mut StrWriter::new([0; 64]);
    ///
    /// buffer.as_mut().write_str_range("trust", 1..usize::MAX);
    ///
    /// assert_eq!(buffer.as_str(), "rust");
    ///
    /// ```
    #[inline(always)]
    pub const fn as_mut(&mut self) -> StrWriterMut<'_> {
        StrWriterMut {
            len: &mut self.len,
            buffer: &mut self.buffer,
            _encoding: PhantomData,
        }
    }

    /// Constructs a [`Formatter`] that writes into this `StrWriter`,
    /// which can be passed to debug and display formatting methods.
    ///
    /// # Example
    ///
    /// ```rust
    ///
    /// use const_format::{Error, Formatter, FormattingFlags, StrWriter, call_debug_fmt};
    ///
    /// use std::ops::Range;
    ///
    /// const fn range_debug_fmt(
    ///     slice: &[Range<usize>],
    ///     f: &mut Formatter<'_>
    /// ) -> Result<(), Error> {
    ///     // We need this macro to debug format arrays of non-primitive types
    ///     // Also, it implicitly returns a `const_format::Error` on error.
    ///     call_debug_fmt!(array, slice, f);
    ///     Ok(())
    /// }
    ///
    /// fn main() -> Result<(), Error> {
    ///     let buffer: &mut StrWriter = &mut StrWriter::new([0; 64]);
    ///
    ///     range_debug_fmt(
    ///         &[0..14, 14..31, 31..48],
    ///         &mut buffer.make_formatter(FormattingFlags::new().set_binary())
    ///     )?;
    ///    
    ///     assert_eq!(buffer.as_str(), "[0..1110, 1110..11111, 11111..110000]");
    ///
    ///     Ok(())
    /// }
    /// ```
    ///
    /// [`Formatter`]: ./struct.Formatter.html
    #[inline(always)]
    pub const fn make_formatter(&mut self, flags: FormattingFlags) -> Formatter<'_> {
        Formatter::from_sw_mut(
            StrWriterMut::<Utf8Encoding> {
                len: &mut self.len,
                buffer: &mut self.buffer,
                _encoding: PhantomData,
            },
            flags,
        )
    }
}

impl<const N: usize> StrWriter<[u8; N]> {
    /// Casts a `&StrWriter<[u8; N]>` to a `&StrWriter<[u8]>`,
    /// for calling methods defined on `StrWriter<[u8]>` (most of them).
    ///
    /// # Example
    ///
    /// ```rust
    /// use const_format::StrWriter;
    ///
    /// let mut buffer = StrWriter::new([0; 64]);
    ///
    /// buffer.as_mut().write_str("Hello,");
    /// buffer.as_mut().write_str(" world!");
    ///
    /// assert_eq!(buffer.r().as_str(), "Hello, world!");
    ///
    /// ```
    ///
    #[inline(always)]
    pub const fn r(&self) -> &StrWriter<[u8]> {
        self
    }
    /// Casts a `&StrWriter<[u8; N]>` to a `&StrWriter<[u8]>`,
    /// for calling methods defined on `StrWriter<[u8]>` (most of them).
    ///
    /// # Example
    ///
    /// ```rust
    /// use const_format::StrWriter;
    ///
    /// let mut buffer = StrWriter::new([0; 64]);
    ///
    /// buffer.as_mut().write_str("Hello,");
    /// buffer.as_mut().write_str(" world!");
    ///
    /// assert_eq!(buffer.unsize().as_str(), "Hello, world!");
    ///
    /// ```
    ///
    #[inline(always)]
    pub const fn unsize(&self) -> &StrWriter<[u8]> {
        self
    }

    /// Borrows this `StrWriter<[u8; N]>` into a `StrWriterMut`.
    ///
    /// # Example
    ///
    /// ```rust
    /// use const_format::StrWriter;
    ///
    /// let mut buffer = StrWriter::new([0; 64]);
    ///
    /// buffer.as_mut().write_str_range("trust", 1..usize::MAX);
    ///
    /// assert_eq!(buffer.r().as_str(), "rust");
    ///
    /// ```
    #[inline(always)]
    pub const fn as_mut(&mut self) -> StrWriterMut<'_> {
        StrWriterMut {
            len: &mut self.len,
            buffer: &mut self.buffer,
            _encoding: PhantomData,
        }
    }
}

impl<A: ?Sized> StrWriter<A> {
    /// For borrowing this mutably in macros, without getting nested mutable references.
    #[inline(always)]
    pub const fn borrow_mutably(&mut self) -> &mut Self {
        self
    }
}


================================================
FILE: const_format/src/fmt/str_writer_mut.rs
================================================
use crate::{
    formatting::{
        hex_as_ascii, ForEscaping, FormattingFlags, HexFormatting, NumberFormatting, FOR_ESCAPING,
    },
    utils::{min_usize, saturate_range, Constructor},
    wrapper_types::{AsciiStr, PWrapper},
};

use super::{Error, Formatter, StrWriter};

use core::{marker::PhantomData, ops::Range};

/// For writing a formatted string into a `[u8]`.
///
/// # Construction
///
/// This type can be constructed in these ways:
///
/// - From a `&mut StrWriter`, with the [`StrWriter::as_mut`] method.
///
/// - From a `&mut StrWriter<_>`, with the [`StrWriterMut::new`] constructor.
///
/// - From a pair of `usize` and `[u8]` mutable references,
/// with the [`from_custom_cleared`] constructor,
/// or the [`from_custom`] constructor.
///
/// # Relation to `Formatter`
///
/// This is the type that [`Formatter`] uses to write formatted text to a slice,
/// sharing all the `write_*` methods,
/// the difference is that this doesn't store `FormattingFlags`,
/// so you must pass them to the `write_*_debug` methods.
///
/// # Errors
///
/// Every single `write_*` method returns an [`Error::NotEnoughSpace`] if
/// there is not enough space to write the argument, leaving the string itself unmodified.
///
/// # Encoding type parameter
///
/// The `E` type parameter represents the encoding of the buffer that this
/// StrWriterMut writes into,
/// currently only [`Utf8Encoding`] and [`NoEncoding`] are supported.
///
/// # Example
///
/// This example demonstrates how you can write a formatted string to a `&mut [u8]`,
/// using a `StrWriterMut`.
///
/// ```rust
///
/// use const_format::{Error, StrWriterMut, try_, writec};
///
/// const fn format_number(number: u32,slice: &mut [u8]) -> Result<usize, Error> {
///     let mut len = 0;
///     let mut writer = StrWriterMut::from_custom_cleared(slice, &mut len);
///     
///     try_!(writec!(writer, "{0} in binary is {0:#b}", number));
///
///     Ok(len)
/// }
///
/// let mut slice = [0; 32];
///
/// let len = format_number(100, &mut slice)?;
///
/// assert_eq!(&slice[..len], "100 in binary is 0b1100100".as_bytes());
///
/// # Ok::<(), const_format::Error>(())
/// ```
///
/// [`from_custom_cleared`]: #method.from_custom_cleared
/// [`from_custom`]: #method.from_custom
///
/// [`Utf8Encoding`]: crate::fmt::Utf8Encoding
/// [`NoEncoding`]: crate::fmt::NoEncoding
/// [`Formatter`]: crate::fmt::Formatter
/// [`Error::NotEnoughSpace`]: crate::fmt::Error::NotEnoughSpace
///
pub struct StrWriterMut<'w, E = Utf8Encoding> {
    pub(super) len: &'w mut usize,
    pub(super) buffer: &'w mut [u8],
    pub(super) _encoding: PhantomData<Constructor<E>>,
}

macro_rules! borrow_fields {
    ($self:ident, $len:ident, $buffer:ident) => {
        let $len = &mut *$self.len;
        let $buffer = &mut *$self.buffer;
    };
}

/// Marker type indicating that the [`StrWriterMut`] is valid utf8,
/// enabling the `as_str` method.
///
/// [`StrWriterMut`]: ./struct.StrWriterMut.html
pub enum Utf8Encoding {}

/// Marker type indicating that the [`StrWriterMut`] is arbitrary bytes,
/// disabling the `as_str` method.
///
/// [`StrWriterMut`]: ./struct.StrWriterMut.html
pub enum NoEncoding {}

impl<'w> StrWriterMut<'w, Utf8Encoding> {
    /// Constructs a `StrWriterMut` from a mutable reference to a `StrWriter`
    ///
    /// # Example
    ///
    /// ```rust
    /// use const_format::{StrWriter, StrWriterMut};
    ///
    /// let buffer: &mut StrWriter = &mut StrWriter::new([0; 128]);
    /// {
    ///     let mut writer = StrWriterMut::new(buffer);
    ///
    ///     let _ = writer.write_str("Number: ");
    ///     let _ = writer.write_u8_display(1);
    /// }
    /// assert_eq!(buffer.as_str(), "Number: 1");
    ///
    /// ```
    pub const fn new(writer: &'w mut StrWriter) -> Self {
        Self {
            len: &mut writer.len,
            buffer: &mut writer.buffer,
            _encoding: PhantomData,
        }
    }
}

impl<'w> StrWriterMut<'w, NoEncoding> {
    /// Construct a `StrWriterMut` from length and byte slice mutable references.
    ///
    /// If `length > buffer.len()` is passed, it's simply assigned the length of the buffer.
    ///
    /// # Example
    ///
    /// ```rust
    /// use const_format::StrWriterMut;
    ///
    /// let mut len = 6;
    /// let mut buffer = *b"Hello,       ";
    ///
    /// let mut writer = StrWriterMut::from_custom(&mut buffer, &mut len);
    ///
    /// writer.write_str(" world!")?;
    ///
    /// assert_eq!(writer.as_bytes(), b"Hello, world!");
    /// assert_eq!(buffer, "Hello, world!".as_bytes());
    /// assert_eq!(len, "Hello, world!".len());
    ///
    /// # Ok::<(), const_format::Error>(())
    /// ```
    pub const fn from_custom(buffer: &'w mut [u8], length: &'w mut usize) -> Self {
        *length = min_usize(*length, buffer.len());

        Self {
            len: length,
            buffer,
            _encoding: PhantomData,
        }
    }
}

impl<'w> StrWriterMut<'w, Utf8Encoding> {
    /// Construct a `StrWriterMut` from length and byte slice mutable references,
    /// truncating the length to `0`.
    ///
    /// Using this instead of [`from_custom`](StrWriterMut::from_custom) allows
    /// safely casting this to a `&str` with [`as_str`]
    ///
    ///
    /// # Example
    ///
    /// ```rust
    /// use const_format::StrWriterMut;
    ///
    /// let mut len = 0;
    /// let mut buffer = [0; 13];
    ///
    /// let mut writer = StrWriterMut::from_custom_cleared(&mut buffer, &mut len);
    ///
    /// writer.write_str("Hello, world!")?;
    ///
    /// assert_eq!(writer.as_str(), "Hello, world!");
    /// assert_eq!(buffer, "Hello, world!".as_bytes());
    /// assert_eq!(len, "Hello, world!".len());
    ///
    /// # Ok::<(), const_format::Error>(())
    /// ```
    ///
    /// [`as_str`]: Self::as_str
    ///
    pub const fn from_custom_cleared(buffer: &'w mut [u8], length: &'w mut usize) -> Self {
        *length = 0;

        Self {
            len: length,
            buffer,
            _encoding: PhantomData,
        }
    }
}

impl<'w, E> StrWriterMut<'w, E> {
    /// Accesses the underlying buffer immutably.
    ///
    /// # Example
    ///
    /// ```rust
    /// use const_format::{StrWriter, StrWriterMut};
    ///
    /// let mut buffer = StrWriter::new([0; 7]);
    /// let mut writer = StrWriterMut::new(&mut buffer);
    /// assert_eq!(writer.buffer(), &[0; 7]);
    ///
    /// writer.write_str("foo")?;
    /// assert_eq!(writer.buffer(), b"foo\0\0\0\0");
    ///
    /// writer.write_str("bar")?;
    /// assert_eq!(writer.buffer(), b"foobar\0");
    ///
    /// # Ok::<(), const_format::Error>(())
    /// ```
    #[inline(always)]
    pub const fn buffer(&self) -> &[u8] {
        self.buffer
    }

    /// The byte length of the string this is writing.
    ///
    /// # Example
    ///
    /// ```rust
    /// use const_format::{StrWriter, StrWriterMut};
    ///
    /// let mut buffer = StrWriter::new([0; 64]);
    /// let mut writer = StrWriterMut::new(&mut buffer);
    ///
    /// assert_eq!(writer.len(), 0);
    ///
    /// writer.write_str("foo")?;
    /// assert_eq!(writer.len(), 3);
    ///
    /// writer.write_str("bar")?;
    /// assert_eq!(writer.len(), 6);
    ///
    /// # Ok::<(), const_format::Error>(())
    /// ```
    #[inline(always)]
    pub const fn len(&self) -> usize {
        *self.len
    }

    /// Whether the string this is writing is empty.
    ///
    /// # Example
    ///
    /// ```rust
    /// use const_format::{StrWriter, StrWriterMut};
    ///
    /// let mut buffer = StrWriter::new([0; 64]);
    /// let mut writer = StrWriterMut::new(&mut buffer);
    ///
    /// assert!( writer.is_empty() );
    ///
    /// writer.write_str("foo")?;
    /// assert!( !writer.is_empty() );
    ///
    /// # Ok::<(), const_format::Error>(())
    /// ```
    #[inline(always)]
    pub const fn is_empty(&self) -> bool {
        *self.len == 0
    }

    /// The maximum byte length of the formatted text for this `StrWriterMut`.
    ///
    /// # Example
    ///
    /// ```rust
    /// use const_format::{Error, StrWriter, StrWriterMut};
    ///
    /// let mut buffer = StrWriter::new([0; 64]);
    /// let mut writer = StrWriterMut::new(&mut buffer);
    ///
    /// assert_eq!(writer.capacity(), 64);
    ///
    /// writer.write_ascii_repeated(b'A', 64)?;
    /// assert_eq!(writer.capacity(), 64);
    ///
    /// assert_eq!(writer.write_str("-").unwrap_err(), Error::NotEnoughSpace);
    /// assert_eq!(writer.capacity(), 64);
    ///
    /// # Ok::<(), const_format::Error>(())
    /// ```
    #[inline(always)]
    pub const fn capacity(&self) -> usize {
        self.buffer.len()
    }

    /// Checks how many more bytes can be written.
    ///
    /// # Example
    ///
    /// ```rust
    /// use const_format::{Error, StrWriter, StrWriterMut};
    ///
    /// let mut buffer = StrWriter::new([0; 64]);
    /// let mut writer = StrWriterMut::new(&mut buffer);
    ///
    /// assert_eq!(writer.remaining_capacity(), 64);
    ///
    /// writer.write_str("foo")?;
    /// assert_eq!(writer.remaining_capacity(), 61);
    ///
    /// writer.write_ascii_repeated(b'a', 61)?;
    /// assert_eq!(writer.remaining_capacity(), 0);
    ///
    /// assert_eq!(writer.write_str(" ").unwrap_err(), Error::NotEnoughSpace);
    ///
    /// # Ok::<(), const_format::Error>(())
    /// ```
    #[inline]
    pub const fn remaining_capacity(&self) -> usize {
        self.buffer.len() - *self.len
    }
}

impl<'w> StrWriterMut<'w, Utf8Encoding> {
    /// Truncates this `StrWriterMut` to `length`.
    ///
    /// If `length` is greater than the current length, this does nothing.
    ///
    /// # Errors
    ///
    /// Returns an `Error::NotOnCharBoundary` if `length` is not on a char boundary.
    ///
    /// # Example
    ///
    /// ```rust
    /// use const_format::{Error, StrWriter, StrWriterMut};
    ///
    /// let mut buffer = StrWriter::new([0; 64]);
    /// let mut writer = StrWriterMut::new(&mut buffer);
    ///
    /// writer.write_str("foo bâr baz");
    /// assert_eq!(writer.as_str(), "foo bâr baz");
    ///
    /// assert_eq!(writer.truncate(6).unwrap_err(), Error::NotOnCharBoundary);
    ///
    /// writer.truncate(3)?;
    /// assert_eq!(writer.as_str(), "foo");
    ///
    /// writer.write_str("ooooooo");
    /// assert_eq!(writer.as_str(), "fooooooooo");
    ///
    /// # Ok::<(), const_format::Error>(())
    /// ```
    #[inline]
    pub const fn truncate(&mut self, length: usize) -> Result<(), Error> {
        if length <= *self.len {
            if !is_valid_str_index(self.buffer, length) {
                return Err(Error::NotOnCharBoundary);
            }

            *self.len = length;
        }
        Ok(())
    }
}

impl<'w> StrWriterMut<'w, NoEncoding> {
    /// Truncates this `StrWriterMut<'w, NoEncoding>` to `length`.
    ///
    /// If `length` is greater than the current length, this does nothing.
    ///
    /// # Example
    ///
    /// ```rust
    /// use const_format::{Error, StrWriter, StrWriterMut};
    ///
    /// let mut buffer = [0; 32];
    /// let mut len = 0;
    /// let mut writer = StrWriterMut::from_custom(&mut buffer, &mut len);
    ///
    /// writer.write_str("foo bar baz");
    /// assert_eq!(writer.as_bytes(), b"foo bar baz");
    ///
    /// // Truncating to anything larger than the length is a no-op.
    /// writer.truncate(usize::MAX / 2);
    /// assert_eq!(writer.as_bytes(), b"foo bar baz");
    ///
    /// writer.truncate(3);
    /// assert_eq!(writer.as_bytes(), b"foo");
    ///
    /// writer.write_str("ooooooo");
    /// assert_eq!(writer.as_bytes(), b"fooooooooo");
    ///
    /// ```
    #[inline]
    pub const fn truncate(&mut self, length: usize) {
        if length < *self.len {
            *self.len = length;
        }
    }
}

impl<'w, E> StrWriterMut<'w, E> {
    /// Truncates this `StrWriterMut` to length 0.
    ///
    /// # Example
    ///
    /// ```rust
    /// use const_format::{Error, StrWriter, StrWriterMut};
    ///
    /// let mut buffer = StrWriter::new([0; 64]);
    /// let mut writer = StrWriterMut::new(&mut buffer);
    ///
    /// writer.write_str("foo")?;
    /// assert_eq!(writer.as_str(), "foo");
    ///
    /// writer.clear();
    /// assert_eq!(writer.as_str(), "");
    /// assert!(writer.is_empty());
    ///
    /// writer.write_str("bar");
    /// assert_eq!(writer.as_str(), "bar");
    ///
    /// # Ok::<(), const_format::Error>(())
    /// ```
    #[inline]
    pub const fn clear(&mut self) {
        *self.len = 0;
    }

    /// This is the same as `as_bytes`
    ///
    /// (this method only exists for backwards compatibility)
    #[deprecated(since = "0.2.36", note = "redundant, same as `as_bytes`")]
    #[inline(always)]
    pub const fn as_bytes_alt(&self) -> &[u8] {
        crate::utils::slice_up_to_len(self.buffer, *self.len)
    }
}

impl<'w> StrWriterMut<'w, Utf8Encoding> {
    /// This is the same as `as_str`
    ///
    /// (this method only exists for backwards compatibility)
    #[deprecated(since = "0.2.36", note = "redundant, same as `as_str`")]
    #[inline(always)]
    pub const fn as_str_alt(&self) -> &str {
        // All the methods that modify the buffer must ensure utf8 validity,
        // only methods from this module need to ensure this.
        unsafe { core::str::from_utf8_unchecked(self.as_bytes_alt()) }
    }

    /// Gets the written part of this StrWriterMut as a `&str`
    ///
    /// # Example
    ///
    /// ```rust
    ///
    /// use const_format::{StrWriter, StrWriterMut};
    ///
    /// let mut buffer = StrWriter::new([0; 64]);
    /// let mut writer = StrWriterMut::new(&mut buffer);
    ///
    /// writer.write_str("Hello, how are you?");
    ///
    /// assert_eq!(writer.as_str(), "Hello, how are you?");
    ///
    /// ```
    #[inline(always)]
    pub const fn as_str(&self) -> &str {
        // All the methods that modify the buffer must ensure utf8 validity,
        // only methods from this module need to ensure this.
        unsafe { core::str::from_utf8_unchecked(self.as_bytes()) }
    }
}

impl<'w, E> StrWriterMut<'w, E> {
    /// Gets the written part of this `StrWriterMut` as a `&[u8]`
    ///
    /// The slice is guaranteed to be valid utf8, so this is mostly for convenience.
    ///
    /// # Example
    ///
    /// ```rust
    ///
    /// use const_format::{StrWriter, StrWriterMut};
    ///
    /// let mut buffer = StrWriter::new([0; 64]);
    /// let mut writer = StrWriterMut::new(&mut buffer);
    ///
    /// writer.write_str("Hello, World!");
    ///
    /// assert_eq!(writer.as_bytes(), "Hello, World!".as_bytes());
    ///
    /// ```
    #[inline(always)]
    pub const fn as_bytes(&self) -> &[u8] {
        crate::utils::slice_up_to_len(self.buffer, *self.len)
    }
}

impl<'w, E> StrWriterMut<'w, E> {
    /// Constructs a [`Formatter`] that writes into this `StrWriterMut`,
    /// which can be passed to debug and display formatting methods.
    ///
    /// # Example
    ///
    /// ```rust
    ///
    /// use const_format::{Error, Formatter, FormattingFlags, StrWriter, StrWriterMut};
    /// use const_format::call_debug_fmt;
    ///
    /// use std::ops::Range;
    ///
    /// const fn range_debug_fmt(
    ///     slice: &[Range<usize>],
    ///     f: &mut Formatter<'_>
    /// ) -> Result<(), Error> {
    ///     // We need this macro to debug format arrays of non-primitive types
    ///     // Also, it implicitly returns a `const_format::Error` on error.
    ///     call_debug_fmt!(array, slice, f);
    ///     Ok(())
    /// }
    ///
    /// let mut buffer = StrWriter::new([0; 64]);
    /// let mut writer = StrWriterMut::new(&mut buffer);
    ///
    /// range_debug_fmt(
    ///     &[0..14, 14..31, 31..48],
    ///     &mut writer.make_formatter(FormattingFlags::new().set_binary())
    /// )?;
    ///    
    /// assert_eq!(writer.as_str(), "[0..1110, 1110..11111, 11111..110000]");
    ///
    /// # Ok::<(), Error>(())
    ///
    /// ```
    ///
    /// [`Formatter`]: ./struct.Formatter.html
    #[inline(always)]
    pub const fn make_formatter(&mut self, flags: FormattingFlags) -> Formatter<'_> {
        Formatter::from_sw_mut(
            StrWriterMut::<NoEncoding> {
                len: self.len,
                buffer: self.buffer,
                _encoding: PhantomData,
            },
            flags,
        )
    }

    /// For borrowing this mutably in macros, without getting nested mutable references.
    #[inline(always)]
    pub const fn borrow_mutably(&mut self) -> &mut StrWriterMut<'w, E> {
        self
    }

    /// For passing a reborrow of this `StrWriterMut` into functions,
    /// without this you'd need to pass a mutable reference instead.
    ///
    /// # Example
    ///
    /// ```rust
    ///
    /// use const_format::{Error, FormattingFlags, StrWriter, StrWriterMut, call_debug_fmt};
    ///
    /// use std::ops::Range;
    ///
    /// const fn range_debug_fmt(
    ///     slice: &[[u32; 2]],
    ///     mut writer: StrWriterMut<'_>
    /// ) -> Result<(), Error> {
    ///     let mut formatter = writer.make_formatter(FormattingFlags::new().set_binary());
    ///
    ///     // We need this macro to debug format arrays of non-primitive types
    ///     // Also, it implicitly returns a `const_format::Error` on error.
    ///     call_debug_fmt!(array, slice, formatter);
    ///     Ok(())
    /// }
    ///
    /// let mut buffer = StrWriter::new([0; 64]);
    /// let mut writer = StrWriterMut::new(&mut buffer);
    ///
    /// range_debug_fmt(&[[3, 5], [8, 13]], writer.reborrow())?;
    ///    
    /// assert_eq!(writer.as_str(), "[[11, 101], [1000, 1101]]");
    ///
    /// # Ok::<(), Error>(())
    ///
    /// ```
    #[inline(always)]
    pub const fn reborrow(&mut self) -> StrWriterMut<'_, E> {
        StrWriterMut {
            len: self.len,
            buffer: self.buffer,
            _encoding: PhantomData,
        }
    }

    // Safety: You must not write invalid utf8 bytes with the returned StrWriterMut.
    pub(crate) const unsafe fn into_byte_encoding(self) -> StrWriterMut<'w, NoEncoding> {
        StrWriterMut {
            len: self.len,
            buffer: self.buffer,
            _encoding: PhantomData,
        }
    }
}

/////////////////////////////////////////////////////////////////////////////////

macro_rules! write_integer_fn {
    (
        display_attrs $display_attrs:tt
        debug_attrs $debug_attrs:tt
        $(($display_fn:ident, $debug_fn:ident, $sign:ident, $ty:ident, $Unsigned:ident))*
    )=>{
        impl<'w,E> StrWriterMut<'w,E>{
            $(
                write_integer_fn!{
                    @methods
                    display_attrs $display_attrs
                    debug_attrs $debug_attrs
                    $display_fn, $debug_fn, $sign, ($ty, $Unsigned), stringify!($ty)
                }
            )*
        }

        $(
            write_integer_fn!{
                @pwrapper
                $display_fn, $debug_fn, $sign, ($ty, $Unsigned), stringify!($ty)
            }
        )*
    };
    (@pwrapper
        $display_fn:ident,
        $debug_fn:ident,
        $sign:ident,
        ($ty:ident, $Unsigned:ident),
        $ty_name:expr
    )=>{
        impl PWrapper<$ty> {
            /// Writes a
            #[doc = $ty_name]
            /// with Display formatting.
            pub const fn const_display_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
                f.$display_fn(self.0)
            }

            /// Writes a
            #[doc = $ty_name]
            /// with Debug formatting.
            pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
                f.$debug_fn(self.0)
            }
        }
    };
    (@methods
        display_attrs( $(#[$display_attrs:meta])* )
        debug_attrs( $(#[$debug_attrs:meta])* )
        $display_fn:ident,
        $debug_fn:ident,
        $sign:ident,
        ($ty:ident, $Unsigned:ident),
        $ty_name:expr
    )=>{
        $(#[$display_attrs])*
        pub const fn $display_fn(&mut self, number: $ty) -> Result<(), Error> {
            borrow_fields!(self, this_len, this_buffer);

            let n = PWrapper(number);
            let len = n.compute_display_len(FormattingFlags::DEFAULT);

            let mut cursor = *this_len + len;

            if cursor > this_buffer.len() {
                return Err(Error::NotEnoughSpace);
            }

            write_integer_fn!(@unsigned_abs $sign, n);

            loop {
                cursor-=1;
                let digit = (n % 10) as u8;
                this_buffer[cursor] = b'0' + digit;
                n/=10;
                if n == 0 { break }
            }

            write_integer_fn!(@write_sign $sign, this_len, this_buffer, number);

            *this_len+=len;
            Ok(())
        }

        $(#[$debug_attrs])*
        pub const fn $debug_fn(
            &mut self,
            number: $ty,
            flags: FormattingFlags,
        ) -> Result<(), Error> {
            const fn hex<E>(
                this: &mut StrWriterMut<'_, E>,
                n: $ty,
                f: FormattingFlags,
            ) -> Result<(), Error> {
                borrow_fields!(this, this_len, this_buffer);

                let is_alternate = f.is_alternate();
                let len = PWrapper(n).hexadecimal_len(f);

                let mut cursor = *this_len + len;

                if cursor > this_buffer.len() {
                    return Err(Error::NotEnoughSpace);
                }

                if is_alternate {
                    this_buffer[*this_len] = b'0';
                    this_buffer[*this_len + 1] = b'x';
                }

                write_integer_fn!(@as_unsigned $sign, n, $Unsigned);

                loop {
                    cursor-=1;
                    let digit = (n & 0b1111) as u8;
                    this_buffer[cursor] = hex_as_ascii(digit, f.hex_fmt());
                    n >>= 4;
                    if n == 0 { break }
                }

                *this_len+=len;
                Ok(())
            }

            const fn binary<E>(
                this: &mut StrWriterMut<'_, E>,
                n: $ty,
                f: FormattingFlags,
            ) -> Result<(), Error> {
                borrow_fields!(this, this_len, this_buffer);

                let is_alternate = f.is_alternate();
                let len = PWrapper(n).binary_len(f);

                let mut cursor = *this_len + len;

                if cursor > this_buffer.len() {
                    return Err(Error::NotEnoughSpace);
                }

                if is_alternate {
                    this_buffer[*this_len] = b'0';
                    this_buffer[*this_len + 1] = b'b';
                }

                write_integer_fn!(@as_unsigned $sign, n, $Unsigned);

                loop {
                    cursor-=1;
                    let digit = (n & 1) as u8;
                    this_buffer[cursor] = hex_as_ascii(digit, f.hex_fmt());
                    n >>= 1;
                    if n == 0 { break }
                }

                *this_len+=len;
                Ok(())
            }

            match flags.num_fmt() {
                NumberFormatting::Decimal=>self.$display_fn(number),
                NumberFormatting::Hexadecimal=>hex(self, number, flags),
                NumberFormatting::Binary=>binary(self, number, flags),
            }
        }
    };
    (@unsigned_abs signed, $n:ident) => (
        let mut $n = $n.unsigned_abs();
    );
    (@unsigned_abs unsigned, $n:ident) => (
        let mut $n = $n.0;
    );
    (@as_unsigned signed, $n:ident, $Unsigned:ident) => (
        let mut $n = $n as $Unsigned;
    );
    (@as_unsigned unsigned, $n:ident, $Unsigned:ident) => (
        let mut $n = $n;
    );
    (@write_sign signed, $self_len:ident, $self_buffer:ident, $n:ident) => ({
        if $n < 0 {
            $self_buffer[*$self_len] = b'-';
        }
    });
    (@write_sign unsigned, $self_len:ident, $self_buffer:ident, $n:ident) => ({});
}

/// Checks that a range is valid for indexing a string,
/// assuming that the range is in-bounds, and start <= end.
#[inline]
const fn is_valid_str_range(s: &[u8], Range { start, end }: Range<usize>) -> bool {
    let len = s.len();

    (end == len || ((s[end] as i8) >= -0x40)) && (start == len || ((s[start] as i8) >= -0x40))
}

/// Checks that an index is valid for indexing a string,
/// assuming that the index is in-bounds.
#[inline]
const fn is_valid_str_index(s: &[u8], index: usize) -> bool {
    let len = s.len();

    index == len || ((s[index] as i8) >= -0x40)
}

impl<'w, E> StrWriterMut<'w, E> {
    /// Writes a subslice of `s` with Display formatting.
    ///
    /// This is a workaround for being unable to do `&foo[start..end]` at compile time.
    ///
    /// # Additional Errors
    ///
    /// This method returns `Error::NotOnCharBoundary` if the range is not
    /// on a character boundary.
    ///
    /// Out of bounds range bounds are treated as being at `s.len()`,
    /// this only returns an error on an in-bounds index that is not on a character boundary.
    ///
    /// # Example
    ///
    /// ```rust
    /// use const_format::{FormattingFlags, StrWriterMut};
    ///
    /// let mut len = 0;
    /// let mut buffer = [0; 64];
    /// let mut writer = StrWriterMut::from_custom_cleared(&mut buffer, &mut len);
    ///
    /// let _ = writer.write_str_range("FOO BAR BAZ", 4..7);
    ///
    /// assert_eq!(writer.as_str(), "BAR");
    ///
    /// ```
    ///
    pub const fn write_str_range(&mut self, s: &str, range: Range<usize>) -> Result<(), Error> {
        let bytes = s.as_bytes();
        let Range { start, end } = saturate_range(bytes, &range);

        if !is_valid_str_range(bytes, start..end) {
            return Err(Error::NotOnCharBoundary);
        }

        self.write_str_inner(bytes, start, end)
    }

    /// Writes `s` with Display formatting.
    ///
    /// # Example
    ///
    /// ```rust
    ///
    /// use const_format::{FormattingFlags, StrWriterMut};
    ///
    /// let mut len = 0;
    /// let mut buffer = [0; 64];
    /// let mut writer = StrWriterMut::from_custom_cleared(&mut buffer, &mut len);
    ///
    /// let _ = writer.write_str("FOO BAR BAZ");
    ///
    /// assert_eq!(writer.as_str(), "FOO BAR BAZ");
    ///
    /// ```
    ///
    pub const fn write_str(&mut self, s: &str) -> Result<(), Error> {
        let bytes = s.as_bytes();

        self.write_str_inner(bytes, 0, s.len())
    }

    /// Writes `character` with Display formatting
    ///
    /// # Example
    ///
    /// ```rust
    ///
    /// use const_format::StrWriterMut;
    ///
    /// let mut len = 0;
    /// let mut buffer = [0; 64];
    /// let mut writer = StrWriterMut::from_custom_cleared(&mut buffer, &mut len);
    ///
    /// let _ = writer.write_char('3');
    /// let _ = writer.write_char('5');
    /// let _ = writer.write_char('8');
    ///
    /// assert_eq!(writer.as_str(), "358");
    ///
    /// ```
    ///
    pub const fn write_char(&mut self, character: char) -> Result<(), Error> {
        let fmt = crate::char_encoding::char_to_display(character);
        self.write_str_inner(fmt.encoded(), 0, fmt.len())
    }

    /// Writes a subslice of `ascii` with Display formatting.
    ///
    /// Out of bounds range bounds are treated as being at `s.len()`.
    ///
    /// This is a workaround for being unable to do `&foo[start..end]` at compile time.
    ///
    /// # Example
    ///
    /// ```rust
    ///
    /// use const_format::{FormattingFlags, StrWriterMut, ascii_str};
    ///
    /// let mut len = 0;
    /// let mut buffer = [0; 64];
    /// let mut writer = StrWriterMut::from_custom_cleared(&mut buffer, &mut len);
    ///
    /// let _ = writer.write_ascii_range(ascii_str!("FOO BAR BAZ"), 4..7);
    ///
    /// assert_eq!(writer.as_str(), "BAR");
    ///
    /// ```
    ///
    pub const fn write_ascii_range(
        &mut self,
        ascii: AsciiStr<'_>,
        range: Range<usize>,
    ) -> Result<(), Error> {
        let bytes = ascii.as_bytes();
        let Range { start, end } = saturate_range(bytes, &range);

        self.write_str_inner(bytes, start, end)
    }

    /// Writes `ascii` with Display formatting.
    ///
    /// # Example
    ///
    /// ```rust
    ///
    /// use const_format::{FormattingFlags, StrWriterMut, ascii_str};
    ///
    /// let mut len = 0;
    /// let mut buffer = [0; 64];
    /// let mut writer = StrWriterMut::from_custom_cleared(&mut buffer, &mut len);
    ///
    /// let _ = writer.write_ascii(ascii_str!("FOO BAR BAZ"));
    ///
    /// assert_eq!(writer.as_str(), "FOO BAR BAZ");
    ///
    /// ```
    ///
    pub const fn write_ascii(&mut self, ascii: AsciiStr<'_>) -> Result<(), Error> {
        let bytes = ascii.as_bytes();

        self.write_str_inner(bytes, 0, bytes.len())
    }

    /// Writes an ascii `character`, `repeated` times.
    ///
    /// # Example
    ///
    /// ```rust
    ///
    /// use const_format::{FormattingFlags, StrWriterMut};
    ///
    /// let mut len = 0;
    /// let mut buffer = [0; 64];
    /// let mut writer = StrWriterMut::from_custom_cleared(&mut buffer, &mut len);
    ///
    /// let _ = writer.write_ascii_repeated(b'A', 10);
    ///
    /// assert_eq!(writer.as_str(), "AAAAAAAAAA");
    ///
    /// ```
    ///
    pub const fn write_ascii_repeated(
        &mut self,
        mut character: u8,
        repeated: usize,
    ) -> Result<(), Error> {
        borrow_fields!(self, self_len, self_buffer);

        // Truncating non-ascii u8s
        character &= 0b111_1111;

        let end = *self_len + repeated;

        if end > self_buffer.len() {
            return Err(Error::NotEnoughSpace);
        }

        while *self_len < end {
            self_buffer[*self_len] = character;
            *self_len += 1;
        }

        Ok(())
    }

    #[inline(always)]
    const fn write_str_inner(
        &mut self,
        bytes: &[u8],
        mut start: usize,
        end: usize,
    ) -> Result<(), Error> {
        borrow_fields!(self, self_len, self_buffer);

        let len = end - start;

        if *self_len + len > self_buffer.len() {
            return Err(Error::NotEnoughSpace);
        }

        while start < end {
            self_buffer[*self_len] = bytes[start];
            *self_len += 1;
            start += 1;
        }

        Ok(())
    }
}

/// Debug-formatted string writing
impl<'w, E> StrWriterMut<'w, E> {
    /// Writes a subslice of `s` with  Debug-like formatting.
    ///
    /// This is a workaround for being unable to do `&foo[start..end]` at compile time.
    ///
    /// # Additional Errors
    ///
    /// This method returns `Error::NotOnCharBoundary` if the range is not
    /// on a character boundary.
    ///
    /// Out of bounds range bounds are treated as being at `s.len()`,
    /// this only returns an error on an in-bounds index that is not on a character boundary.
    ///
    /// # Example
    ///
    /// ```rust
    ///
    /// use const_format::{FormattingFlags, StrWriterMut};
    ///
    /// let mut len = 0;
    /// let mut buffer = [0; 64];
    /// let mut writer = StrWriterMut::from_custom_cleared(&mut buffer, &mut len);
    ///
    /// let _ = writer.write_str_range_debug("FOO\nBAR\tBAZ", 3..8);
    ///
    /// assert_eq!(writer.as_str(), r#""\nBAR\t""#);
    ///
    /// ```
    ///
    pub const fn write_str_range_debug(
        &mut self,
        s: &str,
        range: Range<usize>,
    ) -> Result<(), Error> {
        let bytes = s.as_bytes();
        let Range { start, end } = saturate_range(bytes, &range);

        if !is_valid_str_range(bytes, start..end) {
            return Err(Error::NotOnCharBoundary);
        }

        self.write_str_debug_inner(bytes, start, end)
    }

    /// Writes `s` with Debug-like formatting.
    ///
    /// # Example
    ///
    /// ```rust
    ///
    /// use const_format::{FormattingFlags, StrWriterMut};
    ///
    /// let mut len = 0;
    /// let mut buffer = [0; 64];
    /// let mut writer = StrWriterMut::from_custom_cleared(&mut buffer, &mut len);
    ///
    /// let _ = writer.write_str_debug("FOO\nBAR\tBAZ");
    ///
    /// assert_eq!(writer.as_str(), r#""FOO\nBAR\tBAZ""#);
    ///
    /// ```
    ///
    pub const fn write_str_debug(&mut self, str: &str) -> Result<(), Error> {
        let bytes = str.as_bytes();
        self.write_str_debug_inner(bytes, 0, str.len())
    }

    /// Writes `character` with Debug formatting.
    ///
    /// # Example
    ///
    /// ```rust
    ///
    /// use const_format::StrWriterMut;
    ///
    /// let mut len = 0;
    /// let mut buffer = [0; 64];
    /// let mut writer = StrWriterMut::from_custom_cleared(&mut buffer, &mut len);
    ///
    /// let _ = writer.write_str(" ");
    /// let _ = writer.write_char_debug('\\');
    /// let _ = writer.write_str(" ");
    /// let _ = writer.write_char_debug('A');
    /// let _ = writer.write_str(" ");
    /// let _ = writer.write_char_debug('0');
    /// let _ = writer.write_str(" ");
    /// let _ = writer.write_char_debug('\'');
    /// let _ = writer.write_str(" ");
    ///
    /// assert_eq!(writer.as_str(), r#" '\\' 'A' '0' '\'' "#);
    ///
    /// ```
    ///
    pub const fn write_char_debug(&mut self, character: char) -> Result<(), Error> {
        let fmt = crate::char_encoding::char_to_debug(character);
        self.write_str_inner(fmt.encoded(), 0, fmt.len())
    }

    /// Writes a subslice of `ascii` with Debug-like formatting.
    ///
    /// Out of bounds range bounds are treated as being at `s.len()`.
    ///
    /// This is a workaround for being unable to do `&foo[start..end]` at compile time.
    ///
    /// # Example
    ///
    /// ```rust
    ///
    /// use const_format::{FormattingFlags, StrWriterMut, ascii_str};
    ///
    /// let mut len = 0;
    /// let mut buffer = [0; 64];
    /// let mut writer = StrWriterMut::from_custom_cleared(&mut buffer, &mut len);
    ///
    /// let _ = writer.write_ascii_range_debug(ascii_str!("FOO\nBAR\tBAZ"), 3..8);
    ///
    /// assert_eq!(writer.as_str(), r#""\nBAR\t""#);
    ///
    /// ```
    ///
    pub const fn write_ascii_range_debug(
        &mut self,
        ascii: AsciiStr<'_>,
        range: Range<usize>,
    ) -> Result<(), Error> {
        let bytes = ascii.as_bytes();
        let Range { start, end } = saturate_range(bytes, &range);

        self.write_str_debug_inner(bytes, start, end)
    }

    /// Writes `ascii` with Debug-like formatting.
    ///
    /// # Example
    ///
    /// ```rust
    ///
    /// use const_format::{FormattingFlags, StrWriterMut, ascii_str};
    ///
    /// let mut len = 0;
    /// let mut buffer = [0; 64];
    /// let mut writer = StrWriterMut::from_custom_cleared(&mut buffer, &mut len);
    ///
    /// let _ = writer.write_ascii_debug(ascii_str!("FOO\nBAR\tBAZ"));
    ///
    /// assert_eq!(writer.as_str(), r#""FOO\nBAR\tBAZ""#);
    ///
    /// ```
    ///
    pub const fn write_ascii_debug(&mut self, ascii: AsciiStr<'_>) -> Result<(), Error> {
        let bytes = ascii.as_bytes();
        self.write_str_debug_inner(bytes, 0, bytes.len())
    }

    #[inline(always)]
    const fn write_str_debug_inner(
        &mut self,
        bytes: &[u8],
        mut start: usize,
        end: usize,
    ) -> Result<(), Error> {
        borrow_fields!(self, self_len, self_buffer);

        let len = end - start;

        // + 2 for the quote characters around the string.
        if *self_len + len + 2 > self_buffer.len() {
            return Err(Error::NotEnoughSpace);
        }

        // The amount of bytes available for escapes,
        // not counting the `writte_c`.
        let mut remaining_for_escapes = (self_buffer.len() - 2 - len - *self_len) as isize;
        let mut written = *self_len;

        self_buffer[written] = b'"';
        written += 1;

        while start != end {
            let c = bytes[start];
            let mut written_c = c;

            let shifted;

            if c < 128
                && ({
                    shifted = 1 << c;
                    (FOR_ESCAPING.is_escaped & shifted) != 0
                })
            {
                self_buffer[written] = b'\\';
                written += 1;

                if (FOR_ESCAPING.is_backslash_escaped & shifted) != 0 {
                    remaining_for_escapes -= 1;
                    if remaining_for_escapes < 0 {
                        return Err(Error::NotEnoughSpace);
                    }
                    written_c = ForEscaping::get_backslash_escape(c);
                } else {
                    remaining_for_escapes -= 3;
                    if remaining_for_escapes < 0 {
                        return Err(Error::NotEnoughSpace);
                    }
                    self_buffer[written] = b'x';
                    written += 1;
                    self_buffer[written] = hex_as_ascii(c >> 4, HexFormatting::Upper);
                    written += 1;
                    written_c = hex_as_ascii(c & 0xF, HexFormatting::Upper);
                };
            }

            self_buffer[written] = written_c;
            written += 1;
            start += 1;
        }

        self_buffer[written] = b'"';
        written += 1;

        *self_len = written;

        Ok(())
    }
}

write_integer_fn! {
    display_attrs(
        /// Write `number` with display formatting.
        ///
        /// # Example
        ///
        /// ```rust
        ///
        /// use const_format::{Formatter, FormattingFlags, StrWriterMut, ascii_str};
        ///
        /// le
Download .txt
gitextract_3exoboco/

├── .github/
│   └── workflows/
│       └── rust.yml
├── .gitignore
├── Cargo.toml
├── Changelog.md
├── LICENSE-ZLIB.md
├── README.md
├── commit.sh
├── const_format/
│   ├── Cargo.toml
│   ├── LICENSE-ZLIB.md
│   ├── src/
│   │   ├── __ascii_case_conv/
│   │   │   └── word_iterator.rs
│   │   ├── __ascii_case_conv.rs
│   │   ├── __hidden_utils.rs
│   │   ├── __str_methods/
│   │   │   ├── pattern.rs
│   │   │   ├── str_indexing.rs
│   │   │   ├── str_repeat.rs
│   │   │   ├── str_replace.rs
│   │   │   ├── str_splice.rs
│   │   │   └── str_split.rs
│   │   ├── __str_methods.rs
│   │   ├── char_encoding/
│   │   │   └── tests.rs
│   │   ├── char_encoding.rs
│   │   ├── const_debug_derive.rs
│   │   ├── const_generic_concatcp.rs
│   │   ├── doctests.rs
│   │   ├── equality.rs
│   │   ├── fmt/
│   │   │   ├── error.rs
│   │   │   ├── formatter.rs
│   │   │   ├── std_type_impls/
│   │   │   │   └── ranges.rs
│   │   │   ├── std_type_impls.rs
│   │   │   ├── str_writer.rs
│   │   │   └── str_writer_mut.rs
│   │   ├── fmt.rs
│   │   ├── for_assert_macros.rs
│   │   ├── for_examples.rs
│   │   ├── formatting.rs
│   │   ├── lib.rs
│   │   ├── macros/
│   │   │   ├── assertions/
│   │   │   │   ├── assertc_macros.rs
│   │   │   │   └── assertcp_macros.rs
│   │   │   ├── assertions.rs
│   │   │   ├── call_debug_fmt.rs
│   │   │   ├── constructors.rs
│   │   │   ├── fmt_macros.rs
│   │   │   ├── helper_macros.rs
│   │   │   ├── impl_fmt.rs
│   │   │   ├── map_ascii_case.rs
│   │   │   └── str_methods.rs
│   │   ├── macros.rs
│   │   ├── marker_traits/
│   │   │   ├── format_marker.rs
│   │   │   └── write_marker.rs
│   │   ├── marker_traits.rs
│   │   ├── msg.rs
│   │   ├── pargument.rs
│   │   ├── slice_cmp.rs
│   │   ├── test_utils.rs
│   │   ├── utils.rs
│   │   ├── wrapper_types/
│   │   │   ├── ascii_str.rs
│   │   │   ├── pwrapper/
│   │   │   │   └── tests.rs
│   │   │   ├── pwrapper.rs
│   │   │   └── sliced.rs
│   │   └── wrapper_types.rs
│   └── tests/
│       ├── fmt_tests/
│       │   ├── display_formatting.rs
│       │   ├── formatted_writing.rs
│       │   ├── formatter_methods/
│       │   │   └── debug_methods.rs
│       │   ├── formatter_methods.rs
│       │   ├── std_impl_tests.rs
│       │   ├── str_writer_methods.rs
│       │   └── str_writer_mut.rs
│       ├── fmt_tests_modules.rs
│       ├── misc_tests/
│       │   ├── assertc_tests.rs
│       │   ├── assertcp_tests.rs
│       │   ├── call_debug_fmt_macro.rs
│       │   ├── clippy_warnings.rs
│       │   ├── concatc_macro_tests.rs
│       │   ├── derive_tests/
│       │   │   └── is_a_attributes.rs
│       │   ├── derive_tests.rs
│       │   ├── equality_tests.rs
│       │   ├── formatc_macros.rs
│       │   ├── impl_fmt_macro_tests.rs
│       │   ├── inline_const_pattern_tests.rs
│       │   ├── shared_cp_macro_tests.rs
│       │   ├── type_kind_coercion_macro_tests.rs
│       │   └── writec_macro.rs
│       ├── misc_tests_modules.rs
│       ├── str_methods.rs
│       └── str_methods_modules/
│           ├── conv_ascii_case.rs
│           ├── str_replace.rs
│           ├── str_splice.rs
│           └── str_split_tests.rs
├── const_format_proc_macros/
│   ├── Cargo.toml
│   ├── LICENSE-ZLIB.md
│   └── src/
│       ├── datastructure/
│       │   └── field_map.rs
│       ├── datastructure.rs
│       ├── derive_debug/
│       │   ├── attribute_parsing.rs
│       │   ├── syntax.rs
│       │   └── type_detection.rs
│       ├── derive_debug.rs
│       ├── error.rs
│       ├── format_args/
│       │   └── parsing.rs
│       ├── format_args.rs
│       ├── format_macro/
│       │   └── tests.rs
│       ├── format_macro.rs
│       ├── format_str/
│       │   ├── errors.rs
│       │   ├── parsing.rs
│       │   └── tests.rs
│       ├── format_str.rs
│       ├── formatting.rs
│       ├── lib.rs
│       ├── macros.rs
│       ├── parse_utils.rs
│       ├── respan_to_macro.rs
│       ├── shared_arg_parsing.rs
│       ├── spanned.rs
│       ├── test_utils.rs
│       └── utils.rs
├── print_errors/
│   ├── Cargo.toml
│   └── src/
│       ├── formatc_macros.rs
│       ├── lib.rs
│       ├── using_assertc_macros.rs
│       └── using_writec_macro.rs
└── print_warnings/
    ├── Cargo.toml
    └── src/
        └── main.rs
Download .txt
SYMBOL INDEX (837 symbols across 89 files)

FILE: const_format/src/__ascii_case_conv.rs
  type Case (line 13) | pub enum Case {
  type WordCountAndLength (line 54) | struct WordCountAndLength {
  function words_count_and_length (line 61) | const fn words_count_and_length(bytes: &[u8]) -> WordCountAndLength {
  function size_after_conversion (line 72) | pub const fn size_after_conversion(case: Case, s: &str) -> usize {
  function convert_str (line 86) | pub const fn convert_str<const N: usize>(case: Case, s: &str) -> [u8; N] {
  constant CASE_DIFF (line 169) | const CASE_DIFF: u8 = b'a' - b'A';
  function uppercase_u8 (line 171) | const fn uppercase_u8(b: u8) -> u8 {
  function lowercase_u8 (line 179) | const fn lowercase_u8(b: u8) -> u8 {

FILE: const_format/src/__ascii_case_conv/word_iterator.rs
  type ByteKind (line 19) | struct ByteKind(u8);
    constant Other (line 36) | const Other: Self = Self(0b0001);
    constant Number (line 37) | const Number: Self = Self(0b0010);
    constant LowerCase (line 38) | const LowerCase: Self = Self(0b0100);
    constant UpperCase (line 39) | const UpperCase: Self = Self(0b1000);
    constant Alphabetic (line 40) | const Alphabetic: Self = Self(Self::LowerCase.0 | Self::UpperCase.0);
    constant NonAscii (line 43) | const NonAscii: Self = Self(0b1100);
    method eq (line 49) | pub const fn eq(self, other: Self) -> bool {
    method ne (line 54) | pub const fn ne(self, other: Self) -> bool {
    method is_alphabetic (line 59) | pub const fn is_alphabetic(self) -> bool {
    method is_end_of_word (line 63) | pub const fn is_end_of_word(mut self, prev: Self, other: Self) -> bool {
  method fmt (line 22) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  type WordIterator (line 77) | pub(crate) struct WordIterator<'a> {
  constant BYTE_KIND (line 82) | const BYTE_KIND: &[ByteKind; 256] = &{
  function new (line 95) | pub(crate) const fn new(bytes: &'a [u8]) -> Self {
  function skip_same_kind (line 99) | const fn skip_same_kind(mut self, mut kind: ByteKind) -> (Self, ByteKind) {
  function next (line 130) | pub(crate) const fn next(self) -> Option<(Self, Range<usize>)> {
  function get_words (line 148) | fn get_words(text: &str) -> ArrayVec<&str, 20> {
  function test_word_iter (line 161) | fn test_word_iter() {

FILE: const_format/src/__hidden_utils.rs
  function max_usize (line 1) | pub(crate) const fn max_usize(l: usize, r: usize) -> usize {
  function saturating_add (line 8) | pub(crate) const fn saturating_add(l: usize, r: usize) -> usize {
  function is_char_boundary_no_len_check (line 17) | pub(crate) const fn is_char_boundary_no_len_check(str: &[u8], index: usi...

FILE: const_format/src/__str_methods.rs
  type AsciiByte (line 24) | pub struct AsciiByte(u8);
    method new (line 28) | pub const fn new(byte: u8) -> Self {
    method get (line 37) | pub const fn get(self) -> u8 {
  function bytes_find (line 45) | const fn bytes_find(left: &[u8], right: &[u8], from: usize) -> Option<us...

FILE: const_format/src/__str_methods/pattern.rs
  type PatternCtor (line 3) | pub(crate) struct PatternCtor<T>(pub(crate) T);
  function conv (line 6) | pub(crate) const fn conv(self) -> Pattern {
  function conv (line 12) | pub(crate) const fn conv(self) -> Pattern {
  function conv (line 22) | pub(crate) const fn conv(self) -> Pattern {
  type Pattern (line 33) | pub(crate) enum Pattern {
    method normalize (line 45) | pub(crate) const fn normalize(&self) -> PatternNorm<'_> {
  type PatternNorm (line 39) | pub(crate) enum PatternNorm<'a> {

FILE: const_format/src/__str_methods/str_indexing.rs
  type StrIndexArgsConv (line 1) | pub struct StrIndexArgsConv<T> {
  function StrIndexArgsConv (line 7) | pub const fn StrIndexArgsConv<T>(str: &'static str, arg: T) -> StrIndexA...
  type StrIndexArgs (line 11) | pub struct StrIndexArgs {
  type IndexValidity (line 21) | pub enum IndexValidity {
    method is_valid (line 30) | pub const fn is_valid(self) -> bool {
    method assert_valid (line 34) | pub const fn assert_valid(self) {
  function index_validity_test (line 154) | fn index_validity_test() {

FILE: const_format/src/__str_methods/str_repeat.rs
  type StrRepeatArgs (line 1) | pub struct StrRepeatArgs {
    method assert_valid (line 30) | pub const fn assert_valid(&self) {
  function StrRepeatArgs (line 10) | pub const fn StrRepeatArgs(str: &'static str, repeat: usize) -> StrRepea...
    method assert_valid (line 30) | pub const fn assert_valid(&self) {

FILE: const_format/src/__str_methods/str_replace.rs
  type ReplaceInputConv (line 3) | pub struct ReplaceInputConv<T>(pub &'static str, pub T, pub &'static str);
  type ReplaceInput (line 23) | pub struct ReplaceInput {
    method replace_length (line 30) | pub const fn replace_length(&self) -> usize {
    method replace (line 33) | pub const fn replace<const L: usize>(&self) -> [u8; L] {
  function str_replace_length (line 38) | const fn str_replace_length(inp: &str, r: Pattern, replaced_with: &str) ...
  function str_replace (line 68) | const fn str_replace<const L: usize>(inp: &str, r: Pattern, replaced_wit...

FILE: const_format/src/__str_methods/str_splice.rs
  type StrSplceArgsConv (line 3) | pub struct StrSplceArgsConv<T> {
  function StrSplceArgsConv (line 10) | pub const fn StrSplceArgsConv<T>(
  type StrSpliceArgs (line 18) | pub struct StrSpliceArgs {
  type SplicedStr (line 31) | pub struct SplicedStr {
  type DecomposedString (line 39) | pub struct DecomposedString<P, M, S> {

FILE: const_format/src/__str_methods/str_split.rs
  type SplitInputConv (line 5) | pub struct SplitInputConv<T>(pub &'static str, pub T);
  type SplitInput (line 27) | pub struct SplitInput {
    method compute_length (line 34) | const fn compute_length(mut self) -> Self {
    method split_it (line 39) | pub const fn split_it<const LEN: usize>(self) -> [&'static str; LEN] {
    method length (line 43) | pub const fn length(&self) -> usize {
  function count_splits (line 48) | pub const fn count_splits(SplitInput { str, pattern, .. }: SplitInput) -...
  function find_u8 (line 85) | const fn find_u8(mut slice: &[u8], byte: u8) -> Option<usize> {
  function find_next_char_boundary (line 98) | const fn find_next_char_boundary(str: &str, mut index: usize) -> Option<...
  function split_it (line 111) | pub const fn split_it<const LEN: usize>(args: SplitInput) -> [&'static s...

FILE: const_format/src/char_encoding.rs
  function char_display_len (line 4) | pub(crate) const fn char_display_len(c: char) -> usize {
  function char_debug_len (line 14) | pub(crate) const fn char_debug_len(c: char) -> usize {
  function char_to_utf8 (line 23) | const fn char_to_utf8(char: char) -> ([u8; 4], usize) {
  function char_to_display (line 48) | pub(crate) const fn char_to_display(char: char) -> FmtChar {
  function char_to_debug (line 56) | pub(crate) const fn char_to_debug(c: char) -> FmtChar {
  type FmtChar (line 89) | pub struct FmtChar {
    method encoded (line 97) | pub const fn encoded(&self) -> &[u8; 6] {
    method len (line 101) | pub const fn len(&self) -> usize {
    method as_bytes (line 105) | pub(crate) const fn as_bytes(&self) -> &[u8] {

FILE: const_format/src/char_encoding/tests.rs
  function char_to_utf8_encoding_test (line 4) | fn char_to_utf8_encoding_test() {
  function char_to_utf8_display_test (line 17) | fn char_to_utf8_display_test() {
  function char_to_utf8_debug_test (line 30) | fn char_to_utf8_debug_test() {

FILE: const_format/src/const_generic_concatcp.rs
  function __priv_concatenate (line 6) | pub const fn __priv_concatenate<const LEN: usize>(input: &[PArgument]) -...

FILE: const_format/src/doctests.rs
  type ImplFmtWhereClause (line 45) | pub struct ImplFmtWhereClause;
  type ConstDebugWhereClause (line 67) | pub struct ConstDebugWhereClause;
  type AsStr_For_StrWriterMut_NoEncoding (line 100) | pub struct AsStr_For_StrWriterMut_NoEncoding;
  type Assert (line 153) | pub struct Assert;
  type AssertCmp (line 184) | pub struct AssertCmp;
  type AssertCP (line 195) | pub struct AssertCP;
  type AssertCPCmp (line 218) | pub struct AssertCPCmp;

FILE: const_format/src/fmt/error.rs
  type Error (line 9) | pub enum Error {
    method unwrap (line 48) | pub const fn unwrap<T>(&self) -> T {
  method fmt (line 20) | fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
  type Result (line 70) | pub type Result<T = (), E = Error> = core::result::Result<T, E>;
  type ToResult (line 77) | pub struct ToResult<T>(pub T);
  function to_result (line 82) | pub const fn to_result(self) -> Result {
  function to_result (line 90) | pub const fn to_result(self) -> Result {

FILE: const_format/src/fmt/formatter.rs
  type ComputeStrLength (line 49) | pub struct ComputeStrLength {
    method new (line 55) | pub const fn new() -> Self {
    method make_formatter (line 61) | pub const fn make_formatter(&mut self, flags: FormattingFlags) -> Form...
    method add_len (line 70) | pub const fn add_len(&mut self, len: usize) {
    method len (line 75) | pub const fn len(&self) -> usize {
    method is_empty (line 80) | pub const fn is_empty(&self) -> bool {
    method borrow_mutably (line 86) | pub const fn borrow_mutably(&mut self) -> &mut Self {
  type WriterBackend (line 93) | enum WriterBackend<'w> {
  type Formatter (line 222) | pub struct Formatter<'w> {
  constant MARGIN_STEP (line 228) | const MARGIN_STEP: u16 = 4;
  function from_sw (line 256) | pub const fn from_sw(writer: &'w mut StrWriter, flags: FormattingFlags) ...
  function from_sw_mut (line 295) | pub const fn from_sw_mut<E: 'static>(
  function from_custom (line 352) | pub const fn from_custom(
  function from_custom_cleared (line 372) | pub const fn from_custom_cleared(
  function flags (line 387) | pub const fn flags(&self) -> FormattingFlags {
  function margin (line 392) | pub const fn margin(&self) -> usize {
  function increment_margin (line 397) | const fn increment_margin(&mut self) -> &mut Self {
  function decrement_margin (line 403) | const fn decrement_margin(&mut self) {
  function borrow_mutably (line 411) | pub const fn borrow_mutably(&mut self) -> &mut Self {
  function make_formatter (line 475) | pub const fn make_formatter(&mut self, flags: FormattingFlags) -> Format...
  function debug_struct (line 496) | pub const fn debug_struct(&mut self, name: &str) -> DebugStruct<'_, 'w> {
  function debug_tuple (line 514) | pub const fn debug_tuple(&mut self, name: &str) -> DebugTuple<'_, 'w> {
  function debug_list (line 532) | pub const fn debug_list(&mut self) -> DebugList<'_, 'w> {
  function debug_set (line 549) | pub const fn debug_set(&mut self) -> DebugSet<'_, 'w> {
  constant COLON_SPACE_LEN (line 568) | const COLON_SPACE_LEN: usize = ": ".len();
  constant COMMA_SPACE_LEN (line 569) | const COMMA_SPACE_LEN: usize = ", ".len();
  constant COMMA_NL_LEN (line 570) | const COMMA_NL_LEN: usize = ",\n".len();
  type DebugStruct (line 726) | pub struct DebugStruct<'f, 'w> {
  function field (line 734) | pub const fn field(&mut self, name: &str) -> &mut Formatter<'w> {
  function finish (line 749) | pub const fn finish(self) -> Result<(), Error> {
  type DebugTuple (line 816) | pub struct DebugTuple<'f, 'w> {
  function field (line 824) | pub const fn field(&mut self) -> &mut Formatter<'w> {
  function finish (line 830) | pub const fn finish(self) -> Result<(), Error> {
  type DebugList (line 918) | pub struct DebugList<'f, 'w> {
  function entry (line 926) | pub const fn entry(&mut self) -> &mut Formatter<'w> {
  function finish (line 932) | pub const fn finish(self) -> Result<(), Error> {
  type DebugSet (line 976) | pub struct DebugSet<'f, 'w> {
  function entry (line 984) | pub const fn entry(&mut self) -> &mut Formatter<'w> {
  function finish (line 990) | pub const fn finish(self) -> Result<(), Error> {
  function calculate_display_len (line 1486) | const fn calculate_display_len(b: &[u8], range: &Range<usize>) -> usize {
  function calculate_display_len_debug_range (line 1492) | const fn calculate_display_len_debug_range(b: &[u8], range: &Range<usize...

FILE: const_format/src/fmt/std_type_impls.rs
  function const_display_fmt (line 14) | pub const fn const_display_fmt(&self, f: &mut Formatter<'_>) -> Result<(...
  function const_debug_fmt (line 18) | pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(),...
  function const_display_fmt (line 24) | pub const fn const_display_fmt(&self, f: &mut Formatter<'_>) -> Result<(...
  function const_debug_fmt (line 29) | pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(),...
  function const_display_fmt (line 35) | pub const fn const_display_fmt(&self, f: &mut Formatter<'_>) -> Result<(...
  function const_debug_fmt (line 40) | pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(),...
  constant PTR (line 156) | const PTR: &'static str = "<pointer>";
  function const_debug_fmt (line 159) | pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(),...
  function const_debug_fmt (line 167) | pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(),...
  function const_debug_fmt (line 175) | pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(),...

FILE: const_format/src/fmt/std_type_impls/ranges.rs
  type Kind (line 12) | type Kind = IsStdKind;
  type This (line 13) | type This = Self;
  function coerce (line 18) | pub const fn coerce(self, range: &Range<usize>) -> PWrapper<Range<usize>> {
  constant RANGE (line 27) | const RANGE: &'static str = "..";
  function const_debug_fmt (line 30) | pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(),...
  type Kind (line 41) | type Kind = IsStdKind;
  type This (line 42) | type This = Self;
  function coerce (line 47) | pub const fn coerce(self, range: &RangeFrom<usize>) -> PWrapper<RangeFro...
  constant RANGE (line 53) | const RANGE: &'static str = "..";
  function const_debug_fmt (line 56) | pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(),...
  type Kind (line 66) | type Kind = IsStdKind;
  type This (line 67) | type This = Self;
  function coerce (line 72) | pub const fn coerce(self, range: &RangeTo<usize>) -> PWrapper<RangeTo<us...
  constant RANGE (line 78) | const RANGE: &'static str = "..";
  function const_debug_fmt (line 81) | pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(),...
  type Kind (line 91) | type Kind = IsStdKind;
  type This (line 92) | type This = Self;
  function coerce (line 97) | pub const fn coerce(
  constant RANGE (line 106) | const RANGE: &'static str = "..=";
  function const_debug_fmt (line 109) | pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(),...
  type Kind (line 119) | type Kind = IsStdKind;
  type This (line 120) | type This = Self;
  function coerce (line 125) | pub const fn coerce(self, range: &RangeInclusive<usize>) -> PWrapper<Ran...
  constant RANGE (line 131) | const RANGE: &'static str = "..=";
  function const_debug_fmt (line 134) | pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(),...
  type Kind (line 145) | type Kind = IsStdKind;
  type This (line 146) | type This = Self;
  function coerce (line 151) | pub const fn coerce(self, _: &RangeFull) -> PWrapper<RangeFull> {
  constant RANGE (line 157) | const RANGE: &'static str = "..";
  function const_debug_fmt (line 160) | pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(),...

FILE: const_format/src/fmt/str_writer.rs
  type StrWriter (line 108) | pub struct StrWriter<A: ?Sized = [u8]> {
    method capacity (line 215) | pub const fn capacity(&self) -> usize {
    method remaining_capacity (line 240) | pub const fn remaining_capacity(&self) -> usize {
    method truncate (line 273) | pub const fn truncate(&mut self, length: usize) -> Result<(), Error> {
    method clear (line 299) | pub const fn clear(&mut self) {
    method as_bytes_alt (line 308) | pub const fn as_bytes_alt(&self) -> &[u8] {
    method as_str_alt (line 317) | pub const fn as_str_alt(&self) -> &str {
    method as_str (line 349) | pub const fn as_str(&self) -> &str {
    method as_bytes (line 372) | pub const fn as_bytes(&self) -> &[u8] {
    method as_mut (line 390) | pub const fn as_mut(&mut self) -> StrWriterMut<'_> {
    method make_formatter (line 435) | pub const fn make_formatter(&mut self, flags: FormattingFlags) -> Form...
  function new (line 115) | pub const fn new(array: A) -> Self {
  function buffer (line 143) | pub const fn buffer(&self) -> &A {
  function len (line 166) | pub const fn len(&self) -> usize {
  function is_empty (line 186) | pub const fn is_empty(&self) -> bool {
  function r (line 466) | pub const fn r(&self) -> &StrWriter<[u8]> {
  function unsize (line 487) | pub const fn unsize(&self) -> &StrWriter<[u8]> {
  function as_mut (line 506) | pub const fn as_mut(&mut self) -> StrWriterMut<'_> {
  function borrow_mutably (line 518) | pub const fn borrow_mutably(&mut self) -> &mut Self {

FILE: const_format/src/fmt/str_writer_mut.rs
  type StrWriterMut (line 80) | pub struct StrWriterMut<'w, E = Utf8Encoding> {
  type Utf8Encoding (line 97) | pub enum Utf8Encoding {}
  type NoEncoding (line 103) | pub enum NoEncoding {}
  function new (line 123) | pub const fn new(writer: &'w mut StrWriter) -> Self {
  function from_custom (line 155) | pub const fn from_custom(buffer: &'w mut [u8], length: &'w mut usize) ->...
  function from_custom_cleared (line 195) | pub const fn from_custom_cleared(buffer: &'w mut [u8], length: &'w mut u...
  function buffer (line 227) | pub const fn buffer(&self) -> &[u8] {
  function len (line 252) | pub const fn len(&self) -> usize {
  function is_empty (line 274) | pub const fn is_empty(&self) -> bool {
  function capacity (line 299) | pub const fn capacity(&self) -> usize {
  function remaining_capacity (line 326) | pub const fn remaining_capacity(&self) -> usize {
  function truncate (line 362) | pub const fn truncate(&mut self, length: usize) -> Result<(), Error> {
  function truncate (line 403) | pub const fn truncate(&mut self, length: usize) {
  function clear (line 434) | pub const fn clear(&mut self) {
  function as_bytes_alt (line 443) | pub const fn as_bytes_alt(&self) -> &[u8] {
  function as_str_alt (line 454) | pub const fn as_str_alt(&self) -> &str {
  function as_str (line 477) | pub const fn as_str(&self) -> &str {
  function as_bytes (line 504) | pub const fn as_bytes(&self) -> &[u8] {
  function make_formatter (line 548) | pub const fn make_formatter(&mut self, flags: FormattingFlags) -> Format...
  function borrow_mutably (line 561) | pub const fn borrow_mutably(&mut self) -> &mut StrWriterMut<'w, E> {
  function reborrow (line 599) | pub const fn reborrow(&mut self) -> StrWriterMut<'_, E> {
  function into_byte_encoding (line 608) | pub(crate) const unsafe fn into_byte_encoding(self) -> StrWriterMut<'w, ...
  function is_valid_str_range (line 810) | const fn is_valid_str_range(s: &[u8], Range { start, end }: Range<usize>...
  function is_valid_str_index (line 819) | const fn is_valid_str_index(s: &[u8], index: usize) -> bool {
  function write_str_range (line 853) | pub const fn write_str_range(&mut self, s: &str, range: Range<usize>) ->...
  function write_str (line 882) | pub const fn write_str(&mut self, s: &str) -> Result<(), Error> {
  function write_char (line 908) | pub const fn write_char(&mut self, character: char) -> Result<(), Error> {
  function write_ascii_range (line 935) | pub const fn write_ascii_range(
  function write_ascii (line 964) | pub const fn write_ascii(&mut self, ascii: AsciiStr<'_>) -> Result<(), E...
  function write_ascii_repeated (line 988) | pub const fn write_ascii_repeated(
  function write_str_inner (line 1013) | const fn write_str_inner(
  function write_str_range_debug (line 1067) | pub const fn write_str_range_debug(
  function write_str_debug (line 1100) | pub const fn write_str_debug(&mut self, str: &str) -> Result<(), Error> {
  function write_char_debug (line 1131) | pub const fn write_char_debug(&mut self, character: char) -> Result<(), ...
  function write_ascii_range_debug (line 1158) | pub const fn write_ascii_range_debug(
  function write_ascii_debug (line 1187) | pub const fn write_ascii_debug(&mut self, ascii: AsciiStr<'_>) -> Result...
  function write_str_debug_inner (line 1193) | const fn write_str_debug_inner(

FILE: const_format/src/for_assert_macros.rs
  function assert_ (line 6) | pub const fn assert_(cond: bool, message: &'static str) {
  type ConcatArgsIf (line 14) | pub trait ConcatArgsIf<T, const COND: bool> {
    constant PARGUMENTS (line 15) | const PARGUMENTS: &'static [PArgument];
  constant PARGUMENTS (line 19) | const PARGUMENTS: &'static [PArgument] = &[];

FILE: const_format/src/for_examples.rs
  type Point3 (line 11) | pub struct Point3 {
  type Unit (line 42) | pub struct Unit;

FILE: const_format/src/formatting.rs
  type Formatting (line 3) | pub enum Formatting {
    method is_display (line 11) | pub const fn is_display(self) -> bool {
  type NumberFormatting (line 23) | pub enum NumberFormatting {
    constant ALL (line 47) | pub(crate) const ALL: &'static [Self; 3] = &[
  type HexFormatting (line 35) | pub enum HexFormatting {
  type FormattingFlags (line 101) | pub struct FormattingFlags {
    constant __REG (line 113) | pub const __REG: Self = Self::NEW.set_alternate(false).set_decimal();
    constant __HEX (line 114) | pub const __HEX: Self = Self::NEW.set_alternate(false).set_hexadecimal();
    constant __LOWHEX (line 115) | pub const __LOWHEX: Self = Self::NEW.set_alternate(false).set_lower_he...
    constant __BIN (line 116) | pub const __BIN: Self = Self::NEW.set_alternate(false).set_binary();
    constant __A_REG (line 118) | pub const __A_REG: Self = Self::NEW.set_alternate(true).set_decimal();
    constant __A_HEX (line 119) | pub const __A_HEX: Self = Self::NEW.set_alternate(true).set_hexadecima...
    constant __A_LOWHEX (line 120) | pub const __A_LOWHEX: Self = Self::NEW.set_alternate(true).set_lower_h...
    constant __A_BIN (line 121) | pub const __A_BIN: Self = Self::NEW.set_alternate(true).set_binary();
    constant DEFAULT (line 125) | pub const DEFAULT: Self = Self {
    constant NEW (line 137) | pub const NEW: Self = Self {
    method new (line 150) | pub const fn new() -> Self {
    method set_num_fmt (line 158) | pub const fn set_num_fmt(mut self, num_fmt: NumberFormatting) -> Self {
    method set_decimal (line 167) | pub const fn set_decimal(mut self) -> Self {
    method set_hexadecimal (line 176) | pub const fn set_hexadecimal(mut self) -> Self {
    method set_lower_hexadecimal (line 187) | pub const fn set_lower_hexadecimal(mut self) -> Self {
    method set_binary (line 197) | pub const fn set_binary(mut self) -> Self {
    method set_alternate (line 204) | pub const fn set_alternate(mut self, is_alternate: bool) -> Self {
    method num_fmt (line 211) | pub const fn num_fmt(self) -> NumberFormatting {
    method is_alternate (line 217) | pub const fn is_alternate(self) -> bool {
    method hex_fmt (line 221) | pub(crate) const fn hex_fmt(self) -> HexFormatting {
  type LenAndArray (line 230) | pub struct LenAndArray<T: ?Sized> {
  type StartAndArray (line 238) | pub struct StartAndArray<T: ?Sized> {
  type ForEscaping (line 247) | pub struct ForEscaping {
    method get_backslash_escape (line 256) | pub const fn get_backslash_escape(b: u8) -> u8 {
  function hex_as_ascii (line 264) | pub const fn hex_as_ascii(n: u8, hex_fmt: HexFormatting) -> u8 {
  constant FOR_ESCAPING (line 275) | pub const FOR_ESCAPING: &ForEscaping = {

FILE: const_format/src/lib.rs
  type __AssertStr (line 483) | pub struct __AssertStr {
  type __AssertType (line 489) | pub struct __AssertType<T> {

FILE: const_format/src/marker_traits/format_marker.rs
  type FormatMarker (line 98) | pub trait FormatMarker {
    type Kind (line 261) | type Kind = IsStdKind;
    type This (line 262) | type This = Self;
    type Kind (line 274) | type Kind = IsArrayKind<T>;
    type This (line 275) | type This = Self;
    type Kind (line 279) | type Kind = IsArrayKind<T>;
    type This (line 280) | type This = [T];
    type Kind (line 287) | type Kind = T::Kind;
    type This (line 288) | type This = T::This;
    type Kind (line 295) | type Kind = T::Kind;
    type This (line 296) | type This = T::This;
  type IsArrayKind (line 122) | pub struct IsArrayKind<T>(PhantomData<T>);
  type IsStdKind (line 129) | pub struct IsStdKind;
  type IsNotStdKind (line 136) | pub struct IsNotStdKind;
  type IsAFormatMarker (line 187) | pub struct IsAFormatMarker<K, T: ?Sized, R: ?Sized>(
  method clone (line 198) | fn clone(&self) -> Self {
  constant NEW (line 208) | pub const NEW: Self = Self(PhantomData);
  function infer_type (line 219) | pub const fn infer_type(self, _: &R) -> Self {
  function unreference (line 225) | pub const fn unreference(self, r: &T) -> &T {
  function coerce (line 235) | pub const fn coerce(self, slice: &[U]) -> PWrapper<&[U]> {
  function coerce (line 243) | pub const fn coerce(self, reference: &T) -> &T {
  function coerce (line 268) | pub const fn coerce(self, reference: &str) -> PWrapper<&str> {

FILE: const_format/src/marker_traits/write_marker.rs
  type WriteMarker (line 88) | pub trait WriteMarker {
    type Kind (line 118) | type Kind = IsAStrWriter;
    type This (line 119) | type This = Self;
    type Kind (line 123) | type Kind = IsNotAStrWriter;
    type This (line 124) | type This = Self;
    type Kind (line 128) | type Kind = IsNotAStrWriter;
    type This (line 129) | type This = Self;
    type Kind (line 136) | type Kind = T::Kind;
    type This (line 137) | type This = T::This;
    type Kind (line 144) | type Kind = T::Kind;
    type This (line 145) | type This = T::This;
  type IsAStrWriter (line 106) | pub struct IsAStrWriter;
  type IsNotAStrWriter (line 113) | pub struct IsNotAStrWriter;
  type IsAWriteMarker (line 186) | pub struct IsAWriteMarker<K, T: ?Sized, R: ?Sized>(
  method clone (line 197) | fn clone(&self) -> Self {
  constant NEW (line 207) | pub const NEW: Self = Self(PhantomData);
  function infer_type (line 215) | pub const fn infer_type(self, _: &R) -> Self {
  function coerce (line 225) | pub const fn coerce(self, mutref: &mut StrWriter) -> StrWriterMut<'_> {
  function coerce (line 233) | pub const fn coerce(self, mutref: &mut T) -> &mut T {

FILE: const_format/src/msg.rs
  type ErrorTupleAndStrWriter (line 67) | pub struct ErrorTupleAndStrWriter<A> {
  type ErrorPicker (line 72) | pub struct ErrorPicker<E, Cap>(PhantomData<fn() -> (E, Cap)>);
  type ErrorTuple (line 74) | pub struct ErrorTuple {
  type ErrorAsType (line 79) | pub trait ErrorAsType {

FILE: const_format/src/pargument.rs
  type PArgument (line 11) | pub struct PArgument {
    method calc_len (line 20) | pub const fn calc_len(mut args: &[PArgument]) -> usize {
  type PVariant (line 33) | pub enum PVariant {
  type Integer (line 40) | pub struct Integer {
  type PConvWrapper (line 47) | pub struct PConvWrapper<T>(pub T);
  function to_pargument_display (line 130) | pub const fn to_pargument_display(self, _: FormattingFlags) -> PArgument {
  function to_pargument_debug (line 134) | pub const fn to_pargument_debug(self, _: FormattingFlags) -> PArgument {
  function to_pargument_display (line 142) | pub const fn to_pargument_display(self, _: FormattingFlags) -> PArgument {
  function to_pargument_debug (line 147) | pub const fn to_pargument_debug(self, fmt_flags: FormattingFlags) -> PAr...
  function to_pargument_display (line 155) | pub const fn to_pargument_display(self, fmt_flags: FormattingFlags) -> P...
  function to_pargument_debug (line 165) | pub const fn to_pargument_debug(self, fmt_flags: FormattingFlags) -> PAr...
  function to_pargument_display (line 179) | pub const fn to_pargument_display(self, fmt_flags: FormattingFlags) -> P...
  function to_pargument_debug (line 188) | pub const fn to_pargument_debug(self, fmt_flags: FormattingFlags) -> PAr...

FILE: const_format/src/slice_cmp.rs
  function str_eq (line 36) | pub const fn str_eq(left: &str, right: &str) -> bool {
  function u8_slice_eq (line 75) | pub const fn u8_slice_eq(left: &[u8], right: &[u8]) -> bool {
  function slice_eq_test (line 96) | fn slice_eq_test() {
  function str_eq_test (line 110) | fn str_eq_test() {

FILE: const_format/src/test_utils.rs
  constant ALL_ASCII (line 58) | pub const ALL_ASCII: &str = "\
  constant ALL_ASCII_ESCAPED (line 65) | pub const ALL_ASCII_ESCAPED: &str = "\

FILE: const_format/src/utils.rs
  type Constructor (line 6) | pub(crate) struct Constructor<T>(#[allow(dead_code)] fn() -> T);
  function saturate_range (line 12) | pub const fn saturate_range(s: &[u8], range: &Range<usize>) -> Range<usi...
  function slice_up_to_len_alt (line 32) | pub const fn slice_up_to_len_alt<T>(slice: &[T], len: usize) -> &[T] {
  function slice_up_to_len (line 59) | pub const fn slice_up_to_len<T>(slice: &[T], len: usize) -> &[T] {
  function min_usize (line 69) | pub(crate) const fn min_usize(l: usize, r: usize) -> usize {
  function test_slice_up_to_len_alt (line 82) | fn test_slice_up_to_len_alt() {
  function slice_in_bounds (line 93) | fn slice_in_bounds() {

FILE: const_format/src/wrapper_types/ascii_str.rs
  type AsciiStr (line 41) | pub struct AsciiStr<'a>(&'a [u8]);
  function from_str (line 60) | pub const fn from_str(s: &'a str) -> Result<Self, NotAsciiError> {
  function new (line 79) | pub const fn new(s: &'a [u8]) -> Result<Self, NotAsciiError> {
  function empty (line 97) | pub const fn empty() -> Self {
  function len (line 112) | pub const fn len(self) -> usize {
  function is_empty (line 127) | pub const fn is_empty(self) -> bool {
  function as_bytes (line 142) | pub const fn as_bytes(self) -> &'a [u8] {
  function as_str (line 157) | pub const fn as_str(self) -> &'a str {
  type NotAsciiError (line 168) | pub struct NotAsciiError {
  method fmt (line 174) | fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
  function basic (line 208) | fn basic() {
  function only_ascii_constructible (line 227) | fn only_ascii_constructible() {
  function formatting (line 250) | fn formatting() {

FILE: const_format/src/wrapper_types/pwrapper.rs
  type PWrapper (line 79) | pub struct PWrapper<T>(pub T);
  function slice (line 86) | pub const fn slice(x: &'a [T]) -> Self {
  type UWord (line 223) | type UWord = u16;
  type UWord (line 225) | type UWord = u32;
  type UWord (line 227) | type UWord = u64;
  type UWord (line 229) | type UWord = u128;
  type IWord (line 232) | type IWord = i16;
  type IWord (line 234) | type IWord = i32;
  type IWord (line 236) | type IWord = i64;
  type IWord (line 238) | type IWord = i128;
  function unsigned_abs (line 277) | pub const fn unsigned_abs(self) -> usize {
  function unsigned_abs (line 284) | pub const fn unsigned_abs(self) -> usize {
  method as_negative (line 291) | const fn as_negative(self) -> i128 {
  function to_start_array_binary (line 298) | pub const fn to_start_array_binary(self, flags: FormattingFlags) -> Star...
  function to_start_array_hexadecimal (line 332) | pub const fn to_start_array_hexadecimal(
  function to_start_array_display (line 372) | pub const fn to_start_array_display(self) -> StartAndArray<[u8; 40]> {
  function to_start_array_debug (line 399) | pub const fn to_start_array_debug(self) -> StartAndArray<[u8; 40]> {
  function compute_utf8_debug_len (line 407) | pub const fn compute_utf8_debug_len(self) -> usize {
  function compute_utf8_debug_len_in_range (line 413) | pub const fn compute_utf8_debug_len_in_range(self, mut range: Range<usiz...
  function compute_debug_len (line 437) | pub const fn compute_debug_len(self, _: FormattingFlags) -> usize {
  function compute_display_len (line 444) | pub const fn compute_display_len(self, _: FormattingFlags) -> usize {
  constant _ (line 450) | const _: () = {

FILE: const_format/src/wrapper_types/pwrapper/tests.rs
  function get_digits_display (line 11) | fn get_digits_display(n: impl fmt::Display) -> ArrayString<64> {
  function get_hex_digits (line 16) | fn get_hex_digits(n: impl fmt::UpperHex) -> ArrayString<64> {
  function get_lower_hex_digits (line 21) | fn get_lower_hex_digits(n: impl fmt::LowerHex) -> ArrayString<64> {
  function get_binary_digits (line 26) | fn get_binary_digits(n: impl fmt::Binary) -> ArrayString<192> {
  constant DEF_FLAGS (line 32) | const DEF_FLAGS: FormattingFlags = FormattingFlags::DEFAULT;
  function pwrapper_methods (line 148) | fn pwrapper_methods() {
  function wrapped_formatting (line 165) | fn wrapped_formatting() {

FILE: const_format/src/wrapper_types/sliced.rs
  type Sliced (line 30) | pub struct Sliced<T, R>(pub T, pub R);
  function range (line 76) | const fn range(&self) -> Range<usize> {
  function range (line 83) | const fn range(&self) -> Range<usize> {
  function range (line 90) | const fn range(&self) -> Range<usize> {
  constant UM (line 95) | const UM: usize = usize::MAX >> 1;
  function range (line 101) | const fn range(&self) -> Range<usize> {
  function range (line 108) | const fn range(&self) -> Range<usize> {
  function range (line 117) | const fn range(&self) -> Range<usize> {
  constant S (line 151) | const S: &str = "\x00\n\t3456789\x06\x07";
  function str_tests (line 204) | fn str_tests() {
  function asciistr_tests (line 208) | fn asciistr_tests() {

FILE: const_format/tests/fmt_tests/display_formatting.rs
  type DisplayFoo (line 8) | struct DisplayFoo {
    method const_display_fmt (line 16) | pub const fn const_display_fmt(&self, f: &mut Formatter<'_>) -> Result...
  function inner (line 28) | const fn inner(
  function test_display_foo (line 42) | fn test_display_foo() {
  function display_fmt_other_types (line 152) | fn display_fmt_other_types() {

FILE: const_format/tests/fmt_tests/formatted_writing.rs
  type Foo (line 9) | struct Foo {
    method const_debug_fmt (line 16) | pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(...
  type Bar (line 26) | struct Bar {
    method const_debug_fmt (line 34) | pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(...
  function check_debug_formatting (line 45) | fn check_debug_formatting() {
  type Set (line 208) | pub struct Set(&'static [Foo]);
    method const_debug_fmt (line 211) | pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(...
  function check_set_formatting (line 221) | fn check_set_formatting() {

FILE: const_format/tests/fmt_tests/formatter_methods.rs
  function write_with_flag (line 20) | fn write_with_flag(flags: FormattingFlags, expected: &str, takes_fmt: &d...
  function write_integers (line 45) | fn write_integers() {
  function write_str_methods (line 119) | fn write_str_methods() {
  function remove_margin (line 148) | fn remove_margin(s: &str) -> String {

FILE: const_format/tests/fmt_tests/formatter_methods/debug_methods.rs
  function format_b_field (line 10) | const fn format_b_field(b: &'static [u32], fmt: &mut Formatter<'_>) -> R...
  type BracedStruct (line 21) | struct BracedStruct {
  function formatting_struct (line 47) | fn formatting_struct() {
  type TupleStruct (line 99) | struct TupleStruct {
  function formatting_tuple (line 125) | fn formatting_tuple() {
  type List (line 177) | struct List {
  function formatting_list (line 203) | fn formatting_list() {
  type Set (line 255) | struct Set {
  function formatting_set (line 281) | fn formatting_set() {

FILE: const_format/tests/fmt_tests/std_impl_tests.rs
  constant FLAGS (line 17) | const FLAGS: &[FormattingFlags] = &[
  function array_impls (line 59) | fn array_impls() {
  function range_impls (line 87) | fn range_impls() {
  function options (line 97) | fn options() {
  function pointers (line 127) | fn pointers() {
  function marker (line 134) | fn marker() {
  function miscelaneous_enums (line 141) | fn miscelaneous_enums() {
  function chars (line 156) | fn chars() {

FILE: const_format/tests/fmt_tests/str_writer_methods.rs
  type Formatting (line 18) | enum Formatting {
  function test_write_ints (line 114) | fn test_write_ints() {
  function basic (line 132) | fn basic() {
  function saturate_range_tests (line 140) | fn saturate_range_tests() {
  type WriteArgs (line 157) | struct WriteArgs<'sw, 's> {
  function test_unescaped_str_fn (line 164) | fn test_unescaped_str_fn(
  function write_str (line 246) | fn write_str() {
  function write_ascii (line 264) | fn write_ascii() {
  function is_it_escaped (line 277) | fn is_it_escaped(c: char) -> bool {
  function write_str_debug (line 282) | fn write_str_debug() {
  function returns_error (line 384) | fn returns_error() {
  function remaining_capacity_test (line 423) | fn remaining_capacity_test() {
  function truncation (line 443) | fn truncation() {
  function as_bytes (line 516) | fn as_bytes() {
  function clear (line 532) | fn clear() {
  function write_ascii_debug (line 556) | fn write_ascii_debug() {

FILE: const_format/tests/fmt_tests/str_writer_mut.rs
  function from_custom (line 4) | fn from_custom() -> Result<(), Error> {
  function from_custom_cleared (line 38) | fn from_custom_cleared() -> Result<(), Error> {
  function truncate_no_encoding (line 78) | fn truncate_no_encoding() -> Result<(), Error> {
  function clear_test (line 125) | fn clear_test() {
  function as_bytes (line 153) | fn as_bytes() {

FILE: const_format/tests/fmt_tests_modules.rs
  constant NOT_CF (line 8) | pub const NOT_CF: usize = 13;
  constant _ASSERT_NOT_CF (line 9) | pub const _ASSERT_NOT_CF: [(); 13] = [(); const_format::NOT_CF];

FILE: const_format/tests/misc_tests/assertc_tests.rs
  type Foo (line 7) | struct Foo;
  function assertc_emits_formatting (line 48) | fn assertc_emits_formatting() {
  constant _ (line 62) | const _: () = {

FILE: const_format/tests/misc_tests/assertcp_tests.rs
  type Foo (line 6) | struct Foo;
  function assertcp_emits_formatting (line 33) | fn assertcp_emits_formatting() {
  constant X (line 49) | const X: u8 = 123;
  constant _ (line 52) | const _: () = {

FILE: const_format/tests/misc_tests/call_debug_fmt_macro.rs
  function all_macro_branches (line 7) | fn all_macro_branches() {
  function returns_error (line 51) | fn returns_error() {
  type Hello (line 64) | struct Hello<T>(T);
  type TupleStruct (line 66) | struct TupleStruct(u32);

FILE: const_format/tests/misc_tests/clippy_warnings.rs
  function test_clippy_double_parens_not_triggered (line 3) | fn test_clippy_double_parens_not_triggered() {

FILE: const_format/tests/misc_tests/concatc_macro_tests.rs
  constant STD_TYPES (line 6) | const STD_TYPES: &str = concatc!(
  constant USER_TYPES (line 17) | const USER_TYPES: &str = concatc!(Twice("hello "), ascii_str!("world!"));
  function concatc_test (line 20) | fn concatc_test() {
  type Twice (line 25) | struct Twice(&'static str);

FILE: const_format/tests/misc_tests/derive_tests.rs
  type Dummy (line 12) | struct Dummy;
  type Braced (line 16) | struct Braced {
  type Tupled (line 32) | struct Tupled<T, U>(
  type Unit (line 43) | struct Unit;
  function struct_formatting (line 46) | fn struct_formatting() {
  type Enum (line 100) | enum Enum {
  function enum_formatting (line 121) | fn enum_formatting() {

FILE: const_format/tests/misc_tests/derive_tests/is_a_attributes.rs
  type Bar (line 11) | pub struct Bar(pub u32);
  function fmt_bar_in_hex (line 23) | const fn fmt_bar_in_hex(this: &Bar, f: &mut Formatter<'_>) -> Result<(),...
  type DisplayWrapper (line 30) | pub struct DisplayWrapper<'a, T>(pub &'a T);
  type NotDebug (line 53) | pub struct NotDebug;
  type Option (line 55) | pub struct Option<T>(pub PhantomData<T>);
  type WrapsNamedOption (line 68) | pub(super) struct WrapsNamedOption {
  type Automatic (line 104) | struct Automatic {
  type BarSlice (line 116) | type BarSlice = [Bar];
  type BarArray (line 117) | type BarArray = [Bar; 2];
  type BarOption (line 118) | type BarOption = Option<Bar>;
  type Manual (line 122) | struct Manual {
  function automatic_type_detection (line 159) | fn automatic_type_detection() {
  function manual_type_detection (line 201) | fn manual_type_detection() {
  function opting_out_of_std (line 247) | fn opting_out_of_std() {

FILE: const_format/tests/misc_tests/equality_tests.rs
  function compare_arrays (line 20) | fn compare_arrays() {
  function compare_options (line 67) | fn compare_options() {
  function enums (line 96) | fn enums() {
  function char_cases (line 108) | fn char_cases() {
  function ranges (line 113) | fn ranges() {

FILE: const_format/tests/misc_tests/formatc_macros.rs
  function concat_fmt_strings (line 23) | fn concat_fmt_strings() {
  function positional_and_named_arguments (line 52) | fn positional_and_named_arguments() {
  function debug_formatting (line 75) | fn debug_formatting() {
  function binary_and_hex_formatting (line 255) | fn binary_and_hex_formatting() {
  function other_tests (line 270) | fn other_tests() {
  function escaped_format_string (line 278) | fn escaped_format_string() {
  function raw_literals (line 297) | fn raw_literals() {
  function access_formatter (line 311) | fn access_formatter() {

FILE: const_format/tests/misc_tests/impl_fmt_macro_tests.rs
  type Delegating (line 16) | struct Delegating<T>(T);
  type BracedStruct (line 20) | struct BracedStruct<T: 'static> {
  type TupleStruct (line 26) | struct TupleStruct<T>(T, u32);
  type UnitStruct (line 28) | struct UnitStruct;
  function struct_debug_impl (line 125) | fn struct_debug_impl() {
  type BracedStructNE (line 185) | struct BracedStructNE<T: 'static> {
  type UnDebug (line 194) | struct UnDebug;
  type TupleStructNE (line 196) | struct TupleStructNE<T, U>(T, u32, PhantomData<U>);
  function struct_nonexhaustive_debug_impl (line 230) | fn struct_nonexhaustive_debug_impl() {
  type EnumA (line 254) | enum EnumA<T> {
  function enum_debug_impl (line 293) | fn enum_debug_impl() {
  type EnumA_NE (line 357) | enum EnumA_NE<T> {
  function enum_nonexhaustive_debug_impl (line 399) | fn enum_nonexhaustive_debug_impl() {
  type StructWE (line 435) | struct StructWE<T>(EnumA<T>);
  function enum_inside_struct (line 451) | fn enum_inside_struct() {

FILE: const_format/tests/misc_tests/inline_const_pattern_tests.rs
  function concatc_inline_pat_tests (line 9) | fn concatc_inline_pat_tests() {
  function concatcp_inline_pat_tests (line 15) | fn concatcp_inline_pat_tests() {
  function formatc_inline_pat_tests (line 21) | fn formatc_inline_pat_tests() {
  function formatcp_inline_pat_tests (line 27) | fn formatcp_inline_pat_tests() {
  function map_ascii_case_inline_pat_tests (line 33) | fn map_ascii_case_inline_pat_tests() {
  function str_get_inline_pat_tests (line 42) | fn str_get_inline_pat_tests() {
  function str_splice_out_inline_pat_tests (line 48) | fn str_splice_out_inline_pat_tests() {
  function str_index_inline_pat_tests (line 54) | fn str_index_inline_pat_tests() {
  function str_repeat_inline_pat_tests (line 60) | fn str_repeat_inline_pat_tests() {
  function str_replace_inline_pat_tests (line 66) | fn str_replace_inline_pat_tests() {
  function str_split_pat_inline_pat_tests (line 72) | fn str_split_pat_inline_pat_tests() {

FILE: const_format/tests/misc_tests/shared_cp_macro_tests.rs
  function other_tests (line 81) | fn other_tests() {
  function call_in_braced_macro (line 97) | fn call_in_braced_macro() {

FILE: const_format/tests/misc_tests/type_kind_coercion_macro_tests.rs
  function coercion (line 5) | fn coercion() {
  type UnitStruct (line 37) | struct UnitStruct;

FILE: const_format/tests/misc_tests/writec_macro.rs
  type Foo (line 7) | struct Foo {
  function basic (line 13) | fn basic() {
  function repeated_positional_args (line 36) | fn repeated_positional_args() {
  function write_from_consts (line 62) | fn write_from_consts() {
  function named_parameters (line 84) | fn named_parameters() {
  function write_from_locals (line 104) | fn write_from_locals() {
  function access_formatter (line 129) | fn access_formatter() {

FILE: const_format/tests/misc_tests_modules.rs
  constant NOT_CF (line 7) | pub const NOT_CF: usize = 13;
  constant _ASSERT_NOT_CF (line 8) | pub const _ASSERT_NOT_CF: [(); 13] = [(); const_format::NOT_CF];

FILE: const_format/tests/str_methods_modules/conv_ascii_case.rs
  function test_lowercase (line 22) | fn test_lowercase() {
  function test_uppercase (line 31) | fn test_uppercase() {
  function test_snake_kebab_case (line 40) | fn test_snake_kebab_case() {
  function test_pascal_camel_case (line 58) | fn test_pascal_camel_case() {

FILE: const_format/tests/str_methods_modules/str_replace.rs
  function test_small_pattern (line 23) | fn test_small_pattern() {
  function test_char_pattern (line 35) | fn test_char_pattern() {
  function test_replace_overlapping (line 75) | fn test_replace_overlapping() {
  function test_replace_empty (line 85) | fn test_replace_empty() {

FILE: const_format/tests/str_methods_modules/str_splice.rs
  function ss (line 3) | fn ss(output: &'static str, removed: &'static str) -> SplicedStr {
  constant IN (line 7) | const IN: &str = "abcdefghij";
  constant RW (line 8) | const RW: &str = "_.-";
  function splice_ranges (line 11) | fn splice_ranges() {
  function replacements (line 36) | fn replacements() {
  function splice_out_ranges (line 46) | fn splice_out_ranges() {
  function splice_out_replacements (line 71) | fn splice_out_replacements() {

FILE: const_format/tests/str_methods_modules/str_split_tests.rs
  function test_str_split_pat_basic_equivalence (line 4) | fn test_str_split_pat_basic_equivalence() {
  function test_str_split_with_empty_str_arg (line 19) | fn test_str_split_with_empty_str_arg() {
  function test_str_split_with_space_str_arg (line 32) | fn test_str_split_with_space_str_arg() {
  function test_str_split_with_dash_str_arg (line 41) | fn test_str_split_with_dash_str_arg() {
  function test_str_split_with_word_arg (line 50) | fn test_str_split_with_word_arg() {
  function test_str_split_with_ascii_char_arg (line 59) | fn test_str_split_with_ascii_char_arg() {
  function test_str_split_with_non_ascii_char_arg (line 68) | fn test_str_split_with_non_ascii_char_arg() {

FILE: const_format_proc_macros/src/datastructure.rs
  type DataStructure (line 20) | pub struct DataStructure<'a> {
  function new (line 36) | pub fn new(ast: &'a DeriveInput) -> Self {
  type StructKind (line 98) | pub enum StructKind {
  type DataVariant (line 106) | pub enum DataVariant {
  type FieldIndex (line 113) | pub struct FieldIndex {
  type StructParams (line 121) | struct StructParams<'a> {
  type Struct (line 128) | pub struct Struct<'a> {
  function new (line 141) | fn new(p: StructParams<'a>, fields: &'a SynFields) -> Self {
  function with_fields (line 156) | fn with_fields<I>(p: StructParams<'a>, kind: StructKind, fields: Option<...
  type Field (line 179) | pub struct Field<'a> {
  function new (line 189) | fn new(index: FieldIndex, field: &'a SynField) -> Self {
  function pattern_ident (line 213) | pub fn pattern_ident(&self) -> &Ident {
  function from_iter (line 217) | fn from_iter<I>(p: StructParams<'a>, fields: I) -> Vec<Self>
  type FieldIdent (line 238) | pub enum FieldIdent<'a> {
  method fmt (line 244) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  method to_tokens (line 253) | fn to_tokens(&self, tokens: &mut TokenStream) {
  function new_index (line 262) | fn new_index(index: usize) -> Self {

FILE: const_format_proc_macros/src/datastructure/field_map.rs
  type FieldMap (line 13) | pub struct FieldMap<T> {
  function with (line 22) | pub fn with<'a, F>(ds: &'a DataStructure<'a>, mut f: F) -> Self
  function iter (line 36) | pub fn iter(&self) -> impl Iterator<Item = (FieldIndex, &'_ T)> + Clone ...
  function iter_mut (line 49) | pub fn iter_mut(&mut self) -> impl Iterator<Item = (FieldIndex, &'_ mut ...
  type Output (line 63) | type Output = T;
  function index (line 65) | fn index(&self, index: FieldIndex) -> &T {
  function index_mut (line 71) | fn index_mut(&mut self, index: FieldIndex) -> &mut T {
  type Output (line 77) | type Output = T;
  function index (line 79) | fn index(&self, field: &'a Field<'a>) -> &T {
  function index_mut (line 86) | fn index_mut(&mut self, field: &'a Field<'a>) -> &mut T {

FILE: const_format_proc_macros/src/derive_debug.rs
  function derive_constdebug_impl (line 15) | pub(crate) fn derive_constdebug_impl(input: DeriveInput) -> Result<Token...
  function coerce_and_fmt (line 150) | fn coerce_and_fmt(cratep: &TokenStream2, field: &Field<'_>) -> TokenStre...
  function fmt_slice (line 166) | fn fmt_slice(cratep: &TokenStream2, field: &Field<'_>) -> TokenStream2 {
  function fmt_option (line 189) | fn fmt_option(cratep: &TokenStream2, field: &Field<'_>) -> TokenStream2 {
  function fmt_newtype (line 212) | fn fmt_newtype(cratep: &TokenStream2, newtype: &syn::Ident, field: &Fiel...
  function call_with_function (line 233) | fn call_with_function(cratep: &TokenStream2, field: &Field<'_>, func: &s...
  function call_with_macro (line 240) | fn call_with_macro(cratep: &TokenStream2, field: &Field<'_>, macr: &syn:...
  function call_with_wrapper (line 247) | fn call_with_wrapper(
  function call_debug_fmt (line 261) | fn call_debug_fmt(
  function get_where_clause_tokens (line 281) | fn get_where_clause_tokens(where_clause: &Option<syn::WhereClause>) -> T...

FILE: const_format_proc_macros/src/derive_debug/attribute_parsing.rs
  type ConstDebugConfig (line 14) | pub(crate) struct ConstDebugConfig<'a> {
  function new (line 23) | fn new(roa: ConstDebugAttrs<'a>) -> Result<Self, crate::Error> {
  type ConstDebugAttrs (line 43) | struct ConstDebugAttrs<'a> {
  type FieldConfig (line 54) | pub(crate) struct FieldConfig<'a> {
  type HowToFmt (line 58) | pub(crate) enum HowToFmt<'a> {
  type ParseContext (line 83) | enum ParseContext<'a> {
  function parse_attrs_for_derive (line 88) | pub(crate) fn parse_attrs_for_derive<'a>(
  function parse_inner (line 117) | fn parse_inner<'a, I>(
  function parse_attr_list (line 141) | fn parse_attr_list<'a>(
  function make_err (line 157) | fn make_err(tokens: &dyn ToTokens) -> crate::Error {
  function parse_sabi_attr (line 162) | fn parse_sabi_attr<'a>(
  function parse_the_is_a_attribute (line 245) | fn parse_the_is_a_attribute<'a>(
  function parse_lit (line 270) | fn parse_lit<T>(lit: &syn::Lit) -> Result<T, crate::Error>
  function parse_expr (line 284) | fn parse_expr(lit: syn::Lit) -> Result<syn::Expr, crate::Error> {
  function with_nested_meta (line 295) | pub fn with_nested_meta<F>(

FILE: const_format_proc_macros/src/derive_debug/syntax.rs
  type ImplHeader (line 8) | pub(crate) struct ImplHeader {
  method parse (line 14) | fn parse(input: ParseStream) -> Result<Self, syn::Error> {

FILE: const_format_proc_macros/src/derive_debug/type_detection.rs
  function detect_type_formatting (line 5) | pub(super) fn detect_type_formatting(ty: &Type) -> HowToFmt {
  function unwrap_reference (line 17) | fn unwrap_reference(mut ty: &Type) -> &Type {
  function is_path_an_option (line 29) | fn is_path_an_option(path: &syn::Path) -> bool {
  function parse_type_as_ident (line 48) | pub(super) fn parse_type_as_ident(ty: &Type) -> Result<&syn::Ident, crat...

FILE: const_format_proc_macros/src/error.rs
  type Error (line 11) | pub struct Error {
    method new (line 27) | pub fn new<T: Display>(span: Span, msg: T) -> Self {
    method spanned (line 37) | pub fn spanned<T: Display>(spans: Spans, msg: T) -> Self {
    method to_compile_error (line 47) | pub fn to_compile_error(&self) -> TokenStream2 {
    method combine (line 98) | pub fn combine(&mut self, another: Error) {
    method from (line 105) | fn from(err: syn::Error) -> Self {
  type CompileError (line 16) | enum CompileError {

FILE: const_format_proc_macros/src/format_args.rs
  type UncheckedFormatArgs (line 16) | struct UncheckedFormatArgs {
  type UncheckedFormatArg (line 21) | struct UncheckedFormatArg {
  type FormatArgs (line 32) | pub(crate) struct FormatArgs {
  type FormatIfArgs (line 38) | pub(crate) struct FormatIfArgs {
  type WriteArgs (line 43) | pub(crate) struct WriteArgs {
  type ExpandInto (line 49) | pub(crate) enum ExpandInto {
    method fmt_call (line 91) | pub(crate) fn fmt_call(&self, formatter: &Ident) -> TokenStream2 {
  type ExpandFormatted (line 55) | pub(crate) struct ExpandFormatted {
  type ExpandWithFormatter (line 60) | pub(crate) struct ExpandWithFormatter {
  type LocalVariable (line 66) | pub(crate) struct LocalVariable {
  type FormatArg (line 76) | pub(crate) enum FormatArg {

FILE: const_format_proc_macros/src/format_args/parsing.rs
  method parse (line 19) | fn parse(input: ParseStream<'_>) -> Result<Self, crate::Error> {
  function lit_str_to_fmt_lit (line 62) | fn lit_str_to_fmt_lit(lit: &LitStr) -> Result<FormatStr, crate::Error> {
  function parse_fmt_lit (line 69) | fn parse_fmt_lit(this: &mut FormatStr, input: ParseStream<'_>) -> Result...
  method parse (line 98) | fn parse(input: ParseStream<'_>) -> Result<Self, crate::Error> {
  method parse (line 126) | fn parse(input: ParseStream<'_>) -> Result<Self, crate::Error> {
  method parse_with (line 133) | pub fn parse_with(input: ParseStream<'_>, prefix: Ident) -> Result<Forma...
  method parse (line 312) | fn parse(input: ParseStream) -> Result<Self, crate::Error> {
  method parse (line 325) | fn parse(input: ParseStream) -> Result<Self, crate::Error> {

FILE: const_format_proc_macros/src/format_macro.rs
  function concatcp_impl (line 17) | pub(crate) fn concatcp_impl(value: ExprArgs) -> Result<TokenStream2, cra...
  function formatcp_if_macro_impl (line 44) | pub(crate) fn formatcp_if_macro_impl(value: FormatIfArgs) -> Result<Toke...
  function formatcp_impl (line 48) | pub(crate) fn formatcp_impl(fmt_args: FormatArgs) -> Result<TokenStream2...
  function formatc_if_macro_impl (line 127) | pub(crate) fn formatc_if_macro_impl(value: FormatIfArgs) -> Result<Token...
  function formatc_macro_impl (line 133) | pub(crate) fn formatc_macro_impl(fmt_args: FormatArgs) -> Result<TokenSt...
  function writec_macro_impl (line 170) | pub(crate) fn writec_macro_impl(value: WriteArgs) -> Result<TokenStream2...

FILE: const_format_proc_macros/src/format_macro/tests.rs
  function process_str (line 3) | fn process_str(s: &str) -> Result<String, String> {
  function named_argument_followed_by_positional (line 19) | fn named_argument_followed_by_positional() {
  function access_formatter_error (line 27) | fn access_formatter_error() {
  function nonexistent_argument (line 45) | fn nonexistent_argument() {
  function unused_arguments (line 59) | fn unused_arguments() {

FILE: const_format_proc_macros/src/format_str.rs
  type FormatStr (line 13) | pub(crate) struct FormatStr {
  type FmtStrComponent (line 18) | pub(crate) enum FmtStrComponent {
  type FmtArg (line 25) | pub(crate) struct FmtArg {
  type WhichArg (line 32) | pub(crate) enum WhichArg {

FILE: const_format_proc_macros/src/format_str/errors.rs
  type ParseError (line 9) | pub(crate) struct ParseError {
    method error_span (line 61) | fn error_span(&self) -> Range<usize> {
    method into_crate_err (line 73) | pub(crate) fn into_crate_err(self, span: Span, original_str: &str) -> ...
  type ParseErrorKind (line 15) | pub(crate) enum ParseErrorKind {
    method not_a_number (line 35) | pub fn not_a_number(what: &str) -> Self {
    method not_an_ident (line 40) | pub fn not_an_ident(what: &str) -> Self {
    method unknown_formatting (line 45) | pub fn unknown_formatting(what: &str) -> Self {
  type DisplayParseError (line 55) | pub(crate) struct DisplayParseError<'a> {
  method fmt (line 85) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  method fmt (line 101) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {

FILE: const_format_proc_macros/src/format_str/parsing.rs
  method str (line 10) | pub(super) fn str(s: &str) -> Self {
  method arg (line 13) | pub(super) fn arg(which_arg: WhichArg, formatting: FormattingFlags) -> S...
  method new (line 23) | fn new(which_arg: WhichArg, formatting: FormattingFlags, rawness: StrRaw...
  method ident (line 34) | pub(super) fn ident(s: &str) -> Self {
  type Err (line 43) | type Err = ParseError;
  method from_str (line 45) | fn from_str(input: &str) -> Result<FormatStr, ParseError> {
  method parse (line 51) | pub fn parse(input: &str, rawness: StrRawness) -> Result<FormatStr, Pars...
  function parse_format_str (line 56) | fn parse_format_str(input: &str, rawness: StrRawness) -> Result<FormatSt...
  function parse_mid_str (line 95) | fn parse_mid_str(str: &str, starts_at: usize) -> Result<String, ParseErr...
  function parse_fmt_arg (line 121) | fn parse_fmt_arg(input: &str, starts_at: usize, rawness: StrRawness) -> ...
  function parse_which_arg (line 138) | fn parse_which_arg(input: &str, starts_at: usize) -> Result<WhichArg, Pa...
  function parse_formatting (line 159) | fn parse_formatting(input: &str, starts_at: usize) -> Result<FormattingF...
  function parse_ident (line 197) | fn parse_ident(ident_str: &str, starts_at: usize) -> Result<WhichArg, Pa...
  function is_ident (line 212) | fn is_ident(s: &str) -> bool {
  type VecExt (line 228) | trait VecExt {
    method push_arg_str (line 229) | fn push_arg_str(&mut self, str: String, rawness: StrRawness);
    method push_arg_str (line 233) | fn push_arg_str(&mut self, str: String, rawness: StrRawness) {
  type StrExt (line 240) | trait StrExt {
    method find_from (line 241) | fn find_from(&self, c: char, from: usize) -> Option<usize>;
    method find_from (line 245) | fn find_from(&self, c: char, from: usize) -> Option<usize> {

FILE: const_format_proc_macros/src/format_str/tests.rs
  function err (line 11) | fn err(s: &'static str) -> ParseError {
  function ok (line 15) | fn ok(s: &'static str) -> FormatStr {
  constant NOALT (line 19) | const NOALT: IsAlternate = IsAlternate::No;
  constant NFDEC (line 20) | const NFDEC: NumberFormatting = NumberFormatting::Decimal;
  function unclosed_arg (line 23) | fn unclosed_arg() {
  function invalid_closed_arg (line 48) | fn invalid_closed_arg() {
  function not_a_number (line 73) | fn not_a_number() {
  function not_an_ident (line 98) | fn not_an_ident() {
  function unknown_formatting (line 130) | fn unknown_formatting() {
  function ok_cases (line 148) | fn ok_cases() {
  type RngExt (line 198) | trait RngExt {
    method pick (line 202) | fn pick<'a, T>(&self, slice: &'a [T]) -> &'a T;
    method char_ (line 207) | fn char_(&self, bounds: RangeInclusive<char>) -> char;
    method pick (line 211) | fn pick<'a, T>(&self, slice: &'a [T]) -> &'a T {
    method char_ (line 215) | fn char_(&self, bounds: RangeInclusive<char>) -> char {
  function generate_input (line 230) | fn generate_input() -> String {
  function never_panics (line 262) | fn never_panics() {

FILE: const_format_proc_macros/src/formatting.rs
  type Formatting (line 6) | pub(crate) enum Formatting {
  type NumberFormatting (line 12) | pub(crate) enum NumberFormatting {
    method is_regular (line 20) | pub(crate) fn is_regular(self) -> bool {
  method to_tokens (line 26) | fn to_tokens(&self, ts: &mut TokenStream2) {
  type IsAlternate (line 39) | pub(crate) enum IsAlternate {
  type FormattingFlags (line 47) | pub(crate) struct FormattingFlags {
    method display (line 54) | pub(crate) const fn display(is_alternate: IsAlternate) -> Self {
    method debug (line 62) | pub(crate) const fn debug(num_fmt: NumberFormatting, is_alternate: IsA...
    method to_pargument_method_name (line 71) | pub(crate) fn to_pargument_method_name(self) -> Ident {
    method fmt_method_name (line 81) | pub(crate) fn fmt_method_name(self) -> Ident {
    method len_method_name (line 91) | pub(crate) fn len_method_name(self) -> Ident {
  method to_tokens (line 102) | fn to_tokens(&self, ts: &mut TokenStream2) {

FILE: const_format_proc_macros/src/lib.rs
  function compile_err_empty_str (line 44) | fn compile_err_empty_str(e: crate::Error) -> TokenStream2 {
  function __concatcp_impl (line 54) | pub fn __concatcp_impl(input: TokenStream1) -> TokenStream1 {
  function __formatcp_impl (line 70) | pub fn __formatcp_impl(input: TokenStream1) -> TokenStream1 {
  function __formatc_impl (line 79) | pub fn __formatc_impl(input: TokenStream1) -> TokenStream1 {
  function __formatc_if_impl (line 88) | pub fn __formatc_if_impl(input: TokenStream1) -> TokenStream1 {
  function __formatcp_if_impl (line 97) | pub fn __formatcp_if_impl(input: TokenStream1) -> TokenStream1 {
  function __writec_impl (line 106) | pub fn __writec_impl(input: TokenStream1) -> TokenStream1 {
  function derive_const_debug (line 121) | pub fn derive_const_debug(input: TokenStream1) -> TokenStream1 {
  function respan_to (line 132) | pub fn respan_to(input: TokenStream1) -> TokenStream1 {

FILE: const_format_proc_macros/src/parse_utils.rs
  type ParseStream (line 10) | pub type ParseStream<'a> = &'a mut ParseBuffer;
  type ParseBuffer (line 12) | pub struct ParseBuffer {
    method new (line 17) | pub fn new(ts: TokenStream2) -> Self {
    method is_empty (line 22) | pub fn is_empty(&mut self) -> bool {
    method peek (line 26) | pub fn peek(&mut self) -> Option<&TokenTree2> {
    method peek2 (line 29) | pub fn peek2(&mut self) -> Option<&TokenTree2> {
    method parse_punct (line 33) | pub fn parse_punct(&mut self, c: char) -> Result<Punct, crate::Error> {
    method parse_opt_punct (line 43) | pub fn parse_opt_punct(&mut self, c: char) -> Result<Option<Punct>, cr...
    method parse_ident (line 51) | pub fn parse_ident(&mut self) -> Result<Ident, crate::Error> {
    method parse_paren (line 59) | pub fn parse_paren(&mut self) -> Result<Parentheses, crate::Error> {
    method parse_unwrap_paren (line 78) | pub fn parse_unwrap_paren<F, T>(&mut self, f: F) -> Result<T, crate::E...
    method parse_unwrap_group (line 94) | pub fn parse_unwrap_group<F, T>(&mut self, f: F) -> Result<T, crate::E...
    method parse_token_stream_and_span (line 105) | pub fn parse_token_stream_and_span(&mut self) -> (TokenStream2, Spans) {
    method parse_unwrap_tt (line 128) | pub fn parse_unwrap_tt<F, T>(&mut self, f: F) -> Result<T, crate::Error>
  type Item (line 145) | type Item = TokenTree2;
  method next (line 147) | fn next(&mut self) -> Option<TokenTree2> {
  method size_hint (line 151) | fn size_hint(&self) -> (usize, Option<usize>) {
  type Parentheses (line 158) | pub struct Parentheses {
  type LitStr (line 166) | pub struct LitStr {
    method value (line 174) | pub fn value(&self) -> &str {
    method parse_from_literal (line 177) | pub(crate) fn parse_from_literal(literal: &proc_macro2::Literal) -> Re...
  type StrRawness (line 240) | pub struct StrRawness {
    method dummy (line 253) | pub fn dummy() -> Self {
    method span (line 260) | pub fn span(&self) -> Span {
    method tokenize_sub (line 265) | pub fn tokenize_sub(&self, str: &str) -> TokenStream2 {
  method eq (line 246) | fn eq(&self, other: &Self) -> bool {
  type TokenTreeExt (line 296) | pub trait TokenTreeExt: Sized {
    method as_token_tree (line 297) | fn as_token_tree(&self) -> &TokenTree2;
    method into_token_tree (line 298) | fn into_token_tree(self) -> TokenTree2;
    method is_punct (line 300) | fn is_punct(&self, c: char) -> bool {
    method is_paren (line 305) | fn is_paren(&self) -> bool {
    method is_ident (line 313) | fn is_ident(&self, ident: &str) -> bool {
    method set_span_recursive (line 317) | fn set_span_recursive(self, span: Span) -> TokenTree2 {
    method as_token_tree (line 332) | fn as_token_tree(&self) -> &TokenTree2 {
    method into_token_tree (line 336) | fn into_token_tree(self) -> TokenTree2 {
  type TokenStream2Ext (line 343) | pub trait TokenStream2Ext: Sized {
    method into_token_stream (line 344) | fn into_token_stream(self) -> TokenStream2;
    method set_span_recursive (line 346) | fn set_span_recursive(self, span: Span) -> TokenStream2 {
    method into_token_stream (line 355) | fn into_token_stream(self) -> TokenStream2 {
  type MyParse (line 362) | pub trait MyParse: Sized {
    method parse (line 363) | fn parse(input: ParseStream<'_>) -> Result<Self, crate::Error>;
    method parse_token_stream_1 (line 365) | fn parse_token_stream_1(input: proc_macro::TokenStream) -> Result<Self...
    method parse_token_stream_2 (line 370) | fn parse_token_stream_2(input: TokenStream2) -> Result<Self, crate::Er...

FILE: const_format_proc_macros/src/respan_to_macro.rs
  constant MSG (line 5) | const MSG: &str = "Expected the macro to be called as `respan_to!((token...
  function parse_paren (line 7) | fn parse_paren(tt: TokenTree2) -> TokenStream2 {
  function get_span (line 14) | fn get_span(ts: TokenStream2) -> Span {
  function implementation (line 33) | pub(crate) fn implementation(ts: TokenStream2) -> TokenStream2 {

FILE: const_format_proc_macros/src/shared_arg_parsing.rs
  type ExprArg (line 15) | pub(crate) struct ExprArg {
  method to_tokens (line 23) | fn to_tokens(&self, ts: &mut TokenStream2) {
  type ExprArgs (line 29) | pub(crate) struct ExprArgs {
  method parse (line 36) | fn parse(input: ParseStream<'_>) -> Result<Self, crate::Error> {
  method parse (line 52) | fn parse(input: ParseStream<'_>) -> Result<Self, crate::Error> {

FILE: const_format_proc_macros/src/spanned.rs
  type Spans (line 4) | pub struct Spans {
    method joined (line 10) | pub fn joined(self) -> Span {

FILE: const_format_proc_macros/src/test_utils.rs
  type StrExt (line 1) | pub trait StrExt {
    method as_str (line 2) | fn as_str(&self) -> &str;
    method consecutive_in_self (line 8) | fn consecutive_in_self(&self, needles: &[&str]) -> bool {
    method as_str (line 22) | fn as_str(&self) -> &str {
    method as_str (line 29) | fn as_str(&self) -> &str {

FILE: const_format_proc_macros/src/utils.rs
  function dummy_ident (line 13) | pub(crate) fn dummy_ident() -> proc_macro2::Ident {
  function spanned_err (line 20) | pub fn spanned_err(tokens: &dyn ToTokens, display: &dyn std::fmt::Displa...
  type Peekable2 (line 28) | pub struct Peekable2<I: Iterator> {
  function new (line 35) | pub fn new<I: IntoIterator>(iter: I) -> Peekable2<I::IntoIter> {
  function is_empty (line 44) | pub fn is_empty(&mut self) -> bool {
  function peek (line 48) | pub fn peek(&mut self) -> Option<&I::Item> {
  function peek2 (line 54) | pub fn peek2(&mut self) -> Option<&I::Item> {
  type Item (line 66) | type Item = I::Item;
  method next (line 68) | fn next(&mut self) -> Option<I::Item> {
  method size_hint (line 76) | fn size_hint(&self) -> (usize, Option<usize>) {
  type LinearResult (line 88) | pub struct LinearResult {
    method new (line 100) | pub fn new(res: Result<(), crate::Error>) -> Self {
    method ok (line 105) | pub fn ok() -> Self {
    method from (line 112) | fn from(res: Result<(), crate::Error>) -> Self {
    method into_result (line 134) | pub fn into_result(mut self) -> Result<(), crate::Error> {
    method take (line 139) | pub fn take(&mut self) -> Result<(), crate::Error> {
    method replace (line 144) | pub fn replace(&mut self, other: Result<(), crate::Error>) -> Result<(...
    method push_err (line 149) | pub fn push_err<E>(&mut self, err: E)
    method combine_err (line 161) | pub fn combine_err<E>(&mut self, res: Result<(), E>)
  method drop (line 93) | fn drop(&mut self) {
  type Target (line 118) | type Target = Result<(), crate::Error>;
  method deref (line 120) | fn deref(&self) -> &Result<(), crate::Error> {
  method deref_mut (line 126) | fn deref_mut(&mut self) -> &mut Result<(), crate::Error> {

FILE: print_errors/src/formatc_macros.rs
  constant _ (line 5) | const _: &str = formatcp!("{}");
  constant _ (line 7) | const _: &str = formatcp!("{}", foo = "", 100u8 + 0);
  constant _ (line 9) | const _: &str = formatcp!("{}", 0 + 0);
  constant _ (line 11) | const _: &str = formatcp!("{}", 0u8, 0u8 + 1);
  constant _ (line 13) | const _: &str = formatcp!("{}", |fmt| 0 + 0);
  constant _ (line 15) | const _: () = {

FILE: print_errors/src/lib.rs
  constant _ (line 5) | const _: &str = cfmt::concatcp!(0, 1, ());
  constant _ (line 7) | const _: &str = cfmt::concatc!(0, 1, ());

FILE: print_errors/src/using_writec_macro.rs
  function using_writec (line 3) | fn using_writec(writer: &mut StrWriter) -> cfmt::Result {

FILE: print_warnings/src/main.rs
  constant TWO (line 11) | pub const TWO: u32 = 2;
  constant TEN (line 12) | pub const TEN: u32 = 10;
  constant CONCATC_A (line 18) | pub const CONCATC_A: &str = concatc!("hello", "world");
  constant CONCATC_B (line 19) | pub const CONCATC_B: &str = concatc!(10u8, TWO);
  constant FORMATC_A (line 21) | pub const FORMATC_A: &str = formatc!("{}hello{}{:?}", "foo", 100u8, Unit);
  function as_str_ctor (line 23) | const fn as_str_ctor() -> StrWriter<[u8; 100]> {
  constant __AS_STR (line 35) | pub const __AS_STR: &StrWriter = &as_str_ctor();
  constant AS_STR (line 36) | pub const AS_STR: &str = __AS_STR.as_str();
  constant CONCATCP_A (line 39) | pub const CONCATCP_A: &str = concatcp!("hello", "world");
  constant CONCATCP_B (line 40) | pub const CONCATCP_B: &str = concatcp!(10u8, 20u8);
  constant FORMATCP_A (line 42) | pub const FORMATCP_A: &str = formatcp!("{}hello{:x?}", "foo", 100u8);
  function main (line 46) | fn main() {}
Condensed preview — 121 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (664K chars).
[
  {
    "path": ".github/workflows/rust.yml",
    "chars": 3055,
    "preview": "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  b"
  },
  {
    "path": ".gitignore",
    "chars": 50,
    "preview": "/target\n**/*.rs.bk\n**/*.7z\nCargo.lock\n__ignored__*"
  },
  {
    "path": "Cargo.toml",
    "chars": 132,
    "preview": "[workspace]\nmembers=[\n    \"const_format\",\n    \"const_format_proc_macros\",\n    \"print_errors\",\n    \"print_warnings\",\n]\nre"
  },
  {
    "path": "Changelog.md",
    "chars": 10645,
    "preview": "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\nBreak"
  },
  {
    "path": "LICENSE-ZLIB.md",
    "chars": 855,
    "preview": "Copyright (c) 2020 Matias Rodriguez.\n\nThis software is provided 'as-is', without any express or implied\nwarranty. In no "
  },
  {
    "path": "README.md",
    "chars": 10361,
    "preview": "\n\n[![Rust](https://github.com/rodrimati1992/const_format_crates/workflows/Rust/badge.svg)](https://github.com/rodrimati1"
  },
  {
    "path": "commit.sh",
    "chars": 204,
    "preview": "#!/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  "
  },
  {
    "path": "const_format/Cargo.toml",
    "chars": 1660,
    "preview": "[package]\nname = \"const_format\"\nversion = \"0.2.36\"\nauthors = [\"rodrimati1992 <rodrimatt1985@gmail.com>\"]\nrust-version = "
  },
  {
    "path": "const_format/LICENSE-ZLIB.md",
    "chars": 855,
    "preview": "Copyright (c) 2020 Matias Rodriguez.\n\nThis software is provided 'as-is', without any express or implied\nwarranty. In no "
  },
  {
    "path": "const_format/src/__ascii_case_conv/word_iterator.rs",
    "chars": 5065,
    "preview": "use core::fmt::{self, Debug};\n\nmacro_rules! for_range_inc {\n    ($current:ident in $start:expr, $end:expr => $($code:tt)"
  },
  {
    "path": "const_format/src/__ascii_case_conv.rs",
    "chars": 5395,
    "preview": "mod word_iterator;\n\nuse word_iterator::WordIterator;\n\n/// The casing style of a string.\n///\n/// You can pass this to [`m"
  },
  {
    "path": "const_format/src/__hidden_utils.rs",
    "chars": 542,
    "preview": "pub(crate) const fn max_usize(l: usize, r: usize) -> usize {\n    if l > r {\n        l\n    } else {\n        r\n    }\n}\npub"
  },
  {
    "path": "const_format/src/__str_methods/pattern.rs",
    "chars": 1307,
    "preview": "use super::AsciiByte;\n\npub(crate) struct PatternCtor<T>(pub(crate) T);\n\nimpl PatternCtor<u8> {\n    pub(crate) const fn c"
  },
  {
    "path": "const_format/src/__str_methods/str_indexing.rs",
    "chars": 5511,
    "preview": "pub struct StrIndexArgsConv<T> {\n    pub str: &'static str,\n    pub arg: T,\n}\n\n#[allow(non_snake_case)]\npub const fn Str"
  },
  {
    "path": "const_format/src/__str_methods/str_repeat.rs",
    "chars": 827,
    "preview": "pub struct StrRepeatArgs {\n    pub str: &'static str,\n    pub str_len: usize,\n    pub out_len: usize,\n    pub overflowed"
  },
  {
    "path": "const_format/src/__str_methods/str_replace.rs",
    "chars": 3315,
    "preview": "use super::{bytes_find, Pattern, PatternCtor, PatternNorm};\n\npub struct ReplaceInputConv<T>(pub &'static str, pub T, pub"
  },
  {
    "path": "const_format/src/__str_methods/str_splice.rs",
    "chars": 2188,
    "preview": "use super::str_indexing::{pass_range_types, IndexValidity, StrIndexArgs, StrIndexArgsConv};\n\npub struct StrSplceArgsConv"
  },
  {
    "path": "const_format/src/__str_methods/str_split.rs",
    "chars": 3981,
    "preview": "use super::{Pattern, PatternCtor, PatternNorm};\n\nuse konst::slice::{bytes_find, bytes_find_skip};\n\npub struct SplitInput"
  },
  {
    "path": "const_format/src/__str_methods.rs",
    "chars": 1872,
    "preview": "mod str_replace;\n\npub use self::str_replace::{ReplaceInput, ReplaceInputConv};\n\nmod str_repeat;\npub use str_repeat::StrR"
  },
  {
    "path": "const_format/src/char_encoding/tests.rs",
    "chars": 2908,
    "preview": "use super::{char_debug_len, char_display_len, char_to_debug, char_to_display};\n\n#[test]\nfn char_to_utf8_encoding_test() "
  },
  {
    "path": "const_format/src/char_encoding.rs",
    "chars": 3028,
    "preview": "use crate::formatting::{hex_as_ascii, HexFormatting};\n\n#[cfg(any(test, feature = \"fmt\"))]\npub(crate) const fn char_displ"
  },
  {
    "path": "const_format/src/const_debug_derive.rs",
    "chars": 10161,
    "preview": "/// Derives const debug formatting for a type.\n///\n/// Derives the [`FormatMarker`] trait, and defines an `const_debug_f"
  },
  {
    "path": "const_format/src/const_generic_concatcp.rs",
    "chars": 743,
    "preview": "//! Reimplements some stuff from concatcp to be const generic instead of macro generated\n\nuse crate::pmr::{LenAndArray, "
  },
  {
    "path": "const_format/src/doctests.rs",
    "chars": 4003,
    "preview": "//! This module tests for errors that happen in the expanded code,\n//! errors detectable by the macro itself are tested "
  },
  {
    "path": "const_format/src/equality.rs",
    "chars": 5345,
    "preview": "#![allow(missing_docs, unused_variables)]\n\nuse crate::wrapper_types::PWrapper;\n\nuse core::{\n    cmp::Ordering,\n    marke"
  },
  {
    "path": "const_format/src/fmt/error.rs",
    "chars": 2704,
    "preview": "// <_< clippy you silly\n#![allow(clippy::enum_variant_names)]\n\nuse core::fmt::{self, Display};\n\n/// An error while tryin"
  },
  {
    "path": "const_format/src/fmt/formatter.rs",
    "chars": 45662,
    "preview": "use crate::{\n    fmt::{Error, FormattingFlags, NoEncoding, StrWriter, StrWriterMut},\n    utils::saturate_range,\n    wrap"
  },
  {
    "path": "const_format/src/fmt/std_type_impls/ranges.rs",
    "chars": 4650,
    "preview": "use crate::{\n    fmt::{Error, Formatter},\n    marker_traits::{FormatMarker, IsAFormatMarker, IsStdKind},\n    wrapper_typ"
  },
  {
    "path": "const_format/src/fmt/std_type_impls.rs",
    "chars": 6510,
    "preview": "#![allow(missing_docs)]\n\nuse crate::{\n    fmt::{Error, Formatter},\n    marker_traits::IsStdKind,\n    wrapper_types::PWra"
  },
  {
    "path": "const_format/src/fmt/str_writer.rs",
    "chars": 14483,
    "preview": "use super::{Error, Formatter, FormattingFlags, StrWriterMut, Utf8Encoding};\n\nuse core::marker::PhantomData;\n\n///////////"
  },
  {
    "path": "const_format/src/fmt/str_writer_mut.rs",
    "chars": 40848,
    "preview": "use crate::{\n    formatting::{\n        hex_as_ascii, ForEscaping, FormattingFlags, HexFormatting, NumberFormatting, FOR_"
  },
  {
    "path": "const_format/src/fmt.rs",
    "chars": 9682,
    "preview": "//! [`std::fmt`](https://doc.rust-lang.org/std/fmt/)-like\n//! api that can be used at compile-time.\n//!\n//! # Features\n/"
  },
  {
    "path": "const_format/src/for_assert_macros.rs",
    "chars": 482,
    "preview": "#![allow(non_fmt_panics)]\n\nuse crate::pargument::PArgument;\n\n#[track_caller]\npub const fn assert_(cond: bool, message: &"
  },
  {
    "path": "const_format/src/for_examples.rs",
    "chars": 1267,
    "preview": "//! Types for the documentation examples.\n//!\n//! # Features\n//!\n//! This module is only exported with the \"fmt\" feature"
  },
  {
    "path": "const_format/src/formatting.rs",
    "chars": 8971,
    "preview": "#[doc(hidden)]\n#[derive(Debug, Copy, Clone, PartialEq, Eq)]\npub enum Formatting {\n    Debug,\n    Display,\n}\n\nimpl Format"
  },
  {
    "path": "const_format/src/lib.rs",
    "chars": 14332,
    "preview": "//! Compile-time string formatting.\n//!\n//! This crate provides types and macros for formatting strings at compile-time."
  },
  {
    "path": "const_format/src/macros/assertions/assertc_macros.rs",
    "chars": 12701,
    "preview": "macro_rules! with_shared_docs {(\n    $(#[$before_clarification:meta])*\n    ;clarification\n    $(#[$before_syntax:meta])*"
  },
  {
    "path": "const_format/src/macros/assertions/assertcp_macros.rs",
    "chars": 8697,
    "preview": "macro_rules! with_shared_docs {(\n    $(#[$before_clarification:meta])*\n    ;clarification\n    $(#[$before_syntax:meta])*"
  },
  {
    "path": "const_format/src/macros/assertions.rs",
    "chars": 1412,
    "preview": "#[cfg(feature = \"assertc\")]\nmod assertc_macros;\n\n#[cfg(feature = \"assertcp\")]\nmod assertcp_macros;\n\n#[doc(hidden)]\n#[mac"
  },
  {
    "path": "const_format/src/macros/call_debug_fmt.rs",
    "chars": 5917,
    "preview": "/// For debug formatting of some specific generic std types, and other types.\n///\n/// # Errors\n///\n/// This macro propag"
  },
  {
    "path": "const_format/src/macros/constructors.rs",
    "chars": 1140,
    "preview": "/// Constructs an [`AsciiStr`] constant from an ascii string,\n///\n/// # Compile-time errors\n///\n/// This macro produces "
  },
  {
    "path": "const_format/src/macros/fmt_macros.rs",
    "chars": 19373,
    "preview": "/// Concatenates constants of primitive types into a `&'static str`.\n///\n/// Each argument is stringified after evaluati"
  },
  {
    "path": "const_format/src/macros/helper_macros.rs",
    "chars": 4599,
    "preview": "#[doc(hidden)]\n#[macro_export]\nmacro_rules! __for_range{\n    ( $var:ident in $range:expr => $($for_body:tt)* )=>({\n     "
  },
  {
    "path": "const_format/src/macros/impl_fmt.rs",
    "chars": 8326,
    "preview": "/// For implementing debug or display formatting \"manually\".\n///\n/// # Generated code\n///\n/// This macro generates:\n///\n"
  },
  {
    "path": "const_format/src/macros/map_ascii_case.rs",
    "chars": 2925,
    "preview": "/// Converts the casing style of a `&'static str` constant,\n/// ignoring non-ascii unicode characters.\n///\n/// This nacr"
  },
  {
    "path": "const_format/src/macros/str_methods.rs",
    "chars": 19265,
    "preview": "/// Replaces all the instances of `$pattern` in `$input`\n/// (a `&'static str` constant) with `$replace_with` (a `&'stat"
  },
  {
    "path": "const_format/src/macros.rs",
    "chars": 8340,
    "preview": "#[macro_use]\nmod assertions;\n\n#[macro_use]\n#[cfg(feature = \"fmt\")]\nmod call_debug_fmt;\n\n#[macro_use]\nmod constructors;\n\n"
  },
  {
    "path": "const_format/src/marker_traits/format_marker.rs",
    "chars": 8322,
    "preview": "//! Marker trait for types that implement the const formatting methods.\n//!\n//!\n\nuse crate::wrapper_types::PWrapper;\n\nus"
  },
  {
    "path": "const_format/src/marker_traits/write_marker.rs",
    "chars": 6796,
    "preview": "//! Marker trait for types that can be written to.\n//!\n//!\n\nuse crate::fmt::{Formatter, StrWriter, StrWriterMut};\n\nuse c"
  },
  {
    "path": "const_format/src/marker_traits.rs",
    "chars": 394,
    "preview": "//! Marker traits for types that can be formatted and/or be written to.\n//!\n//! # Features\n//!\n//! This module is only e"
  },
  {
    "path": "const_format/src/msg.rs",
    "chars": 2190,
    "preview": "#![allow(non_camel_case_types)]\n\nuse crate::fmt::{Error, StrWriter};\n\nuse core::marker::PhantomData;\n\nmacro_rules! type_"
  },
  {
    "path": "const_format/src/pargument.rs",
    "chars": 5522,
    "preview": "#![allow(clippy::wrong_self_convention)]\n\nuse crate::{\n    char_encoding::FmtChar,\n    formatting::{Formatting, Formatti"
  },
  {
    "path": "const_format/src/slice_cmp.rs",
    "chars": 3169,
    "preview": "/// A const equivalent of `&str` equality comparison.\n///\n/// # Example\n///\n#[cfg_attr(feature = \"fmt\", doc = \"```rust\")"
  },
  {
    "path": "const_format/src/test_utils.rs",
    "chars": 2205,
    "preview": "#![allow(missing_docs)]\n\n#[doc(hidden)]\n#[macro_export]\nmacro_rules! __identity {\n    ($($tt:tt)*) => {$($tt)*};\n}\n\n#[do"
  },
  {
    "path": "const_format/src/utils.rs",
    "chars": 2546,
    "preview": "//! Miscelaneous functions.\n\nuse core::ops::Range;\n\n/// Newtype wrapper to get around limitations in `const fn`s\npub(cra"
  },
  {
    "path": "const_format/src/wrapper_types/ascii_str.rs",
    "chars": 9103,
    "preview": "// use crate::fmt::Error;\n\n#[cfg(feature = \"fmt\")]\nuse crate::fmt::{Error, Formatter};\n\nuse core::fmt::{self, Display};\n"
  },
  {
    "path": "const_format/src/wrapper_types/pwrapper/tests.rs",
    "chars": 5670,
    "preview": "use crate::{\n    formatting::{FormattingFlags, NumberFormatting as NF},\n    pargument::PConvWrapper,\n    wrapper_types::"
  },
  {
    "path": "const_format/src/wrapper_types/pwrapper.rs",
    "chars": 15641,
    "preview": "#![allow(unexpected_cfgs)]\n\nuse crate::{\n    formatting::{FormattingFlags, NumberFormatting, StartAndArray, FOR_ESCAPING"
  },
  {
    "path": "const_format/src/wrapper_types/sliced.rs",
    "chars": 5689,
    "preview": "use crate::{\n    fmt::{Error, Formatter},\n    wrapper_types::AsciiStr,\n};\n\nuse core::ops::{Range, RangeFrom, RangeFull, "
  },
  {
    "path": "const_format/src/wrapper_types.rs",
    "chars": 416,
    "preview": "//! Some wrapper types.\n//!\n//! # Features\n//!\n//! This module is only exported with the \"fmt\" feature.\n\n#[cfg(feature ="
  },
  {
    "path": "const_format/tests/fmt_tests/display_formatting.rs",
    "chars": 5465,
    "preview": "use cfmt_a::{\n    fmt::{ComputeStrLength, Error, Formatter, FormattingFlags, StrWriter},\n    try_,\n    wrapper_types::PW"
  },
  {
    "path": "const_format/tests/fmt_tests/formatted_writing.rs",
    "chars": 6951,
    "preview": "use cfmt_a::{\n    __for_range,\n    fmt::{ComputeStrLength, Error, Formatter, FormattingFlags, StrWriter},\n    try_,\n    "
  },
  {
    "path": "const_format/tests/fmt_tests/formatter_methods/debug_methods.rs",
    "chars": 7586,
    "preview": "use super::{remove_margin, write_with_flag};\n\nuse cfmt_a::{\n    fmt::{Error, Formatter, FormattingFlags},\n    impl_fmt, "
  },
  {
    "path": "const_format/tests/fmt_tests/formatter_methods.rs",
    "chars": 5867,
    "preview": "use cfmt_a::{\n    ascii_str,\n    fmt::{ComputeStrLength, Formatter, FormattingFlags},\n    AsciiStr,\n};\n\nmod debug_method"
  },
  {
    "path": "const_format/tests/fmt_tests/std_impl_tests.rs",
    "chars": 5136,
    "preview": "use cfmt_a::{\n    coerce_to_fmt,\n    fmt::{ComputeStrLength, Error, FormattingFlags, StrWriter},\n    try_,\n    wrapper_t"
  },
  {
    "path": "const_format/tests/fmt_tests/str_writer_methods.rs",
    "chars": 17800,
    "preview": "use crate::RngExt;\n\nuse cfmt_a::{\n    fmt::{Error, FormattingFlags, StrWriter, StrWriterMut},\n    formatcp,\n    test_uti"
  },
  {
    "path": "const_format/tests/fmt_tests/str_writer_mut.rs",
    "chars": 4721,
    "preview": "use cfmt_a::fmt::{Error, StrWriterMut};\n\n#[test]\nfn from_custom() -> Result<(), Error> {\n    let mut len = 4;\n    let mu"
  },
  {
    "path": "const_format/tests/fmt_tests_modules.rs",
    "chars": 819,
    "preview": "#![cfg(feature = \"fmt\")]\n\n// Prevents importing from const_format, requiring importing from cfmt_b.\nextern crate const_f"
  },
  {
    "path": "const_format/tests/misc_tests/assertc_tests.rs",
    "chars": 2409,
    "preview": "#![allow(unreachable_code)]\n#![allow(non_local_definitions)]\n\nuse cfmt_b::for_examples::{Point3, Unit};\nuse cfmt_b::{ass"
  },
  {
    "path": "const_format/tests/misc_tests/assertcp_tests.rs",
    "chars": 2262,
    "preview": "#![allow(unreachable_code)]\n#![allow(non_local_definitions)]\n\nuse cfmt_b::{assertcp, assertcp_eq, assertcp_ne};\n\nstruct "
  },
  {
    "path": "const_format/tests/misc_tests/call_debug_fmt_macro.rs",
    "chars": 2001,
    "preview": "use cfmt_b::fmt::{Error, Formatter, FormattingFlags, StrWriter};\nuse cfmt_b::{call_debug_fmt, impl_fmt, try_};\n\nuse core"
  },
  {
    "path": "const_format/tests/misc_tests/clippy_warnings.rs",
    "chars": 144,
    "preview": "#[deny(clippy::double_parens)]\n#[test]\nfn test_clippy_double_parens_not_triggered() {\n    std::convert::identity(cfmt_b:"
  },
  {
    "path": "const_format/tests/misc_tests/concatc_macro_tests.rs",
    "chars": 744,
    "preview": "use cfmt_b::Formatter;\nuse cfmt_b::{ascii_str, concatc, impl_fmt, try_};\n\nuse std::num::NonZeroUsize;\n\nconst STD_TYPES: "
  },
  {
    "path": "const_format/tests/misc_tests/derive_tests/is_a_attributes.rs",
    "chars": 6904,
    "preview": "use cfmt_b::{\n    coerce_to_fmt,\n    fmt::{Error, Formatter, FormattingFlags, StrWriter},\n    impl_fmt, try_,\n    wrappe"
  },
  {
    "path": "const_format/tests/misc_tests/derive_tests.rs",
    "chars": 4242,
    "preview": "use cfmt_b::{\n    fmt::{Error, Formatter, FormattingFlags, StrWriter},\n    try_, writec, ConstDebug,\n};\n\nuse core::marke"
  },
  {
    "path": "const_format/tests/misc_tests/equality_tests.rs",
    "chars": 3965,
    "preview": "use cfmt_b::coerce_to_fmt;\n\nuse core::{\n    cmp::Ordering,\n    num::{NonZeroU128, NonZeroU8, NonZeroUsize},\n    sync::at"
  },
  {
    "path": "const_format/tests/misc_tests/formatc_macros.rs",
    "chars": 9515,
    "preview": "use cfmt_b::formatcp;\nuse cfmt_b::test_utils::{ALL_ASCII, ALL_ASCII_ESCAPED};\n\n#[cfg(feature = \"fmt\")]\nuse cfmt_b::forma"
  },
  {
    "path": "const_format/tests/misc_tests/impl_fmt_macro_tests.rs",
    "chars": 11889,
    "preview": "#![allow(non_camel_case_types)]\n#![allow(non_local_definitions)]\n\nuse cfmt_b::{\n    fmt::{ComputeStrLength, Error, Forma"
  },
  {
    "path": "const_format/tests/misc_tests/inline_const_pattern_tests.rs",
    "chars": 2117,
    "preview": "use crate::cfmt_b;\n\nuse crate::cfmt_b::{\n    concatc, concatcp, formatc, formatcp, map_ascii_case, str_get, str_index, s"
  },
  {
    "path": "const_format/tests/misc_tests/shared_cp_macro_tests.rs",
    "chars": 3436,
    "preview": "use cfmt_b::{__identity, concatcp, formatcp};\n\n#[cfg(feature = \"fmt\")]\nuse cfmt_b::{concatc, formatc};\n\nuse arrayvec::Ar"
  },
  {
    "path": "const_format/tests/misc_tests/type_kind_coercion_macro_tests.rs",
    "chars": 1187,
    "preview": "use cfmt_b::fmt::{Error, Formatter, FormattingFlags, StrWriter};\nuse cfmt_b::{coerce_to_fmt, impl_fmt};\n\n#[test]\nfn coer"
  },
  {
    "path": "const_format/tests/misc_tests/writec_macro.rs",
    "chars": 4459,
    "preview": "// Don't need the tests for this macro to be thorough,\n// since this uses a lot of the same machinery as `formatcp` and "
  },
  {
    "path": "const_format/tests/misc_tests_modules.rs",
    "chars": 1480,
    "preview": "#![cfg_attr(feature = \"__inline_const_pat_tests\", feature(inline_const_pat))]\n\nextern crate const_format as cfmt_b;\nexte"
  },
  {
    "path": "const_format/tests/str_methods.rs",
    "chars": 122,
    "preview": "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"
  },
  {
    "path": "const_format/tests/str_methods_modules/conv_ascii_case.rs",
    "chars": 1870,
    "preview": "use const_format::__ascii_case_conv::{convert_str, size_after_conversion};\nuse const_format::{map_ascii_case, Case};\n\nma"
  },
  {
    "path": "const_format/tests/str_methods_modules/str_replace.rs",
    "chars": 2736,
    "preview": "use const_format::__str_methods::{ReplaceInput, ReplaceInputConv};\nuse const_format::str_replace;\n\nmacro_rules! assert_c"
  },
  {
    "path": "const_format/tests/str_methods_modules/str_splice.rs",
    "chars": 3109,
    "preview": "use const_format::{str_splice, str_splice_out, SplicedStr};\n\nfn ss(output: &'static str, removed: &'static str) -> Splic"
  },
  {
    "path": "const_format/tests/str_methods_modules/str_split_tests.rs",
    "chars": 3952,
    "preview": "use const_format::{str_split, str_split_pat};\n\n#[test]\nfn test_str_split_pat_basic_equivalence() {\n    assert_eq!(str_sp"
  },
  {
    "path": "const_format_proc_macros/Cargo.toml",
    "chars": 939,
    "preview": "[package]\nname = \"const_format_proc_macros\"\nversion = \"0.2.34\"\nauthors = [\"rodrimati1992 <rodrimatt1985@gmail.com>\"]\nrus"
  },
  {
    "path": "const_format_proc_macros/LICENSE-ZLIB.md",
    "chars": 855,
    "preview": "Copyright (c) 2020 Matias Rodriguez.\n\nThis software is provided 'as-is', without any express or implied\nwarranty. In no "
  },
  {
    "path": "const_format_proc_macros/src/datastructure/field_map.rs",
    "chars": 2625,
    "preview": "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"
  },
  {
    "path": "const_format_proc_macros/src/datastructure.rs",
    "chars": 7060,
    "preview": "use syn::{\n    self, Attribute, Data, DeriveInput, Field as SynField, Fields as SynFields, Generics, Ident,\n    Type, Vi"
  },
  {
    "path": "const_format_proc_macros/src/derive_debug/attribute_parsing.rs",
    "chars": 9550,
    "preview": "use crate::{\n    datastructure::{DataStructure, Field, FieldMap},\n    utils::LinearResult,\n};\n\nuse super::{syntax::ImplH"
  },
  {
    "path": "const_format_proc_macros/src/derive_debug/syntax.rs",
    "chars": 530,
    "preview": "use syn::{\n    parse::{Parse, ParseStream},\n    Generics,\n};\n\n//////////////////////////////////////////////////////////"
  },
  {
    "path": "const_format_proc_macros/src/derive_debug/type_detection.rs",
    "chars": 1542,
    "preview": "use super::HowToFmt;\n\nuse syn::Type;\n\npub(super) fn detect_type_formatting(ty: &Type) -> HowToFmt {\n    let ty = unwrap_"
  },
  {
    "path": "const_format_proc_macros/src/derive_debug.rs",
    "chars": 8647,
    "preview": "use crate::datastructure::{DataStructure, DataVariant, Field, StructKind};\n\nuse proc_macro2::{Span, TokenStream as Token"
  },
  {
    "path": "const_format_proc_macros/src/error.rs",
    "chars": 3281,
    "preview": "use crate::spanned::Spans;\n\nuse proc_macro2::{\n    Delimiter, Group, Ident, Literal, Punct, Spacing, Span, TokenStream a"
  },
  {
    "path": "const_format_proc_macros/src/format_args/parsing.rs",
    "chars": 11916,
    "preview": "use super::{\n    ExpandFormatted, ExpandInto, ExpandWithFormatter, FormatArg, FormatArgs, FormatIfArgs,\n    LocalVariabl"
  },
  {
    "path": "const_format_proc_macros/src/format_args.rs",
    "chars": 3924,
    "preview": "use crate::{\n    format_str::FormatStr, formatting::FormattingFlags, parse_utils::StrRawness,\n    parse_utils::TokenStre"
  },
  {
    "path": "const_format_proc_macros/src/format_macro/tests.rs",
    "chars": 2581,
    "preview": "use crate::{parse_utils::MyParse, test_utils::StrExt};\n\nfn process_str(s: &str) -> Result<String, String> {\n    MyParse:"
  },
  {
    "path": "const_format_proc_macros/src/format_macro.rs",
    "chars": 7144,
    "preview": "use crate::{\n    format_args::{ExpandInto, FormatArgs, FormatIfArgs, LocalVariable, WriteArgs},\n    parse_utils::TokenSt"
  },
  {
    "path": "const_format_proc_macros/src/format_str/errors.rs",
    "chars": 3279,
    "preview": "use proc_macro2::Span;\n\nuse std::{\n    fmt::{self, Display},\n    ops::Range,\n};\n\n#[derive(Debug, PartialEq)]\npub(crate) "
  },
  {
    "path": "const_format_proc_macros/src/format_str/parsing.rs",
    "chars": 7443,
    "preview": "use super::{FmtArg, FmtStrComponent, FormatStr, ParseError, ParseErrorKind, WhichArg};\n\nuse crate::{\n    formatting::{Fo"
  },
  {
    "path": "const_format_proc_macros/src/format_str/tests.rs",
    "chars": 6676,
    "preview": "use super::*;\n\nuse super::{ParseError as PE, ParseErrorKind as PEK};\n\nuse crate::formatting::{FormattingFlags as FF, IsA"
  },
  {
    "path": "const_format_proc_macros/src/format_str.rs",
    "chars": 729,
    "preview": "use crate::{formatting::FormattingFlags, parse_utils::StrRawness};\n\nmod errors;\n\nmod parsing;\n\n#[cfg(test)]\nmod tests;\n\n"
  },
  {
    "path": "const_format_proc_macros/src/formatting.rs",
    "chars": 3839,
    "preview": "use proc_macro2::{Ident, Span, TokenStream as TokenStream2};\n\nuse quote::{quote, ToTokens, TokenStreamExt};\n\n#[derive(De"
  },
  {
    "path": "const_format_proc_macros/src/lib.rs",
    "chars": 3322,
    "preview": "#![allow(clippy::or_fun_call)]\n#![allow(clippy::derive_partial_eq_without_eq)]\n\nuse proc_macro::TokenStream as TokenStre"
  },
  {
    "path": "const_format_proc_macros/src/macros.rs",
    "chars": 966,
    "preview": "#![allow(unused_macros)]\n\n#[doc(hidden)]\nmacro_rules! to_stream {\n    ( $stream:ident ; $($expr:expr),* $(,)* ) => {{\n  "
  },
  {
    "path": "const_format_proc_macros/src/parse_utils.rs",
    "chars": 11058,
    "preview": "use crate::{spanned::Spans, utils::Peekable2, Error};\n\nuse proc_macro2::{\n    token_stream::IntoIter, Delimiter, Group, "
  },
  {
    "path": "const_format_proc_macros/src/respan_to_macro.rs",
    "chars": 1136,
    "preview": "use crate::parse_utils::TokenTreeExt;\n\nuse proc_macro2::{Delimiter, Span, TokenStream as TokenStream2, TokenTree as Toke"
  },
  {
    "path": "const_format_proc_macros/src/shared_arg_parsing.rs",
    "chars": 1641,
    "preview": "//! Types for parsing arguments, shared by many of the macros\n\nuse crate::{\n    parse_utils::{MyParse, ParseBuffer, Pars"
  },
  {
    "path": "const_format_proc_macros/src/spanned.rs",
    "chars": 220,
    "preview": "use proc_macro2::Span;\n\n#[derive(Copy, Clone)]\npub struct Spans {\n    pub start: Span,\n    pub end: Span,\n}\n\nimpl Spans "
  },
  {
    "path": "const_format_proc_macros/src/test_utils.rs",
    "chars": 804,
    "preview": "pub trait StrExt {\n    fn as_str(&self) -> &str;\n\n    /// Checks that these needles exist consequtively in self.\n    ///"
  },
  {
    "path": "const_format_proc_macros/src/utils.rs",
    "chars": 4002,
    "preview": "use proc_macro2::Span;\n\n#[cfg(feature = \"derive\")]\nuse quote::ToTokens;\n\nuse std::{\n    collections::VecDeque,\n    iter:"
  },
  {
    "path": "print_errors/Cargo.toml",
    "chars": 215,
    "preview": "[package]\nname = \"print_errors\"\nversion = \"0.1.0\"\nauthors = [\"rodrimati1992 <rodrimatt1985@gmail.com>\"]\nedition = \"2018\""
  },
  {
    "path": "print_errors/src/formatc_macros.rs",
    "chars": 521,
    "preview": "use cfmt::formatcp;\n\nuse cfmt::formatc;\n\nconst _: &str = formatcp!(\"{}\");\n\nconst _: &str = formatcp!(\"{}\", foo = \"\", 100"
  },
  {
    "path": "print_errors/src/lib.rs",
    "chars": 186,
    "preview": "#![allow(unused_imports)]\n\nmod formatc_macros;\n\nconst _: &str = cfmt::concatcp!(0, 1, ());\n\nconst _: &str = cfmt::concat"
  },
  {
    "path": "print_errors/src/using_assertc_macros.rs",
    "chars": 394,
    "preview": "use cfmt::{assertc, assertc_eq, assertc_ne};\n\n// uninferred argument\nassertc!(false, \"{}\", 0);\n\nassertc!(true, \"{}\");\n\na"
  },
  {
    "path": "print_errors/src/using_writec_macro.rs",
    "chars": 465,
    "preview": "use cfmt::{writec, StrWriter};\n\nfn using_writec(writer: &mut StrWriter) -> cfmt::Result {\n    // Trying to write to a no"
  },
  {
    "path": "print_warnings/Cargo.toml",
    "chars": 225,
    "preview": "[package]\nname = \"print_warnings\"\nversion = \"0.1.0\"\nauthors = [\"rodrimati1992 <rodrimatt1985@gmail.com>\"]\nedition = \"201"
  },
  {
    "path": "print_warnings/src/main.rs",
    "chars": 1262,
    "preview": "#![deny(non_camel_case_types)]\n\nuse const_format::{assertcp, concatcp, formatcp};\n\npub mod rust_1_83 {\n    use const_for"
  }
]

About this extraction

This page contains the full source code of the rodrimati1992/const_format_crates GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 121 files (611.2 KB), approximately 167.5k tokens, and a symbol index with 837 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!