summaryrefslogtreecommitdiffstats
path: root/src/env.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/env.rs')
-rw-r--r--src/env.rs31
1 files changed, 31 insertions, 0 deletions
diff --git a/src/env.rs b/src/env.rs
index 432df2c..9302903 100644
--- a/src/env.rs
+++ b/src/env.rs
@@ -5,6 +5,13 @@ use crate::map::Map;
use crate::source::Source;
use crate::value::{Value, ValueKind};
+#[cfg(feature = "convert-case")]
+use convert_case::{Case, Casing};
+
+/// An environment source collects a dictionary of environment variables values into a hierarchical
+/// config Value type. We have to be aware how the config tree is created from the environment
+/// dictionary, therefore we are mindful about prefixes for the environment keys, level separators,
+/// encoding form (kebab, snake case) etc.
#[must_use]
#[derive(Clone, Debug, Default)]
pub struct Environment {
@@ -25,6 +32,12 @@ pub struct Environment {
/// an environment key of `REDIS_PASSWORD` to match.
separator: Option<String>,
+ /// Optional directive to translate collected keys into a form that matches what serializers
+ /// that the configuration would expect. For example if you have the `kebab-case` attribute
+ /// for your serde config types, you may want to pass Case::Kebab here.
+ #[cfg(feature = "convert-case")]
+ convert_case: Option<convert_case::Case>,
+
/// Optional character sequence that separates each env value into a vector. only works when try_parsing is set to true
/// Once set, you cannot have type String on the same environment, unless you set list_parse_keys.
list_separator: Option<String>,
@@ -95,6 +108,17 @@ impl Environment {
self
}
+ #[cfg(feature = "convert-case")]
+ pub fn with_convert_case(tt: Case) -> Self {
+ Self::default().convert_case(tt)
+ }
+
+ #[cfg(feature = "convert-case")]
+ pub fn convert_case(mut self, tt: Case) -> Self {
+ self.convert_case = Some(tt);
+ self
+ }
+
pub fn prefix_separator(mut self, s: &str) -> Self {
self.prefix_separator = Some(s.into());
self
@@ -160,6 +184,8 @@ impl Source for Environment {
let uri: String = "the environment".into();
let separator = self.separator.as_deref().unwrap_or("");
+ #[cfg(feature = "convert-case")]
+ let convert_case = &self.convert_case;
let prefix_separator = match (self.prefix_separator.as_deref(), self.separator.as_deref()) {
(Some(pre), _) => pre,
(None, Some(sep)) => sep,
@@ -198,6 +224,11 @@ impl Source for Environment {
key = key.replace(separator, ".");
}
+ #[cfg(feature = "convert-case")]
+ if let Some(convert_case) = convert_case {
+ key = key.to_case(*convert_case);
+ }
+
let value = if self.try_parsing {
// convert to lowercase because bool parsing expects all lowercase
if let Ok(parsed) = value.to_lowercase().parse::<bool>() {