use std::path::PathBuf;
fn xdg(var: &str, default: &str) -> Option<PathBuf> {
std::env::var_os(var)
.filter(|v| !v.is_empty())
.map(PathBuf::from)
.or_else(|| dirs::home_dir().map(|h| h.join(default)))
}
pub fn config_dir() -> Option<PathBuf> {
xdg("XDG_CONFIG_HOME", ".config")
}
pub fn cache_dir() -> Option<PathBuf> {
xdg("XDG_CACHE_HOME", ".cache")
}
pub fn state_dir() -> Option<PathBuf> {
xdg("XDG_STATE_HOME", ".local/state")
}
pub fn data_dir() -> Option<PathBuf> {
xdg("XDG_DATA_HOME", ".local/share")
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn unset_vars_fall_back_to_xdg_defaults() {
for (var, default) in [
("XDG_CONFIG_HOME", ".config"),
("XDG_CACHE_HOME", ".cache"),
("XDG_STATE_HOME", ".local/state"),
("XDG_DATA_HOME", ".local/share"),
] {
assert!(
std::env::var_os(var).is_none(),
"{var} must not leak into tests"
);
let home = dirs::home_dir().unwrap();
assert_eq!(xdg(var, default), Some(home.join(default)));
}
}
}