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 次下载

MIT/Apache

41KB
836

Sourcegen

源代码生成器

crates.io Documentation Build Status

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模式定义了一个包含两个字段的数据类型,即nameweight

#[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在构建期间生成代码相比,这种生成源代码方式的优点是什么?

相较于过程宏的优势

  1. 不占用编译时间。
  2. 编译不依赖于用于生成的原始元数据。
  3. 您有源代码可以查看。当生成的代码是某种数据类型时,这尤其有用。
  4. 生成代码可以依赖于生成的类型(自举)。

相对于 build.rs 源代码生成的优势

  1. 不占用编译时间。
  2. 编译不依赖于用于生成的原始元数据。
  3. 更灵活的设置:可以直接在代码使用的地方生成代码片段。
  4. 无需通过 include! 或其他方式包含生成的代码(build.rs 无法写入源代码)。

然而,也存在一些缺点

  1. 真实元数据源与源代码之间可能存在潜在的不同步。
  2. 如果源生成器依赖于自己的输出,那么在源生成器本身上工作会更困难(如果生成无效代码,可能需要通过源代码控制撤回生成的代码)。
  3. 过于神秘。

依赖项

~3–13MB
~151K SLoC