twelve_factor/
configuration.rs

1use config::{Config, ConfigError, Environment, File};
2use serde::Deserialize;
3
4pub trait ConfigProvider {
5    fn get_value<'de, T: Deserialize<'de>>(&self, key: &'de str) -> Result<T, ConfigError>;
6}
7
8pub struct ConfigurationPreferences{
9    pub config_file: Option<String>,
10    pub secrets_file: Option<String>,
11    pub prefix: Option<String>,
12    pub separator: Option<String>,
13}
14
15impl Default for ConfigurationPreferences{
16    fn default() -> Self {
17        ConfigurationPreferences{
18            config_file: None,
19            secrets_file: None,
20            prefix: None,
21            separator: None,
22        }
23    }
24}
25
26pub struct Configuration {
27    configuration: Config,
28}
29
30impl Configuration {
31    pub fn read_configuration(prefs: &ConfigurationPreferences) -> Configuration{
32        let paths = match (prefs.config_file.clone(), prefs.secrets_file.clone()) {
33            (Some(config), Some(secrets)) => {
34                vec![File::with_name(&config), File::with_name(&secrets)]
35            }
36            (Some(config), None) => vec![File::with_name(&config)],
37            (None, Some(secrets)) => vec![File::with_name(&secrets)],
38            (None, None) => vec![],
39        };
40
41        let env = match (prefs.prefix.clone(), prefs.separator.clone()){
42            (Some(prefix) , Some(separator)) => {
43                Environment::with_prefix(&prefix).separator(&separator)
44            },
45            (Some(prefix), None) => {
46                Environment::with_prefix(&prefix)
47            },
48            (None, Some(separator)) => {
49                Environment::default().separator(&separator)
50            },
51            (None, None) => {
52                Environment::default()
53            },
54        };
55
56        let mut a_config = Config::new();
57        a_config.merge(paths).unwrap()
58        .merge(env);
59        Configuration{
60            configuration : a_config,
61        }
62    }
63}
64
65impl ConfigProvider for Configuration{
66    fn get_value<'de, T: Deserialize<'de>>(&self, key: &'de str) -> Result<T, ConfigError>{
67        self.configuration.get(key)
68    }
69}
70
71#[cfg(test)]
72mod tests{
73    
74}