forge_core_utils/
log_msg.rs1use axum::{extract::ws::Message, response::sse::Event};
2use json_patch::Patch;
3use serde::{Deserialize, Serialize};
4
5pub const EV_STDOUT: &str = "stdout";
6pub const EV_STDERR: &str = "stderr";
7pub const EV_JSON_PATCH: &str = "json_patch";
8pub const EV_SESSION_ID: &str = "session_id";
9pub const EV_FINISHED: &str = "finished";
10
11#[derive(Clone, Debug, Serialize, Deserialize)]
12pub enum LogMsg {
13 Stdout(String),
14 Stderr(String),
15 JsonPatch(Patch),
16 SessionId(String),
17 Finished,
18}
19
20impl LogMsg {
21 pub fn name(&self) -> &'static str {
22 match self {
23 LogMsg::Stdout(_) => EV_STDOUT,
24 LogMsg::Stderr(_) => EV_STDERR,
25 LogMsg::JsonPatch(_) => EV_JSON_PATCH,
26 LogMsg::SessionId(_) => EV_SESSION_ID,
27 LogMsg::Finished => EV_FINISHED,
28 }
29 }
30
31 pub fn to_sse_event(&self) -> Event {
32 match self {
33 LogMsg::Stdout(s) => Event::default().event(EV_STDOUT).data(s.clone()),
34 LogMsg::Stderr(s) => Event::default().event(EV_STDERR).data(s.clone()),
35 LogMsg::JsonPatch(patch) => {
36 let data = serde_json::to_string(patch).unwrap_or_else(|_| "[]".to_string());
37 Event::default().event(EV_JSON_PATCH).data(data)
38 }
39 LogMsg::SessionId(s) => Event::default().event(EV_SESSION_ID).data(s.clone()),
40 LogMsg::Finished => Event::default().event(EV_FINISHED).data(""),
41 }
42 }
43
44 pub fn to_ws_message(&self) -> Result<Message, serde_json::Error> {
46 let json = serde_json::to_string(self)?;
47 Ok(Message::Text(json.into()))
48 }
49
50 pub fn to_ws_message_unchecked(&self) -> Message {
55 let json = match self {
57 LogMsg::Finished => r#"{"finished":true}"#.to_string(),
58 _ => serde_json::to_string(self)
59 .unwrap_or_else(|_| r#"{"error":"serialization_failed"}"#.to_string()),
60 };
61
62 Message::Text(json.into())
63 }
64
65 pub fn approx_bytes(&self) -> usize {
67 const OVERHEAD: usize = 8;
68 match self {
69 LogMsg::Stdout(s) => EV_STDOUT.len() + s.len() + OVERHEAD,
70 LogMsg::Stderr(s) => EV_STDERR.len() + s.len() + OVERHEAD,
71 LogMsg::JsonPatch(patch) => {
72 let json_len = serde_json::to_string(patch).map(|s| s.len()).unwrap_or(2);
73 EV_JSON_PATCH.len() + json_len + OVERHEAD
74 }
75 LogMsg::SessionId(s) => EV_SESSION_ID.len() + s.len() + OVERHEAD,
76 LogMsg::Finished => EV_FINISHED.len() + OVERHEAD,
77 }
78 }
79}