diff options
author | Ryan Leckey <ryan@launchbadge.com> | 2017-06-22 17:10:47 -0700 |
---|---|---|
committer | Ryan Leckey <ryan@launchbadge.com> | 2017-06-22 17:10:47 -0700 |
commit | 6bfaf90fdf67197c511a7594b37d835e964edccd (patch) | |
tree | aedca78e59887c30bd2e34626b06f24f29de0d81 /src/source.rs | |
parent | 159bb52c595384fed44a2c669198d50f2a758a9a (diff) |
Implement Source for Vec<T: Source> and From<Path> for File
Diffstat (limited to 'src/source.rs')
-rw-r--r-- | src/source.rs | 69 |
1 files changed, 68 insertions, 1 deletions
diff --git a/src/source.rs b/src/source.rs index c8a0e83..9bf28c5 100644 --- a/src/source.rs +++ b/src/source.rs @@ -1,7 +1,9 @@ use error::*; use std::fmt::Debug; -use value::Value; +use std::str::FromStr; +use value::{Value, ValueKind}; use std::collections::HashMap; +use path; /// Describes a generic _source_ of configuration properties. pub trait Source: Debug { @@ -10,6 +12,27 @@ pub trait Source: Debug { /// Collect all configuration properties available from this source and return /// a HashMap. fn collect(&self) -> Result<HashMap<String, Value>>; + + fn collect_to(&self, cache: &mut Value) -> Result<()> { + let props = match self.collect() { + Ok(props) => props, + Err(error) => { + return Err(error); + } + }; + + for (key, val) in &props { + match path::Expression::from_str(key) { + // Set using the path + Ok(expr) => expr.set(cache, val.clone()), + + // Set diretly anyway + _ => path::Expression::Identifier(key.clone()).set(cache, val.clone()), + } + } + + Ok(()) + } } impl Clone for Box<Source + Send + Sync> { @@ -17,3 +40,47 @@ impl Clone for Box<Source + Send + Sync> { self.clone_into_box() } } + +impl Source for Vec<Box<Source + Send + Sync>> { + fn clone_into_box(&self) -> Box<Source + Send + Sync> { + Box::new((*self).clone()) + } + + fn collect(&self) -> Result<HashMap<String, Value>> { + let mut cache: Value = HashMap::<String, Value>::new().into(); + + for source in self { + source.collect_to(&mut cache)?; + } + + if let ValueKind::Table(table) = cache.kind { + Ok(table) + } else { + unreachable!(); + } + } +} + +impl<T> Source for Vec<T> + where T: Source + Sync + Send, + T: Clone, + T: 'static +{ + fn clone_into_box(&self) -> Box<Source + Send + Sync> { + Box::new((*self).clone()) + } + + fn collect(&self) -> Result<HashMap<String, Value>> { + let mut cache: Value = HashMap::<String, Value>::new().into(); + + for source in self { + source.collect_to(&mut cache)?; + } + + if let ValueKind::Table(table) = cache.kind { + Ok(table) + } else { + unreachable!(); + } + } +} |