macro_rules! create_options {
(
$(#[$attr:meta])*
pub struct Options {
$(
$(#[$field_attr:meta])*
pub $name:ident: $ty:ty,
)+
}
) => {
#[cfg_attr(feature = "schema", derive(JsonSchema))]
$(#[$attr])*
pub struct Options {
$(
$(#[$field_attr])*
pub $name: $ty,
)+
}
impl Options {
pub fn update(&mut self, incomplete: OptionsIncomplete) {
$(
if let Some(v) = incomplete.$name {
self.$name = v;
}
)+
}
pub fn update_camel(&mut self, incomplete: OptionsIncompleteCamel) {
$(
if let Some(v) = incomplete.$name {
self.$name = v;
}
)+
}
pub fn update_from_str<S: AsRef<str>, I: Iterator<Item = (S, S)>>(
&mut self,
values: I,
) -> Result<(), OptionParseError> {
for (key, val) in values {
$(
if key.as_ref() == stringify!($name) {
self.$name =
val.as_ref()
.parse()
.map_err(|error| OptionParseError::InvalidValue {
key: key.as_ref().into(),
error: Box::new(error),
})?;
continue;
}
)+
return Err(OptionParseError::InvalidOption(key.as_ref().into()));
}
Ok(())
}
}
#[cfg_attr(feature = "schema", derive(JsonSchema))]
$(#[$attr])*
#[derive(Default)]
pub struct OptionsIncomplete {
$(
$(#[$field_attr])*
pub $name: Option<$ty>,
)+
}
impl OptionsIncomplete {
pub fn from_options(opts: Options) -> Self {
let mut o = Self::default();
$(
o.$name = Some(opts.$name);
)+
o
}
}
#[cfg_attr(feature = "schema", derive(JsonSchema))]
$(#[$attr])*
#[derive(Default)]
#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
pub struct OptionsIncompleteCamel {
$(
$(#[$field_attr])*
pub $name: Option<$ty>,
)+
}
impl OptionsIncompleteCamel {
pub fn from_options(opts: Options) -> Self {
let mut o = Self::default();
$(
o.$name = Some(opts.$name);
)+
o
}
}
};
}