use std::io::Write;
pub struct SseMessage<W: Write>(W);
impl<W: Write> SseMessage<W> {
pub fn new(stream: W) -> Self {
SseMessage(stream)
}
pub fn data(&mut self) -> std::io::Result<SseField<&mut W>> {
SseField::new(&mut self.0, "data")
}
pub fn event(&mut self) -> std::io::Result<SseField<&mut W>> {
SseField::new(&mut self.0, "event")
}
pub fn id(&mut self) -> std::io::Result<SseField<&mut W>> {
SseField::new(&mut self.0, "id")
}
pub fn retry(&mut self) -> std::io::Result<SseField<&mut W>> {
SseField::new(&mut self.0, "retry")
}
pub fn finish(&mut self) -> std::io::Result<()> {
try!(self.0.write(b"\n"));
Ok(())
}
}
impl<W: Write> Drop for SseMessage<W> {
fn drop(&mut self) {
self.finish().is_ok();
self.0.flush().is_ok();
}
}
pub struct SseField<W: Write>(W);
impl<W: Write> SseField<W> {
fn new(mut stream: W, name: &'static str) -> std::io::Result<Self> {
try!(write!(&mut stream, "{}:", name));
Ok(SseField(stream))
}
}
impl<W: Write> Write for SseField<W> {
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> { self.0.write(buf) }
fn flush(&mut self) -> std::io::Result<()> { self.0.flush() }
}
impl<W: Write> Drop for SseField<W> {
fn drop(&mut self) { self.0.write(b"\n").is_ok(); }
}
#[cfg(test)]
mod test {
use super::*;
use std::io::Cursor;
#[test]
fn test_sse_field() {
let mut buf = [0u8; 37];
{
let mut f = SseField::new(&mut buf[..], "hello").unwrap();
write!(f, "a message {}", 1337).unwrap();
write!(f, " another message").unwrap();
}
assert_eq!(&buf[..], &b"hello:a message 1337 another message\n"[..]);
}
#[test]
fn test_sse_msg() {
let mut buf = [0u8; 44];
{
let mut msg = SseMessage::new(&mut buf[..]);
write!(msg.event().unwrap(), "1337").unwrap();
write!(msg.data().unwrap(), "abc").unwrap();
write!(msg.data().unwrap(), "def").unwrap();
write!(msg.id().unwrap(), "42").unwrap();
write!(msg.retry().unwrap(), "7").unwrap();
}
assert_eq!(&buf[..], &b"event:1337\ndata:abc\ndata:def\nid:42\nretry:7\n\n"[..]);
let mut buf = [0u8; 20];
{
let mut c = Cursor::new(&mut buf[..]);
{
let mut msg = SseMessage::new(&mut c);
write!(msg.data().unwrap(), "abc").unwrap();
}
{
let mut msg = SseMessage::new(&mut c);
write!(msg.data().unwrap(), "def").unwrap();
}
}
assert_eq!(&buf[..], &b"data:abc\n\ndata:def\n\n"[..]);
}
#[test]
fn test_finish() {
let mut buf = vec![];
{
let mut msg = SseMessage::new(&mut buf);
write!(msg.data().unwrap(), "abc").unwrap();
msg.finish().unwrap();
write!(msg.data().unwrap(), "123").unwrap();
}
assert_eq!(buf, b"data:abc\n\ndata:123\n\n");
}
}