arcly_http/realtime/
sse.rs1use std::convert::Infallible;
13use std::time::Duration;
14
15use axum::response::sse::{Event, KeepAlive, Sse};
16use futures::stream::{BoxStream, Stream, StreamExt};
17use serde::Serialize;
18
19#[derive(Debug, Default, Clone)]
21pub struct SseEvent {
22 event: Option<String>,
23 data: String,
24 id: Option<String>,
25 retry: Option<u64>,
26}
27
28impl SseEvent {
29 pub fn data(mut self, data: impl Into<String>) -> Self {
31 self.data = data.into();
32 self
33 }
34
35 pub fn json_data<T: Serialize>(mut self, value: T) -> Result<Self, serde_json::Error> {
37 self.data = serde_json::to_string(&value)?;
38 Ok(self)
39 }
40
41 pub fn event(mut self, name: impl Into<String>) -> Self {
43 self.event = Some(name.into());
44 self
45 }
46
47 pub fn id(mut self, id: impl Into<String>) -> Self {
49 self.id = Some(id.into());
50 self
51 }
52
53 pub fn retry(mut self, millis: u64) -> Self {
55 self.retry = Some(millis);
56 self
57 }
58
59 fn into_transport(self) -> Event {
61 let mut e = Event::default().data(self.data);
62 if let Some(name) = self.event {
63 e = e.event(name);
64 }
65 if let Some(id) = self.id {
66 e = e.id(id);
67 }
68 if let Some(ms) = self.retry {
69 e = e.retry(Duration::from_millis(ms));
70 }
71 e
72 }
73}
74
75pub struct SseStream {
81 inner: BoxStream<'static, Result<SseEvent, Infallible>>,
82 keep_alive: Duration,
83}
84
85impl SseStream {
86 pub fn new<S>(stream: S) -> Self
89 where
90 S: Stream<Item = Result<SseEvent, Infallible>> + Send + 'static,
91 {
92 Self {
93 inner: stream.boxed(),
94 keep_alive: Duration::from_secs(15),
95 }
96 }
97
98 pub fn keep_alive(mut self, interval: Duration) -> Self {
100 self.keep_alive = interval;
101 self
102 }
103}
104
105impl axum::response::IntoResponse for SseStream {
106 fn into_response(self) -> axum::response::Response {
107 let interval = self.keep_alive;
108 let mapped = self.inner.map(|res| res.map(SseEvent::into_transport));
109 Sse::new(mapped)
110 .keep_alive(KeepAlive::new().interval(interval))
111 .into_response()
112 }
113}