Skip to main content

rootle_provider/
paths.rs

1//! Linux XDG paths shared by the app, providers and hermetic test sessions.
2//! Use the explicit environment directory when set; otherwise use the XDG
3//! default below the user's home.
4
5use std::path::PathBuf;
6
7fn xdg(var: &str, default: &str) -> Option<PathBuf> {
8    std::env::var_os(var)
9        .filter(|v| !v.is_empty())
10        .map(PathBuf::from)
11        .or_else(|| dirs::home_dir().map(|h| h.join(default)))
12}
13
14/// $XDG_CONFIG_HOME or ~/.config
15pub fn config_dir() -> Option<PathBuf> {
16    xdg("XDG_CONFIG_HOME", ".config")
17}
18
19/// $XDG_CACHE_HOME or ~/.cache
20pub fn cache_dir() -> Option<PathBuf> {
21    xdg("XDG_CACHE_HOME", ".cache")
22}
23
24/// $XDG_STATE_HOME or ~/.local/state
25pub fn state_dir() -> Option<PathBuf> {
26    xdg("XDG_STATE_HOME", ".local/state")
27}
28
29/// $XDG_DATA_HOME or ~/.local/share
30pub fn data_dir() -> Option<PathBuf> {
31    xdg("XDG_DATA_HOME", ".local/share")
32}
33
34#[cfg(test)]
35mod tests {
36    use super::*;
37
38    #[test]
39    fn unset_vars_fall_back_to_xdg_defaults() {
40        // Env-safe: the test binary never sets these (the sandbox
41        // does it per child process, not in-process).
42        for (var, default) in [
43            ("XDG_CONFIG_HOME", ".config"),
44            ("XDG_CACHE_HOME", ".cache"),
45            ("XDG_STATE_HOME", ".local/state"),
46            ("XDG_DATA_HOME", ".local/share"),
47        ] {
48            assert!(
49                std::env::var_os(var).is_none(),
50                "{var} must not leak into tests"
51            );
52            let home = dirs::home_dir().unwrap();
53            assert_eq!(xdg(var, default), Some(home.join(default)));
54        }
55    }
56}