use std::path::{Path, PathBuf};
pub(crate) fn resolve(explicit: Option<&Path>) -> Option<PathBuf> {
resolve_from(
explicit,
non_empty_var("XDG_DATA_HOME"),
non_empty_var("HOME"),
)
}
fn resolve_from(
explicit: Option<&Path>,
xdg_data_home: Option<std::ffi::OsString>,
home: Option<std::ffi::OsString>,
) -> Option<PathBuf> {
if let Some(dir) = explicit {
return Some(dir.to_path_buf());
}
if let Some(base) = xdg_data_home {
return Some(Path::new(&base).join("carta"));
}
home.map(|home| Path::new(&home).join(".local").join("share").join("carta"))
}
fn non_empty_var(name: &str) -> Option<std::ffi::OsString> {
std::env::var_os(name).filter(|value| !value.is_empty())
}
#[cfg(test)]
mod tests {
use super::resolve_from;
use std::ffi::OsString;
use std::path::{Path, PathBuf};
fn os(value: &str) -> OsString {
OsString::from(value)
}
#[test]
fn explicit_directory_wins_over_the_environment() {
let chosen = resolve_from(
Some(Path::new("/custom/dir")),
Some(os("/xdg")),
Some(os("/home/user")),
);
assert_eq!(chosen, Some(PathBuf::from("/custom/dir")));
}
#[test]
fn xdg_data_home_is_suffixed_with_the_app_name() {
let chosen = resolve_from(None, Some(os("/xdg")), Some(os("/home/user")));
assert_eq!(chosen, Some(PathBuf::from("/xdg/carta")));
}
#[test]
fn falls_back_to_the_home_data_location() {
let chosen = resolve_from(None, None, Some(os("/home/user")));
assert_eq!(chosen, Some(PathBuf::from("/home/user/.local/share/carta")));
}
#[test]
fn no_directory_when_nothing_is_available() {
assert_eq!(resolve_from(None, None, None), None);
}
}