| Crates.io | const_format |
| lib.rs | const_format |
| version | 0.2.34 |
| created_at | 2020-08-17 03:38:43.263493+00 |
| updated_at | 2024-12-06 21:10:12.913219+00 |
| description | Compile-time string formatting |
| homepage | |
| repository | https://github.com/rodrimati1992/const_format_crates/ |
| max_upload_size | |
| id | 277417 |
| size | 391,584 |
Compile-time string formatting.
This crate provides types and macros for formatting strings at compile-time.
There are some features that require a variety of Rust versions, the sections below describe the features that are available for each version.
These macros are available in Rust 1.57.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.
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).
The "rust_1_64" feature enables these macros:
str_split: splits a string constantBy 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.
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.
use const_format::concatcp;
const NAME: &str = "Bob";
const FOO: &str = concatcp!(NAME, ", age ", 21u8,"!");
assert_eq!(FOO, "Bob, age 21!");
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 }
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.
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!\" }"
);
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
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 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.
They cannot be used places that take string literals.
So #[doc = "foobar"] cannot be replaced with #[doc = concatcp!("foo", "bar") ].
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");
None right now.
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"}
"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.
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.
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.
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_64": Enables the str_split macro.
Allows the as_bytes_alt methods and slice_up_to_len_alt methods 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.
const_format is unconditionally #![no_std], it can be used anywhere Rust can be used.
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.