12个不稳定版本 (3个重大变更)
0.4.0 | 2020年1月9日 |
---|---|
0.3.6 | 2019年12月7日 |
0.3.4 | 2019年11月20日 |
0.3.3 | 2019年9月27日 |
0.1.0 | 2019年7月30日 |
#368 在 过程宏 中
每月45 次下载
41KB
836 行
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
无法写入源代码)。
然而,也存在一些缺点
- 真实元数据源与源代码之间可能存在潜在的不同步。
- 如果源生成器依赖于自己的输出,那么在源生成器本身上工作会更困难(如果生成无效代码,可能需要通过源代码控制撤回生成的代码)。
- 过于神秘。
依赖项
~3–13MB
~151K SLoC