Skip to main content

specfold_core/config/
paths.rs

1//! Locations on the user's machine: home, cache, and `~` expansion.
2
3use std::path::{Path, PathBuf};
4
5pub fn home_dir() -> Option<PathBuf> {
6    std::env::var_os("HOME").or_else(|| std::env::var_os("USERPROFILE")).map(PathBuf::from)
7}
8
9/// The per-user cache directory: `$SPECFOLD_CACHE`, `$XDG_CACHE_HOME`, `%LOCALAPPDATA%`,
10/// `~/Library/Caches` or `~/.cache`.
11pub fn cache_dir() -> Option<PathBuf> {
12    if let Some(p) = std::env::var_os("SPECFOLD_CACHE") {
13        return Some(PathBuf::from(p));
14    }
15    if let Some(p) = std::env::var_os("XDG_CACHE_HOME") {
16        return Some(PathBuf::from(p).join("specfold"));
17    }
18    if cfg!(windows) {
19        return std::env::var_os("LOCALAPPDATA").map(|p| PathBuf::from(p).join("specfold"));
20    }
21    let home = home_dir()?;
22    if cfg!(target_os = "macos") {
23        return Some(home.join("Library/Caches/specfold"));
24    }
25    Some(home.join(".cache/specfold"))
26}
27
28/// Expands `~/` and resolves a relative path against `base`.
29pub fn expand(base: &Path, p: &str) -> PathBuf {
30    if let Some(rest) = p.strip_prefix("~/")
31        && let Some(home) = home_dir()
32    {
33        return home.join(rest);
34    }
35    let path = PathBuf::from(p);
36    if path.is_absolute() { path } else { base.join(path) }
37}