#configuration #macro #struct-fields

revolt_optional_struct

Crate 定义了一个宏,可以从一个结构体生成另一个仅包含 Option 字段的新的结构体

1 个不稳定版本

0.2.0 2023 年 4 月 22 日

#114#struct-fields

Download history 95/week @ 2024-03-14 53/week @ 2024-03-21 44/week @ 2024-03-28 77/week @ 2024-04-04 30/week @ 2024-04-11 40/week @ 2024-04-18 67/week @ 2024-04-25 38/week @ 2024-05-02 35/week @ 2024-05-09 41/week @ 2024-05-16 48/week @ 2024-05-23 52/week @ 2024-05-30 57/week @ 2024-06-06 86/week @ 2024-06-13 103/week @ 2024-06-20 40/week @ 2024-06-27

每月 293 次下载
4 crates 使用

Apache-2.0

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

Crates.io

目标

这个 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