1use crate::{pascal_case, path, Result, Settings};
2use std::{borrow::Cow, env::vars};
3
4fn escape(name: &str) -> Cow<'_, str> {
5 if name.contains("__") {
6 Cow::Owned(name.replace("__", ":"))
7 } else {
8 Cow::Borrowed(name)
9 }
10}
11
12#[derive(Debug, Default)]
14pub struct Provider(String);
15
16impl Provider {
17 #[inline]
27 pub fn new(prefix: impl Into<String>) -> Self {
28 Self(prefix.into())
29 }
30}
31
32impl crate::Provider for Provider {
33 #[inline]
34 fn name(&self) -> &str {
35 "Environment"
36 }
37
38 fn load(&self, settings: &mut Settings) -> Result {
39 if self.0.is_empty() {
40 for (key, value) in vars() {
41 settings.insert(pascal_case(&escape(&key)), value);
42 }
43 } else {
44 let prefix = &self.0;
45 let len = prefix.len();
46
47 for (key, value) in vars() {
48 if path::starts_with(&key, prefix) {
49 settings.insert(pascal_case(&escape(&key[len..])), value);
50 }
51 }
52 }
53
54 Ok(())
55 }
56}