Skip to content

Commit

Permalink
Release fix of custom merge fn for non-Copy types
Browse files Browse the repository at this point in the history
Closes #32
  • Loading branch information
Kixunil committed Oct 3, 2019
1 parent 8600183 commit 924e19a
Show file tree
Hide file tree
Showing 16 changed files with 68 additions and 14 deletions.
4 changes: 2 additions & 2 deletions configure_me/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ build = "build.rs"
configure_me = "0.3.3"

[build-dependencies]
configure_me_codegen = "0.3.10"
configure_me_codegen = "0.3.11"
```

And finally add appropriate incantiations into `src/main.rs`:
Expand Down Expand Up @@ -97,7 +97,7 @@ This crate also contains experimental debconf support behind `debconf` feature.
In order to use this feature, you must enable the flag in `Cargo.toml`:

```toml
configure_me_codegen = { version = "0.3.10", features = ["debconf"] }
configure_me_codegen = { version = "0.3.11", features = ["debconf"] }
```

Then add debconf options to your configuration specification:
Expand Down
2 changes: 1 addition & 1 deletion configure_me_codegen/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "configure_me_codegen"
version = "0.3.10"
version = "0.3.11"
authors = ["Martin Habovštiak <[email protected]>"]
description = "A library for processing application configuration easily."
homepage = "https://github.com/Kixunil/configure_me"
Expand Down
11 changes: 6 additions & 5 deletions configure_me_codegen/src/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,11 +160,12 @@ impl VisitWrite<visitor::ConstructConfig> for ::config::Switch {
impl VisitWrite<visitor::MergeIn> for ::config::Param {
fn visit_write<W: fmt::Write>(&self, mut output: W) -> fmt::Result {
if let Some(merge_fn) = &self.merge_fn {
writeln!(output, " match (&mut self.{}, other.{}) {{", self.name.as_snake_case(), self.name.as_snake_case())?;
writeln!(output, " (None, None) => (),")?;
writeln!(output, " (None, Some(val)) => self.{} = Some(val),", self.name.as_snake_case())?;
writeln!(output, " (Some(_), None) => (),")?;
writeln!(output, " (Some(val0), Some(val1)) => {}(val0, val1),", merge_fn)?;
writeln!(output, " if let Some({}) = other.{} {{", self.name.as_snake_case(), self.name.as_snake_case())?;
writeln!(output, " if let Some({}_old) = &mut self.{} {{", self.name.as_snake_case(), self.name.as_snake_case())?;
writeln!(output, " {}({}_old, {});", merge_fn, self.name.as_snake_case(), self.name.as_snake_case())?;
writeln!(output, " }} else {{")?;
writeln!(output, " self.{} = Some({});", self.name.as_snake_case(), self.name.as_snake_case())?;
writeln!(output, " }}")?;
writeln!(output, " }}")
} else {
writeln!(output, " if other.{}.is_some() {{", self.name.as_snake_case())?;
Expand Down
5 changes: 5 additions & 0 deletions configure_me_codegen/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,11 @@ env_prefix = "TEST_APP"
name = "foo"
type = "u32"
merge_fn = "(|a: &mut u32, b: u32| *a += b)"
[[param]]
name = "bar"
type = "String"
merge_fn = "(|a: &mut String, b: String| a.push_str(&b))"
"#;

pub struct ExpectedOutput {
Expand Down
1 change: 1 addition & 0 deletions configure_me_codegen/tests/config_files/bar_hello.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
bar = "Hello"
7 changes: 7 additions & 0 deletions configure_me_codegen/tests/custom_merge_fn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ fn custom_merge_fn() {
this.push("tests");
this.push("config_files");
let fortytwo = this.join("fortytwo.toml");
let bar_hello = this.join("bar_hello.toml");
let empty_args: &[&str] = &[];

let (config, _) = config::Config::custom_args_and_optional_files(&["test", "--foo=42"], empty_args).unwrap();
Expand All @@ -35,4 +36,10 @@ fn custom_merge_fn() {
assert_eq!(config.foo, Some(47));
let (config, _) = config::Config::custom_args_and_optional_files(&["test", "--foo=5"], &[fortytwo]).unwrap();
assert_eq!(config.foo, Some(47));
let (config, _) = config::Config::custom_args_and_optional_files(&["test", "--bar=Hello"], empty_args).unwrap();
assert_eq!(config.bar.as_ref().map(AsRef::as_ref), Some("Hello"));
let (config, _) = config::Config::custom_args_and_optional_files(&["test", "--bar=Hello", "--bar= world"], empty_args).unwrap();
assert_eq!(config.bar.as_ref().map(AsRef::as_ref), Some("Hello world"));
let (config, _) = config::Config::custom_args_and_optional_files(&["test", "--bar= world"], &[bar_hello]).unwrap();
assert_eq!(config.bar.as_ref().map(AsRef::as_ref), Some("Hello world"));
}
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
FieldFoo(<u32 as ::configure_me::parse_arg::ParseArg>::Error),
FieldBar(<String as ::configure_me::parse_arg::ParseArg>::Error),
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
pub foo: Option<u32>,
pub bar: Option<String>,
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
ArgParseError::HelpRequested(program_name) => write!(f, "Usage: {} [--foo FOO]", program_name),
ArgParseError::HelpRequested(program_name) => write!(f, "Usage: {} [--foo FOO] [--bar BAR]", program_name),
ArgParseError::FieldFoo(err) => {
write!(f, "Failed to parse argument '--foo': {}.\n\nHint: the value must be ", err)?;
<u32 as ::configure_me::parse_arg::ParseArg>::describe_type(&mut *f)?;
write!(f, ".")
},
ArgParseError::FieldBar(err) => {
write!(f, "Failed to parse argument '--bar': {}.\n\nHint: the value must be ", err)?;
<String as ::configure_me::parse_arg::ParseArg>::describe_type(&mut *f)?;
write!(f, ".")
},
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,8 @@
<u32 as ::configure_me::parse_arg::ParseArg>::describe_type(&mut *f)?;
write!(f, ".")
},
EnvParseError::FieldBar(ref err) => {
write!(f, "Failed to parse environment variable 'TEST_APP_BAR': {}.\n\nHint: the value must be ", err)?;
<String as ::configure_me::parse_arg::ParseArg>::describe_type(&mut *f)?;
write!(f, ".")
},
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
FieldFoo(<u32 as ::configure_me::parse_arg::ParseArg>::Error),
FieldBar(<String as ::configure_me::parse_arg::ParseArg>::Error),
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,11 @@
} else {
self.foo = Some(foo);
}
} else if let Some(value) = ::configure_me::parse_arg::match_arg("--bar", &arg, &mut iter) {
let bar = value.map_err(|err| err.map_or(ArgParseError::MissingArgument("--bar"), ArgParseError::FieldBar))?;

if let Some(bar_old) = &mut self.bar {
(|a: &mut String, b: String| a.push_str(&b))(bar_old, bar);
} else {
self.bar = Some(bar);
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,11 @@
self.foo = Some(val);
}
}
if let Some(val) = ::std::env::var_os("TEST_APP_BAR") {
let val = ::configure_me::parse_arg::ParseArg::parse_owned_arg(val).map_err(super::EnvParseError::FieldBar)?;
if let Some(bar_old) = &mut self.bar {
(|a: &mut String, b: String| a.push_str(&b))(bar_old, val);
} else {
self.bar = Some(val);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
match (&mut self.foo, other.foo) {
(None, None) => (),
(None, Some(val)) => self.foo = Some(val),
(Some(_), None) => (),
(Some(val0), Some(val1)) => (|a: &mut u32, b: u32| *a += b)(val0, val1),
if let Some(foo) = other.foo {
if let Some(foo_old) = &mut self.foo {
(|a: &mut u32, b: u32| *a += b)(foo_old, foo);
} else {
self.foo = Some(foo);
}
}
if let Some(bar) = other.bar {
if let Some(bar_old) = &mut self.bar {
(|a: &mut String, b: String| a.push_str(&b))(bar_old, bar);
} else {
self.bar = Some(bar);
}
}
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
foo: Option<u32>,
bar: Option<String>,
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
let foo = self.foo;
let bar = self.bar;

Ok(super::Config {
foo: foo.map(Into::into),
bar: bar.map(Into::into),
})

0 comments on commit 924e19a

Please sign in to comment.