Rust动态字符串格式化库dynfmt的使用,dynfmt提供灵活高效的运行时字符串模板渲染功能
Rust动态字符串格式化库dynfmt的使用,dynfmt提供灵活高效的运行时字符串模板渲染功能
简介
dynfmt
是一个用于动态格式化字符串的Rust库。它提供了几种实现格式化的方式,这些实现都支持std::fmt
功能的一个子集。格式字符串的解析和参数检查都在运行时进行,同时还支持创建新的自定义格式。
基本用法
use dynfmt::{Format, NoopFormat};
let formatted = NoopFormat.format("hello, world", &["unused"]);
assert_eq!("hello, world", formatted.expect("formatting failed"));
特性
该库提供以下特性(可通过Cargo features启用):
- json (默认启用): 通过JSON实现复杂结构的序列化
- python: 实现类似Python 2的
printf
风格字符串格式化 - curly: 使用花括号的简单格式字符串语法,类似于.NET和Rust
扩展性
可以通过实现Format
trait来创建新的格式。唯一必须实现的方法是iter_args
,它需要返回一个迭代ArgumentSpec
结构的迭代器。
示例代码展示了如何创建一个自定义的HashFormat
格式:
use std::str::MatchIndices;
use dynfmt::{ArgumentSpec, Format, Error};
struct HashFormat;
impl<'f> Format<'f> for HashFormat {
type Iter = HashIter<'f>;
fn iter_args(&self, format: &'f str) -> Result<Self::Iter, Error<'f>> {
Ok(HashIter(format.match_indices('#')))
}
}
struct HashIter<'f>(MatchIndices<'f, char>);
impl<'f> Iterator for HashIter<'f> {
type Item = Result<ArgumentSpec<'f>, Error<'f>>;
fn next(&mut self) -> Option<Self::Item> {
self.0.next().map(|(index, _)| Ok(ArgumentSpec::new(index, index + 1)))
}
}
let formatted = HashFormat.format("hello, #", &["world"]);
assert_eq!("hello, world", formatted.expect("formatting failed"));
完整示例
下面是一个使用dynfmt库的完整示例,展示了如何使用Python风格的格式化:
use dynfmt::{Format, PythonFormat};
fn main() {
// 使用Python风格的格式化
let python_fmt = PythonFormat;
// 格式化字符串
let formatted = python_fmt.format(
"Hello, %s! Today is %02d/%02d/%04d",
&["Rust", 3, 17, 2023]
).expect("Formatting failed");
println!("{}", formatted); // 输出: "Hello, Rust! Today is 03/17/2023"
}
要使用这个示例,需要在Cargo.toml中添加以下依赖:
[dependencies]
dynfmt = { version = "0.1.5", features = ["python"] }
完整示例代码
下面是一个更完整的示例,展示了dynfmt库的多种用法:
// 引入必要的模块
use dynfmt::{Format, PythonFormat, CurlyFormat, NoopFormat};
fn main() {
// 示例1: 使用NoopFormat基本格式化
let noop_formatted = NoopFormat.format("静态文本,无需参数", &[]).unwrap();
println!("NoopFormat示例: {}", noop_formatted);
// 示例2: 使用Python风格的格式化
let python_fmt = PythonFormat;
let python_formatted = python_fmt.format(
"Python风格: 姓名: %s, 年龄: %d, 余额: %.2f",
&["张三", 25, 1234.5678]
).unwrap();
println!("{}", python_formatted);
// 示例3: 使用花括号风格的格式化
let curly_fmt = CurlyFormat;
let curly_formatted = curly_fmt.format(
"花括号风格: 姓名: {}, 年龄: {}, 余额: {:.2}",
&["李四", 30, 5678.1234]
).unwrap();
println!("{}", curly_formatted);
// 示例4: 自定义HashFormat
struct HashFormat;
impl<'f> Format<'f> for HashFormat {
type Iter = std::iter::Map<
std::str::MatchIndices<'f, char>,
fn((usize, char)) -> Result<ArgumentSpec<'f>, Error<'f>>
>;
fn iter_args(&self, format: &'f str) -> Result<Self::Iter, Error<'f>> {
Ok(format.match_indices('#').map(|(i, _)|
Ok(ArgumentSpec::new(i, i + 1))
))
}
}
let hash_fmt = HashFormat;
let hash_formatted = hash_fmt.format(
"自定义格式: 姓名: #, 年龄: #",
&["王五", 35]
).unwrap();
println!("{}", hash_formatted);
}
对应的Cargo.toml依赖配置:
[dependencies]
dynfmt = { version = "0.1.5", features = ["python", "curly"] }
许可证
MIT License
1 回复
Rust动态字符串格式化库dynfmt使用指南
dynfmt
是一个Rust库,提供了运行时字符串模板渲染功能,相比标准库的格式化功能更加灵活高效。
主要特性
- 运行时解析和渲染字符串模板
- 支持多种格式化语法
- 高性能的模板渲染
- 支持自定义格式化函数
基本用法
首先在Cargo.toml
中添加依赖:
[dependencies]
dynfmt = "0.3"
简单示例
use dynfmt::{Format, SimpleCurlyFormat};
fn main() {
let formatted = SimpleCurlyFormat.format("Hello, {}!", &["Rust"]);
assert_eq!(formatted.expect("formatting failed"), "Hello, Rust!");
}
使用命名参数
use dynfmt::{Format, SimpleCurlyFormat};
fn main() {
let formatted = SimpleCurlyFormat.format(
"Hello, {name}! You have {count} new messages.",
&[("name", "Alice"), ("count", "5")]
);
assert_eq!(formatted.unwrap(), "Hello, Alice! You have 5 new messages.");
}
支持的格式化语法
dynfmt
支持多种格式化语法风格:
-
花括号语法 (默认)
SimpleCurlyFormat.format("{} {}", &["Hello", "world"]);
-
Python风格语法
use dynfmt::PythonFormat; PythonFormat.format("{0} {1}", &["Hello", "world"]);
-
Shell风格语法
use dynfmt::ShellFormat; ShellFormat.format("$0 $1", &["Hello", "world"]);
高级用法
自定义格式化器
use dynfmt::{Format, Formatter, SimpleCurlyFormat};
struct UppercaseFormatter;
impl Formatter for UppercaseFormatter {
fn format(&self, value: &dyn std::fmt::Display) -> Result<String, dynfmt::Error> {
Ok(value.to_string().to_uppercase())
}
}
fn main() {
let formatted = SimpleCurlyFormat.format_with(
"Hello, {name}!",
&[("name", &"rust")],
&UppercaseFormatter
);
assert_eq!(formatted.unwrap(), "Hello, RUST!");
}
性能优化
对于需要重复使用的模板,可以先编译模板:
use dynfmt::{CompiledFormat, SimpleCurlyFormat};
fn main() {
let template = SimpleCurlyFormat.compile("Hello, {name}!").unwrap();
let formatted = template.format(&[("name", "World")]).unwrap();
assert_eq!(formatted, "Hello, World!");
}
错误处理
dynfmt
提供了详细的错误信息:
use dynfmt::{Format, SimpleCurlyFormat};
match SimpleCurlyFormat.format("Hello, {name}", &[]) {
Ok(result) => println!("{}", result),
Err(e) => eprintln!("Formatting error: {}", e),
}
完整示例
下面是一个结合多种功能的完整示例:
use dynfmt::{Format, SimpleCurlyFormat, PythonFormat, ShellFormat, Formatter, CompiledFormat};
// 自定义格式化器 - 将值转换为大写
struct UppercaseFormatter;
impl Formatter for UppercaseFormatter {
fn format(&self, value: &dyn std::fmt::Display) -> Result<String, dynfmt::Error> {
Ok(value.to_string().to_uppercase())
}
}
fn main() {
// 1. 简单格式化示例
let simple_result = SimpleCurlyFormat.format("Hello, {}!", &["Rust"])
.expect("简单格式化失败");
println!("简单格式化结果: {}", simple_result);
// 2. 命名参数示例
let named_result = SimpleCurlyFormat.format(
"Hello, {name}! Age: {age}",
&[("name", "Bob"), ("age", "30")]
).unwrap();
println!("命名参数结果: {}", named_result);
// 3. Python风格格式化
let python_result = PythonFormat.format("{0} {1} {0}", &["Repeat", "me"])
.unwrap();
println!("Python风格结果: {}", python_result);
// 4. Shell风格格式化
let shell_result = ShellFormat.format("$1 $0", &["World", "Hello"])
.unwrap();
println!("Shell风格结果: {}", shell_result);
// 5. 使用自定义格式化器
let custom_result = SimpleCurlyFormat.format_with(
"Shout: {msg}",
&[("msg", &"hello world")],
&UppercaseFormatter
).unwrap();
println!("自定义格式化器结果: {}", custom_result);
// 6. 编译模板重用
let template = SimpleCurlyFormat.compile("重用的模板: {data}")
.unwrap();
for i in 1..=3 {
let result = template.format(&[("data", &i.to_string())]).unwrap();
println!("编译模板结果 {}: {}", i, result);
}
// 7. 错误处理示例
match SimpleCurlyFormat.format("Missing {parameter}", &[]) {
Ok(r) => println!("成功: {}", r),
Err(e) => println!("错误处理示例 - 预期错误: {}", e),
}
}
这个完整示例展示了:
- 基本格式化功能
- 命名参数使用
- 不同语法风格
- 自定义格式化器
- 模板编译和重用
- 错误处理
dynfmt
是处理运行时字符串格式化的强大工具,特别适合模板内容在运行时确定或需要从外部加载的场景。