1use std::fmt;
2
3use crate::{Error, EventCode, EventType, Message, MessageCode, MessageData, MessageType, Result};
4
5mod escrow_event;
6mod inhibit_event;
7mod rejected_event;
8
9pub use escrow_event::*;
10pub use inhibit_event::*;
11pub use rejected_event::*;
12
13#[repr(C)]
15#[derive(Clone, Debug, Eq, PartialEq)]
16pub struct Event {
17 event_type: EventType,
18 event_code: EventCode,
19 additional: Vec<u8>,
20}
21
22impl Event {
23 pub const fn new() -> Self {
25 Self {
26 event_type: EventType::new(),
27 event_code: EventCode::new(),
28 additional: Vec::new(),
29 }
30 }
31
32 pub const fn message_type(&self) -> MessageType {
34 MessageType::Event(self.event_type)
35 }
36
37 pub const fn event_type(&self) -> EventType {
39 self.event_type
40 }
41
42 pub fn set_event_type(&mut self, event_type: EventType) {
44 self.event_type = event_type;
45 }
46
47 pub fn with_event_type(mut self, event_type: EventType) -> Self {
49 self.set_event_type(event_type);
50 self
51 }
52
53 pub const fn message_code(&self) -> MessageCode {
55 MessageCode::Event(self.event_code)
56 }
57
58 pub const fn event_code(&self) -> EventCode {
60 self.event_code
61 }
62
63 pub fn set_event_code(&mut self, code: EventCode) {
65 self.event_code = code;
66 }
67
68 pub fn with_event_code(mut self, code: EventCode) -> Self {
70 self.set_event_code(code);
71 self
72 }
73
74 pub fn additional(&self) -> &[u8] {
76 &self.additional
77 }
78
79 pub fn set_additional(&mut self, additional: &[u8]) {
81 self.additional = additional.into();
82 }
83
84 pub fn with_additional(mut self, additional: &[u8]) -> Self {
86 self.set_additional(additional);
87 self
88 }
89
90 pub fn len(&self) -> usize {
92 Self::meta_len() + self.additional.len()
93 }
94
95 pub(crate) const fn meta_len() -> usize {
96 EventType::len() + EventCode::len()
97 }
98
99 pub const fn is_empty(&self) -> bool {
101 self.event_type.is_empty() || self.event_code.is_empty()
102 }
103
104 pub fn to_bytes(&self, buf: &mut [u8]) -> Result<()> {
106 let len = self.len();
107 let buf_len = buf.len();
108
109 if buf_len < len {
110 Err(Error::InvalidMessageLen((buf_len, len)))
111 } else {
112 let msg_iter = [self.event_type.to_u8()]
113 .into_iter()
114 .chain(self.event_code.to_bytes())
115 .chain(self.additional.iter().cloned());
116
117 buf.iter_mut()
118 .take(len)
119 .zip(msg_iter)
120 .for_each(|(dst, src)| *dst = src);
121
122 Ok(())
123 }
124 }
125}
126
127impl TryFrom<&[u8]> for Event {
128 type Error = Error;
129
130 fn try_from(val: &[u8]) -> Result<Self> {
131 let meta_len = Self::meta_len();
132 let len = val.len();
133
134 match len {
135 l if l < meta_len => Err(Error::InvalidEventLen((len, meta_len))),
136 l if l == meta_len => Ok(Self {
137 event_type: val[0].try_into()?,
138 event_code: val[EventType::len()..].try_into()?,
139 additional: Vec::new(),
140 }),
141 _ => Ok(Self {
142 event_type: val[0].try_into()?,
143 event_code: val[EventType::len()..].try_into()?,
144 additional: val[Self::meta_len()..].into(),
145 }),
146 }
147 }
148}
149
150impl TryFrom<&Message> for Event {
151 type Error = Error;
152
153 fn try_from(val: &Message) -> Result<Self> {
154 Ok(Self {
155 event_type: val.data().message_type().event_type()?,
156 event_code: val.data().message_code().event_code()?,
157 additional: val.data().additional().into(),
158 })
159 }
160}
161
162impl TryFrom<Message> for Event {
163 type Error = Error;
164
165 fn try_from(val: Message) -> Result<Self> {
166 (&val).try_into()
167 }
168}
169
170impl From<&Event> for Message {
171 fn from(val: &Event) -> Self {
172 Self::new().with_data(
173 MessageData::new()
174 .with_message_type(val.message_type())
175 .with_message_code(val.message_code())
176 .with_additional(val.additional()),
177 )
178 }
179}
180
181impl From<Event> for Message {
182 fn from(val: Event) -> Self {
183 (&val).into()
184 }
185}
186
187impl Default for Event {
188 fn default() -> Self {
189 Self::new()
190 }
191}
192
193impl fmt::Display for Event {
194 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
195 write!(f, "{{")?;
196 write!(f, r#""event_type":{}, "#, self.event_type)?;
197 write!(f, r#""event_code":{}, "#, self.event_code)?;
198 write!(f, r#""additional_data": ["#)?;
199
200 for (i, d) in self.additional.iter().enumerate() {
201 if i != 0 {
202 write!(f, ",")?;
203 }
204 write!(f, "{d}")?;
205 }
206
207 write!(f, "]}}")
208 }
209}
210
211#[cfg(test)]
212mod tests {
213 use super::*;
214
215 #[test]
216 fn test_event() {
217 let type_bytes = EventType::Sequence0.to_u8();
218 let code_bytes = EventCode::PowerUp.to_bytes();
219
220 let raw = [type_bytes, code_bytes[0], code_bytes[1]];
221
222 let msg = Message::new().with_data(
223 MessageData::new()
224 .with_message_type(MessageType::Event(EventType::Sequence0))
225 .with_message_code(MessageCode::Event(EventCode::PowerUp)),
226 );
227
228 let exp = Event::new()
229 .with_event_type(EventType::Sequence0)
230 .with_event_code(EventCode::PowerUp);
231
232 assert_eq!(Event::try_from(raw.as_ref()), Ok(exp.clone()));
233 assert_eq!(Event::try_from(&msg), Ok(exp.clone()));
234 assert_eq!(Event::try_from(msg), Ok(exp.clone()));
235
236 let mut out = [0u8; Event::meta_len()];
237 assert_eq!(exp.to_bytes(out.as_mut()), Ok(()));
238 assert_eq!(out, raw);
239 }
240
241 #[test]
242 fn test_event_with_data() {
243 let type_bytes = EventType::Sequence0.to_u8();
244 let code_bytes = EventCode::Escrow.to_bytes();
245
246 let raw = [
247 type_bytes,
248 code_bytes[0],
249 code_bytes[1],
250 b'U',
251 b'S',
252 b'D',
253 0x64,
254 0x00,
255 ];
256
257 let msg = Message::new().with_data(
258 MessageData::new()
259 .with_message_type(MessageType::Event(EventType::Sequence0))
260 .with_message_code(MessageCode::Event(EventCode::Escrow))
261 .with_additional(raw[Event::meta_len()..].as_ref()),
262 );
263
264 let exp = Event::new()
265 .with_event_type(EventType::Sequence0)
266 .with_event_code(EventCode::Escrow)
267 .with_additional(raw[Event::meta_len()..].as_ref());
268
269 assert_eq!(Event::try_from(raw.as_ref()), Ok(exp.clone()));
270 assert_eq!(Event::try_from(&msg), Ok(exp.clone()));
271 assert_eq!(Event::try_from(msg), Ok(exp.clone()));
272
273 let mut out = [0u8; 8];
274 assert_eq!(exp.to_bytes(out.as_mut()), Ok(()));
275 assert_eq!(out, raw);
276 }
277}