better_config_loader/
env.rs

1use better_config_core::{AbstractConfig, Error};
2use dotenvy::from_filename;
3use std::collections::HashMap;
4
5/// Indicates that structure can be initialize from environment variables.
6pub trait EnvConfig<T = HashMap<String, String>>: AbstractConfig<T> {
7    /// Load specified env files to environment variables and initialize the structure.
8    ///
9    /// # Arguments
10    /// * `target` - A comma-separated string of env file paths, e.g., ".env,.env.local".
11    ///
12    /// # Errors
13    /// * `Error::LoadFileError` - If any of the specified env files cannot be loaded.
14    fn load(target: Option<String>) -> Result<T, Error>
15    where
16        T: Default,
17        HashMap<String, String>: Into<T>,
18        Self: Sized,
19    {
20        let target = target.or(Some(".env".to_string()));
21
22        if let Some(target) = target {
23            let file_paths: Vec<String> = target
24                .split(',')
25                .map(|s| s.trim().to_string())
26                .filter(|s| !s.is_empty())
27                .collect();
28
29            for file_path in file_paths {
30                if let Err(e) = from_filename(&file_path) {
31                    return Err(Error::LoadFileError {
32                        name: file_path,
33                        source: Some(Box::new(e)),
34                    });
35                }
36            }
37        }
38
39        let mut env_map = HashMap::new();
40        for (key, value) in std::env::vars() {
41            env_map.insert(key, value);
42        }
43
44        Ok(env_map.into())
45    }
46}