Expand description
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.57.0
These macros are available in Rust 1.57.0:
-
concatcp: Concatenatesintegers,bool,char, and&strconstants into a&'static strconstant. -
formatcp:format-like formatting which takesintegers,bool,char, and&strconstants, and emits a&'static strconstant. -
str_get: Indexes a&'static strconstant, returningNonewhen the index is out of bounds. -
str_index: Indexes a&'static strconstant. -
str_repeat: Creates a&'static strby repeating a&'static strconstanttimestimes. -
str_splice: Replaces a substring in a&'static strconstant. -
map_ascii_case: Converts a&'static strconstant to a different casing style, determined by aCaseargument. -
str_replace: Replaces all the instances of a pattern in a&'static strconstant with another&'static strconstant.
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.64.0
The "rust_1_64" feature enables these macros:
str_split: splits a string constant
§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 strconstant. -
formatc:format-like macro that can format many standard library and user defined types into a&'static strconstant. -
writec:write-like macro that can format many standard library and user defined types into a type that implementsWriteMarker.
The "derive" feature enables the ConstDebug macro,
and the "fmt" feature.
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.
These macros are like the standard library assert macros, but evaluated at compile-time.
§Examples
§Concatenation of primitive types
use const_format::concatcp;
const NAME: &str = "Bob";
const FOO: &str = concatcp!(NAME, ", age ", 21u8,"!");
assert_eq!(FOO, "Bob, age 21!");§Formatting primitive types
use const_format::formatcp;
const NAME: &str = "John";
const FOO: &str = formatcp!("{NAME}, age {}!", compute_age(NAME));
assert_eq!(FOO, "John, age 24!");
§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 the "derive" feature
and Rust 1.83.0, because it uses &mut in a const context.
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.
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:
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
§Limitations
All of the macros from const_format have these limitations:
-
The formatting macros that expand to
&'static strs can only use constants from concrete types, so while aType::<u8>::FOOargument would be fine,Type::<T>::FOOwould not be (Tbeing a type parameter). -
Integer arguments must have a type inferrable from context, more details in the Integer arguments section.
-
They cannot be used places that take string literals. So
#[doc = "foobar"]cannot be replaced with#[doc = concatcp!("foo", "bar") ].
§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:
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:
assert_eq!(const_format::concatcp!(1 + 1, 2 + 1), "23");§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:
[dependencies]
cfmt = {version = "0.*", package = "const_format"}§Cargo features
-
"fmt": Enables thestd::fmt-like API and"rust_1_83"feature, requires Rust 1.83.0 because it uses mutable references in const fn.
This feature includes theformatc/writecformatting macros. -
"derive": requires Rust 1.83.0, implies the"fmt"feature, provides theConstDebugderive macro to format user-defined types at compile-time.
This implicitly uses thesyncrate, so clean compiles take a bit longer than without the feature. -
"assertc": requires Rust 1.83.0, implies the"fmt"feature, enables theassertc,assertc_eq, andassertc_neassertion macros.
This feature was previously named"assert", but it was renamed to avoid confusion with the"assertcp"feature. -
"assertcp": Enables theassertcp,assertcp_eq, andassertcp_neassertion macros. -
"rust_1_64": Enables thestr_splitmacro. Allows theas_bytes_altmethods andslice_up_to_len_altmethods to run in constant time, rather than linear time (proportional to the truncated part of the slice). -
"rust_1_83": Enables the"rust_1_64"feature and makes macros that evaluate to a value 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.57.0.
Features that require newer versions of Rust, or the nightly compiler, need to be explicitly enabled with cargo features.
Macros§
- Concatenates constants of primitive types into a
&'static str. - Formats constants of primitive types into a
&'static str - Converts the casing style of a
&'static strconstant, ignoring non-ascii unicode characters. - Indexes a
&'static strconstant, returningNonewhen the index is not on a character boundary. - Indexes a
&'static strconstant. - Creates a
&'static strby repeating a&'static strconstanttimestimes - Replaces all the instances of
$patternin$input(a&'static strconstant) with$replace_with(a&'static strconstant). - Replaces a substring in a
&'static strconstant. Returns both the new resulting&'static str, and the replaced substring. - Alternative version of
str_splicewhich only returns the string with the applied replacement.
Structs§
- Wrapper for many std types, which implements the
const_debug_fmtand/orconst_display_fmtmethods for them. - The return value of
str_splice
Enums§
- The casing style of a string.