summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Beyer <mail@beyermatthias.de>2021-05-08 18:23:00 +0200
committerGitHub <noreply@github.com>2021-05-08 18:23:00 +0200
commit266f504d9f23e192c03ef486f58a678847249b60 (patch)
tree815674a16f873fb1dd52d111f9e2de7c6757724f
parent79883ff7f8ab246c8993f6276d97e5670271cb8c (diff)
parentc4d296482db823221f16d7b26d498810cb26ba59 (diff)
Merge pull request #196 from szarykott/builder
Create the ConfigBuilder
-rw-r--r--src/builder.rs159
-rw-r--r--src/config.rs27
-rw-r--r--src/lib.rs2
-rw-r--r--src/ser.rs2
-rw-r--r--src/source.rs20
-rw-r--r--tests/datetime.rs21
-rw-r--r--tests/env.rs110
-rw-r--r--tests/errors.rs24
-rw-r--r--tests/file.rs26
-rw-r--r--tests/file_hjson.rs14
-rw-r--r--tests/file_ini.rs13
-rw-r--r--tests/file_json.rs22
-rw-r--r--tests/file_ron.rs14
-rw-r--r--tests/file_toml.rs14
-rw-r--r--tests/file_yaml.rs14
-rw-r--r--tests/get.rs9
-rw-r--r--tests/legacy/datetime.rs137
-rw-r--r--tests/legacy/env.rs350
-rw-r--r--tests/legacy/errors.rs132
-rw-r--r--tests/legacy/file.rs56
-rw-r--r--tests/legacy/file_hjson.rs78
-rw-r--r--tests/legacy/file_ini.rs69
-rw-r--r--tests/legacy/file_json.rs102
-rw-r--r--tests/legacy/file_ron.rs80
-rw-r--r--tests/legacy/file_toml.rs92
-rw-r--r--tests/legacy/file_yaml.rs82
-rw-r--r--tests/legacy/get.rs272
-rw-r--r--tests/legacy/merge.rs49
-rw-r--r--tests/legacy/mod.rs12
-rw-r--r--tests/legacy/set.rs93
-rw-r--r--tests/legacy_tests.rs5
-rw-r--r--tests/merge.rs35
-rw-r--r--tests/set.rs112
33 files changed, 2045 insertions, 202 deletions
diff --git a/src/builder.rs b/src/builder.rs
new file mode 100644
index 0000000..627ba2a
--- /dev/null
+++ b/src/builder.rs
@@ -0,0 +1,159 @@
+use std::str::FromStr;
+use std::{collections::HashMap, iter::IntoIterator};
+
+use crate::{config::Config, error, path::Expression, source::Source, value::Value};
+
+/// A configuration builder
+///
+/// It registers ordered sources of configuration to later build consistent [`Config`] from them.
+/// Configuration sources it defines are defaults, [`Source`]s and overrides.
+///
+/// Defaults are alaways loaded first and can be overwritten by any of two other sources.
+/// Overrides are always loaded last, thus cannot be overridden.
+/// Both can be only set explicitly key by key in code
+/// using [`set_default`](Self::set_default) or [`set_override`](Self::set_override).
+///
+/// An intermediate category, [`Source`], set groups of keys at once implicitly using data coming from external sources
+/// like files, environment variables or others that one implements. Defining a [`Source`] is as simple as implementing
+/// a trait for a struct.
+///
+/// Adding sources, setting defaults and overrides does not invoke any I/O nor builds a config.
+/// It happens on demand when [`build`](Self::build) (or its alternative) is called.
+/// Therefore all errors, related to any of the [`Source`] will only show up then.
+///
+/// # Examples
+///
+/// ```rust
+/// # use config::*;
+/// # use std::error::Error;
+/// # fn main() -> Result<(), Box<dyn Error>> {
+/// let mut builder = ConfigBuilder::default()
+/// .set_default("default", "1")?
+/// .add_source(File::new("config/settings", FileFormat::Json))
+/// .set_override("override", "1")?;
+///
+/// match builder.build() {
+/// Ok(config) => {
+/// // use your config
+/// },
+/// Err(e) => {
+/// // something went wrong
+/// }
+/// }
+/// # Ok(())
+/// # }
+/// ```
+///
+/// Calls can be not chained as well
+/// ```rust
+/// # use std::error::Error;
+/// # use config::*;
+/// # fn main() -> Result<(), Box<dyn Error>> {
+/// let mut builder = ConfigBuilder::default();
+/// builder = builder.set_default("default", "1")?;
+/// builder = builder.add_source(File::new("config/settings", FileFormat::Json));
+/// builder = builder.add_source(File::new("config/settings.prod", FileFormat::Json));
+/// builder = builder.set_override("override", "1")?;
+/// # Ok(())
+/// # }
+/// ```
+#[derive(Debug, Clone, Default)]
+pub struct ConfigBuilder {
+ defaults: HashMap<Expression, Value>,
+ overrides: HashMap<Expression, Value>,
+ sources: Vec<Box<dyn Source + Send + Sync>>,
+}
+
+impl ConfigBuilder {
+ /// Set a default `value` at `key`
+ ///
+ /// This value can be overwritten by any [`Source`] or override.
+ ///
+ /// # Errors
+ ///
+ /// Fails if `Expression::from_str(key)` fails.
+ pub fn set_default<S, T>(mut self, key: S, value: T) -> error::Result<ConfigBuilder>
+ where
+ S: AsRef<str>,
+ T: Into<Value>,
+ {
+ self.defaults
+ .insert(Expression::from_str(key.as_ref())?, value.into());
+ Ok(self)
+ }
+
+ /// Registers new [`Source`] in this builder.
+ ///
+ /// Calling this method does not invoke any I/O. [`Source`] is only saved in internal register for later use.
+ pub fn add_source<T>(mut self, source: T) -> Self
+ where
+ T: Source + Send + Sync + 'static,
+ {
+ self.sources.push(Box::new(source));
+ self
+ }
+
+ /// Set an override
+ ///
+ /// This function sets an overwrite value. It will not be altered by any default or [`Source`]
+ ///
+ /// # Errors
+ ///
+ /// Fails if `Expression::from_str(key)` fails.
+ pub fn set_override<S, T>(mut self, key: S, value: T) -> error::Result<ConfigBuilder>
+ where
+ S: AsRef<str>,
+ T: Into<Value>,
+ {
+ self.overrides
+ .insert(Expression::from_str(key.as_ref())?, value.into());
+ Ok(self)
+ }
+
+ /// Reads all registered [`Source`]s.
+ ///
+ /// This is the method that invokes all I/O operations.
+ /// For a non consuming alternative see [`build_cloned`](Self::build_cloned)
+ ///
+ /// # Errors
+ /// If source collection fails, be it technical reasons or related to inability to read data as `Config` for different reasons,
+ /// this method returns error.
+ pub fn build(self) -> error::Result<Config> {
+ Self::build_internal(self.defaults, self.overrides, &self.sources)
+ }
+
+ /// Reads all registered [`Source`]s.
+ ///
+ /// Similar to [`build`](Self::build), but it does not take ownership of `ConfigBuilder` to allow later reuse.
+ /// Internally it clones data to achieve it.
+ ///
+ /// # Errors
+ /// If source collection fails, be it technical reasons or related to inability to read data as `Config` for different reasons,
+ /// this method returns error.
+ pub fn build_cloned(&self) -> error::Result<Config> {
+ Self::build_internal(self.defaults.clone(), self.overrides.clone(), &self.sources)
+ }
+
+ fn build_internal(
+ defaults: HashMap<Expression, Value>,
+ overrides: HashMap<Expression, Value>,
+ sources: &[Box<dyn Source + Send + Sync>],
+ ) -> error::Result<Config> {
+ let mut cache: Value = HashMap::<String, Value>::new().into();
+
+ // Add defaults
+ for (key, val) in defaults.into_iter() {
+ key.set(&mut cache, val);
+ }
+
+ // Add sources
+ sources.collect_to(&mut cache)?;
+
+ // Add overrides
+ for (key, val) in overrides.into_iter() {
+ key.set(&mut cache, val);
+ }
+
+ Ok(Config::new(cache))
+ }
+}
diff --git a/src/config.rs b/src/config.rs
index 2b6c5b6..3d80aeb 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -1,6 +1,7 @@
use std::collections::HashMap;
use std::fmt::Debug;
+use crate::builder::ConfigBuilder;
use serde::de::Deserialize;
use serde::ser::Serialize;
@@ -35,23 +36,41 @@ impl Default for Config {
}
impl Config {
+ pub(crate) fn new(value: Value) -> Self {
+ Config {
+ cache: value,
+ ..Default::default()
+ }
+ }
+
+ /// Creates new [`ConfigBuilder`] instance
+ pub fn builder() -> ConfigBuilder {
+ ConfigBuilder::default()
+ }
+
/// Merge in a configuration property source.
+ #[deprecated(since = "0.12.0", note = "please use 'ConfigBuilder' instead")]
pub fn merge<T>(&mut self, source: T) -> Result<&mut Config>
where
T: 'static,
T: Source + Send + Sync,
{
self.sources.push(Box::new(source));
+
+ #[allow(deprecated)]
self.refresh()
}
/// Merge in a configuration property source.
+ #[deprecated(since = "0.12.0", note = "please use 'ConfigBuilder' instead")]
pub fn with_merged<T>(mut self, source: T) -> Result<Self>
where
T: 'static,
T: Source + Send + Sync,
{
self.sources.push(Box::new(source));
+
+ #[allow(deprecated)]
self.refresh()?;
Ok(self)
}
@@ -61,6 +80,7 @@ impl Config {
///
/// Configuration is automatically refreshed after a mutation
/// operation (`set`, `merge`, `set_default`, etc.).
+ #[deprecated(since = "0.12.0", note = "please use 'ConfigBuilder' instead")]
pub fn refresh(&mut self) -> Result<&mut Config> {
self.cache = {
let mut cache: Value = HashMap::<String, Value>::new().into();
@@ -85,11 +105,14 @@ impl Config {
}
/// Set a default `value` at `key`
+ #[deprecated(since = "0.12.0", note = "please use 'ConfigBuilder' instead")]
pub fn set_default<T>(&mut self, key: &str, value: T) -> Result<&mut Config>
where
T: Into<Value>,
{
self.defaults.insert(key.parse()?, value.into());
+
+ #[allow(deprecated)]
self.refresh()
}
@@ -101,14 +124,18 @@ impl Config {
/// # Warning
///
/// Errors if config is frozen
+ #[deprecated(since = "0.12.0", note = "please use 'ConfigBuilder' instead")]
pub fn set<T>(&mut self, key: &str, value: T) -> Result<&mut Config>
where
T: Into<Value>,
{
self.overrides.insert(key.parse()?, value.into());
+
+ #[allow(deprecated)]
self.refresh()
}
+ #[deprecated(since = "0.12.0", note = "please use 'ConfigBuilder' instead")]
pub fn set_once(&mut self, key: &str, value: Value) -> Result<()> {
let expr: path::Expression = key.parse()?;
diff --git a/src/lib.rs b/src/lib.rs
index 2dbd7b8..ae02c36 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -51,6 +51,7 @@ extern crate ini;
#[cfg(feature = "ron")]
extern crate ron;
+mod builder;
mod config;
mod de;
mod env;
@@ -61,6 +62,7 @@ mod ser;
mod source;
mod value;
+pub use crate::builder::ConfigBuilder;
pub use crate::config::Config;
pub use crate::env::Environment;
pub use crate::error::ConfigError;
diff --git a/src/ser.rs b/src/ser.rs
index a303408..b5c7f4f 100644
--- a/src/ser.rs
+++ b/src/ser.rs
@@ -27,6 +27,8 @@ impl ConfigSerializer {
)))
}
};
+
+ #[allow(deprecated)]
self.output.set(&key, value.into())?;
Ok(())
}
diff --git a/src/source.rs b/src/source.rs
index 2b0eb30..dc5f3b5 100644
--- a/src/source.rs
+++ b/src/source.rs
@@ -55,6 +55,26 @@ impl Source for Vec<Box<dyn Source + Send + Sync>> {
}
}
+impl Source for [Box<dyn Source + Send + Sync>] {
+ fn clone_into_box(&self) -> Box<dyn Source + Send + Sync> {
+ Box::new(self.to_owned())
+ }
+
+ fn collect(&self) -> Result<HashMap<String, Value>> {
+ let mut cache: Value = HashMap::<String, Value>::new().into();
+
+ for source in self {
+ source.collect_to(&mut cache)?;
+ }
+
+ if let ValueKind::Table(table) = cache.kind {
+ Ok(table)
+ } else {
+ unreachable!();
+ }
+ }
+}
+
impl<T> Source for Vec<T>
where
T: Source + Sync + Send,
diff --git a/tests/datetime.rs b/tests/datetime.rs
index 471da47..2b0c22d 100644
--- a/tests/datetime.rs
+++ b/tests/datetime.rs
@@ -14,8 +14,8 @@ use chrono::{DateTime, TimeZone, Utc};
use config::*;
fn make() -> Config {
- Config::default()
- .merge(File::from_str(
+ Config::builder()
+ .add_source(File::from_str(
r#"
{
"json_datetime": "2017-05-10T02:14:53Z"
@@ -23,22 +23,19 @@ fn make() -> Config {
"#,
FileFormat::Json,
))
- .unwrap()
- .merge(File::from_str(
+ .add_source(File::from_str(
r#"
yaml_datetime: 2017-06-12T10:58:30Z
"#,
FileFormat::Yaml,
))
- .unwrap()
- .merge(File::from_str(
+ .add_source(File::from_str(
r#"
toml_datetime = 2017-05-11T14:55:15Z
"#,
FileFormat::Toml,
))
- .unwrap()
- .merge(File::from_str(
+ .add_source(File::from_str(
r#"
{
"hjson_datetime": "2017-05-10T02:14:53Z"
@@ -46,15 +43,13 @@ fn make() -> Config {
"#,
FileFormat::Hjson,
))
- .unwrap()
- .merge(File::from_str(
+ .add_source(File::from_str(
r#"
ini_datetime = 2017-05-10T02:14:53Z
"#,
FileFormat::Ini,
))
- .unwrap()
- .merge(File::from_str(
+ .add_source(File::from_str(
r#"
(
ron_datetime: "2021-04-19T11:33:02Z"
@@ -62,8 +57,8 @@ fn make() -> Config {
"#,
FileFormat::Ron,
))
+ .build()
.unwrap()
- .clone()
}
#[test]
diff --git a/tests/env.rs b/tests/env.rs
index 6ce82c7..560ec3b 100644
--- a/tests/env.rs
+++ b/tests/env.rs
@@ -105,11 +105,13 @@ fn test_parse_int() {
env::set_var("INT_VAL", "42");
let environment = Environment::new().try_parsing(true);
- let mut config = Config::default();
- config.set("tag", "Int").unwrap();
-
- config.merge(environment).unwrap();
+ let config = Config::builder()
+ .set_default("tag", "Int")
+ .unwrap()
+ .add_source(environment)
+ .build()
+ .unwrap();
let config: TestIntEnum = config.try_into().unwrap();
@@ -135,11 +137,13 @@ fn test_parse_float() {
env::set_var("FLOAT_VAL", "42.3");
let environment = Environment::new().try_parsing(true);
- let mut config = Config::default();
-
- config.set("tag", "Float").unwrap();
- config.merge(environment).unwrap();
+ let config = Config::builder()
+ .set_default("tag", "Float")
+ .unwrap()
+ .add_source(environment)
+ .build()
+ .unwrap();
let config: TestFloatEnum = config.try_into().unwrap();
@@ -168,11 +172,13 @@ fn test_parse_bool() {
env::set_var("BOOL_VAL", "true");
let environment = Environment::new().try_parsing(true);
- let mut config = Config::default();
-
- config.set("tag", "Bool").unwrap();
- config.merge(environment).unwrap();
+ let config = Config::builder()
+ .set_default("tag", "Bool")
+ .unwrap()
+ .add_source(environment)
+ .build()
+ .unwrap();
let config: TestBoolEnum = config.try_into().unwrap();
@@ -202,11 +208,13 @@ fn test_parse_off_int() {
env::set_var("INT_VAL_1", "42");
let environment = Environment::new().try_parsing(false);
- let mut config = Config::default();
- config.set("tag", "Int").unwrap();
-
- config.merge(environment).unwrap();
+ let config = Config::builder()
+ .set_default("tag", "Int")
+ .unwrap()
+ .add_source(environment)
+ .build()
+ .unwrap();
env::remove_var("INT_VAL_1");
@@ -231,11 +239,13 @@ fn test_parse_off_float() {
env::set_var("FLOAT_VAL_1", "42.3");
let environment = Environment::new().try_parsing(false);
- let mut config = Config::default();
-
- config.set("tag", "Float").unwrap();
- config.merge(environment).unwrap();
+ let config = Config::builder()
+ .set_default("tag", "Float")
+ .unwrap()
+ .add_source(environment)
+ .build()
+ .unwrap();
env::remove_var("FLOAT_VAL_1");
@@ -260,11 +270,13 @@ fn test_parse_off_bool() {
env::set_var("BOOL_VAL_1", "true");
let environment = Environment::new().try_parsing(false);
- let mut config = Config::default();
-
- config.set("tag", "Bool").unwrap();
- config.merge(environment).unwrap();
+ let config = Config::builder()
+ .set_default("tag", "Bool")
+ .unwrap()
+ .add_source(environment)
+ .build()
+ .unwrap();
env::remove_var("BOOL_VAL_1");
@@ -289,11 +301,13 @@ fn test_parse_int_fail() {
env::set_var("INT_VAL_2", "not an int");
let environment = Environment::new().try_parsing(true);
- let mut config = Config::default();
- config.set("tag", "Int").unwrap();
-
- config.merge(environment).unwrap();
+ let config = Config::builder()
+ .set_default("tag", "Int")
+ .unwrap()
+ .add_source(environment)
+ .build()
+ .unwrap();
env::remove_var("INT_VAL_2");
@@ -318,11 +332,13 @@ fn test_parse_float_fail() {
env::set_var("FLOAT_VAL_2", "not a float");
let environment = Environment::new().try_parsing(true);
- let mut config = Config::default();
-
- config.set("tag", "Float").unwrap();
- config.merge(environment).unwrap();
+ let config = Config::builder()
+ .set_default("tag", "Float")
+ .unwrap()
+ .add_source(environment)
+ .build()
+ .unwrap();
env::remove_var("FLOAT_VAL_2");
@@ -347,11 +363,13 @@ fn test_parse_bool_fail() {
env::set_var("BOOL_VAL_2", "not a bool");
let environment = Environment::new().try_parsing(true);
- let mut config = Config::default();
-
- config.set("tag", "Bool").unwrap();
- config.merge(environment).unwrap();
+ let config = Config::builder()
+ .set_default("tag", "Bool")
+ .unwrap()
+ .add_source(environment)
+ .build()
+ .unwrap();
env::remove_var("BOOL_VAL_2");
@@ -375,11 +393,13 @@ fn test_parse_string() {
env::set_var("STRING_VAL", "test string");
let environment = Environment::new().try_parsing(true);
- let mut config = Config::default();
- config.set("tag", "String").unwrap();
-
- config.merge(environment).unwrap();
+ let config = Config::builder()
+ .set_default("tag", "String")
+ .unwrap()
+ .add_source(environment)
+ .build()
+ .unwrap();
let config: TestStringEnum = config.try_into().unwrap();
@@ -409,11 +429,13 @@ fn test_parse_off_string() {
env::set_var("STRING_VAL_1", "test string");
let environment = Environment::new().try_parsing(false);
- let mut config = Config::default();
-
- config.set("tag", "String").unwrap();
- config.merge(environment).unwrap();
+ let config = Config::builder()
+ .set_default("tag", "String")
+ .unwrap()
+ .add_source(environment)
+ .build()
+ .unwrap();
let config: TestStringEnum = config.try_into().unwrap();
diff --git a/tests/errors.rs b/tests/errors.rs
index cb7f637..54bbe95 100644
--- a/tests/errors.rs
+++ b/tests/errors.rs
@@ -10,17 +10,17 @@ use std::path::PathBuf;
use config::*;
fn make() -> Config {
- let mut c = Config::default();
- c.merge(File::new("tests/Settings", FileFormat::Toml))
- .unwrap();
-
- c
+ Config::builder()
+ .add_source(File::new("tests/Settings", FileFormat::Toml))
+ .build()
+ .unwrap()
}
#[test]
fn test_error_parse() {
- let mut c = Config::default();
- let res = c.merge(File::new("tests/Settings-invalid", FileFormat::Toml));
+ let res = Config::builder()
+ .add_source(File::new("tests/Settings-invalid", FileFormat::Toml))
+ .build();
let path: PathBuf = ["tests", "Settings-invalid.toml"].iter().collect();
@@ -121,9 +121,13 @@ inner:
test: ABC
"#;
- let mut cfg = Config::default();
- cfg.merge(File::from_str(CFG, FileFormat::Yaml)).unwrap();
- let e = cfg.try_into::<Outer>().unwrap_err();
+ let e = Config::builder()
+ .add_source(File::from_str(CFG, FileFormat::Yaml))
+ .build()
+ .unwrap()
+ .try_into::<Outer>()
+ .unwrap_err();
+
if let ConfigError::Type {
key: Some(path), ..
} = e
diff --git a/tests/file.rs b/tests/file.rs
index 0680c2a..c282691 100644
--- a/tests/file.rs
+++ b/tests/file.rs
@@ -6,16 +6,18 @@ use config::*;
#[test]
fn test_file_not_required() {
- let mut c = Config::default();
- let res = c.merge(File::new("tests/NoSettings", FileFormat::Yaml).required(false));
+ let res = Config::builder()
+ .add_source(File::new("tests/NoSettings", FileFormat::Yaml).required(false))
+ .build();
assert!(res.is_ok());
}
#[test]
fn test_file_required_not_found() {
- let mut c = Config::default();
- let res = c.merge(File::new("tests/NoSettings", FileFormat::Yaml));
+ let res = Config::builder()
+ .add_source(File::new("tests/NoSettings", FileFormat::Yaml))
+ .build();
assert!(res.is_err());
assert_eq!(
@@ -26,8 +28,9 @@ fn test_file_required_not_found() {
#[test]
fn test_file_auto() {
- let mut c = Config::default();
- c.merge(File::with_name("tests/Settings-production"))
+ let c = Config::builder()
+ .add_source(File::with_name("tests/Settings-production"))
+ .build()
.unwrap();
assert_eq!(c.get("debug").ok(), Some(false));
@@ -36,8 +39,9 @@ fn test_file_auto() {
#[test]
fn test_file_auto_not_found() {
- let mut c = Config::default();
- let res = c.merge(File::with_name("tests/NoSettings"));
+ let res = Config::builder()
+ .add_source(File::with_name("tests/NoSettings"))
+ .build();
assert!(res.is_err());
assert_eq!(
@@ -48,8 +52,10 @@ fn test_file_auto_not_found() {
#[test]
fn test_file_ext() {
- let mut c = Config::default();
- c.merge(File::with_name("tests/Settings.json")).unwrap();
+ let c = Config::builder()
+ .add_source(File::with_name("tests/Settings.json"))
+ .build()
+ .unwrap();
assert_eq!(c.get("debug").ok(), Some(true));
assert_eq!(c.get("production").ok(), Some(false));
diff --git a/tests/file_hjson.rs b/tests/file_hjson.rs
index 4ef48ac..4002a90 100644
--- a/tests/file_hjson.rs
+++ b/tests/file_hjson.rs
@@ -35,11 +35,10 @@ struct Settings {
}
fn make() -> Config {
- let mut c = Config::default();
- c.merge(File::new("tests/Settings", FileFormat::Hjson))
- .unwrap();
-
- c
+ Config::builder()
+ .add_source(File::new("tests/Settings", FileFormat::Hjson))
+ .build()
+ .unwrap()
}
#[test]
@@ -68,8 +67,9 @@ fn test_file() {
#[test]
fn test_error_parse() {
- let mut c = Config::default();
- let res = c.merge(File::new("tests/Settings-invalid", FileFormat::Hjson));
+ let res = Config::builder()
+ .add_source(File::new("tests/Settings-invalid", FileFormat::Hjson))
+ .build();
let path: PathBuf = ["tests", "Settings-invalid.hjson"].iter().collect();
diff --git a/tests/file_ini.rs b/tests/file_ini.rs
index 437c0d9..332d3ea 100644
--- a/tests/file_ini.rs
+++ b/tests/file_ini.rs
@@ -28,10 +28,10 @@ struct Settings {
}
fn make() -> Config {
- let mut c = Config::default();
- c.merge(File::new("tests/Settings", FileFormat::Ini))
- .unwrap();
- c
+ Config::builder()
+ .add_source(File::new("tests/Settings", FileFormat::Ini))
+ .build()
+ .unwrap()
}
#[test]
@@ -56,8 +56,9 @@ fn test_file() {
#[test]
fn test_error_parse() {
- let mut c = Config::default();
- let res = c.merge(File::new("tests/Settings-invalid", FileFormat::Ini));
+ let res = Config::builder()
+ .add_source(File::new("tests/Settings-invalid", FileFormat::Ini))
+ .build();
let path: PathBuf = ["tests", "Settings-invalid.ini"].iter().collect();
diff --git a/tests/file_json.rs b/tests/file_json.rs
index bd27572..4563e42 100644
--- a/tests/file_json.rs
+++ b/tests/file_json.rs
@@ -35,11 +35,10 @@ struct Settings {
}
fn make() -> Config {
- let mut c = Config::default();
- c.merge(File::new("tests/Settings", FileFormat::Json))
- .unwrap();
-
- c
+ Config::builder()
+ .add_source(File::new("tests/Settings", FileFormat::Json))
+ .build()
+ .unwrap()
}
#[test]
@@ -68,8 +67,9 @@ fn test_file() {
#[test]
fn test_error_parse() {
- let mut c = Config::default();
- let res = c.merge(File::new("tests/Settings-invalid", FileFormat::Json));
+ let res = Config::builder()
+ .add_source(File::new("tests/Settings-invalid", FileFormat::Json))
+ .build();
let path_with_extension: PathBuf = ["tests", "Settings-invalid.json"].iter().collect();
@@ -85,8 +85,8 @@ fn test_error_parse() {
#[test]
fn test_json_vec() {
- let c = Config::default()
- .merge(File::from_str(
+ let c = Config::builder()
+ .add_source(File::from_str(
r#"
{
"WASTE": ["example_dir1", "example_dir2"]
@@ -94,8 +94,8 @@ fn test_json_vec() {
"#,
FileFormat::Json,
))
- .unwrap()
- .clone();
+ .build()
+ .unwrap();
let v = c.get_array("WASTE").unwrap();
let mut vi = v.into_iter();
diff --git a/tests/file_ron.rs b/tests/file_ron.rs
index 1f1ede2..d60c890 100644
--- a/tests/file_ron.rs
+++ b/tests/file_ron.rs
@@ -36,11 +36,10 @@ struct Settings {
}
fn make() -> Config {
- let mut c = Config::default();
- c.merge(File::new("tests/Settings", FileFormat::Ron))
- .unwrap();
-
- c
+ Config::builder()
+ .add_source(File::new("tests/Settings", FileFormat::Ron))
+ .build()
+ .unwrap()
}
#[test]
@@ -70,8 +69,9 @@ fn test_file() {
#[test]
fn test_error_parse() {
- let mut c = Config::default();
- let res = c.merge(File::new("tests/Settings-invalid", FileFormat::Ron));
+ let res = Config::builder()
+ .add_source(File::new("tests/Settings-invalid", FileFormat::Ron))
+ .build();
let path_with_extension: PathBuf = ["tests", "Settings-invalid.ron"].iter().collect();