Skip to main content

nms_copilot/
paths.rs

1//! Path resolution for NMS Copilot data files.
2
3use std::path::PathBuf;
4
5/// Base directory for NMS Copilot data: `~/.nms-copilot/`.
6pub fn data_dir() -> PathBuf {
7    dirs::home_dir()
8        .expect("Could not determine home directory")
9        .join(".nms-copilot")
10}
11
12/// Path to the history file: `~/.nms-copilot/history.txt`.
13pub fn history_path() -> PathBuf {
14    data_dir().join("history.txt")
15}
16
17/// Path to the config file: `~/.nms-copilot/config.toml`.
18pub fn config_path() -> PathBuf {
19    data_dir().join("config.toml")
20}
21
22/// Default cache path (legacy): `~/.nms-copilot/galaxy.rkyv`.
23pub fn cache_path() -> PathBuf {
24    data_dir().join("galaxy.rkyv")
25}
26
27/// Per-save cache path: `~/.nms-copilot/<account_dir>/<save_stem>/galaxy.rkyv`.
28///
29/// Derives cache location from the save file path, using the parent directory
30/// name (account) and file stem (no extension) as path components.
31/// For example, `…/st_76561198025707979/save3.hg` becomes
32/// `~/.nms-copilot/st_76561198025707979/save3/galaxy.rkyv`.
33pub fn cache_path_for_save(save_path: &std::path::Path) -> PathBuf {
34    let save_stem = save_path
35        .file_stem()
36        .and_then(|s| s.to_str())
37        .unwrap_or("save");
38    let account_dir = save_path
39        .parent()
40        .and_then(|p| p.file_name())
41        .and_then(|s| s.to_str())
42        .unwrap_or("default");
43    data_dir()
44        .join(account_dir)
45        .join(save_stem)
46        .join("galaxy.rkyv")
47}
48
49/// Ensure the data directory exists.
50pub fn ensure_data_dir() -> std::io::Result<()> {
51    std::fs::create_dir_all(data_dir())
52}
53
54#[cfg(test)]
55mod tests {
56    use super::*;
57
58    #[test]
59    fn test_data_dir_ends_with_nms_copilot() {
60        let dir = data_dir();
61        assert!(dir.ends_with(".nms-copilot"));
62    }
63
64    #[test]
65    fn test_history_path_under_data_dir() {
66        let path = history_path();
67        assert!(path.starts_with(data_dir()));
68        assert_eq!(path.file_name().unwrap(), "history.txt");
69    }
70
71    #[test]
72    fn test_config_path_under_data_dir() {
73        let path = config_path();
74        assert!(path.starts_with(data_dir()));
75        assert_eq!(path.file_name().unwrap(), "config.toml");
76    }
77
78    #[test]
79    fn test_cache_path_under_data_dir() {
80        let path = cache_path();
81        assert!(path.starts_with(data_dir()));
82        assert_eq!(path.file_name().unwrap(), "galaxy.rkyv");
83    }
84
85    #[test]
86    fn test_cache_path_for_save_uses_account_and_stem() {
87        let save = std::path::Path::new("/nms/st_76561198025707979/save3.hg");
88        let path = cache_path_for_save(save);
89        assert!(path.starts_with(data_dir()));
90        assert!(path.ends_with("st_76561198025707979/save3/galaxy.rkyv"));
91    }
92
93    #[test]
94    fn test_cache_path_for_save_slot1_manual() {
95        let save = std::path::Path::new("/nms/st_12345/save.hg");
96        let path = cache_path_for_save(save);
97        assert!(path.ends_with("st_12345/save/galaxy.rkyv"));
98    }
99
100    #[test]
101    fn test_ensure_data_dir_creates_directory() {
102        ensure_data_dir().unwrap();
103        assert!(data_dir().is_dir());
104    }
105}