httpmcp_rust/sse/
stream.rs1use actix_web::web::Bytes;
2use serde::Serialize;
3use uuid::Uuid;
4
5#[derive(Debug, Clone)]
7pub struct SseEvent {
8 pub id: Option<String>,
9 pub event: Option<String>,
10 pub data: String,
11}
12
13impl SseEvent {
14 pub fn new(data: impl Into<String>) -> Self {
16 Self {
17 id: Some(Uuid::new_v4().to_string()),
18 event: Some("message".to_string()),
19 data: data.into(),
20 }
21 }
22
23 pub fn with_event(mut self, event: impl Into<String>) -> Self {
25 self.event = Some(event.into());
26 self
27 }
28
29 pub fn from_json<T: Serialize>(data: &T) -> Result<Self, serde_json::Error> {
31 let json = serde_json::to_string(data)?;
32 Ok(Self::new(json))
33 }
34
35 pub fn to_bytes(&self) -> Bytes {
37 let mut output = String::new();
38
39 if let Some(id) = &self.id {
40 output.push_str(&format!("id: {}\n", id));
41 }
42
43 if let Some(event) = &self.event {
44 output.push_str(&format!("event: {}\n", event));
45 }
46
47 output.push_str(&format!("data: {}\n\n", self.data));
48
49 Bytes::from(output)
50 }
51}
52
53#[cfg(test)]
54mod tests {
55 use super::*;
56
57 #[test]
58 fn test_sse_event_format() {
59 let event = SseEvent {
60 id: Some("123".to_string()),
61 event: Some("message".to_string()),
62 data: "test data".to_string(),
63 };
64
65 let bytes = event.to_bytes();
66 let text = String::from_utf8(bytes.to_vec()).unwrap();
67
68 assert!(text.contains("id: 123\n"));
69 assert!(text.contains("event: message\n"));
70 assert!(text.contains("data: test data\n"));
71 }
72}