summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRyan Leckey <ryan@launchbadge.com>2017-01-27 11:14:28 -0800
committerRyan Leckey <ryan@launchbadge.com>2017-01-27 11:15:21 -0800
commitf3b6fd435478a129dbf6ede37d8881c7a55efc42 (patch)
tree9e9e3eb6be09f6a80d9ed7d49781a1d9afb4b380
parent3af8fb895f002c8e1a3728d64bfe901b3cab3dfc (diff)
Move 'Envrionment' into its own source
-rw-r--r--src/config.rs64
-rw-r--r--src/env.rs43
-rw-r--r--src/lib.rs10
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)
+ }
+}
diff --git a/src/lib.rs b/src/lib.rs
index 99a6da3..0fa3d70 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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>
{