cuenv_events/renderers/
json.rs1#![allow(clippy::print_stdout)]
7
8use crate::bus::EventReceiver;
9use crate::event::{CuenvEvent, EventCategory, SystemEvent};
10
11#[derive(Debug, Default)]
13pub struct JsonRenderer {
14 pretty: bool,
16}
17
18impl JsonRenderer {
19 #[must_use]
21 pub const fn new() -> Self {
22 Self { pretty: false }
23 }
24
25 #[must_use]
27 pub const fn pretty() -> Self {
28 Self { pretty: true }
29 }
30
31 pub async fn run(self, mut receiver: EventReceiver) {
36 while let Some(event) = receiver.recv().await {
37 self.render(&event);
38 if matches!(event.category, EventCategory::System(SystemEvent::Shutdown)) {
40 break;
41 }
42 }
43 }
44
45 pub fn render(&self, event: &CuenvEvent) {
47 let json = if self.pretty {
48 serde_json::to_string_pretty(event)
49 } else {
50 serde_json::to_string(event)
51 };
52
53 if let Ok(json) = json {
54 println!("{json}");
55 }
56 }
57
58 #[must_use]
60 pub fn render_to_string(&self, event: &CuenvEvent) -> Option<String> {
61 if self.pretty {
62 serde_json::to_string_pretty(event).ok()
63 } else {
64 serde_json::to_string(event).ok()
65 }
66 }
67}
68
69#[cfg(test)]
70mod tests {
71 use super::*;
72 use crate::event::{EventCategory, EventSource, OutputEvent};
73 use uuid::Uuid;
74
75 fn create_test_event() -> CuenvEvent {
76 CuenvEvent::new(
77 Uuid::nil(),
78 EventSource::new("test::target"),
79 EventCategory::Output(OutputEvent::Stdout {
80 content: "Test message".to_string(),
81 }),
82 )
83 }
84
85 #[test]
86 fn test_json_renderer_new_is_compact() {
87 let renderer = JsonRenderer::new();
88 assert!(!renderer.pretty);
89 }
90
91 #[test]
92 fn test_json_renderer_pretty() {
93 let renderer = JsonRenderer::pretty();
94 assert!(renderer.pretty);
95 }
96
97 #[test]
98 fn test_json_renderer_default_is_compact() {
99 let renderer = JsonRenderer::default();
100 assert!(!renderer.pretty);
101 }
102
103 #[test]
104 fn test_json_renderer_debug() {
105 let renderer = JsonRenderer::new();
106 let debug = format!("{renderer:?}");
107 assert!(debug.contains("JsonRenderer"));
108 assert!(debug.contains("pretty"));
109 }
110
111 #[test]
112 fn test_render_to_string_compact() {
113 let renderer = JsonRenderer::new();
114 let event = create_test_event();
115
116 let json = renderer.render_to_string(&event);
117 assert!(json.is_some());
118
119 let json_str = json.unwrap();
120 assert!(!json_str.contains("\n "));
122 assert!(json_str.contains("\"id\""));
124 assert!(json_str.contains("\"correlation_id\""));
125 assert!(json_str.contains("test::target"));
126 assert!(json_str.contains("Test message"));
127 }
128
129 #[test]
130 fn test_render_to_string_pretty() {
131 let renderer = JsonRenderer::pretty();
132 let event = create_test_event();
133
134 let json = renderer.render_to_string(&event);
135 assert!(json.is_some());
136
137 let json_str = json.unwrap();
138 assert!(json_str.contains('\n'));
140 assert!(json_str.contains(" "));
141 assert!(json_str.contains("\"id\""));
143 assert!(json_str.contains("test::target"));
144 }
145
146 #[test]
147 fn test_render_to_string_is_valid_json() {
148 let renderer = JsonRenderer::new();
149 let event = create_test_event();
150
151 let json_str = renderer.render_to_string(&event).unwrap();
152
153 let parsed: serde_json::Value = serde_json::from_str(&json_str).unwrap();
155 assert!(parsed.is_object());
156 assert!(parsed.get("id").is_some());
157 assert!(parsed.get("timestamp").is_some());
158 assert!(parsed.get("source").is_some());
159 assert!(parsed.get("category").is_some());
160 }
161
162 #[test]
163 fn test_render_to_string_pretty_is_valid_json() {
164 let renderer = JsonRenderer::pretty();
165 let event = create_test_event();
166
167 let json_str = renderer.render_to_string(&event).unwrap();
168
169 let parsed: serde_json::Value = serde_json::from_str(&json_str).unwrap();
171 assert!(parsed.is_object());
172 }
173}