systemprompt_cloud/paths/
context.rs1use 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}