1个不稳定版本
0.1.0 | 2023年5月16日 |
---|
#449 在 模板引擎 中
15KB
281 行
概述
此crate定义了一种简单的模板语言,格式为%(SELECTOR)
,可以在结构体上运行。给定的SELECTOR
通过闭包Fn(&T) -> Option<String>
访问类型为T
的结构体。使用闭包允许复杂的逻辑访问结构体,例如,“如果字段x不存在,则尝试字段y,否则返回默认值或None
”。
(此库绝对不是生产就绪的)
术语
- 模板 是一个字符串
%(X)
,其中X
是一个 选择器 - 选择器 是任何不包含圆括号的字符串(包括空字符串)
- 与给定 选择器 关联的闭包称为 访问器
- 格式字符串 是包含零个或多个模板以及其他非模板字符的字符串,例如
%(id) - %(title)
快速入门
在 Cargo.toml
中
[dependencies]
struct_string_template = "0.1.0"
假设我们有一个 struct
定义和一个 struct
实例
struct Book {
id: i64,
title: String,
author: String,
contributors: Option<String>
}
let my_book = Book {
id: 9784832275492,
title: "Hidamari Sketch".to_owned(),
author: "蒼樹うめ".to_owned(),
contributors: None,
};
定义一个格式字符串
let format_string = "[%(id)] %(title) %(所有作者)";
通过执行以下操作构建 Templater<Book>
use struct_string_template::TemplaterBuilder;
let templater = TemplaterBuilder::<Book>::new()
.with_selector("id", |book| Some(book.id.to_string()))
.with_selector("title", |book| Some(book.title.clone()))
.with_selector("所有作者", |book| {
Some(format!("(By: {}{})",
&book.author,
&book.contributors.clone().map(|x| format!(", {}", x)).or(Some("".to_owned())).unwrap())
)
})
.build();
使用 Templater
的 render
函数进行渲染
let result = templater.render(&my_book, format_string).ok().unwrap();
println!("{}", &result);
高级用法
不使用 TemplateBuilder
构建 Templater
如果需要迭代地构建 Templater
而不是使用构建器类,则使用 Templater::new()
,然后使用 insert
或 extend
方法添加闭包。
let mut templater = Templater::<Book>::new();
templater.insert("id", |book| Some(book.id.to_string()));
templater.insert("title", |book| Some(book.title.clone()));
templater.insert("所有作者", |book| {
Some(format!("(By: {}{})",
&book.author,
&book.contributors.clone().map(|x| format!(", {}", x)).or(Some("".to_owned())).unwrap())
)
});
格式化器
如果您打算多次使用格式化字符串,可以使用类似于正则表达式的“预编译”它,以使用 Formatter
类(render
将格式化字符串内部转换为 Formatter
)来提高性能,然后传递 Formatter
变量到 renderf
函数
use struct_string_template::Formatter;
let formatter = Formatter::build(format_string).ok().unwrap();
let result = templater.renderf(&my_book, &formatter);
println!("{}", &result);
错误处理
有关抛出的错误,请参阅 src/err.rs
模板规则
在本节中,X
是任何 选择器
%%
被视为一个字面量%
%
后跟一个不是(
的字符(或字符串的结尾)是无效的%(X)
总是有效的%(X)A
其中A
是任何有效的字符串是有效的%(X
(模板未终止)是无效的- 没有与
X
关联的闭包是无效的 - 如果结构上闭包的返回值为
None
,则打印NA
。这目前无法配置,除非修改闭包本身。
限制
由于闭包类型,当前无法复制 Templater
对象,因为存在这个问题。我尚未找到解决方案。
动机
我在几个个人应用程序中使用这个库,并发现保持库更改在不同应用程序之间同步很麻烦。
依赖关系
~0.8–1.4MB
~27K SLoC