From 4573e911816ecba90565d33d219e6f04ee7e2f05 Mon Sep 17 00:00:00 2001 From: Ryan Leckey Date: Tue, 13 Jun 2017 18:34:28 -0700 Subject: Add Environment --- src/env.rs | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 2 ++ 2 files changed, 90 insertions(+) create mode 100644 src/env.rs diff --git a/src/env.rs b/src/env.rs new file mode 100644 index 0000000..c49bb0e --- /dev/null +++ b/src/env.rs @@ -0,0 +1,88 @@ +use std::env; +use std::collections::HashMap; +use error::*; +use source::Source; +use value::{Value, ValueKind}; + +pub struct Environment { + /// 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, + + /// 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() -> 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 Default for Environment { + fn default() -> Environment { + Environment { + prefix: None, + separator: "_".into(), + } + } +} + +impl Source for Environment { + fn collect(&self) -> Result> { + let mut m = HashMap::new(); + let uri: String = "the environment".into(); + + // 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 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; + } + } + + // Replace `separator` with `.` + key = key.replace(&self.separator, "."); + + m.insert(key, Value::new(Some(&uri), ValueKind::String(value))); + } + + Ok(m) + } +} diff --git a/src/lib.rs b/src/lib.rs index 534533d..fe02a93 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -43,9 +43,11 @@ mod path; mod source; mod config; mod file; +mod env; pub use config::Config; pub use error::ConfigError; pub use value::Value; pub use source::Source; pub use file::{File, FileFormat}; +pub use env::Environment; -- cgit v1.2.3