#proc-macro #source #procedural #generator #generate #together #sourcegen-cli

sourcegen

此crate包含一个过程宏,与"sourcegen-cli" crate协同工作

3个版本 (重大更新)

0.3.0 2019年8月14日
0.2.0 2019年8月4日
0.1.0 2019年7月30日

1582过程宏

Download history 41/week @ 2024-03-04 60/week @ 2024-03-11 118/week @ 2024-03-18 111/week @ 2024-04-01 92/week @ 2024-04-08 59/week @ 2024-04-22 139/week @ 2024-04-29 30/week @ 2024-05-06 47/week @ 2024-05-13 89/week @ 2024-05-20 66/week @ 2024-05-27 33/week @ 2024-06-03 49/week @ 2024-06-10 100/week @ 2024-06-17

每月248次下载

MIT/Apache

6KB

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. 过于神奇。

无运行时依赖