summaryrefslogtreecommitdiffstats
path: root/src/source.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/source.rs')
-rw-r--r--src/source.rs69
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!();
+ }
+ }
+}