use std::path::{Path, PathBuf};
pub const FALLBACK_CACHE_DIR: &str = ".flowmark-cache";
pub const TEMP_FALLBACK_CACHE_DIR: &str = "flowmark-cache";
pub const APP_CACHE_DIR: &str = "flowmark";
pub const INCREMENTAL_CACHE_SUBDIR: &str = "incremental";
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CacheRootSource {
OsCacheDir,
HomeFallback,
TempFallback,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct CacheRootResolution {
pub path: PathBuf,
pub source: CacheRootSource,
}
pub fn resolve_default_cache_root() -> CacheRootResolution {
let temp_dir = std::env::temp_dir();
resolve_default_cache_root_with(dirs::cache_dir(), dirs::home_dir(), &temp_dir)
}
pub fn default_cache_root() -> PathBuf {
resolve_default_cache_root().path
}
fn resolve_default_cache_root_with(
os_cache: Option<PathBuf>,
home: Option<PathBuf>,
temp_dir: &Path,
) -> CacheRootResolution {
if let Some(cache_dir) = os_cache {
return CacheRootResolution {
path: cache_dir.join(APP_CACHE_DIR),
source: CacheRootSource::OsCacheDir,
};
}
if let Some(home_dir) = home {
return CacheRootResolution {
path: home_dir.join(FALLBACK_CACHE_DIR).join(APP_CACHE_DIR),
source: CacheRootSource::HomeFallback,
};
}
CacheRootResolution {
path: temp_dir.join(TEMP_FALLBACK_CACHE_DIR).join(APP_CACHE_DIR),
source: CacheRootSource::TempFallback,
}
}
#[cfg(test)]
mod tests {
use super::{
APP_CACHE_DIR, CacheRootSource, FALLBACK_CACHE_DIR, TEMP_FALLBACK_CACHE_DIR,
resolve_default_cache_root_with,
};
use std::path::{Path, PathBuf};
#[test]
fn default_cache_root_prefers_os_cache_dir() {
let resolution = resolve_default_cache_root_with(
Some(PathBuf::from("/os-cache")),
Some(PathBuf::from("/home")),
Path::new("/tmp"),
);
assert_eq!(resolution.source, CacheRootSource::OsCacheDir);
assert_eq!(resolution.path, PathBuf::from("/os-cache").join(APP_CACHE_DIR));
}
#[test]
fn default_cache_root_uses_home_fallback_when_os_cache_missing() {
let resolution = resolve_default_cache_root_with(
None,
Some(PathBuf::from("/home/user")),
Path::new("/tmp"),
);
assert_eq!(resolution.source, CacheRootSource::HomeFallback);
assert_eq!(
resolution.path,
PathBuf::from("/home/user").join(FALLBACK_CACHE_DIR).join(APP_CACHE_DIR)
);
}
#[test]
fn default_cache_root_uses_temp_fallback_when_os_and_home_missing() {
let resolution = resolve_default_cache_root_with(None, None, Path::new("/tmp"));
assert_eq!(resolution.source, CacheRootSource::TempFallback);
assert_eq!(
resolution.path,
PathBuf::from("/tmp").join(TEMP_FALLBACK_CACHE_DIR).join(APP_CACHE_DIR)
);
}
}