diff options
Diffstat (limited to 'src/env.rs')
-rw-r--r-- | src/env.rs | 88 |
1 files changed, 58 insertions, 30 deletions
@@ -1,60 +1,88 @@ use std::env; -use std::error::Error; use std::collections::HashMap; +use error::*; +use source::Source; +use value::{Value, ValueKind}; -use source; -use value::Value; - -#[derive(Clone)] pub struct Environment { - /// Optional prefix that would restrict environment consideration - /// to only variables which begin with that prefix. + /// Optional prefix that will limit access to the environment to only keys that + /// begin with the defined prefix. + /// + /// A prefix, followed by `_` (the seperator), + /// is tested to be present on each key before its considered + /// to be part of the source environment. + /// + /// For example, the key `CONFIG_DEBUG` would become `DEBUG` with a prefix of `config`. prefix: Option<String>, + + /// The character sequence that separates each key segment in an environment key pattern. + /// Consider a nested configuration such as `redis.password`, a separator of `_` would allow + /// an environment key of `REDIS_PASSWORD` to match. + /// + /// The default separator is `_`. + separator: String, } impl Environment { - pub fn new<'a, T>(prefix: T) -> Environment - where T: Into<Option<&'a str>> - { - Environment { prefix: prefix.into().map(String::from) } + pub fn new() -> Self { + Environment::default() + } + + pub fn with_prefix(s: String) -> Self { + Environment { separator: s, ..Environment::default() } + } + + pub fn prefix(&mut self, s: String) -> &mut Self { + self.prefix = s.into(); + self + } + + pub fn separator(&mut self, s: String) -> &mut Self { + self.separator = s; + self } } -impl source::SourceBuilder for Environment { - fn build(&self) -> Result<Box<source::Source + Send + Sync>, Box<Error>> { - Ok(Box::new(self.clone())) +impl Default for Environment { + fn default() -> Environment { + Environment { + prefix: None, + separator: "_".into(), + } } } -impl source::Source for Environment { - fn collect(&self) -> HashMap<String, Value> { - // Iterate through environment variables - let mut r = HashMap::new(); +impl Source for Environment { + fn collect(&self) -> Result<HashMap<String, Value>> { + let mut m = HashMap::new(); + let uri: String = "the environment".into(); - // Make prefix pattern - let prefix_pat = if let Some(ref prefix) = self.prefix { - Some(prefix.clone() + "_".into()) - } else { - None + // Define a prefiux pattern to test and exclude from keys + let prefix_pattern = match self.prefix { + Some(ref prefix) => Some(prefix.clone() + &self.separator), + _ => None, }; for (key, value) in env::vars() { let mut key = key.to_string(); - // Check if key matches prefix - if let Some(ref prefix_pat) = prefix_pat { - if key.starts_with(prefix_pat) { - // Remove the prefix from the key - key = key[prefix_pat.len()..].to_string(); + // Check for prefix + if let Some(ref prefix_pattern) = prefix_pattern { + if key.starts_with(prefix_pattern) { + // Remove this prefix from the key + key = key[prefix_pattern.len()..].to_string(); } else { // Skip this key continue; } } - r.insert(key, Value::String(value)); + // Replace `separator` with `.` + key = key.replace(&self.separator, "."); + + m.insert(key, Value::new(Some(&uri), ValueKind::String(value))); } - r + Ok(m) } } |