use std::collections::BTreeMap;
use std::path::Path;
use crate::support::PathNormalizer;
#[derive(Debug, Clone)]
pub struct EnvConfig {
values: BTreeMap<String, String>,
}
impl EnvConfig {
pub fn load(project_root: &str, env_file: &str) -> Self {
let env_path = if PathNormalizer::is_absolute(env_file) {
env_file.to_string()
} else {
PathNormalizer::normalize(&Path::new(project_root).join(env_file).to_string_lossy())
};
if Path::new(&env_path).is_file() {
let _ = dotenvy::from_path_override(&env_path);
}
let mut values = BTreeMap::new();
for (key, value) in std::env::vars() {
values.insert(key, value);
}
Self { values }
}
pub fn get_string(&self, key: &str, default: &str) -> String {
self.values
.get(key)
.map(|value| value.trim().to_string())
.filter(|value| !value.is_empty())
.unwrap_or_else(|| default.to_string())
}
pub fn get_bool(&self, key: &str, default: bool) -> bool {
match self.get_string(key, if default { "true" } else { "false" }).to_ascii_lowercase().as_str() {
"1" | "true" | "yes" | "on" => true,
_ => false,
}
}
pub fn get_csv_array(&self, key: &str, default: Vec<String>) -> Vec<String> {
let raw = self.get_string(key, "");
if raw.is_empty() {
return default;
}
raw.split(',')
.map(|item| item.trim().to_string())
.filter(|item| !item.is_empty())
.collect()
}
}