systemprompt_cloud/paths/
context.rs1#![allow(clippy::redundant_closure_for_method_calls)]
2
3use std::path::{Path, PathBuf};
4
5use super::{CloudPath, CloudPaths, DiscoveredProject};
6use crate::constants::{dir_names, file_names};
7
8#[derive(Debug, Clone)]
9pub struct UnifiedContext {
10 project: Option<DiscoveredProject>,
11 cloud_paths: Option<CloudPaths>,
12}
13
14impl UnifiedContext {
15 #[must_use]
16 pub fn discover() -> Self {
17 let project = DiscoveredProject::discover();
18 Self {
19 project,
20 cloud_paths: None,
21 }
22 }
23
24 #[must_use]
25 pub fn discover_from(start: &Path) -> Self {
26 let project = DiscoveredProject::discover_from(start);
27 Self {
28 project,
29 cloud_paths: None,
30 }
31 }
32
33 pub fn with_profile_paths(
34 mut self,
35 profile_dir: &Path,
36 credentials_path: &str,
37 tenants_path: &str,
38 ) -> Self {
39 self.cloud_paths = Some(CloudPaths::from_config(
40 profile_dir,
41 credentials_path,
42 tenants_path,
43 ));
44 self
45 }
46
47 #[must_use]
48 pub fn has_project(&self) -> bool {
49 self.project.is_some()
50 }
51
52 #[must_use]
53 pub fn project_root(&self) -> Option<&Path> {
54 self.project.as_ref().map(|p| p.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(|p| p.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(|p| p.docker_dir())
111 }
112
113 #[must_use]
114 pub fn storage_dir(&self) -> Option<PathBuf> {
115 self.project.as_ref().map(|p| p.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
136 .as_ref()
137 .map(|p| p.has_profile(name))
138 .unwrap_or(false)
139 }
140
141 #[must_use]
142 pub fn project(&self) -> Option<&DiscoveredProject> {
143 self.project.as_ref()
144 }
145
146 #[must_use]
147 pub fn cloud_paths(&self) -> Option<&CloudPaths> {
148 self.cloud_paths.as_ref()
149 }
150}
151
152impl Default for UnifiedContext {
153 fn default() -> Self {
154 Self::discover()
155 }
156}