From c26907b3ecf2b139fe61bf1403c952b85285ae02 Mon Sep 17 00:00:00 2001 From: Ryan Leckey Date: Sat, 3 Jun 2017 01:21:10 -0700 Subject: Add set and set_default (and deep merging) --- src/config.rs | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 68 insertions(+), 7 deletions(-) (limited to 'src/config.rs') diff --git a/src/config.rs b/src/config.rs index 4d24a1d..ad5421b 100644 --- a/src/config.rs +++ b/src/config.rs @@ -3,14 +3,15 @@ use serde::de::Deserialize; use error::*; use source::Source; -use value::Value; + +use value::{Value, ValueWithKey}; use path; enum ConfigKind { // A mutable configuration. This is the default. Mutable { - defaults: HashMap, - overrides: HashMap, + defaults: HashMap, + overrides: HashMap, sources: Vec>, }, @@ -71,7 +72,29 @@ impl Config { ref overrides, ref sources, ref defaults, - } => sources[0].collect()?, + } => { + let mut cache: Value = HashMap::::new().into(); + + // Add defaults + for (key, val) in defaults { + key.set(&mut cache, val.clone()); + } + + // Add sources + for source in sources { + let props = source.collect()?; + for (key, val) in &props { + path::Expression::Identifier(key.clone()).set(&mut cache, val.clone()); + } + } + + // Add overrides + for (key, val) in overrides { + key.set(&mut cache, val.clone()); + } + + cache + }, ConfigKind::Frozen => { return Err(ConfigError::Frozen); @@ -81,11 +104,11 @@ impl Config { Ok(()) } - pub fn deserialize(&self) -> Result { + pub fn deserialize<'de, T: Deserialize<'de>>(&self) -> Result { return T::deserialize(self.cache.clone()); } - pub fn get(&self, key: &str) -> Result { + pub fn get<'de, T: Deserialize<'de>>(&self, key: &'de str) -> Result { // Parse the key into a path expression let expr: path::Expression = key.to_lowercase().parse()?; @@ -95,10 +118,48 @@ impl Config { match value { Some(value) => { // Deserialize the received value into the requested type - T::deserialize(value) + T::deserialize(ValueWithKey::new(value, key)) } None => Err(ConfigError::NotFound(key.into())), } } + + pub fn set_default(&mut self, key: &str, value: T) -> Result<()> + where T: Into + { + match self.kind { + ConfigKind::Mutable { + ref mut defaults, + .. + } => { + defaults.insert(key.parse()?, value.into()); + } + + ConfigKind::Frozen => { + return Err(ConfigError::Frozen) + } + }; + + self.refresh() + } + + pub fn set(&mut self, key: &str, value: T) -> Result<()> + where T: Into + { + match self.kind { + ConfigKind::Mutable { + ref mut overrides, + .. + } => { + overrides.insert(key.parse()?, value.into()); + } + + ConfigKind::Frozen => { + return Err(ConfigError::Frozen) + } + }; + + self.refresh() + } } -- cgit v1.2.3