use bytes::Bytes;
use core::fmt;
#[derive(Clone, Default)]
pub struct SseEvent {
pub event: Option<String>,
pub data: Option<Bytes>,
pub id: Option<String>,
pub retry: Option<u64>,
}
impl SseEvent {
pub fn new<T: Into<String>>(data: T) -> Self {
Self {
event: None,
data: Some(Bytes::from(data.into())),
id: None,
retry: None,
}
}
pub fn with_event<T: Into<String>>(mut self, event: T) -> Self {
self.event = Some(event.into());
self
}
pub fn with_id<T: Into<String>>(mut self, id: T) -> Self {
self.id = Some(id.into());
self
}
pub fn with_retry(mut self, retry: u64) -> Self {
self.retry = Some(retry);
self
}
pub fn with_data_bytes(mut self, data: Bytes) -> Self {
self.data = Some(data);
self
}
pub fn with_data(mut self, data: String) -> Self {
self.data = Some(Bytes::from(data));
self
}
pub fn to_sse_string(&self) -> String {
self.to_string()
}
pub fn as_bytes(&self) -> Bytes {
Bytes::from(self.to_string())
}
}
impl std::fmt::Display for SseEvent {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
if let Some(retry) = self.retry {
writeln!(f, "retry: {retry}")?;
}
if let Some(id) = &self.id {
writeln!(f, "id: {id}")?;
}
if let Some(event) = &self.event {
writeln!(f, "event: {event}")?;
}
if let Some(data) = &self.data {
match std::str::from_utf8(data) {
Ok(text) => {
for line in text.lines() {
writeln!(f, "data: {line}")?;
}
}
Err(_) => {
writeln!(f, "data: [binary data]")?;
}
}
}
writeln!(f)?; Ok(())
}
}
impl fmt::Debug for SseEvent {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let data_str = self
.data
.as_ref()
.map(|b| String::from_utf8_lossy(b).to_string());
f.debug_struct("SseEvent")
.field("event", &self.event)
.field("data", &data_str)
.field("id", &self.id)
.field("retry", &self.retry)
.finish()
}
}