summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRyan Leckey <leckey.ryan@gmail.com>2017-07-30 13:20:36 -0700
committerRyan Leckey <leckey.ryan@gmail.com>2017-07-30 13:20:36 -0700
commit14224be23dc2f253a240b85214927d97e1160669 (patch)
tree6f5b02b26aef5cf37bb14f32b9048165b67109ce
parent71f4b182d1e56febda64bd620ae0e0f65de333cd (diff)
Remove ConfigResult; close #36
-rw-r--r--examples/global/Cargo.toml7
-rw-r--r--examples/global/src/main.rs26
-rw-r--r--examples/hierarchical-env/src/settings.rs16
-rw-r--r--examples/pattern/src/main.rs16
-rw-r--r--examples/simple/src/main.rs8
-rw-r--r--examples/watch/Settings.toml2
-rw-r--r--examples/watch/src/main.rs10
-rw-r--r--src/config.rs268
-rw-r--r--src/de.rs23
-rw-r--r--src/env.rs6
-rw-r--r--src/error.rs65
-rw-r--r--src/file/format/json.rs21
-rw-r--r--src/file/format/mod.rs9
-rw-r--r--src/file/format/toml.rs7
-rw-r--r--src/file/format/yaml.rs5
-rw-r--r--src/file/mod.rs23
-rw-r--r--src/file/source/file.rs71
-rw-r--r--src/file/source/mod.rs7
-rw-r--r--src/file/source/string.rs15
-rw-r--r--src/lib.rs1
-rw-r--r--src/path/mod.rs121
-rw-r--r--src/source.rs7
-rw-r--r--src/value.rs262
-rw-r--r--tests/datetime.rs5
-rw-r--r--tests/errors.rs21
-rw-r--r--tests/file.rs21
-rw-r--r--tests/file_json.rs12
-rw-r--r--tests/file_toml.rs12
-rw-r--r--tests/file_yaml.rs14
-rw-r--r--tests/get.rs22
-rw-r--r--tests/merge.rs5
-rw-r--r--tests/set.rs3
32 files changed, 536 insertions, 575 deletions
diff --git a/examples/global/Cargo.toml b/examples/global/Cargo.toml
new file mode 100644
index 0000000..ec24740
--- /dev/null
+++ b/examples/global/Cargo.toml
@@ -0,0 +1,7 @@
+[package]
+name = "global"
+version = "0.1.0"
+
+[dependencies]
+config = { path = "../../" }
+lazy_static = "^0.2.8"
diff --git a/examples/global/src/main.rs b/examples/global/src/main.rs
new file mode 100644
index 0000000..4fe0864
--- /dev/null
+++ b/examples/global/src/main.rs
@@ -0,0 +1,26 @@
+#[macro_use]
+extern crate lazy_static;
+
+extern crate config;
+
+use std::error::Error;
+use std::sync::RwLock;
+use config::Config;
+
+lazy_static! {
+ static ref SETTINGS: RwLock<Config> = RwLock::new(Config::default());
+}
+
+fn try_main() -> Result<(), Box<Error>> {
+ // Set property
+ SETTINGS.write()?.set("property", 42)?;
+
+ // Get property
+ println!("property: {}", SETTINGS.read()?.get::<i32>("property")?);
+
+ Ok(())
+}
+
+fn main() {
+ try_main().unwrap()
+}
diff --git a/examples/hierarchical-env/src/settings.rs b/examples/hierarchical-env/src/settings.rs
index 43897b3..9e07054 100644
--- a/examples/hierarchical-env/src/settings.rs
+++ b/examples/hierarchical-env/src/settings.rs
@@ -1,5 +1,5 @@
use std::env;
-use config::{Config, File, Environment};
+use config::{ConfigError, Config, File, Environment};
#[derive(Debug, Deserialize)]
struct Database {
@@ -37,34 +37,34 @@ pub struct Settings {
}
impl Settings {
- pub fn new() -> Self {
+ pub fn new() -> Result<Self, ConfigError> {
let mut s = Config::new();
// Start off by merging in the "default" configuration file
- s.merge(File::with_name("config/default")).unwrap();
+ s.merge(File::with_name("config/default"))?;
// Add in the current environment file
// Default to 'development' env
// Note that this file is _optional_
let env = env::var("RUN_MODE").unwrap_or("development".into());
- s.merge(File::with_name(&format!("config/{}", env)).required(false)).unwrap();
+ s.merge(File::with_name(&format!("config/{}", env)).required(false))?;
// Add in a local configuration file
// This file shouldn't be checked in to git
- s.merge(File::with_name("config/local").required(false)).unwrap();
+ s.merge(File::with_name("config/local").required(false))?;
// Add in settings from the environment (with a prefix of APP)
// Eg.. `APP_DEBUG=1 ./target/app` would set the `debug` key
- s.merge(Environment::with_prefix("app")).unwrap();
+ s.merge(Environment::with_prefix("app"))?;
// You may also programmatically change settings
- s.set("database.url", "postgres://").unwrap();
+ s.set("database.url", "postgres://")?;
// Now that we're done, let's access our configuration
println!("debug: {:?}", s.get_bool("debug"));
println!("database: {:?}", s.get::<String>("database.url"));
// You can deserialize (and thus freeze) the entire configuration as
- s.deserialize().unwrap()
+ s.deserialize()
}
}
diff --git a/examples/pattern/src/main.rs b/examples/pattern/src/main.rs
index aaf164d..f88f1ed 100644
--- a/examples/pattern/src/main.rs
+++ b/examples/pattern/src/main.rs
@@ -10,12 +10,12 @@ fn main() {
// Option 1
// --------
// Gather all conf files from conf/ manually
- let settings = Config::default()
+ let mut settings = Config::default();
+ settings
// File::with_name(..) is shorthand for File::from(Path::new(..))
- .merge(File::with_name("conf/00-default.toml"))
- .merge(File::from(Path::new("conf/05-some.yml")))
- .merge(File::from(Path::new("conf/99-extra.json")))
- .unwrap();
+ .merge(File::with_name("conf/00-default.toml")).unwrap()
+ .merge(File::from(Path::new("conf/05-some.yml"))).unwrap()
+ .merge(File::from(Path::new("conf/99-extra.json"))).unwrap();
// Print out our settings (as a HashMap)
println!("\n{:?} \n\n-----------",
@@ -24,7 +24,8 @@ fn main() {
// Option 2
// --------
// Gather all conf files from conf/ manually, but put in 1 merge call.
- let settings = Config::default()
+ let mut settings = Config::default();
+ settings
.merge(vec![File::with_name("conf/00-default.toml"),
File::from(Path::new("conf/05-some.yml")),
File::from(Path::new("conf/99-extra.json"))])
@@ -37,7 +38,8 @@ fn main() {
// Option 3
// --------
// Gather all conf files from conf/ using glob and put in 1 merge call.
- let settings = Config::default()
+ let mut settings = Config::default();
+ settings
.merge(glob("conf/*")
.unwrap()
.map(|path| File::from(path.unwrap()))
diff --git a/examples/simple/src/main.rs b/examples/simple/src/main.rs
index debad02..fb66e03 100644
--- a/examples/simple/src/main.rs
+++ b/examples/simple/src/main.rs
@@ -3,13 +3,13 @@ extern crate config;
use std::collections::HashMap;
fn main() {
- let settings = config::Config::default()
+ let mut settings = config::Config::default();
+ settings
// Add in `./Settings.toml`
- .merge(config::File::with_name("Settings"))
+ .merge(config::File::with_name("Settings")).unwrap()
// Add in settings from the environment (with a prefix of APP)
// Eg.. `APP_DEBUG=1 ./target/app` would set the `debug` key
- .merge(config::Environment::with_prefix("APP"))
- .unwrap();
+ .merge(config::Environment::with_prefix("APP")).unwrap();
// Print out our settings (as a HashMap)
println!("{:?}",
diff --git a/examples/watch/Settings.toml b/examples/watch/Settings.toml
index f7881bb..8443f7b 100644
--- a/examples/watch/Settings.toml
+++ b/examples/watch/Settings.toml
@@ -1,3 +1,3 @@
-debug = true
+debug = false
port = 8080
host = "0.0.0.0"
diff --git a/examples/watch/src/main.rs b/examples/watch/src/main.rs
index 70fb7ef..0976f74 100644
--- a/examples/watch/src/main.rs
+++ b/examples/watch/src/main.rs
@@ -12,10 +12,12 @@ use std::sync::mpsc::channel;
use std::time::Duration;
lazy_static! {
- static ref SETTINGS: RwLock<Config> = RwLock::new(Config::default()
- .merge(File::with_name("Settings.toml"))
- .unwrap()
- );
+ static ref SETTINGS: RwLock<Config> = RwLock::new({
+ let mut settings = Config::default();
+ settings.merge(File::with_name("Settings.toml")).unwrap();
+
+ settings
+ });
}
fn show() {
diff --git a/src/config.rs b/src/config.rs
index 5b669a0..0ff2601 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -51,17 +51,20 @@ impl Config {
}
/// Merge in a configuration property source.
- pub fn merge<T>(&mut self, source: T) -> ConfigResult
- where T: 'static,
- T: Source + Send + Sync
+ pub fn merge<T>(&mut self, source: T) -> Result<&mut Config>
+ where
+ T: 'static,
+ T: Source + Send + Sync,
{
match self.kind {
- ConfigKind::Mutable { ref mut sources, .. } => {
+ ConfigKind::Mutable {
+ ref mut sources, ..
+ } => {
sources.push(Box::new(source));
}
ConfigKind::Frozen => {
- return ConfigResult::Err(ConfigError::Frozen);
+ return Err(ConfigError::Frozen);
}
}
@@ -73,7 +76,7 @@ impl Config {
///
/// Configuration is automatically refreshed after a mutation
/// operation (`set`, `merge`, `set_default`, etc.).
- pub fn refresh(&mut self) -> ConfigResult {
+ pub fn refresh(&mut self) -> Result<&mut Config> {
self.cache = match self.kind {
// TODO: We need to actually merge in all the stuff
ConfigKind::Mutable {
@@ -89,9 +92,7 @@ impl Config {
}
// Add sources
- if let Err(error) = sources.collect_to(&mut cache) {
- return ConfigResult::Err(error);
- }
+ sources.collect_to(&mut cache)?;
// Add overrides
for (key, val) in overrides {
@@ -102,11 +103,11 @@ impl Config {
}
ConfigKind::Frozen => {
- return ConfigResult::Err(ConfigError::Frozen);
+ return Err(ConfigError::Frozen);
}
};
- ConfigResult::Ok(self)
+ Ok(self)
}
/// Deserialize the entire configuration.
@@ -114,41 +115,35 @@ impl Config {
T::deserialize(self.cache.clone())
}
- pub fn set_default<T>(&mut self, key: &str, value: T) -> ConfigResult
- where T: Into<Value>
+ pub fn set_default<T>(&mut self, key: &str, value: T) -> Result<&mut Config>
+ where
+ T: Into<Value>,
{
match self.kind {
- ConfigKind::Mutable { ref mut defaults, .. } => {
- defaults.insert(match key.to_lowercase().parse() {
- Ok(expr) => expr,
- Err(error) => {
- return ConfigResult::Err(error);
- }
- },
- value.into());
+ ConfigKind::Mutable {
+ ref mut defaults, ..
+ } => {
+ defaults.insert(key.to_lowercase().parse()?, value.into());
}
- ConfigKind::Frozen => return ConfigResult::Err(ConfigError::Frozen),
+ ConfigKind::Frozen => return Err(ConfigError::Frozen),
};
self.refresh()
}
- pub fn set<T>(&mut self, key: &str, value: T) -> ConfigResult
- where T: Into<Value>
+ pub fn set<T>(&mut self, key: &str, value: T) -> Result<&mut Config>
+ where
+ T: Into<Value>,
{
match self.kind {
- ConfigKind::Mutable { ref mut overrides, .. } => {
- overrides.insert(match key.to_lowercase().parse() {
- Ok(expr) => expr,
- Err(error) => {
- return ConfigResult::Err(error);
- }
- },
- value.into());
+ ConfigKind::Mutable {
+ ref mut overrides, ..
+ } => {
+ overrides.insert(key.to_lowercase().parse()?, value.into());
}
- ConfigKind::Frozen => return ConfigResult::Err(ConfigError::Frozen),
+ ConfigKind::Frozen => return Err(ConfigError::Frozen),
};
self.refresh()
@@ -195,210 +190,3 @@ impl Config {
self.get(key).and_then(Value::into_array)
}
}
-
-/// Holds the result of configuration alteration functions.
-/// A manual alias of Result to enable a chained API and error forwarding.
-pub enum ConfigResult<'a> {
- Ok(&'a mut Config),
- Err(ConfigError),
-}
-
-#[inline]
-fn unwrap_failed<E: Debug>(msg: &str, error: E) -> ! {
- panic!("{}: {:?}", msg, error)
-}
-
-impl<'a> ConfigResult<'a> {
- /// Forwards `Config::merge`
- pub fn merge<T>(self, source: T) -> ConfigResult<'a>
- where T: 'static,
- T: Source + Send + Sync
- {
- match self {
- // If OK, Proceed to nested method
- ConfigResult::Ok(instance) => instance.merge(source),
-
- // Else, Forward the error
- error => error,
- }
- }
-
- /// Forwards `Config::set_default`
- pub fn set_default<T>(self, key: &str, value: T) -> ConfigResult<'a>
- where T: Into<Value>,
- T: 'static
- {
- match self {
- // If OK, Proceed to nested method
- ConfigResult::Ok(instance) => instance.set_default(key, value),
-
- // Else, Forward the error
- error => error,
- }
- }
-
- /// Forwards `Config::set`
- pub fn set<T>(self, key: &str, value: T) -> ConfigResult<'a>
- where T: Into<Value>,
- T: 'static
- {
- match self {
- // If OK, Proceed to nested method
- ConfigResult::Ok(instance) => instance.set(key, value),
-
- // Else, Forward the error
- error => error,
- }
- }
-
- /// Deserialize the entire configuration.
- pub fn deserialize<'de, T: Deserialize<'de>>(self) -> Result<T> {
- self.and_then(|instance| instance.deserialize())
- }
-
- /// Creates a `Result` out of this `ConfigResult`
- #[inline]
- pub fn to_result(self) -> Result<Config> {
- match self {
- ConfigResult::Ok(value) => Ok(value.clone()),
- ConfigResult::Err(error) => Err(error),
- }
- }
-
- /// Forwards `Result::is_ok`
- #[inline]
- pub fn is_ok(&self) -> bool {
- match *self {
- ConfigResult::Ok(_) => true,
- ConfigResult::Err(_) => false,
- }
- }
-
- /// Forwards `Result::is_err`
- #[inline]
- pub fn is_err(&self) -> bool {
- !self.is_ok()
- }
-
- /// Forwards `Result::ok`
- #[inline]
- pub fn ok(self) -> Option<Config> {
- match self {
- ConfigResult::Ok(x) => Some(x.clone()),
- ConfigResult::Err(_) => None,
- }
- }
-
- /// Forwards `Result::err`
- #[inline]
- pub fn err(self) -> Option<ConfigError> {
- match self {
- ConfigResult::Ok(_) => None,
- ConfigResult::Err(x) => Some(x),
- }
- }
-
- /// Forwards `Result::map`
- #[inline]
- pub fn map<U, F>(self, op: F) -> Result<U>
- where
- F: FnOnce(Config) -> U,
- {
- match self {
- ConfigResult::Ok(x) => Ok(op(x.clone())),
- ConfigResult::Err(error) => Err(error),
- }
- }
-
- /// Forwards `Result::map_err`
- #[inline]
- pub fn map_err<F, O>(self, op: O) -> ::std::result::Result<Config, F>
- where
- O: FnOnce(ConfigError) -> F,
- {
- match self {
- ConfigResult::Err(error) => Err(op(error)),
- ConfigResult::Ok(value) => Ok(value.clone()),
- }
- }
-
- /// Forwards `Result::and`
- #[inline]
- pub fn and<U>(self, res: Result<U>) -> Result<U>
- {
- match self {
- ConfigResult::Ok(_) => res,
- ConfigResult::Err(error) => Err(error),
- }
- }
-
- /// Forwards `Result::and_then`
- #[inline]
- pub fn and_then<U, F>(self, op: F) -> Result<U>
- where
- F: FnOnce(Config) -> Result<U>,
- {
- match self {
- ConfigResult::Ok(value) => op(value.clone()),
- ConfigResult::Err(error) => Err(error),
- }
- }
-
- /// Forwards `Result::or`
- #[inline]
- pub fn or<F>(self, res: ::std::result::Result<Config, F>) -> ::std::result::Result<Config, F>
- {
- match self {
- ConfigResult::Ok(value) => Ok(value.clone()),
- ConfigResult::Err(_) => res,
- }
- }
-
- /// Forwards `Result::or_else`
- #[inline]
- pub fn or_else<F, O>(self, op: O) -> ::std::result::Result<Config, F>
- where
- O: FnOnce(ConfigError) -> ::std::result::Result<Config, F>,
- {
- match self {
- ConfigResult::Ok(value) => Ok(value.clone()),
- ConfigResult::Err(error) => op(error),
- }
- }
-
- /// Forwards `Result::unwrap`
- #[inline]
- pub fn unwrap(self) -> Config {
- match self {
- ConfigResult::Ok(instance) => instance.clone(),
- ConfigResult::Err(error) => unwrap_failed("called `ConfigResult::unwrap()` on an `Err` value", error),
- }
- }
-
- /// Forwards `Result::expect`
- #[inline]
- pub fn expect(self, msg: &str) -> Config {
- match self {
- ConfigResult::Ok(instance) => instance.clone(),
- ConfigResult::Err(error) => unwrap_failed(msg, error),
- }
- }
-
- /// Forwards `Result::unwrap_err`
- #[inline]
- pub fn unwrap_err(self) -> ConfigError {
- match self {
- ConfigResult::Ok(t) => unwrap_failed("called `ConfigResult::unwrap_err()` on an `Ok` value", t),
- ConfigResult::Err(e) => e,
- }
- }
-
- /// Forwards `Result::expect_err`
- #[inline]
- pub fn expect_err(self, msg: &str) -> ConfigError {
- match self {
- ConfigResult::Ok(t) => unwrap_failed(msg, t),
- ConfigResult::Err(e) => e,
- }
- }
-}
diff --git a/src/de.rs b/src/de.rs
index 6487f8b..2ff49e9 100644
--- a/src/de.rs
+++ b/src/de.rs
@@ -1,5 +1,5 @@
use serde::de;
-use value::{Value, ValueWithKey, ValueKind};
+use value::{Value, ValueKind, ValueWithKey};
use error::*;
use std::borrow::Cow;
use std::iter::Peekable;
@@ -13,7 +13,8 @@ impl<'de> de::Deserializer<'de> for ValueWithKey<'de> {
#[inline]
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
- where V: de::Visitor<'de>
+ where
+ V: de::Visitor<'de>,
{
// Deserialize based on the underlying type
match self.0.kind {
@@ -101,7 +102,8 @@ impl<'de> de::Deserializer<'de> for ValueWithKey<'de> {
#[inline]
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
- where V: de::Visitor<'de>
+ where
+ V: de::Visitor<'de>,
{
// Match an explicit nil as None and everything else as Some
match self.0.kind {
@@ -122,7 +124,8 @@ impl<'de> de::Deserializer<'de> for Value {
#[inline]
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
- where V: de::Visitor<'de>
+ where
+ V: de::Visitor<'de>,
{
// Deserialize based on the underlying type
match self.kind {
@@ -210,7 +213,8 @@ impl<'de> de::Deserializer<'de> for Value {
#[inline]
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
- where V: de::Visitor<'de>
+ where
+ V: de::Visitor<'de>,
{
// Match an explicit nil as None and everything else as Some
match self.kind {
@@ -265,7 +269,8 @@ impl<'de> de::SeqAccess<'de> for SeqAccess {
type Error = ConfigError;
fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
- where T: de::DeserializeSeed<'de>
+ where
+ T: de::DeserializeSeed<'de>,
{
match self.elements.next() {
Some(value) => seed.deserialize(value).map(Some),
@@ -299,7 +304,8 @@ impl<'de> de::MapAccess<'de> for MapAccess {
type Error = ConfigError;
fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
- where K: de::DeserializeSeed<'de>
+ where
+ K: de::DeserializeSeed<'de>,
{
if self.index >= self.elements.len() {
return Ok(None);
@@ -313,7 +319,8 @@ impl<'de> de::MapAccess<'de> for MapAccess {
}
fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
- where V: de::DeserializeSeed<'de>
+ where
+ V: de::DeserializeSeed<'de>,
{
de::DeserializeSeed::deserialize(seed, self.elements.remove(0).1)
}
diff --git a/src/env.rs b/src/env.rs
index abadea2..aec4de4 100644
--- a/src/env.rs
+++ b/src/env.rs
@@ -88,8 +88,10 @@ impl Source for Environment {
// Replace `separator` with `.`
key = key.replace(&self.separator, ".");
- m.insert(key.to_lowercase(),
- Value::new(Some(&uri), ValueKind::String(value)));
+ m.insert(
+ key.to_lowercase(),
+ Value::new(Some(&uri), ValueKind::String(value)),
+ );
}
Ok(m)
diff --git a/src/error.rs b/src/error.rs
index 514a5e2..eff3c7c 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -13,7 +13,7 @@ pub enum Unexpected {
Str(String),
Unit,
Seq,
- Map
+ Map,
}
impl fmt::Display for Unexpected {
@@ -50,7 +50,7 @@ pub enum ConfigError {
/// The captured error from attempting to parse the file in its desired format.
/// This is the actual error object from the library used for the parsing.
- cause: Box<Error + Send + Sync>
+ cause: Box<Error + Send + Sync>,
},
/// Value could not be converted into the requested type.
@@ -81,27 +81,34 @@ pub enum ConfigError {
impl ConfigError {
// FIXME: pub(crate)
#[doc(hidden)]
- pub fn invalid_type(origin: Option<String>, unexpected: Unexpected, expected: &'static str) -> Self {
+ pub fn invalid_type(
+ origin: Option<String>,
+ unexpected: Unexpected,
+ expected: &'static str,
+ ) -> Self {
ConfigError::Type {
origin: origin,
unexpected: unexpected,
expected: expected,
key: None,
- }
+ }
}
// FIXME: pub(crate)
#[doc(hidden)]
pub fn extend_with_key(self, key: &str) -> Self {
match self {
- ConfigError::Type { origin, unexpected, expected, .. } => {
- ConfigError::Type {
- origin: origin,
- unexpected: unexpected,
- expected: expected,
- key: Some(key.into()),
- }
- }
+ ConfigError::Type {
+ origin,
+ unexpected,
+ expected,
+ ..
+ } => ConfigError::Type {
+ origin: origin,
+ unexpected: unexpected,
+ expected: expected,
+ key: Some(key.into()),
+ },
_ => self,
}
@@ -113,7 +120,7 @@ pub type Result<T> = result::Result<T, ConfigError>;
// Forward Debug to Display for readable panic! messages
impl fmt::Debug for ConfigError {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", *self)
}
}
@@ -121,25 +128,23 @@ impl fmt::Debug for ConfigError {
impl fmt::Display for ConfigError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
- ConfigError::Frozen | ConfigError::PathParse(_) => {
- write!(f, "{}", self.description())
- }
+ ConfigError::Frozen | ConfigError::PathParse(_) => write!(f, "{}", self.description()),
- ConfigError::Message(ref s) => {
- write!(f, "{}", s)
- }
+ ConfigError::Message(ref s) => write!(f, "{}", s),
- ConfigError::Foreign(ref cause) => {
- write!(f, "{}", cause)
- }
+ ConfigError::Foreign(ref cause) => write!(f, "{}", cause),
ConfigError::NotFound(ref key) => {
write!(f, "configuration property {:?} not found", key)
}
- ConfigError::Type { ref origin, ref unexpected, expected, ref key } => {
- write!(f, "invalid type: {}, expected {}",
- unexpected, expected)?;
+ ConfigError::Type {
+ ref origin,
+ ref unexpected,
+ expected,
+ ref key,
+ } => {
+ write!(f, "invalid type: {}, expected {}", unexpected, expected)?;
if let Some(ref key) = *key {
write!(f, " for key `{}`", key)?;
@@ -171,7 +176,9 @@ impl Error for ConfigError {
ConfigError::Frozen => "configuration is frozen",
ConfigError::NotFound(_) => "configuration property not found",
ConfigError::Type { .. } => "invalid type",
- ConfigError::Foreign(ref cause) | ConfigError::FileParse { ref cause, .. } => cause.description(),
+ ConfigError::Foreign(ref cause) | ConfigError::FileParse { ref cause, .. } => {
+ cause.description()
+ }
ConfigError::PathParse(ref kind) => kind.description(),
_ => "configuration error",
@@ -180,9 +187,11 @@ impl Error for ConfigError {
fn cause(&self) -> Option<&Error> {
match *self {
- ConfigError::Foreign(ref cause) | ConfigError::FileParse { ref cause, .. } => Some(cause.as_ref()),
+ ConfigError::Foreign(ref cause) | ConfigError::FileParse { ref cause, .. } => {
+ Some(cause.as_ref())
+ }
- _ => None
+ _ => None,
}
}
}
diff --git a/src/file/format/json.rs b/src/file/format/json.rs
index ead99f8..caf62f5 100644
--- a/src/file/format/json.rs
+++ b/src/file/format/json.rs
@@ -4,7 +4,10 @@ use std::collections::HashMap;
use std::error::Error;
use value::{Value, ValueKind};
-pub fn parse(uri: Option<&String>, text: &str) -> Result<HashMap<String, Value>, Box<Error + Send + Sync>> {
+pub fn parse(
+ uri: Option<&String>,
+ text: &str,
+) -> Result<HashMap<String, Value>, Box<Error + Send + Sync>> {
// Parse a JSON object value from the text
// TODO: Have a proper error fire if the root of a file is ever not a Table
let value = from_json_value(uri, &serde_json::from_str(text)?);
@@ -19,15 +22,13 @@ fn from_json_value(uri: Option<&String>, value: &serde_json::Value) -> Value {
match *value {
serde_json::Value::String(ref value) => Value::new(uri, ValueKind::String(value.clone())),
- serde_json::Value::Number(ref value) => {
- if let Some(value) = value.as_i64() {
- Value::new(uri, ValueKind::Integer(value))
- } else if let Some(value) = value.as_f64() {
- Value::new(uri, ValueKind::Float(value))
- } else {
- unreachable!();
- }
- }
+ serde_json::Value::Number(ref