use std::path::PathBuf;
#[must_use]
pub fn dir() -> PathBuf {
resolve(|name| std::env::var(name).ok())
}
fn resolve(var: impl Fn(&str) -> Option<String>) -> PathBuf {
let var = |name: &str| var(name).filter(|value| !value.is_empty());
if let Some(set) = var("RUCC_CACHE_DIR") {
return PathBuf::from(set);
}
if cfg!(windows) {
if let Some(local) = var("LOCALAPPDATA") {
return PathBuf::from(local).join("rucc").join("cache");
}
}
if let Some(xdg) = var("XDG_CACHE_HOME") {
return PathBuf::from(xdg).join("rucc");
}
if let Some(home) = var("HOME") {
return PathBuf::from(home).join(".cache").join("rucc");
}
std::env::temp_dir().join("rucc")
}
#[cfg(test)]
mod tests {
use super::resolve;
use std::path::PathBuf;
fn env<'a>(pairs: &'a [(&'a str, &'a str)]) -> impl Fn(&str) -> Option<String> + 'a {
move |name| pairs.iter().find(|(key, _)| *key == name).map(|(_, value)| (*value).to_owned())
}
#[test]
fn the_variable_that_names_it_outright_wins() {
let dir = resolve(env(&[
("RUCC_CACHE_DIR", "/build/cache"),
("XDG_CACHE_HOME", "/home/a/.cache"),
("HOME", "/home/a"),
]));
assert_eq!(dir, PathBuf::from("/build/cache"));
}
#[test]
fn then_the_platforms_own_place_for_a_cache() {
let dir = resolve(env(&[("XDG_CACHE_HOME", "/home/a/.cache"), ("HOME", "/home/a")]));
assert_eq!(dir, PathBuf::from("/home/a/.cache/rucc"));
}
#[test]
#[cfg(windows)]
fn on_windows_it_is_where_a_windows_program_keeps_a_cache() {
let dir = resolve(env(&[("LOCALAPPDATA", r"C:\Users\a\AppData\Local")]));
assert_eq!(dir, PathBuf::from(r"C:\Users\a\AppData\Local\rucc\cache"));
}
#[test]
fn then_the_home_directory() {
let dir = resolve(env(&[("HOME", "/home/a")]));
assert_eq!(dir, PathBuf::from("/home/a/.cache/rucc"));
}
#[test]
fn and_a_machine_with_nothing_set_still_gets_an_answer() {
let dir = resolve(env(&[]));
assert!(dir.ends_with("rucc"), "{}", dir.display());
assert!(dir.is_absolute(), "{}", dir.display());
}
#[test]
fn an_empty_variable_is_not_an_answer() {
let dir = resolve(env(&[("RUCC_CACHE_DIR", ""), ("HOME", "/home/a")]));
assert_eq!(dir, PathBuf::from("/home/a/.cache/rucc"));
}
}