From e8985eacc7de0fb1916ab20a7bb40b9851c0f7da Mon Sep 17 00:00:00 2001 From: Conrad Ludgate Date: Thu, 24 Feb 2022 09:28:03 +0000 Subject: [PATCH] add prefix separator support --- src/env.rs | 17 +++++++++++++++-- tests/env.rs | 13 +++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/env.rs b/src/env.rs index ef91ef88..99681064 100644 --- a/src/env.rs +++ b/src/env.rs @@ -16,6 +16,9 @@ pub struct Environment { /// For example, the key `CONFIG_DEBUG` would become `DEBUG` with a prefix of `config`. prefix: Option, + /// Optional character sequence that separates the prefix from the rest of the key + prefix_separator: Option, + /// Optional character sequence that separates each key segment in an environment key pattern. /// Consider a nested configuration such as `redis.password`, a separator of `_` would allow /// an environment key of `REDIS_PASSWORD` to match. @@ -83,6 +86,12 @@ impl Environment { self } + #[must_use] + pub fn prefix_separator(mut self, s: &str) -> Self { + self.prefix_separator = Some(s.into()); + self + } + #[must_use] pub fn separator(mut self, s: &str) -> Self { self.separator = Some(s.into()); @@ -120,13 +129,17 @@ impl Source for Environment { let uri: String = "the environment".into(); let separator = self.separator.as_deref().unwrap_or(""); - let group_separator = self.separator.as_deref().unwrap_or("_"); + let prefix_separator = match (self.prefix_separator.as_deref(), self.separator.as_deref()) { + (Some(pre), _) => pre, + (None, Some(sep)) => sep, + (None, None) => "_", + }; // Define a prefix pattern to test and exclude from keys let prefix_pattern = self .prefix .as_ref() - .map(|prefix| format!("{}{}", prefix, group_separator).to_lowercase()); + .map(|prefix| format!("{}{}", prefix, prefix_separator).to_lowercase()); let collector = |(key, value): (String, String)| { // Treat empty environment variables as unset diff --git a/tests/env.rs b/tests/env.rs index edd8dff9..90852e0e 100644 --- a/tests/env.rs +++ b/tests/env.rs @@ -85,6 +85,19 @@ fn test_custom_separator_behavior() { env::remove_var("C.B.A"); } +#[test] +fn test_custom_prefix_separator_behavior() { + env::set_var("C-B.A", "abc"); + + let environment = Environment::with_prefix("C") + .separator(".") + .prefix_separator("-"); + + assert!(environment.collect().unwrap().contains_key("b.a")); + + env::remove_var("C-B.A"); +} + #[test] fn test_parse_int() { // using a struct in an enum here to make serde use `deserialize_any`