Skip to main content

systemprompt_cloud/paths/
context.rs

1use std::path::{Path, PathBuf};
2
3use super::{CloudPath, CloudPaths, DiscoveredProject};
4use crate::constants::{dir_names, file_names};
5
6#[derive(Debug, Clone)]
7pub struct UnifiedContext {
8    project: Option<DiscoveredProject>,
9    cloud_paths: Option<CloudPaths>,
10}
11
12impl UnifiedContext {
13    #[must_use]
14    pub fn discover() -> Self {
15        let project = DiscoveredProject::discover();
16        Self {
17            project,
18            cloud_paths: None,
19        }
20    }
21
22    #[must_use]
23    pub fn discover_from(start: &Path) -> Self {
24        let project = DiscoveredProject::discover_from(start);
25        Self {
26            project,
27            cloud_paths: None,
28        }
29    }
30
31    pub fn with_profile_paths(
32        mut self,
33        profile_dir: &Path,
34        credentials_path: &str,
35        tenants_path: &str,
36    ) -> Self {
37        self.cloud_paths = Some(CloudPaths::from_config(
38            profile_dir,
39            credentials_path,
40            tenants_path,
41        ));
42        self
43    }
44
45    #[must_use]
46    pub const fn has_project(&self) -> bool {
47        self.project.is_some()
48    }
49
50    #[must_use]
51    pub fn project_root(&self) -> Option<&Path> {
52        self.project
53            .as_ref()
54            .map(DiscoveredProject::root)
55    }
56
57    #[must_use]
58    pub fn systemprompt_dir(&self) -> Option<PathBuf> {
59        self.project
60            .as_ref()
61            .map(DiscoveredProject::systemprompt_dir)
62            .map(Path::to_path_buf)
63    }
64
65    #[must_use]
66    pub fn credentials_path(&self) -> PathBuf {
67        if let Some(cloud) = &self.cloud_paths {
68            return cloud.resolve(CloudPath::Credentials);
69        }
70        if let Some(project) = &self.project {
71            return project.credentials_path();
72        }
73        PathBuf::from(dir_names::SYSTEMPROMPT).join(file_names::CREDENTIALS)
74    }
75
76    #[must_use]
77    pub fn tenants_path(&self) -> PathBuf {
78        if let Some(cloud) = &self.cloud_paths {
79            return cloud.resolve(CloudPath::Tenants);
80        }
81        if let Some(project) = &self.project {
82            return project.tenants_path();
83        }
84        PathBuf::from(dir_names::SYSTEMPROMPT).join(file_names::TENANTS)
85    }
86
87    #[must_use]
88    pub fn session_path(&self) -> PathBuf {
89        if let Some(cloud) = &self.cloud_paths {
90            return cloud.resolve(CloudPath::CliSession);
91        }
92        if let Some(project) = &self.project {
93            return project.session_path();
94        }
95        PathBuf::from(dir_names::SYSTEMPROMPT).join(file_names::SESSION)
96    }
97
98    #[must_use]
99    pub fn profiles_dir(&self) -> Option<PathBuf> {
100        self.project.as_ref().map(DiscoveredProject::profiles_dir)
101    }
102
103    #[must_use]
104    pub fn profile_dir(&self, name: &str) -> Option<PathBuf> {
105        self.project.as_ref().map(|p| p.profile_dir(name))
106    }
107
108    #[must_use]
109    pub fn docker_dir(&self) -> Option<PathBuf> {
110        self.project.as_ref().map(DiscoveredProject::docker_dir)
111    }
112
113    #[must_use]
114    pub fn storage_dir(&self) -> Option<PathBuf> {
115        self.project.as_ref().map(DiscoveredProject::storage_dir)
116    }
117
118    #[must_use]
119    pub fn has_credentials(&self) -> bool {
120        self.credentials_path().exists()
121    }
122
123    #[must_use]
124    pub fn has_tenants(&self) -> bool {
125        self.tenants_path().exists()
126    }
127
128    #[must_use]
129    pub fn has_session(&self) -> bool {
130        self.session_path().exists()
131    }
132
133    #[must_use]
134    pub fn has_profile(&self, name: &str) -> bool {
135        self.project.as_ref().is_some_and(|p| p.has_profile(name))
136    }
137
138    #[must_use]
139    pub const fn project(&self) -> Option<&DiscoveredProject> {
140        self.project.as_ref()
141    }
142
143    #[must_use]
144    pub const fn cloud_paths(&self) -> Option<&CloudPaths> {
145        self.cloud_paths.as_ref()
146    }
147}
148
149impl Default for UnifiedContext {
150    fn default() -> Self {
151        Self::discover()
152    }
153}