jcm/message/
event.rs

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/// Represents an event [Message] sent by the device.
14#[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    /// Creates a new [Event].
24    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    /// Gets the [MessageType] of the [Event].
33    pub const fn message_type(&self) -> MessageType {
34        MessageType::Event(self.event_type)
35    }
36
37    /// Gets the [EventType] of the [Event].
38    pub const fn event_type(&self) -> EventType {
39        self.event_type
40    }
41
42    /// Sets the [EventType] of the [Event].
43    pub fn set_event_type(&mut self, event_type: EventType) {
44        self.event_type = event_type;
45    }
46
47    /// Builder function that sets the [EventType] of the [Event].
48    pub fn with_event_type(mut self, event_type: EventType) -> Self {
49        self.set_event_type(event_type);
50        self
51    }
52
53    /// Gets the [MessageCode] of the [Event].
54    pub const fn message_code(&self) -> MessageCode {
55        MessageCode::Event(self.event_code)
56    }
57
58    /// Gets the [EventCode] of the [Event].
59    pub const fn event_code(&self) -> EventCode {
60        self.event_code
61    }
62
63    /// Sets the [EventCode] of the [Event].
64    pub fn set_event_code(&mut self, code: EventCode) {
65        self.event_code = code;
66    }
67
68    /// Builder function that sets the [EventCode] of the [Event].
69    pub fn with_event_code(mut self, code: EventCode) -> Self {
70        self.set_event_code(code);
71        self
72    }
73
74    /// Gets a reference to the additional data of the [Event].
75    pub fn additional(&self) -> &[u8] {
76        &self.additional
77    }
78
79    /// Sets the additional data of the [Event].
80    pub fn set_additional(&mut self, additional: &[u8]) {
81        self.additional = additional.into();
82    }
83
84    /// Builder function that sets the additional data of the [Event].
85    pub fn with_additional(mut self, additional: &[u8]) -> Self {
86        self.set_additional(additional);
87        self
88    }
89
90    /// Gets the length of the [Message].
91    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    /// Gets whether the [Event] is empty.
100    pub const fn is_empty(&self) -> bool {
101        self.event_type.is_empty() || self.event_code.is_empty()
102    }
103
104    /// Writes the [Message] to the provided byte buffer.
105    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}