1 个不稳定版本
0.2.0 | 2023 年 4 月 22 日 |
---|
#114 在 #struct-fields
每月 293 次下载
被 4 crates 使用
16KB
276 行
分支更改
这个分支修改了一些东西
- 允许为结构体值设置文档字符串。
- 允许设置
#[opt_lenient]
以允许在结构体上设置其他属性,例如来自 wither 的#[model]
- 允许设置
#[opt_skip_serializing_none]
以向所有字段添加#[serde(skip_serializing_if = "Option::is_none")]
- 允许设置
#[opt_some_priority]
使现有的 Option 值在可选结构体中优于 None 值。 - 允许在单个结构体字段上设置
#[opt_passthrough]
,以便将字段上的下一个属性也包含在可选结构体中。
OptionalStruct
目标
这个 crate 允许用户生成一个包含与原始结构体相同字段但包装在 Option 中的结构体。同时,还实现了原始结构体的一个方法 apply_options
。该方法消耗生成的可选结构体,并为每个 Some(x) 字段,将原始结构体的值分配给可选结构体的值。
这是一个有些混乱的解释(我的英语技能需要一些帮助),但基本上
#[derive(OptionalStruct)]
struct Foo {
meow: u32,
woof: String,
}
将生成
struct OptionalFoo {
meow: Option<u32>,
woof: Option<String>,
}
impl Foo {
pub fn apply_options(&mut self, optional_struct: OptionalFoo) {
if Some(field) = optional_struct.meow {
self.meow = field;
}
if Some(field) = optional_struct.woof {
self.woof = field;
}
}
}
使用
您可以使用此工具更轻松地为您的程序生成配置。如果您使用toml-rs(使用serde)来解析配置文件,您需要将您的值包裹在Option中,或者它们需要在配置文件中存在。使用此crate,您可以轻松地为每个字段生成整个Config结构体,并使用Option包装。这意味着如果配置文件中缺少配置,您将获得None。
然后您可以轻松处理配置的默认值
impl Config {
pub fn get_user_conf() -> OptionalConfig {
toml::from_str<OptionalConfig>(r#"
ip = '127.0.0.1'
[keys]
github = 'xxxxxxxxxxxxxxxxx'
travis = 'yyyyyyyyyyyyyyyyy'
"#).unwrap()
}
}
let mut conf = Config::get_default();
let user_conf = Config::get_user_conf();
conf.apply_options(user_conf);
功能
- 原始结构体内的Option被处理。生成的结构体将具有相同的字段,而不是Option<Option>
- 您可以重命名生成的结构体
#[derive(OptionalStruct)]
#[optional_name = "FoorBarMeowWoof"]
- 您还可以为生成的结构体添加derives
#[derive(OptionalStruct)]
#[optional_derive(Serialize, Copy, Display)]
- 您还可以通过映射原始类型到新名称来嵌套生成的结构体
#[derive(OptionalStruct)]
#[opt_nested_original(LogConfig)]
#[opt_nested_generated(OptionalLogConfig)]
struct Config {
timeout: Option<u32>,
log_config: LogConfig,
}
#[derive(OptionalStruct)]
struct LogConfig {
log_file: String,
log_level: usize,
}
您可以在测试文件夹中找到一些示例(是的,我知道)。
依赖关系
~1.5MB
~41K SLoC