1use std::path::{Path, PathBuf};
2
3use anyhow::{Result, anyhow};
4const APP_DIR: &str = ".mag";
5
6#[derive(Debug, Clone, PartialEq, Eq)]
7pub struct AppPaths {
8 pub home_dir: PathBuf,
9 pub data_root: PathBuf,
10 pub database_path: PathBuf,
11 pub model_root: PathBuf,
12 pub benchmark_root: PathBuf,
13}
14
15pub fn home_dir() -> Result<PathBuf> {
16 std::env::var_os("HOME")
17 .or_else(|| std::env::var_os("USERPROFILE"))
18 .map(PathBuf::from)
19 .ok_or_else(|| anyhow!("neither HOME nor USERPROFILE is set"))
20}
21
22pub fn resolve_app_paths() -> Result<AppPaths> {
23 Ok(app_paths_for_home(&home_dir()?))
24}
25
26fn app_paths_for_home(home: &Path) -> AppPaths {
27 let data_root = home.join(APP_DIR);
28
29 AppPaths {
30 home_dir: home.to_path_buf(),
31 data_root: data_root.clone(),
32 database_path: data_root.join("memory.db"),
33 model_root: data_root.join("models"),
34 benchmark_root: data_root.join("benchmarks"),
35 }
36}
37
38#[cfg(test)]
39mod tests {
40 use super::*;
41
42 #[test]
43 fn uses_mag_root() {
44 let home = std::env::temp_dir().join(format!("mag-paths-{}", uuid::Uuid::new_v4()));
45 let paths = app_paths_for_home(&home);
46 assert_eq!(paths.data_root, home.join(".mag"));
47 assert_eq!(paths.database_path, home.join(".mag/memory.db"));
48 assert_eq!(paths.model_root, home.join(".mag/models"));
49 assert_eq!(paths.benchmark_root, home.join(".mag/benchmarks"));
50 }
51}