1use std::collections::HashMap;
7use std::path::PathBuf;
8
9use chrono::{DateTime, Utc};
10use serde::{Deserialize, Serialize};
11
12use super::sub_project::SubProject;
13
14#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
19pub struct Workspace {
20 pub metadata: WorkspaceMetadata,
22
23 pub shared_patterns: SharedPatterns,
25
26 pub current_context: CurrentContext,
28
29 pub sub_projects: HashMap<String, SubProject>,
31
32 pub snapshots: Vec<ContextSnapshot>,
34}
35
36#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
38pub struct WorkspaceMetadata {
39 pub name: String,
41
42 pub description: Option<String>,
44
45 pub created_at: DateTime<Utc>,
47
48 pub updated_at: DateTime<Utc>,
50
51 pub version: String,
53
54 pub root_path: PathBuf,
56
57 pub metadata: HashMap<String, String>,
59}
60
61#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
63pub struct SharedPatterns {
64 pub implementation_patterns: Vec<Pattern>,
66
67 pub architecture_patterns: Vec<Pattern>,
69
70 pub methodology_patterns: Vec<Pattern>,
72
73 pub shared_utilities: Vec<SharedUtility>,
75}
76
77#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
79pub struct Pattern {
80 pub name: String,
82
83 pub description: String,
85
86 pub usage_context: String,
88
89 pub examples: Vec<String>,
91
92 pub references: Vec<String>,
94
95 pub tags: Vec<String>,
97}
98
99#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
101pub struct SharedUtility {
102 pub name: String,
104
105 pub description: String,
107
108 pub location: String,
110
111 pub usage: String,
113
114 pub dependencies: Vec<String>,
116}
117
118#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
120pub struct CurrentContext {
121 pub active_sub_project: String,
123
124 pub switched_on: DateTime<Utc>,
126
127 pub switched_by: String,
129
130 pub status: String,
132
133 pub metadata: HashMap<String, String>,
135}
136
137#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
139pub struct ContextSnapshot {
140 pub timestamp: DateTime<Utc>,
142
143 pub description: String,
145
146 pub active_sub_project: String,
148
149 pub workspace_state: WorkspaceMetadata,
151
152 pub sub_project_states: HashMap<String, SubProject>,
154}
155
156impl Workspace {
157 pub fn new(name: String, root_path: PathBuf) -> Self {
159 let now = Utc::now();
160
161 Self {
162 metadata: WorkspaceMetadata {
163 name: name.clone(),
164 description: None,
165 created_at: now,
166 updated_at: now,
167 version: "1.0.0".to_string(),
168 root_path,
169 metadata: HashMap::new(),
170 },
171 shared_patterns: SharedPatterns {
172 implementation_patterns: Vec::new(),
173 architecture_patterns: Vec::new(),
174 methodology_patterns: Vec::new(),
175 shared_utilities: Vec::new(),
176 },
177 current_context: CurrentContext {
178 active_sub_project: String::new(),
179 switched_on: now,
180 switched_by: "system".to_string(),
181 status: "initialized".to_string(),
182 metadata: HashMap::new(),
183 },
184 sub_projects: HashMap::new(),
185 snapshots: Vec::new(),
186 }
187 }
188
189 pub fn add_sub_project(&mut self, name: String, sub_project: SubProject) {
191 self.sub_projects.insert(name, sub_project);
192 self.metadata.updated_at = Utc::now();
193 }
194
195 pub fn switch_context(
197 &mut self,
198 sub_project: String,
199 switched_by: String,
200 ) -> Result<(), String> {
201 if !self.sub_projects.contains_key(&sub_project) {
202 return Err(format!("Sub-project '{sub_project}' not found"));
203 }
204
205 self.current_context = CurrentContext {
206 active_sub_project: sub_project,
207 switched_on: Utc::now(),
208 switched_by,
209 status: "active".to_string(),
210 metadata: HashMap::new(),
211 };
212
213 self.metadata.updated_at = Utc::now();
214 Ok(())
215 }
216
217 pub fn get_active_sub_project(&self) -> Option<&SubProject> {
219 if self.current_context.active_sub_project.is_empty() {
220 return None;
221 }
222 self.sub_projects
223 .get(&self.current_context.active_sub_project)
224 }
225
226 pub fn create_snapshot(&mut self, description: String) {
228 let snapshot = ContextSnapshot {
229 timestamp: Utc::now(),
230 description,
231 active_sub_project: self.current_context.active_sub_project.clone(),
232 workspace_state: self.metadata.clone(),
233 sub_project_states: self.sub_projects.clone(),
234 };
235
236 self.snapshots.push(snapshot);
237 self.metadata.updated_at = Utc::now();
238 }
239}