summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/builder.rs22
-rw-r--r--src/env.rs14
-rw-r--r--tests/env.rs21
3 files changed, 54 insertions, 3 deletions
diff --git a/src/builder.rs b/src/builder.rs
index 018713c..6f928c6 100644
--- a/src/builder.rs
+++ b/src/builder.rs
@@ -11,7 +11,7 @@ use crate::{config::Config, path::Expression, source::Source, value::Value};
/// 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.
+/// Defaults are always 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).
@@ -173,6 +173,26 @@ impl<St: BuilderState> ConfigBuilder<St> {
.insert(Expression::from_str(key.as_ref())?, value.into());
Ok(self)
}
+
+ /// Sets an override if value is Some(_)
+ ///
+ /// This function sets an overwrite value if Some(_) is passed. If None is passed, this function does nothing.
+ /// It will not be altered by any default, [`Source`] nor [`AsyncSource`]
+ ///
+ /// # Errors
+ ///
+ /// Fails if `Expression::from_str(key)` fails.
+ pub fn set_override_option<S, T>(mut self, key: S, value: Option<T>) -> Result<Self>
+ where
+ S: AsRef<str>,
+ T: Into<Value>,
+ {
+ if let Some(value) = value {
+ self.overrides
+ .insert(Expression::from_str(key.as_ref())?, value.into());
+ }
+ Ok(self)
+ }
}
impl ConfigBuilder<DefaultState> {
diff --git a/src/env.rs b/src/env.rs
index 03d5785..432df2c 100644
--- a/src/env.rs
+++ b/src/env.rs
@@ -37,6 +37,9 @@ pub struct Environment {
/// Parses booleans, integers and floats if they're detected (can be safely parsed).
try_parsing: bool,
+ // Preserve the prefix while parsing
+ keep_prefix: bool,
+
/// Alternate source for the environment. This can be used when you want to test your own code
/// using this source, without the need to change the actual system environment variables.
///
@@ -136,6 +139,11 @@ impl Environment {
self
}
+ pub fn keep_prefix(mut self, keep: bool) -> Self {
+ self.keep_prefix = keep;
+ self
+ }
+
pub fn source(mut self, source: Option<Map<String, String>>) -> Self {
self.source = source;
self
@@ -175,8 +183,10 @@ impl Source for Environment {
// Check for prefix
if let Some(ref prefix_pattern) = prefix_pattern {
if key.starts_with(prefix_pattern) {
- // Remove this prefix from the key
- key = key[prefix_pattern.len()..].to_string();
+ if !self.keep_prefix {
+ // Remove this prefix from the key
+ key = key[prefix_pattern.len()..].to_string();
+ }
} else {
// Skip this key
return;
diff --git a/tests/env.rs b/tests/env.rs
index fcadf81..166a83f 100644
--- a/tests/env.rs
+++ b/tests/env.rs
@@ -75,6 +75,27 @@ fn test_empty_value_is_ignored() {
}
#[test]
+fn test_keep_prefix() {
+ env::set_var("C_A_B", "");
+
+ // Do not keep the prefix
+ let environment = Environment::with_prefix("C");
+
+ assert!(environment.collect().unwrap().contains_key("a_b"));
+
+ let environment = Environment::with_prefix("C").keep_prefix(false);
+
+ assert!(environment.collect().unwrap().contains_key("a_b"));
+
+ // Keep the prefix
+ let environment = Environment::with_prefix("C").keep_prefix(true);
+
+ assert!(environment.collect().unwrap().contains_key("c_a_b"));
+
+ env::remove_var("C_A_B");
+}
+
+#[test]
fn test_custom_separator_behavior() {
env::set_var("C.B.A", "abc");