use std::path::{Path, PathBuf};
use anyhow::{Context, Result};
use crate::theme::UserConfig;
pub struct ResolvedConfig {
pub dir: Option<PathBuf>,
pub settings: UserConfig,
}
pub fn resolve_config_dir(cli_override: Option<&Path>) -> Option<PathBuf> {
if let Some(p) = cli_override {
return Some(normalize_dir(p));
}
if let Ok(env_path) = std::env::var("COLORLS_CONFIG") {
if !env_path.trim().is_empty() {
return Some(normalize_dir(Path::new(&env_path)));
}
}
if let Some(d) = dirs::config_dir() {
return Some(d.join("colorls"));
}
if let Ok(home) = std::env::var("HOME") {
if !home.trim().is_empty() {
return Some(PathBuf::from(home).join(".config").join("colorls"));
}
}
None
}
fn normalize_dir(p: &Path) -> PathBuf {
if p.is_file() {
return p
.parent()
.map(Path::to_path_buf)
.unwrap_or_else(|| p.to_path_buf());
}
p.to_path_buf()
}
pub fn load_settings(dir: Option<&Path>) -> Result<UserConfig> {
let Some(dir) = dir else {
return Ok(UserConfig::default());
};
let path = dir.join("config.yaml");
if !path.is_file() {
return Ok(UserConfig::default());
}
let content =
std::fs::read_to_string(&path).with_context(|| format!("reading {}", path.display()))?;
let settings: UserConfig = serde_yaml::from_str(&content)
.with_context(|| format!("parsing {} as YAML", path.display()))?;
Ok(settings)
}
pub fn load(cli_override: Option<&Path>) -> Result<ResolvedConfig> {
let dir = resolve_config_dir(cli_override);
let settings = load_settings(dir.as_deref())?;
Ok(ResolvedConfig { dir, settings })
}