【问题标题】:How to annotate code to generate artifacts during compilation?如何在编译期间注释代码以生成工件?
【发布时间】:2020-11-11 08:28:31
【问题描述】:

我有一个这样的配置结构:

pub struct Configuration {
    flag1: bool,
    flag2: String,
    flag3: i32,
    flag4: String
}

我想生成一个用户可以使用值编辑的配置文件模板。我将允许用户在启动时传递配置文件并将其加载到配置结构中。

有没有办法通过某种注释来生成这个工件?

我正在成像类似于“serde”但生成文件的东西:

#[derive(Template)] // create the file during build
pub struct Configuration {
    #[template(default = true)] // set some sort of defaults for the template file
    flag1: bool,
    #[template(default = "yes")]
    flag2: String,
    #[template(default = 42)]
    flag3: i32,
    #[template(default = "no")]
    flag4: String
}

结果将是一个类似的文件:

flag1: true
flag2: "yes"
flag3: 42
flag4: "no"

【问题讨论】:

  • 据我了解,您有一个配置文件,您想根据该配置文件确定结构的默认值?也许你可以根据文件编写一个proc宏来实现struct的Default trait?
  • 反过来。我想提供与我的结构对齐的默认文件
  • 好的,如果我错了,请纠正我,您的意思是将文件与您的结构相关联,这样如果您对结构进行任何更改,它们就会反映在该文件中?如果是这样的话,你把#[template(default = "yes")]放在每个字段上是什么意思?
  • 是的。因此,如果我要向结构中添加另一个字段,则会再次生成模板文件并添加该字段
  • AFAIK 无法跟踪对 struct 字段的更改。您可以定义像fn set_flag1(&mut self, new_val: bool) {} 这样的setter 方法,在其中您可以使用代码来更新结构和文件。您可以将 struct 字段保持私有,以便只能通过这些 setter 方法进行修改。 Setter 方法可以很容易地由 proc-macro (#[derive(..)]) 自动生成。

标签: rust rust-cargo serde


【解决方案1】:

这看起来像askama。它具有可扩展的模板语法和对 HTML 的特殊支持。

生锈示例:

#[derive(Template)] ​// this will generate the code...​
#[template(path = ​"sample.conf", escape = "none"​)]
​struct​ ​SampleConfig<​'​a​> { ​// the name of the struct can be anything​
    b: &​'​a​ ​str​,
    c: Some(&'a str),​// the field name should match the variable name​
                   ​// in your template​
}

模板(在 /templates/sample.conf 中):

field b: {{ b }}
{% match c %}
  {% when Some with (val) %}
    field c: {{ val }}
  {% when None %}
    field c: some default
{% endmatch %}

您可以在book中看到更多示例

PS: 据我所知,默认语法是不可能的,需要用匹配来处理。但请记住,您的模板将在编译时进行预处理并打包到您的二进制文件中。

【讨论】:

  • 看起来很相似,但反过来。我想要从代码生成的模板,而不是从模板生成的代码
  • TinyTemplate 将完成这项工作
  • 不要关注。你会怎么做
猜你喜欢
  • 1970-01-01
  • 2011-11-14
  • 2020-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-17
相关资源
最近更新 更多