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