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.as_ref().map(DiscoveredProject::root)
53 }
54
55 #[must_use]
56 pub fn systemprompt_dir(&self) -> Option<PathBuf> {
57 self.project
58 .as_ref()
59 .map(DiscoveredProject::systemprompt_dir)
60 .map(Path::to_path_buf)
61 }
62
63 #[must_use]
64 pub fn credentials_path(&self) -> PathBuf {
65 if let Some(cloud) = &self.cloud_paths {
66 return cloud.resolve(CloudPath::Credentials);
67 }
68 if let Some(project) = &self.project {
69 return project.credentials_path();
70 }
71 PathBuf::from(dir_names::SYSTEMPROMPT).join(file_names::CREDENTIALS)
72 }
73
74 #[must_use]
75 pub fn tenants_path(&self) -> PathBuf {
76 if let Some(cloud) = &self.cloud_paths {
77 return cloud.resolve(CloudPath::Tenants);
78 }
79 if let Some(project) = &self.project {
80 return project.tenants_path();
81 }
82 PathBuf::from(dir_names::SYSTEMPROMPT).join(file_names::TENANTS)
83 }
84
85 #[must_use]
86 pub fn session_path(&self) -> PathBuf {
87 if let Some(cloud) = &self.cloud_paths {
88 return cloud.resolve(CloudPath::CliSession);
89 }
90 if let Some(project) = &self.project {
91 return project.session_path();
92 }
93 PathBuf::from(dir_names::SYSTEMPROMPT).join(file_names::SESSION)
94 }
95
96 #[must_use]
97 pub fn profiles_dir(&self) -> Option<PathBuf> {
98 self.project.as_ref().map(DiscoveredProject::profiles_dir)
99 }
100
101 #[must_use]
102 pub fn profile_dir(&self, name: &str) -> Option<PathBuf> {
103 self.project.as_ref().map(|p| p.profile_dir(name))
104 }
105
106 #[must_use]
107 pub fn docker_dir(&self) -> Option<PathBuf> {
108 self.project.as_ref().map(DiscoveredProject::docker_dir)
109 }
110
111 #[must_use]
112 pub fn storage_dir(&self) -> Option<PathBuf> {
113 self.project.as_ref().map(DiscoveredProject::storage_dir)
114 }
115
116 #[must_use]
117 pub fn has_credentials(&self) -> bool {
118 self.credentials_path().exists()
119 }
120
121 #[must_use]
122 pub fn has_tenants(&self) -> bool {
123 self.tenants_path().exists()
124 }
125
126 #[must_use]
127 pub fn has_session(&self) -> bool {
128 self.session_path().exists()
129 }
130
131 #[must_use]
132 pub fn has_profile(&self, name: &str) -> bool {
133 self.project.as_ref().is_some_and(|p| p.has_profile(name))
134 }
135
136 #[must_use]
137 pub const fn project(&self) -> Option<&DiscoveredProject> {
138 self.project.as_ref()
139 }
140
141 #[must_use]
142 pub const fn cloud_paths(&self) -> Option<&CloudPaths> {
143 self.cloud_paths.as_ref()
144 }
145}
146
147impl Default for UnifiedContext {
148 fn default() -> Self {
149 Self::discover()
150 }
151}