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