1use std::collections::{BTreeMap, HashMap};
2
3pub trait EnvSource {
14 fn get(&self, key: &str) -> Option<String>;
16}
17
18impl<T: EnvSource + ?Sized> EnvSource for &T {
20 fn get(&self, key: &str) -> Option<String> {
21 (**self).get(key)
22 }
23}
24
25impl EnvSource for HashMap<String, String> {
27 fn get(&self, key: &str) -> Option<String> {
28 self.get(key).cloned()
29 }
30}
31
32impl EnvSource for BTreeMap<String, String> {
34 fn get(&self, key: &str) -> Option<String> {
35 self.get(key).cloned()
36 }
37}
38
39impl<'a> EnvSource for &'a [(&'a str, &'a str)] {
41 fn get(&self, key: &str) -> Option<String> {
42 self.iter().find(|(k, _)| *k == key).map(|(_, v)| (*v).to_owned())
43 }
44}
45
46impl EnvSource for std::env::Vars {
48 fn get(&self, key: &str) -> Option<String> {
49 std::env::var(key).ok()
50 }
51}
52
53impl EnvSource for std::env::VarsOs {
55 fn get(&self, key: &str) -> Option<String> {
56 std::env::var_os(key).and_then(|v| v.into_string().ok())
57 }
58}
59
60pub struct FnEnvSource<F>(pub F);
70
71impl<F> EnvSource for FnEnvSource<F>
72where
73 for<'a> F: Fn(&'a str) -> Option<String>,
74{
75 fn get(&self, key: &str) -> Option<String> {
76 self.0(key)
77 }
78}
79
80pub struct EnvSourceChain<A, B> {
83 pub primary: A,
85 pub fallback: B,
87}
88
89impl<A: EnvSource, B: EnvSource> EnvSource for EnvSourceChain<A, B> {
90 fn get(&self, key: &str) -> Option<String> {
91 self.primary.get(key).or_else(|| self.fallback.get(key))
92 }
93}