diff options
author | Brahm Lower <bplower@gmail.com> | 2022-11-20 09:27:48 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-11-20 18:27:48 +0100 |
commit | 1b03ef21f34fc4acf890b01cfca3d07158ef5c46 (patch) | |
tree | f3e7e9abfcf1dc87721093b20ce05f9af7dcda99 /src/config.rs | |
parent | c2d3845dbbb4fbf4fcb034f952be668929246bd0 (diff) |
fix(config): unrecognized config properties don't cause config error (#4547)
* Fix #4481, config does not error when unrecognized properties are present
* cleanup: use stuct update syntax to improve readability
from review feedback
Co-authored-by: David Knaack <davidkna@users.noreply.github.com>
* cleanup: renamed ValueDeserializer func w/ better name
* cleanup: added test to cover unknown key retry condition
Co-authored-by: David Knaack <davidkna@users.noreply.github.com>
Diffstat (limited to 'src/config.rs')
-rw-r--r-- | src/config.rs | 30 |
1 files changed, 29 insertions, 1 deletions
diff --git a/src/config.rs b/src/config.rs index 35cb86563..e0aa016ac 100644 --- a/src/config.rs +++ b/src/config.rs @@ -48,7 +48,17 @@ impl<'a, T: Deserialize<'a> + Default> ModuleConfig<'a, ValueError> for T { /// Create `ValueDeserializer` wrapper and use it to call `Deserialize::deserialize` on it. fn from_config(config: &'a Value) -> Result<Self, ValueError> { let deserializer = ValueDeserializer::new(config); - T::deserialize(deserializer) + T::deserialize(deserializer).or_else(|err| { + // If the error is an unrecognized key, print a warning and run + // deserialize ignoring that error. Otherwise, just return the error + if err.to_string().contains("Unknown key") { + log::warn!("{}", err); + let deserializer2 = ValueDeserializer::new(config).with_allow_unknown_keys(); + T::deserialize(deserializer2) + } else { + Err(err) + } + }) } } @@ -583,6 +593,24 @@ mod tests { } #[test] + fn test_load_unknown_key_config() { + #[derive(Clone, Default, Deserialize)] + #[serde(default)] + struct TestConfig<'a> { + pub foo: &'a str, + } + + let config = toml::toml! { + foo = "test" + bar = "ignore me" + }; + let rust_config = TestConfig::from_config(&config); + + assert!(rust_config.is_ok()); + assert_eq!(rust_config.unwrap().foo, "test"); + } + + #[test] fn test_from_string() { let config = Value::String(String::from("S")); assert_eq!(<&str>::from_config(&config).unwrap(), "S"); |