steer_core/utils/
paths.rs1use std::path::PathBuf;
2
3pub struct AppPaths;
9
10impl AppPaths {
11 pub fn project_dir() -> PathBuf {
13 PathBuf::from(".steer")
14 }
15
16 pub fn project_catalog() -> PathBuf {
18 Self::project_dir().join("catalog.toml")
19 }
20
21 pub fn user_config_dir() -> Option<PathBuf> {
23 directories::ProjectDirs::from("", "", "steer").map(|d| d.config_dir().to_path_buf())
24 }
25
26 pub fn user_data_dir() -> Option<PathBuf> {
28 directories::ProjectDirs::from("", "", "steer").map(|d| d.data_dir().to_path_buf())
29 }
30
31 pub fn user_catalog() -> Option<PathBuf> {
33 Self::user_config_dir().map(|d| d.join("catalog.toml"))
34 }
35
36 pub fn discover_catalogs() -> Vec<PathBuf> {
39 let mut paths = Vec::new();
40 paths.push(Self::project_catalog());
41 if let Some(user_cat) = Self::user_catalog() {
42 paths.push(user_cat);
43 }
44 paths
45 }
46
47 pub fn discover_session_configs() -> Vec<PathBuf> {
49 let mut paths = Vec::new();
50 let project = Self::project_dir().join("session.toml");
52 if project.exists() {
53 paths.push(project);
54 }
55 if let Some(user_cfg) = Self::user_config_dir() {
56 let user = user_cfg.join("session.toml");
57 if user.exists() {
58 paths.push(user);
59 }
60 }
61 paths
62 }
63}
64
65#[cfg(test)]
66mod tests {
67 use super::*;
68
69 #[test]
70 fn project_paths_are_static() {
71 assert_eq!(AppPaths::project_dir(), PathBuf::from(".steer"));
72 assert_eq!(
73 AppPaths::project_catalog(),
74 PathBuf::from(".steer/catalog.toml")
75 );
76 }
77
78 #[test]
79 fn discover_catalogs_order_is_deterministic() {
80 let catalogs = AppPaths::discover_catalogs();
81 assert!(catalogs.len() == 1 || catalogs.len() == 2);
83 assert_eq!(catalogs[0], PathBuf::from(".steer/catalog.toml"));
84 if catalogs.len() == 2 {
85 let expected_user =
86 AppPaths::user_catalog().expect("user catalog path should exist when returned");
87 assert_eq!(catalogs[1], expected_user);
88 }
89 }
90
91 #[test]
92 fn discover_session_configs_order_is_deterministic() {
93 let configs = AppPaths::discover_session_configs();
94 assert!(configs.len() <= 2);
96 if configs.len() == 2 {
97 assert_eq!(configs[0], PathBuf::from(".steer/session.toml"));
99 let expected_user = AppPaths::user_config_dir().unwrap().join("session.toml");
100 assert_eq!(configs[1], expected_user);
101 } else if configs.len() == 1 {
102 let single = &configs[0];
104 let is_project = *single == PathBuf::from(".steer/session.toml");
105 let is_user = AppPaths::user_config_dir()
106 .map(|d| single == &d.join("session.toml"))
107 .unwrap_or(false);
108 assert!(is_project || is_user);
109 }
110 }
111}