1use std::sync::Arc;
4
5use async_trait::async_trait;
6use serde_json::Value;
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10pub enum StepStatus {
11 Ok,
13 Skipped,
15 Error,
17}
18
19impl StepStatus {
20 pub fn as_str(self) -> &'static str {
22 match self {
23 Self::Ok => "ok",
24 Self::Skipped => "skipped",
25 Self::Error => "error",
26 }
27 }
28}
29
30#[derive(Debug, Clone, Copy, PartialEq, Eq)]
32pub enum RunStatus {
33 Ok,
35 Skipped,
37 Error,
39}
40
41impl RunStatus {
42 pub fn as_str(self) -> &'static str {
44 match self {
45 Self::Ok => "ok",
46 Self::Skipped => "skipped",
47 Self::Error => "error",
48 }
49 }
50}
51
52#[async_trait]
54pub trait RunHandle: Send {
55 async fn record_step(
57 &mut self,
58 node_id: &str,
59 node_type: &str,
60 status: StepStatus,
61 exit_reason: Option<&str>,
62 detail: Value,
63 );
64
65 async fn mark_filtered(&mut self, node_id: &str, node_type: &str, reason: &str);
67
68 async fn end(self: Box<Self>, status: RunStatus, exit_reason: Option<&str>);
70}
71
72#[async_trait]
74pub trait RunRecorder: Send + Sync {
75 async fn start(&self, trigger_kind: &str, trigger: Value) -> Box<dyn RunHandle>;
77}
78
79pub struct NoopRecorder;
81
82#[async_trait]
83impl RunRecorder for NoopRecorder {
84 async fn start(&self, _trigger_kind: &str, _trigger: Value) -> Box<dyn RunHandle> {
85 Box::new(NoopHandle)
86 }
87}
88
89struct NoopHandle;
90
91#[async_trait]
92impl RunHandle for NoopHandle {
93 async fn record_step(&mut self, _: &str, _: &str, _: StepStatus, _: Option<&str>, _: Value) {}
94 async fn mark_filtered(&mut self, _: &str, _: &str, _: &str) {}
95 async fn end(self: Box<Self>, _: RunStatus, _: Option<&str>) {}
96}
97
98pub fn noop_recorder() -> Arc<dyn RunRecorder> {
100 Arc::new(NoopRecorder)
101}