3个版本 (重大更新)
0.3.0 | 2019年8月14日 |
---|---|
0.2.0 | 2019年8月4日 |
0.1.0 | 2019年7月30日 |
1582 在 过程宏 中
每月248次下载
6KB
Sourcegen
源代码生成器
Sourcegen是Rust中就地源代码生成的工具包。
就地源代码生成类似于Rust中的过程宏,但不同之处在于它在Rust代码编译之前进行展开。例如,一个用例可以是基于外部定义生成数据类型。
你从以下代码开始
#[sourcegen::sourcegen(generator = "json-schema", schema = "widget.json")]
struct Widget;
然后,运行一个基于sourcegen-cli
crate构建的特殊工具
cargo run --package json-schema-sourcegen
该工具将上述代码展开成类似的形式(这里假设widget.json
模式定义了一个具有两个字段的数据类型,分别是name
和weight
)
#[sourcegen::sourcegen(generator = "json-schema", schema = "widget.json")]
struct Widget {
/// Name of the widget
name: String,
/// Weight of the widget
weight: usize,
}
下次你运行工具时,它不会更改代码,因为它已经是正确的形式。
创建工具
在当前形式中,你在sourcegen_cli::run_tool
入口点之上构建自己的工具。此函数接受多个输入参数和一系列源代码生成器实现。
源代码生成器类似于过程宏,它们接收语法作为输入,并返回令牌流作为输出。源代码生成器的输入使用syn
crate表示语法树。返回的令牌由生成器渲染到源代码中,并通过rustfmt
进行格式化。
理由
与使用过程宏或通过build.rs
在构建过程中生成代码相比,以这种方式生成源代码有哪些好处?
相对于过程宏的优点
- 不占用编译时间。
- 编译不依赖于用于生成的原始元数据。
- 你可以查看源代码。这对于生成某种类型的数据类型特别有用。
- 生成器代码可以依赖于生成的类型(引导)。
相对于build.rs
源代码生成的优点
- 不占用编译时间。
- 编译不依赖于用于生成的原始元数据。
- 更灵活的设置:可以直接在使用的位置分块生成代码。
- 无需通过
include!
或其他方式(build.rs
无法写入源代码)来包含生成的代码。
然而,也存在一些缺点
- 真实元数据源与源代码之间的潜在不同步。
- 如果源生成器依赖于自己的输出,那么在源生成器本身上进行工作会变得困难(如果生成无效代码,恢复可能需要通过源控制回滚生成的代码)。
- 过于神奇。