Crates.io | revolt_optional_struct |
lib.rs | revolt_optional_struct |
version | 0.2.0 |
source | src |
created_at | 2023-04-22 16:52:51.307602 |
updated_at | 2023-04-22 16:52:51.307602 |
description | Crate defining a macro that will generate, from a structure, another structure with only Option |
homepage | |
repository | https://github.com/revoltchat/OptionalStruct |
max_upload_size | |
id | 846053 |
size | 31,891 |
This fork changes a few things:
#[opt_lenient]
to allow other attributes on a struct, e.g. #[model]
from wither.#[opt_skip_serializing_none]
to add #[serde(skip_serializing_if = "Option::is_none")]
to all fields.#[opt_some_priority]
make existing Option values take presence over None values in the optional struct.#[opt_passthrough]
on individual struct fields to include the next attribute on the field in the optional struct as well.This crate allows the user to generate a structure containing the same fields as the original struct but wrapped in Optionapply_options
. It consumes the generated optional_struct, and for every Some(x) field, it assigns the original structure's value with the optional_struct one.
Now that's some confusing explanation (my English skills could use some help), but basically:
#[derive(OptionalStruct)]
struct Foo {
meow: u32,
woof: String,
}
will generate:
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;
}
}
}
You can use this to generate a configuration for you program more easily.
If you use toml-rs to parse your config file (using serde),
you'll need to wrap your values in Option
You can then easily handle default values for your config:
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);
#[derive(OptionalStruct)]
#[optional_name = "FoorBarMeowWoof"]
#[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,
}
You'll find some examples in the tests folder (yes I know).