1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
use std::fmt::{self, Write};

use bytes::Bytes;

/// Event Message
///
/// [mdn]: <https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#event_stream_format>
#[derive(Debug, Default)]
pub struct Event {
    id: Option<String>,
    data: Option<String>,
    event: Option<String>,
    retry: Option<u64>,
    comment: Option<String>,
}

impl Event {
    /// The event ID to set the EventSource object's last event ID value.
    pub fn id(mut self, id: impl Into<String>) -> Self {
        self.id.replace(id.into());
        self
    }

    /// The data field for the message.
    pub fn data(mut self, data: impl Into<String>) -> Self {
        self.data.replace(data.into());
        self
    }

    /// A string identifying the type of event described.
    pub fn event(mut self, event: impl Into<String>) -> Self {
        self.event.replace(event.into());
        self
    }

    /// The reconnection time.
    pub fn retry(mut self, retry: u64) -> Self {
        self.retry.replace(retry);
        self
    }

    /// The comment field for the message.
    pub fn comment(mut self, comment: impl Into<String>) -> Self {
        self.comment.replace(comment.into());
        self
    }
}

impl fmt::Display for Event {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        if let Some(comment) = &self.comment {
            ":".fmt(f)?;
            comment.fmt(f)?;
            f.write_char('\n')?;
        }
        if let Some(event) = &self.event {
            "event:".fmt(f)?;
            event.fmt(f)?;
            f.write_char('\n')?;
        }
        if let Some(data) = &self.data {
            for line in data.lines() {
                "data: ".fmt(f)?;
                line.fmt(f)?;
                f.write_char('\n')?;
            }
        }
        if let Some(id) = &self.id {
            "id:".fmt(f)?;
            id.fmt(f)?;
            f.write_char('\n')?;
        }
        if let Some(millis) = self.retry {
            "retry:".fmt(f)?;
            millis.fmt(f)?;
            f.write_char('\n')?;
        }
        f.write_char('\n')
    }
}

impl From<Event> for Bytes {
    fn from(e: Event) -> Self {
        Bytes::from(e.to_string())
    }
}