diff options
-rw-r--r-- | src/config.rs | 51 | ||||
-rw-r--r-- | src/lib.rs | 52 | ||||
-rw-r--r-- | src/value.rs | 63 |
3 files changed, 72 insertions, 94 deletions
diff --git a/src/config.rs b/src/config.rs index 4df5377..cdb241b 100644 --- a/src/config.rs +++ b/src/config.rs @@ -5,7 +5,6 @@ use path; use std::error::Error; use std::fmt; use std::str::FromStr; -use std::borrow::Cow; use std::collections::HashMap; #[derive(Default, Debug)] @@ -357,7 +356,7 @@ impl Config { } } - pub fn get<'a>(&'a self, key_path: &str) -> Option<&'a Value> { + pub fn get(&self, key_path: &str) -> Option<Value> { let key_expr: path::Expression = match key_path.to_lowercase().parse() { Ok(expr) => expr, Err(_) => { @@ -366,31 +365,31 @@ impl Config { } }; - self.path_get(key_expr) + self.path_get(key_expr).cloned() } - pub fn get_str<'a>(&'a self, key: &str) -> Option<Cow<'a, str>> { - self.get(key).and_then(Value::as_str) + pub fn get_str(&self, key: &str) -> Option<String> { + self.get(key).and_then(Value::into_str) } pub fn get_int(&self, key: &str) -> Option<i64> { - self.get(key).and_then(Value::as_int) + self.get(key).and_then(Value::into_int) } pub fn get_float(&self, key: &str) -> Option<f64> { - self.get(key).and_then(Value::as_float) + self.get(key).and_then(Value::into_float) } pub fn get_bool(&self, key: &str) -> Option<bool> { - self.get(key).and_then(Value::as_bool) + self.get(key).and_then(Value::into_bool) } - pub fn get_map<'a>(&'a self, key: &str) -> Option<&'a HashMap<String, Value>> { - self.get(key).and_then(Value::as_map) + pub fn get_table(&self, key: &str) -> Option<HashMap<String, Value>> { + self.get(key).and_then(Value::into_table) } - pub fn get_slice<'a>(&'a self, key: &str) -> Option<&'a [Value]> { - self.get(key).and_then(Value::as_slice) + pub fn get_array(self, key: &str) -> Option<Vec<Value>> { + self.get(key).and_then(Value::into_array) } } @@ -556,10 +555,10 @@ mod test { vec![Value::Integer(10), Value::Integer(325), Value::Integer(12)]) .unwrap(); - let values = c.get_slice("values").unwrap(); + let values = c.get_array("values").unwrap(); assert_eq!(values.len(), 3); - assert_eq!(values[1].as_int(), Some(325)); + assert_eq!(values[1].clone().into_int(), Some(325)); } #[test] @@ -569,10 +568,10 @@ mod test { c.set("values", vec![10, 325, 12]) .unwrap(); - let values = c.get_slice("values").unwrap(); + let values = c.get_array("values").unwrap(); assert_eq!(values.len(), 3); - assert_eq!(values[1].as_int(), Some(325)); + assert_eq!(values[1].clone().into_int(), Some(325)); } @@ -589,10 +588,10 @@ mod test { } { - let m = c.get_map("redis").unwrap(); + let m = c.get_table("redis").unwrap(); - assert_eq!(m.get("port").unwrap().as_int().unwrap(), 6379); - assert_eq!(m.get("address").unwrap().as_str().unwrap(), "::1"); + assert_eq!(m.get("port").cloned().unwrap().into_int().unwrap(), 6379); + assert_eq!(m.get("address").cloned().unwrap().into_str().unwrap(), "::1"); } { @@ -604,11 +603,11 @@ mod test { } { - let m = c.get_map("redis").unwrap(); + let m = c.get_table("redis").unwrap(); - assert_eq!(m.get("port").unwrap().as_int().unwrap(), 6379); - assert_eq!(m.get("address").unwrap().as_str().unwrap(), "::0"); - assert_eq!(m.get("db").unwrap().as_str().unwrap(), "1"); + assert_eq!(m.get("port").cloned().unwrap().into_int().unwrap(), 6379); + assert_eq!(m.get("address").cloned().unwrap().into_str().unwrap(), "::0"); + assert_eq!(m.get("db").cloned().unwrap().into_str().unwrap(), "1"); } } @@ -647,10 +646,10 @@ mod test { } { - let m = c.get_map("redis").unwrap(); + let m = c.get_table("redis").unwrap(); - assert_eq!(m.get("port").unwrap().as_int().unwrap(), 6379); - assert_eq!(m.get("db").unwrap().as_int().unwrap(), 2); + assert_eq!(m.get("port").cloned().unwrap().into_int().unwrap(), 6379); + assert_eq!(m.get("db").cloned().unwrap().into_int().unwrap(), 2); } } @@ -30,7 +30,7 @@ //! ```rust //! // Get 'debug' and coerce to a boolean //! if let Some(value) = config::get("debug") { -//! println!("{:?}", value.as_bool()); +//! println!("{:?}", value.into_bool()); //! } //! //! // You can use a type suffix @@ -62,7 +62,7 @@ mod config; use std::error::Error; use std::sync::{Once, ONCE_INIT, RwLock}; -use std::borrow::Cow; +use std::collections::HashMap; pub use source::{Source, SourceBuilder}; pub use file::{File, FileFormat}; @@ -105,52 +105,32 @@ pub fn set<T>(key: &str, value: T) -> Result<(), Box<Error>> global().write().unwrap().set(key, value) } -pub fn get<'a>(key: &str) -> Option<&'a Value> { +pub fn get(key: &str) -> Option<Value> { // TODO(~): Should this panic! or return None with an error message? // Make an issue if you think it should be an error message. - let r = global().read().unwrap(); - - let c = &*r; - - // TODO(@rust): Figure out how to not to use unsafe here - unsafe { - let c: &'static Config = std::mem::transmute(c); - c.get(key) - } + global().read().unwrap().get(key) } -pub fn get_str<'a>(key: &str) -> Option<Cow<'a, str>> { - let r = global().read().unwrap(); - - unsafe { - let c: &'static Config = std::mem::transmute(&*r); - c.get_str(key) - } +pub fn get_str(key: &str) -> Option<String> { + get(key).and_then(Value::into_str) } pub fn get_int(key: &str) -> Option<i64> { - let r = global().read().unwrap(); - - unsafe { - let c: &'static Config = std::mem::transmute(&*r); - c.get_int(key) - } + get(key).and_then(Value::into_int) } pub fn get_float(key: &str) -> Option<f64> { - let r = global().read().unwrap(); - - unsafe { - let c: &'static Config = std::mem::transmute(&*r); - c.get_float(key) - } + get(key).and_then(Value::into_float) } pub fn get_bool(key: &str) -> Option<bool> { - let r = global().read().unwrap(); + get(key).and_then(Value::into_bool) +} - unsafe { - let c: &'static Config = std::mem::transmute(&*r); - c.get_bool(key) - } +pub fn get_table(key: &str) -> Option<HashMap<String, Value>> { + get(key).and_then(Value::into_table) +} + +pub fn get_array(key: &str) -> Option<Vec<Value>> { + get(key).and_then(Value::into_array) } diff --git a/src/value.rs b/src/value.rs index bb88c34..5b5a838 100644 --- a/src/value.rs +++ b/src/value.rs @@ -1,6 +1,5 @@ use std::convert::From; use std::collections::HashMap; -use std::borrow::Cow; /// A configuration value. /// @@ -18,22 +17,23 @@ pub enum Value { } impl Value { - /// Gets the underlying value as a string, performing a conversion only if neccessary. - #[allow(needless_lifetimes)] - pub fn as_str<'a>(&'a self) -> Option<Cow<'a, str>> { - match *self { - Value::String(ref value) => Some(Cow::Borrowed(value)), - Value::Integer(value) => Some(Cow::Owned(value.to_string())), - Value::Float(value) => Some(Cow::Owned(value.to_string())), - Value::Boolean(value) => Some(Cow::Owned(value.to_string())), + /// Converts `self` into a string, if possible. + /// Returns None otherwise. + pub fn into_str(self) -> Option<String> { + match self { + Value::String(value) => Some(value), + Value::Integer(value) => Some(value.to_string()), + Value::Float(value) => Some(value.to_string()), + Value::Boolean(value) => Some(value.to_string()), _ => None, } } - /// Gets the underlying type as a boolean, performing a conversion only if neccessary. - pub fn as_bool(&self) -> Option<bool> { - match *self { + /// Converts `self` into a bool, if possible. + /// Returns None otherwise. + pub fn into_bool(self) -> Option<bool> { + match self { Value::Boolean(value) => Some(value), Value::Integer(value) => Some(value != 0), Value::Float(value) => Some(value != 0.0), @@ -50,9 +50,10 @@ impl Value { } } - /// Gets the underlying type as an integer, performing a conversion only if neccessary. - pub fn as_int(&self) -> Option<i64> { - match *self { + /// Converts `self` into an i64, if possible. + /// Returns None otherwise. + pub fn into_int(self) -> Option<i64> { + match self { Value::Integer(value) => Some(value), Value::String(ref value) => value.parse().ok(), Value::Boolean(value) => Some(if value { 1 } else { 0 }), @@ -62,9 +63,10 @@ impl Value { } } - /// Gets the underlying type as a floating-point, performing a conversion only if neccessary. - pub fn as_float(&self) -> Option<f64> { - match *self { + /// Converts `self` into a f64, if possible. + /// Returns None otherwise. + pub fn into_float(self) -> Option<f64> { + match self { Value::Float(value) => Some(value), Value::String(ref value) => value.parse().ok(), Value::Integer(value) => Some(value as f64), @@ -74,17 +76,20 @@ impl Value { } } - /// Gets the underlying type as a map; only works if the type is actually a map. - pub fn as_map(&self) -> Option<&HashMap<String, Value>> { - match *self { - Value::Table(ref value) => Some(value), + /// If the `Value` is a Table, returns the associated Map. + /// Returns None otherwise. + pub fn into_table(self) -> Option<HashMap<String, Value>> { + match self { + Value::Table(value) => Some(value), _ => None, } } - /// Gets the underlying type as a slice; only works if the type is actually a slice. - pub fn as_slice(&self) -> Option<&[Value]> { - match *self { - Value::Array(ref value) => Some(value), + + /// If the `Value` is an Array, returns the associated Vector. + /// Returns None otherwise. + pub fn into_array(self) -> Option<Vec<Value>> { + match self { + Value::Array(value) => Some(value), _ => None, } } @@ -123,12 +128,6 @@ impl From<bool> for Value { } } -// impl From<HashMap<String, Value>> for Value { -// fn from(value: HashMap<String, Value>) -> Value { -// Value::Table(value) -// } -// } - impl<T> From<HashMap<String, T>> for Value where T: Into<Value> { |