Skip to main content

update_kit/platform/
paths.rs

1use std::path::PathBuf;
2
3/// Returns the default cache directory for the current platform.
4///
5/// - Windows: `%LOCALAPPDATA%` or `<home>/AppData/Local`
6/// - Unix: `$XDG_CACHE_HOME` or `<home>/.cache`
7pub fn get_default_cache_dir() -> PathBuf {
8    if cfg!(windows) {
9        if let Ok(val) = std::env::var("LOCALAPPDATA") {
10            return PathBuf::from(val);
11        }
12        if let Some(home) = dirs::home_dir() {
13            return home.join("AppData").join("Local");
14        }
15        PathBuf::from("AppData/Local")
16    } else {
17        if let Ok(val) = std::env::var("XDG_CACHE_HOME") {
18            return PathBuf::from(val);
19        }
20        if let Some(home) = dirs::home_dir() {
21            return home.join(".cache");
22        }
23        PathBuf::from(".cache")
24    }
25}
26
27/// Returns the default config directory for the current platform.
28///
29/// - Windows: `%LOCALAPPDATA%` or `<home>/AppData/Local`
30/// - Unix: `$XDG_CONFIG_HOME` or `<home>/.config`
31pub fn get_default_config_dir() -> PathBuf {
32    if cfg!(windows) {
33        if let Ok(val) = std::env::var("LOCALAPPDATA") {
34            return PathBuf::from(val);
35        }
36        if let Some(home) = dirs::home_dir() {
37            return home.join("AppData").join("Local");
38        }
39        PathBuf::from("AppData/Local")
40    } else {
41        if let Ok(val) = std::env::var("XDG_CONFIG_HOME") {
42            return PathBuf::from(val);
43        }
44        if let Some(home) = dirs::home_dir() {
45            return home.join(".config");
46        }
47        PathBuf::from(".config")
48    }
49}
50
51#[cfg(test)]
52mod tests {
53    use super::*;
54
55    #[test]
56    fn cache_dir_is_non_empty() {
57        let dir = get_default_cache_dir();
58        assert!(
59            !dir.as_os_str().is_empty(),
60            "cache dir should be non-empty"
61        );
62    }
63
64    #[test]
65    fn config_dir_is_non_empty() {
66        let dir = get_default_config_dir();
67        assert!(
68            !dir.as_os_str().is_empty(),
69            "config dir should be non-empty"
70        );
71    }
72
73    #[test]
74    fn cache_dir_contains_cache_segment() {
75        // On unix the path should end with .cache (unless XDG_CACHE_HOME is set)
76        let dir = get_default_cache_dir();
77        let dir_str = dir.to_string_lossy();
78        assert!(
79            dir_str.contains("cache") || dir_str.contains("Cache") || dir_str.contains("Local"),
80            "cache dir should reference a cache location: {dir_str}"
81        );
82    }
83
84    #[test]
85    fn config_dir_contains_config_segment() {
86        let dir = get_default_config_dir();
87        let dir_str = dir.to_string_lossy();
88        assert!(
89            dir_str.contains("config") || dir_str.contains("Config") || dir_str.contains("Local"),
90            "config dir should reference a config location: {dir_str}"
91        );
92    }
93
94    #[cfg(not(windows))]
95    #[test]
96    fn cache_dir_respects_xdg_cache_home() {
97        let original = std::env::var("XDG_CACHE_HOME").ok();
98        std::env::set_var("XDG_CACHE_HOME", "/tmp/test-xdg-cache");
99        let dir = get_default_cache_dir();
100        assert_eq!(dir, PathBuf::from("/tmp/test-xdg-cache"));
101        match original {
102            Some(v) => std::env::set_var("XDG_CACHE_HOME", v),
103            None => std::env::remove_var("XDG_CACHE_HOME"),
104        }
105    }
106
107    #[cfg(not(windows))]
108    #[test]
109    fn config_dir_respects_xdg_config_home() {
110        let original = std::env::var("XDG_CONFIG_HOME").ok();
111        std::env::set_var("XDG_CONFIG_HOME", "/tmp/test-xdg-config");
112        let dir = get_default_config_dir();
113        assert_eq!(dir, PathBuf::from("/tmp/test-xdg-config"));
114        match original {
115            Some(v) => std::env::set_var("XDG_CONFIG_HOME", v),
116            None => std::env::remove_var("XDG_CONFIG_HOME"),
117        }
118    }
119
120    #[test]
121    fn cache_and_config_dirs_are_different() {
122        let cache = get_default_cache_dir();
123        let config = get_default_config_dir();
124        assert!(!cache.as_os_str().is_empty());
125        assert!(!config.as_os_str().is_empty());
126        // On most systems they should be different (unless Windows defaults)
127        if !cfg!(windows) {
128            assert_ne!(cache, config, "Cache and config dirs should differ on Unix");
129        }
130    }
131
132    #[test]
133    fn dirs_are_absolute_or_relative_fallback() {
134        let cache = get_default_cache_dir();
135        let config = get_default_config_dir();
136        // With HOME set, dirs should be absolute. Without HOME, they'd be relative fallbacks.
137        // Just verify they don't panic and return something.
138        let _ = cache.to_string_lossy();
139        let _ = config.to_string_lossy();
140    }
141}