23次发布
0.7.1 | 2021年8月6日 |
---|---|
0.7.0 | 2021年6月7日 |
0.6.0 | 2021年1月3日 |
0.5.7 | 2019年11月21日 |
0.2.1 | 2017年11月18日 |
#52 在 模板引擎 类别
12,090 每月下载量
在 7 个 包中使用
175KB
5K SLoC
gtmpl-rust – Rust的Golang模板
gtmpl-rust 为Rust提供了 Golang text/template 引擎,这使得Rust应用程序可以无缝集成到围绕 kubernetes、docker 等devops工具的世界中。
入门
将以下依赖项添加到您的Cargo清单中...
[dependencies]
gtmpl = "0.7"
并查看文档
它还不是完美的。欢迎提出帮助和建议。
一些示例
基本模板
use gtmpl;
fn main() {
let output = gtmpl::template("Finally! Some {{ . }} for Rust", "gtmpl");
assert_eq!(&output.unwrap(), "Finally! Some gtmpl for Rust");
}
添加自定义函数
use gtmpl_value::Function;
use gtmpl::{FuncError, gtmpl_fn, template, Value};
fn main() {
gtmpl_fn!(
fn add(a: u64, b: u64) -> Result<u64, FuncError> {
Ok(a + b)
});
let equal = template(r#"{{ call . 1 2 }}"#, Value::Function(Function { f: add }));
assert_eq!(&equal.unwrap(), "3");
}
将结构体作为上下文传递
use gtmpl_derive::Gtmpl;
#[derive(Gtmpl)]
struct Foo {
bar: u8
}
fn main() {
let foo = Foo { bar: 42 };
let output = gtmpl::template("The answer is: {{ .bar }}", foo);
assert_eq!(&output.unwrap(), "The answer is: 42");
}
在上下文中调用 方法
use gtmpl_derive::Gtmpl;
use gtmpl::{Func, FuncError, Value};
fn plus_one(args: &[Value]) -> Result<Value, FuncError> {
if let Value::Object(ref o) = &args[0] {
if let Some(Value::Number(ref n)) = o.get("num") {
if let Some(i) = n.as_i64() {
return Ok((i +1).into())
}
}
}
Err(anyhow!("integer required, got: {:?}", args))
}
#[derive(Gtmpl)]
struct AddMe {
num: u8,
plus_one: Func
}
fn main() {
let add_me = AddMe { num: 42, plus_one };
let output = gtmpl::template("The answer is: {{ .plus_one }}", add_me);
assert_eq!(&output.unwrap(), "The answer is: 43");
}
当前限制
这是一个正在进行中的项目。目前不支持以下功能:
- 复数
- 以下函数尚未实现:
html
、js
printf
尚未完全稳定,但应支持所有 合理 输入
增强
尽管它从未打算扩展Golang text/template的语法,但仍可能有一些方便的添加
动态模板
在您的 Cargo.toml
中启用 gtmpl_dynamic_template
[dependencies.gtmpl]
version = "0.7"
features = ["gtmpl_dynamic_template"]
现在您可以为 template
操作提供动态模板名称。
示例
use gtmpl::{Context, Template};
fn main() {
let mut template = Template::default();
template
.parse(
r#"
{{- define "tmpl1"}} some {{ end -}}
{{- define "tmpl2"}} some other {{ end -}}
there is {{- template (.) -}} template
"#,
)
.unwrap();
let context = Context::from("tmpl2");
let output = template.render(&context);
assert_eq!(output.unwrap(), "there is some other template".to_string());
}
以下语法被使用:
{{template (pipeline)}}
The template with the name evaluated from the pipeline (parenthesized) is
executed with nil data.
{{template (pipeline) pipeline}}
The template with the name evaluated from the first pipeline (parenthesized)
is executed with dot set to the value of the second pipeline.
上下文
我们使用 gtmpl_value 的 Value 作为内部数据类型。 gtmpl_derive 提供了一个方便的 derive
宏,用于为 Value
生成 From
实现方法。
参见
为什么我们需要这个?
为什么?亲爱的上帝,为什么?我都能想象到有人会问,为什么有人会做这种事情。当第一次需要为 docker 编写一些自定义格式化字符串时,我并不是一个 Go 语言的模板的大粉丝。学习一种新的模板语言通常不是人们期待的事情。大多数人都会完全避免它。然而,如果你在寻找比完整的 DSL 更轻量级的自动化工具,它实际上是非常有用的。
这主要的原因是为了使在 Rust 中编写感觉更本地的 DevOps 工具变得更加容易。 docker 和 helm (kubernetes)使用 Go 语言模板,如果围绕这些模板的工具使用相同的模板,则会感觉更自然。
依赖项
~0.4–1MB
~21K SLoC