1use crate::runner::RunResult;
2use chrono::SecondsFormat;
3use serde::Serialize;
4use std::env;
5
6#[derive(Debug, Clone, Serialize)]
8pub struct CompletionEvent {
9 pub tool: String,
11
12 pub status: String,
14
15 pub command: Vec<String>,
17
18 pub cwd: String,
20
21 pub started_at: String,
23
24 pub finished_at: String,
26
27 pub duration_ms: u128,
29
30 pub exit_code: i32,
32
33 pub host: String,
35}
36
37impl CompletionEvent {
38 pub fn from_run(run: &RunResult) -> Self {
40 let cwd = env::current_dir()
41 .map(|path| path.display().to_string())
42 .unwrap_or_else(|_| ".".to_string());
43
44 let host = hostname::get()
45 .ok()
46 .map(|name| name.to_string_lossy().to_string())
47 .filter(|name| !name.is_empty())
48 .unwrap_or_else(|| "unknown-host".to_string());
49
50 Self {
51 tool: "brb".to_string(),
52 status: if run.exit_code == 0 {
53 "success".to_string()
54 } else {
55 "failure".to_string()
56 },
57 command: run.command.clone(),
58 cwd,
59 started_at: run.started_at.to_rfc3339_opts(SecondsFormat::Millis, true),
60 finished_at: run.finished_at.to_rfc3339_opts(SecondsFormat::Millis, true),
61 duration_ms: run.duration.as_millis(),
62 exit_code: run.exit_code,
63 host,
64 }
65 }
66
67 pub fn test_event() -> Self {
69 let run = RunResult {
70 command: vec![
71 "brb".to_string(),
72 "channels".to_string(),
73 "test".to_string(),
74 ],
75 started_at: chrono::Utc::now(),
76 finished_at: chrono::Utc::now(),
77 duration: std::time::Duration::from_millis(1),
78 exit_code: 0,
79 spawn_error: None,
80 };
81 Self::from_run(&run)
82 }
83}