1pub struct EventBuilder {
2 pending_event: EventBuilderState
3}
4
5#[derive(Debug, PartialEq, Clone)]
7pub struct Event {
8 pub id: String,
10 pub type_: String,
12 pub data: String
14}
15
16#[derive(Debug, PartialEq, Clone)]
17pub enum EventBuilderState {
18 Empty,
19 Pending(Event),
20 Complete(Event)
21}
22
23impl Event {
24 pub fn new(type_: &str, data: &str) -> Event {
25 Event { id: String::from(""), type_: String::from(type_), data: String::from(data) }
26 }
27}
28
29impl EventBuilder {
30 pub fn new() -> EventBuilder {
31 EventBuilder { pending_event: EventBuilderState::Empty }
32 }
33
34 pub fn update(&mut self, message: &str) -> EventBuilderState {
35 if message == "" {
36 self.finalize_event();
37 } else if !message.starts_with(":") && message.contains(":") {
38 self.pending_event = self.update_event(message);
39 }
40
41 self.get_event()
42 }
43
44 fn finalize_event(&mut self) {
45 self.pending_event = match self.pending_event {
46 EventBuilderState::Complete(_) => EventBuilderState::Empty,
47 EventBuilderState::Pending(ref event) => EventBuilderState::Complete(event.clone()),
48 ref e => e.clone()
49 };
50 }
51
52 fn update_event(&mut self, message: &str) -> EventBuilderState {
53 let mut pending_event = match &self.pending_event {
54 EventBuilderState::Pending(ref e) => e.clone(),
55 _ => Event::new("message", "")
56 };
57
58 match parse_field(message) {
59 ("data", value) => pending_event.data = String::from(value),
60 ("event", value) => pending_event.type_ = String::from(value),
61 ("id", value) => pending_event.id = String::from(value),
62 _ => {}
63 }
64
65 EventBuilderState::Pending(pending_event)
66 }
67
68 pub fn clear(&mut self) {
69 self.pending_event = EventBuilderState::Empty;
70 }
71
72 pub fn get_event(&self) -> EventBuilderState {
73 self.pending_event.clone()
74 }
75}
76
77fn parse_field<'a>(message: &'a str) -> (&'a str, &'a str) {
78 let parts: Vec<&str> = message.splitn(2, ":").collect();
79 (parts[0], parts[1].trim())
80}
81
82#[cfg(test)]
83mod tests {
84 use super::*;
85
86 #[test]
87 fn should_start_with_empty_state() {
88 let e = EventBuilder::new();
89
90 assert_eq!(e.get_event(), EventBuilderState::Empty);
91 }
92
93 #[test]
94 fn should_set_message_as_default_event_type() {
95 let mut e = EventBuilder::new();
96 e.update("data: test");
97
98 if let EventBuilderState::Pending(event) = e.get_event() {
99 assert_eq!(event.type_, String::from("message"));
100 } else {
101 panic!("event should be pending");
102 }
103 }
104
105 #[test]
106 fn should_change_status_to_complete_when_empty_message_received() {
107 let mut e = EventBuilder::new();
108 e.update("data: test");
109 e.update("");
110
111 if let EventBuilderState::Complete(event) = e.get_event() {
112 assert_eq!(event.data, String::from("test"));
113 } else {
114 panic!("event should be complete");
115 }
116 }
117
118 #[test]
119 fn should_remain_as_empty_if_empty_message_is_received_while_buffer_is_empty() {
120 let mut e = EventBuilder::new();
121 e.update("");
122
123 assert_eq!(e.get_event(), EventBuilderState::Empty);
124 }
125
126 #[test]
127 fn should_fill_data_field() {
128 let mut e = EventBuilder::new();
129 e.update("data: test");
130
131 if let EventBuilderState::Pending(event) = e.get_event() {
132 assert_eq!(event.data, String::from("test"));
133 } else {
134 panic!("event should be pending");
135 }
136 }
137
138 #[test]
139 fn should_fill_event_type_field() {
140 let mut e = EventBuilder::new();
141 e.update("event: some_event");
142
143 if let EventBuilderState::Pending(event) = e.get_event() {
144 assert_eq!(event.type_, String::from("some_event"));
145 } else {
146 panic!("event should be pending");
147 }
148 }
149
150 #[test]
151 fn should_fill_event_id_field() {
152 let mut e = EventBuilder::new();
153 e.update("id: 123abc");
154
155 if let EventBuilderState::Pending(event) = e.get_event() {
156 assert_eq!(event.id, String::from("123abc"));
157 } else {
158 panic!("event should be pending");
159 }
160 }
161
162 #[test]
163 fn should_incrementally_fill_event_fields() {
164 let expected_event = Event::new("some_event", "test");
165 let mut e = EventBuilder::new();
166 e.update("event: some_event");
167 e.update("data: test");
168
169 if let EventBuilderState::Pending(event) = e.get_event() {
170 assert_eq!(event, expected_event);
171 } else {
172 panic!("event should be pending");
173 }
174 }
175
176 #[test]
177 fn should_change_status_to_empty_when_event_is_complete_and_empty_message_is_received() {
178 let mut e = EventBuilder::new();
179
180 e.update("data: test");
181 e.update("");
182 e.update("");
183
184 assert_eq!(e.get_event(), EventBuilderState::Empty);
185 }
186
187 #[test]
188 fn should_start_clean_event_after_previous_is_completed() {
189 let expected_event = Event::new("message", "test2");
190 let mut e = EventBuilder::new();
191
192 e.update("event: some_event");
193 e.update("data: test");
194 e.update("");
195 e.update("data: test2");
196
197 if let EventBuilderState::Pending(event) = e.get_event() {
198 assert_eq!(event, expected_event);
199 } else {
200 panic!("event should be pending");
201 }
202 }
203
204 #[test]
205 fn should_ignore_updates_started_with_colon() {
206 let expected_event = Event::new("some_event", "test");
207 let mut e = EventBuilder::new();
208
209 e.update("event: some_event");
210 e.update(":some commentary");
211 e.update("data: test");
212
213 if let EventBuilderState::Pending(event) = e.get_event() {
214 assert_eq!(event, expected_event);
215 } else {
216 panic!("event should be pending");
217 }
218 }
219
220 #[test]
221 fn should_return_event_on_update() {
222 let mut e = EventBuilder::new();
223 assert_eq!(e.update("event: some_event"), e.get_event());
224 assert_eq!(e.update("data: test"), e.get_event());
225 }
226
227 #[test]
228 fn should_parse_messages_even_with_colons() {
229 let expected_event = Event::new("some:id:with:colons", "some:data:with:colons");
230 let mut e = EventBuilder::new();
231
232 e.update("event: some:id:with:colons");
233 e.update("data: some:data:with:colons");
234
235 if let EventBuilderState::Pending(event) = e.get_event() {
236 assert_eq!(event, expected_event);
237 } else {
238 panic!("event should be pending");
239 }
240
241 }
242
243 #[test]
244 fn should_be_empty_when_only_comments_received() {
245 let mut e = EventBuilder::new();
246
247 e.update(":hi");
248 e.update("");
249
250 assert_eq!(e.get_event(), EventBuilderState::Empty);
251 }
252
253 #[test]
254 fn should_ignore_messages_without_colon() {
255 let expected_event = Event::new("some_event", "test");
256 let mut e = EventBuilder::new();
257
258 e.update("event: some_event");
259 e.update("this is a random message that should be ignored");
260 e.update("data: test");
261
262 if let EventBuilderState::Pending(event) = e.get_event() {
263 assert_eq!(event, expected_event);
264 } else {
265 panic!("event should be pending");
266 }
267 }
268}