1use serde::{Deserialize, Serialize};
7
8#[derive(Debug, Clone, Serialize, Deserialize)]
12#[serde(tag = "type")]
13pub enum SystemEvent {
14 #[serde(rename = "file_saved")]
16 FileSaved(FileSavedEvent),
17
18 #[serde(rename = "test_passed")]
20 TestPassed(TestPassedEvent),
21
22 #[serde(rename = "test_failed")]
24 TestFailed(TestFailedEvent),
25
26 #[serde(rename = "generation_complete")]
28 GenerationComplete(GenerationCompleteEvent),
29
30 #[serde(rename = "refactoring_complete")]
32 RefactoringComplete(RefactoringCompleteEvent),
33
34 #[serde(rename = "review_complete")]
36 ReviewComplete(ReviewCompleteEvent),
37
38 #[serde(rename = "build_success")]
40 BuildSuccess(BuildSuccessEvent),
41
42 #[serde(rename = "build_failed")]
44 BuildFailedEvent(BuildFailedEvent),
45
46 #[serde(rename = "deployment_complete")]
48 DeploymentComplete(DeploymentCompleteEvent),
49
50 #[serde(rename = "custom")]
52 Custom(CustomEvent),
53}
54
55#[derive(Debug, Clone, Serialize, Deserialize)]
59pub struct FileSavedEvent {
60 pub file_path: String,
62
63 pub size: u64,
65
66 pub hash: String,
68
69 pub timestamp: String,
71
72 pub language: Option<String>,
74}
75
76#[derive(Debug, Clone, Serialize, Deserialize)]
80pub struct TestPassedEvent {
81 pub test_name: String,
83
84 pub duration_ms: u64,
86
87 pub assertions_passed: u32,
89
90 pub timestamp: String,
92}
93
94#[derive(Debug, Clone, Serialize, Deserialize)]
98pub struct TestFailedEvent {
99 pub test_name: String,
101
102 pub duration_ms: u64,
104
105 pub assertions_failed: u32,
107
108 pub error_message: String,
110
111 pub timestamp: String,
113}
114
115#[derive(Debug, Clone, Serialize, Deserialize)]
119pub struct GenerationCompleteEvent {
120 pub spec_path: String,
122
123 pub output_dir: String,
125
126 pub files_generated: u32,
128
129 pub duration_ms: u64,
131
132 pub timestamp: String,
134}
135
136#[derive(Debug, Clone, Serialize, Deserialize)]
140pub struct RefactoringCompleteEvent {
141 pub file_path: String,
143
144 pub changes_made: u32,
146
147 pub duration_ms: u64,
149
150 pub timestamp: String,
152}
153
154#[derive(Debug, Clone, Serialize, Deserialize)]
158pub struct ReviewCompleteEvent {
159 pub file_path: String,
161
162 pub issues_found: u32,
164
165 pub severity: String,
167
168 pub duration_ms: u64,
170
171 pub timestamp: String,
173}
174
175#[derive(Debug, Clone, Serialize, Deserialize)]
179pub struct BuildSuccessEvent {
180 pub target: String,
182
183 pub duration_ms: u64,
185
186 pub artifacts: Vec<String>,
188
189 pub timestamp: String,
191}
192
193#[derive(Debug, Clone, Serialize, Deserialize)]
197pub struct BuildFailedEvent {
198 pub target: String,
200
201 pub duration_ms: u64,
203
204 pub error_message: String,
206
207 pub timestamp: String,
209}
210
211#[derive(Debug, Clone, Serialize, Deserialize)]
215pub struct DeploymentCompleteEvent {
216 pub target: String,
218
219 pub environment: String,
221
222 pub duration_ms: u64,
224
225 pub timestamp: String,
227}
228
229#[derive(Debug, Clone, Serialize, Deserialize)]
233pub struct CustomEvent {
234 pub name: String,
236
237 pub data: serde_json::Value,
239
240 pub timestamp: String,
242}
243
244impl SystemEvent {
245 pub fn event_type(&self) -> &'static str {
247 match self {
248 SystemEvent::FileSaved(_) => "file_saved",
249 SystemEvent::TestPassed(_) => "test_passed",
250 SystemEvent::TestFailed(_) => "test_failed",
251 SystemEvent::GenerationComplete(_) => "generation_complete",
252 SystemEvent::RefactoringComplete(_) => "refactoring_complete",
253 SystemEvent::ReviewComplete(_) => "review_complete",
254 SystemEvent::BuildSuccess(_) => "build_success",
255 SystemEvent::BuildFailedEvent(_) => "build_failed",
256 SystemEvent::DeploymentComplete(_) => "deployment_complete",
257 SystemEvent::Custom(_) => "custom",
258 }
259 }
260
261 pub fn to_event_context(&self) -> crate::types::EventContext {
263 crate::types::EventContext {
264 data: serde_json::to_value(self).unwrap_or(serde_json::json!({})),
265 metadata: serde_json::json!({
266 "event_type": self.event_type(),
267 "timestamp": chrono::Utc::now().to_rfc3339(),
268 }),
269 }
270 }
271}
272
273#[cfg(test)]
274mod tests {
275 use super::*;
276
277 #[test]
278 fn test_file_saved_event() {
279 let event = FileSavedEvent {
280 file_path: "/path/to/file.rs".to_string(),
281 size: 1024,
282 hash: "abc123".to_string(),
283 timestamp: "2024-01-01T12:00:00Z".to_string(),
284 language: Some("rust".to_string()),
285 };
286
287 assert_eq!(event.file_path, "/path/to/file.rs");
288 assert_eq!(event.size, 1024);
289 }
290
291 #[test]
292 fn test_test_passed_event() {
293 let event = TestPassedEvent {
294 test_name: "test_example".to_string(),
295 duration_ms: 100,
296 assertions_passed: 5,
297 timestamp: "2024-01-01T12:00:00Z".to_string(),
298 };
299
300 assert_eq!(event.test_name, "test_example");
301 assert_eq!(event.duration_ms, 100);
302 }
303
304 #[test]
305 fn test_system_event_type() {
306 let event = SystemEvent::FileSaved(FileSavedEvent {
307 file_path: "/path/to/file.rs".to_string(),
308 size: 1024,
309 hash: "abc123".to_string(),
310 timestamp: "2024-01-01T12:00:00Z".to_string(),
311 language: Some("rust".to_string()),
312 });
313
314 assert_eq!(event.event_type(), "file_saved");
315 }
316
317 #[test]
318 fn test_custom_event() {
319 let event = SystemEvent::Custom(CustomEvent {
320 name: "my_event".to_string(),
321 data: serde_json::json!({"key": "value"}),
322 timestamp: "2024-01-01T12:00:00Z".to_string(),
323 });
324
325 assert_eq!(event.event_type(), "custom");
326 }
327
328 #[test]
329 fn test_event_serialization() {
330 let event = SystemEvent::FileSaved(FileSavedEvent {
331 file_path: "/path/to/file.rs".to_string(),
332 size: 1024,
333 hash: "abc123".to_string(),
334 timestamp: "2024-01-01T12:00:00Z".to_string(),
335 language: Some("rust".to_string()),
336 });
337
338 let json = serde_json::to_string(&event).unwrap();
339 assert!(json.contains("file_saved"));
340 assert!(json.contains("/path/to/file.rs"));
341 }
342}