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