diff options
author | Ryan Leckey <ryan@launchbadge.com> | 2017-01-27 11:14:28 -0800 |
---|---|---|
committer | Ryan Leckey <ryan@launchbadge.com> | 2017-01-27 11:15:21 -0800 |
commit | f3b6fd435478a129dbf6ede37d8881c7a55efc42 (patch) | |
tree | 9e9e3eb6be09f6a80d9ed7d49781a1d9afb4b380 | |
parent | 3af8fb895f002c8e1a3728d64bfe901b3cab3dfc (diff) |
Move 'Envrionment' into its own source
-rw-r--r-- | src/config.rs | 64 | ||||
-rw-r--r-- | src/env.rs | 43 | ||||
-rw-r--r-- | src/lib.rs | 10 |
3 files changed, 47 insertions, 70 deletions
diff --git a/src/config.rs b/src/config.rs index 42e6c5c..e5b25f6 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,14 +1,11 @@ use value::Value; use source::{Source, SourceBuilder}; -use std::env; use std::error::Error; use std::collections::HashMap; #[derive(Default)] pub struct Config { - env_prefix: Option<String>, - defaults: HashMap<String, Value>, overrides: HashMap<String, Value>, sources: Vec<Box<Source>>, @@ -28,15 +25,6 @@ impl Config { Ok(()) } - /// Defines a prefix that environment variables - /// must start with to be considered. - /// - /// By default all environment variables are considered. This can lead to unexpected values - /// in configuration (eg. `PATH`). - pub fn set_env_prefix(&mut self, prefix: &str) { - self.env_prefix = Some(prefix.to_uppercase()); - } - /// Sets the default value for this key. The default value is only used /// when no other value is provided. pub fn set_default<T>(&mut self, key: &str, value: T) @@ -59,23 +47,6 @@ impl Config { return Some(value.clone()); } - // Check environment - - // Transform key into an env_key which is uppercased - // and has the optional prefix applied - let mut env_key = String::new(); - - if let Some(ref env_prefix) = self.env_prefix { - env_key.push_str(env_prefix); - env_key.push('_'); - } - - env_key.push_str(&key.to_uppercase()); - - if let Ok(value) = env::var(env_key.clone()) { - return Some(Value::from(value)); - } - // Check sources for source in &mut self.sources.iter().rev() { @@ -118,44 +89,11 @@ mod test { // Retrieval of a non-existent key #[test] fn test_not_found() { - let mut c = Config::new(); + let c = Config::new(); assert_eq!(c.get_int("key"), None); } - // // Environment override - // #[test] - // fn test_env_override() { - // let mut c = Config::new(); - - // c.set_default("key_1", false); - - // env::set_var("KEY_1", "1"); - - // assert_eq!(c.get_bool("key_1"), Some(true)); - - // // TODO(@rust): Is there a way to easily kill this at the end of a test? - // env::remove_var("KEY_1"); - // } - - // // Environment prefix - // #[test] - // fn test_env_prefix() { - // let mut c = Config::new(); - - // env::set_var("KEY_1", "1"); - // env::set_var("CFG_KEY_2", "false"); - - // c.set_env_prefix("CFG"); - - // assert_eq!(c.get_bool("key_1"), None); - // assert_eq!(c.get_bool("key_2"), Some(false)); - - // // TODO(@rust): Is there a way to easily kill this at the end of a test? - // env::remove_var("KEY_1"); - // env::remove_var("CFG_KEY_2"); - // } - // Explicit override #[test] fn test_default_override() { diff --git a/src/env.rs b/src/env.rs new file mode 100644 index 0000000..612b97d --- /dev/null +++ b/src/env.rs @@ -0,0 +1,43 @@ +use std::env; +use std::error::Error; + +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. + prefix: Option<String>, +} + +impl Environment { + pub fn new<'a, T>(prefix: T) -> Environment + where T: Into<Option<&'a str>> + { + Environment { prefix: prefix.into().map(String::from) } + } +} + +impl source::SourceBuilder for Environment { + fn build(&self) -> Result<Box<source::Source>, Box<Error>> { + Ok(Box::new(self.clone())) + } +} + +impl source::Source for Environment { + fn get(&self, key: &str) -> Option<Value> { + let mut env_key = String::new(); + + // Apply prefix + if let Some(ref prefix) = self.prefix { + env_key.push_str(prefix); + env_key.push('_'); + } + + env_key.push_str(&key.to_uppercase()); + + // Attempt to retreive environment variable and coerce into a Value + env::var(env_key.clone()).ok().map(Value::from) + } +} @@ -10,6 +10,7 @@ extern crate serde_json; mod value; mod source; mod file; +mod env; mod config; use std::error::Error; @@ -17,6 +18,7 @@ use std::sync::{Once, ONCE_INIT}; pub use source::{Source, SourceBuilder}; pub use file::{File, FileFormat}; +pub use env::Environment; pub use value::Value; @@ -29,9 +31,7 @@ static CONFIG_INIT: Once = ONCE_INIT; // Get the global configuration instance fn global() -> &'static mut Config { unsafe { - CONFIG_INIT.call_once(|| { - CONFIG = Some(Default::default()); - }); + CONFIG_INIT.call_once(|| { CONFIG = Some(Default::default()); }); CONFIG.as_mut().unwrap() } @@ -43,10 +43,6 @@ pub fn merge<T>(source: T) -> Result<(), Box<Error>> global().merge(source) } -pub fn set_env_prefix(prefix: &str) { - global().set_env_prefix(prefix) -} - pub fn set_default<T>(key: &str, value: T) where T: Into<Value> { |