13个版本
0.2.32 | 2023年10月14日 |
---|---|
0.2.31 | 2023年5月29日 |
0.2.29 | 2022年10月11日 |
0.2.22 | 2021年10月14日 |
0.2.8 | 2020年10月7日 |
#1513 在 文本处理
1,137,419 每月下载量
在 827 个crate中使用了(通过 const_format)
110KB
3K SLoC
编译时字符串格式化。
此crate提供用于编译时格式化字符串的类型和宏。
Rust版本
某些功能需要各种稳定的Rust版本,而其他功能则需要Rust nightly版本,下面的部分描述了每个版本可用的功能。
Rust 1.57.0
以下宏在Rust 1.57.0中可用
-
concatcp
:将integers
、bool
、char
和&str
常量连接成一个&'static str
常量。 -
formatcp
:类似于format
的格式化,它接受integers
、bool
、char
和&str
常量,并输出一个&'static str
常量。 -
str_get
:索引一个&'static str
常量,当索引超出范围时返回None
。 -
str_index
:索引一个常量字符串。 -
str_repeat
:通过重复一个常量字符串来创建一个新的常量字符串。 -
str_splice
:替换一个常量字符串中的子字符串。 -
map_ascii_case
:将一个常量字符串转换为不同的大小写风格,由一个Case
参数决定。 -
str_replace
:将一个常量字符串中所有模式实例替换为另一个常量字符串。
"assertcp"
功能启用 assertcp
、assertcp_eq
和 assertcp_ne
宏。这些宏类似于标准库 assert 宏,但在编译时评估,限制是它们只能有原始类型作为参数(就像 concatcp
和 formatcp
)。
Rust 1.64.0
"rust_1_64"
功能启用这些宏
str_split
:分割一个字符串常量
Rust nightly
通过启用 "fmt" 功能,您可以使用类似 std::fmt
的 API。
这需要 nightly 编译器,因为它在 const fn 中使用可变引用,这在撰写这些文档时尚未稳定。
此包的所有其他功能都是在 const_format::fmt
API 的基础上实现的。
-
concatc
:将许多标准库和用户定义的类型连接到一个常量字符串。 -
writec
:类似于write
的宏,可以将许多标准库和用户定义的类型格式化为实现WriteMarker
的类型。
"derive"
功能启用了 ConstDebug
宏和 "fmt"
功能。
ConstDebug
继承了 FormatMarker
特性,并实现了一个用于编译时调试格式化的内在方法 const_debug_fmt
。
"assertc"
功能启用了 assertc
、assertc_eq
、assertc_ne
宏和 "fmt"
功能。
这些宏类似于标准库 assert 宏,但会在编译时进行评估。
示例
原始类型的连接
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 }
格式化自定义类型
此示例演示了如何使用 ConstDebug
继承宏,然后将类型格式化为 &'static str
常量。
此示例需要 Rust 夜间版本,并且需要 "derive"
功能。
#![feature(const_mut_refs)]
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!\" }"
);
格式化的 const 断言
此示例演示了如何使用 assertcp_ne
宏进行编译时不等式断言,并带有格式化的错误消息。
此功能需要 "assertcp"
功能。
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");
这是编译器的输出
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
限制
const_format
中的所有宏都有以下限制
-
扩展为
&'static str
的格式化宏只能使用具体类型的常量,因此虽然Type::<u8>::FOO
参数是合适的,但Type::<T>::FOO
就不合适了(T
是一个类型参数)。 -
整数参数必须具有可从上下文推断的类型,有关更多详细信息,请参阅 整数参数部分。
-
它们不能用于需要字符串字面量的地方。所以
#[doc = "foobar"]
不能替换为#[doc = concatcp!("foo", "bar") ]
。
整数参数
整数参数必须有从上下文中可推断的类型。因此,如果只传递一个整数字面量,它必须有一个后缀。
可编译示例
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");
不可编译示例
assert_eq!(const_format::concatcp!(1 + 1, 2 + 1), "23");
计划
目前没有。
重命名crate
当crate重命名时,所有来自 const_format
的函数式宏都可以使用。
ConstDebug
derive宏有一个#[cdeb(crate = "foo::bar")]
属性,用于指示在哪里可以找到const_format
crate。
在Cargo.toml文件中重命名const_format
crate的示例
[dependencies]
cfmt = {version = "0.*", package = "const_format"}
Cargo功能
-
"fmt"
:启用类似std::fmt
的API,因为使用了在const fn中的可变引用,所以需要Rust nightly版本。
此功能包括formatc
/writec
格式化宏。 -
"derive"
:需要Rust nightly版本,隐含了"fmt"
功能,提供ConstDebug
derive宏,在编译时格式化用户定义的类型。
此功能隐式使用syn
crate,因此带有该功能的编译会比不带该功能的编译慢一些。 -
"assertc"
:需要Rust nightly版本,隐含了"fmt"
功能,启用了assertc
、assertc_eq
和assertc_ne
断言宏。
此功能之前命名为"assert"
,但为了避免与"assertcp"
功能混淆,已将其重命名。 -
"assertcp"
:启用assertcp
、assertcp_eq
和assertcp_ne
断言宏。 -
"rust_1_64"
:启用str_split
宏。允许as_bytes_alt
方法以及slice_up_to_len_alt
方法以常量时间运行,而不是线性时间(与切片被截断的部分成比例)。
无标准支持
const_format
无条件地 #![no_std]
,可以在Rust能使用的任何地方使用。
最低支持的Rust版本
const_format
需要 Rust 1.57.0。
需要较新版本的Rust或夜间编译器的特性需要通过cargo features显式启用。
依赖项
~73–480KB
~11K SLoC