razeri_plugin_api/sinks/
stdout.rs1use async_trait::async_trait;
17
18use crate::error::EventSinkError;
19use crate::event::{EventSink, RazeriEvent};
20
21pub struct StdoutSink;
23
24impl StdoutSink {
25 #[must_use]
27 pub fn new() -> Self {
28 Self
29 }
30}
31
32impl Default for StdoutSink {
33 fn default() -> Self {
34 Self::new()
35 }
36}
37
38#[async_trait]
39impl EventSink for StdoutSink {
40 fn name(&self) -> &'static str {
41 "stdout"
42 }
43
44 async fn on_event(&self, event: &RazeriEvent) -> Result<(), EventSinkError> {
45 let json = serde_json::to_string(event)
46 .map_err(|e| EventSinkError::SinkError(format!("serialization failed: {e}")))?;
47 eprintln!("{json}");
48 Ok(())
49 }
50
51 async fn flush(&self) -> Result<(), EventSinkError> {
52 Ok(())
53 }
54}
55
56#[cfg(test)]
57mod tests {
58 use super::*;
59
60 #[test]
65 fn the_console_sink_is_registered_only_when_asked() {
66 let linked = crate::PluginRegistryBuilder::new().with_auto_discovered().build().events;
67 let names = linked.sink_names();
68 assert!(!names.iter().any(|name| name == "stdout"), "{names:?}");
69 }
70 use crate::event::{RazeriEvent, WorkflowContext};
71 use chrono::Utc;
72
73 fn test_workflow() -> WorkflowContext {
74 WorkflowContext::new("test-wf").unwrap()
75 }
76
77 #[tokio::test]
78 async fn stdout_sink_accepts_events() {
79 let sink = StdoutSink::new();
80 assert_eq!(sink.name(), "stdout");
81
82 let event = RazeriEvent::design_validated(
83 "test-stdout-1",
84 Utc::now(),
85 test_workflow(),
86 "test.yaml",
87 0,
88 0,
89 )
90 .unwrap();
91 let result = sink.on_event(&event).await;
92 assert!(result.is_ok());
93 }
94
95 #[tokio::test]
96 async fn stdout_sink_flush_is_noop() {
97 let sink = StdoutSink::new();
98 assert!(sink.flush().await.is_ok());
99 }
100}