1use std::{fmt, mem};
2
3use crate::{Error, FuncId, MessageType, Result};
4
5mod event_code;
6mod request_code;
7
8pub use event_code::*;
9pub use request_code::*;
10
11const RESERVED: u16 = 0xffff;
12
13#[repr(u16)]
14#[derive(Copy, Clone, Debug, Eq, PartialEq)]
15pub enum MessageCode {
16 Request(RequestCode),
17 Event(EventCode),
18 Reserved = RESERVED,
19}
20
21impl MessageCode {
22 pub const fn new() -> Self {
24 Self::Request(RequestCode::new())
25 }
26
27 pub const fn create(msg_type: MessageType, val: u16) -> Self {
29 match msg_type {
30 MessageType::Request(_ty) => Self::Request(RequestCode::from_u16(val)),
31 MessageType::Event(_ty) => Self::Event(EventCode::from_u16(val)),
32 _ => Self::Reserved,
33 }
34 }
35
36 pub const fn is_request_code(&self) -> bool {
38 matches!(self, Self::Request(_))
39 }
40
41 pub const fn request_code(&self) -> Result<RequestCode> {
43 match self {
44 Self::Request(code) => Ok(*code),
45 _ => Err(Error::InvalidRequestCode(RESERVED)),
46 }
47 }
48
49 pub const fn is_event_code(&self) -> bool {
51 matches!(self, Self::Event(_))
52 }
53
54 pub const fn is_power_up_event(&self) -> bool {
56 matches!(
57 self,
58 Self::Event(EventCode::PowerUp)
59 | Self::Event(EventCode::PowerUpAcceptor)
60 | Self::Event(EventCode::PowerUpStacker)
61 | Self::Event(EventCode::PowerUpAcceptorAccepting)
62 | Self::Event(EventCode::PowerUpStackerAccepting)
63 )
64 }
65
66 pub const fn event_code(&self) -> Result<EventCode> {
68 match self {
69 Self::Event(code) => Ok(*code),
70 _ => Err(Error::InvalidEventCode(RESERVED)),
71 }
72 }
73
74 pub const fn func_id(&self) -> FuncId {
76 match self {
77 Self::Request(code) => code.func_id(),
78 Self::Event(code) => code.func_id(),
79 _ => FuncId::Reserved,
80 }
81 }
82
83 pub fn to_bytes(&self) -> [u8; 2] {
85 u16::from(self).to_le_bytes()
86 }
87
88 pub const fn len() -> usize {
90 mem::size_of::<u16>()
91 }
92
93 pub const fn is_empty(&self) -> bool {
95 matches!(
96 self,
97 Self::Reserved
98 | Self::Request(RequestCode::Reserved)
99 | Self::Event(EventCode::Reserved)
100 )
101 }
102
103 pub const fn is_valid(&self) -> bool {
105 !self.is_empty()
106 }
107}
108
109impl From<MessageCode> for u16 {
110 fn from(val: MessageCode) -> Self {
111 match val {
112 MessageCode::Request(c) => c.into(),
113 MessageCode::Event(c) => c.into(),
114 _ => RESERVED,
115 }
116 }
117}
118
119impl From<&MessageCode> for u16 {
120 fn from(val: &MessageCode) -> Self {
121 (*val).into()
122 }
123}
124
125impl From<MessageCode> for u8 {
126 fn from(val: MessageCode) -> Self {
127 u16::from(val) as u8
128 }
129}
130
131impl From<&MessageCode> for u8 {
132 fn from(val: &MessageCode) -> Self {
133 (*val).into()
134 }
135}
136
137impl TryFrom<RawMessageCode> for MessageCode {
138 type Error = Error;
139
140 fn try_from(val: RawMessageCode) -> Result<Self> {
141 match Self::create(val.msg_type, val.code) {
142 Self::Reserved
143 | Self::Request(RequestCode::Reserved)
144 | Self::Event(EventCode::Reserved) => {
145 Err(Error::InvalidMessageCode((val.msg_type.into(), val.code)))
146 }
147 v => Ok(v),
148 }
149 }
150}
151
152impl Default for MessageCode {
153 fn default() -> Self {
154 Self::new()
155 }
156}
157
158impl fmt::Display for MessageCode {
159 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
160 match self {
161 Self::Request(c) => write!(
162 f,
163 r#"{{"message_type": "request", "code": {c}, "details": {}}}"#,
164 RequestCodeDetails(*c)
165 ),
166 Self::Event(c) => write!(
167 f,
168 r#"{{"message_type": "event", "code": {c}, "details": {}}}"#,
169 EventCodeDetails(*c)
170 ),
171 Self::Reserved => write!(
172 f,
173 r#"{{"message_type": "reserved", "code": {RESERVED:#x}, "details": "reserved"}}"#
174 ),
175 }
176 }
177}
178
179#[repr(C)]
181#[derive(Copy, Clone, Debug, Eq, PartialEq)]
182pub(crate) struct RawMessageCode {
183 pub msg_type: MessageType,
184 pub code: u16,
185}
186
187impl RawMessageCode {
188 pub const fn new() -> Self {
190 Self {
191 msg_type: MessageType::new(),
192 code: 0,
193 }
194 }
195
196 pub const fn create(msg_type: MessageType, code: u16) -> Self {
198 Self { msg_type, code }
199 }
200}
201
202impl Default for RawMessageCode {
203 fn default() -> Self {
204 Self::new()
205 }
206}
207
208#[cfg(test)]
209mod tests {
210 use super::*;
211 use crate::{EventType, RequestType};
212
213 #[test]
214 fn test_message_code() {
215 let req_type = MessageType::Request(RequestType::new());
216 let event_type = MessageType::Event(EventType::new());
217
218 let raw_vals = [
219 RawMessageCode::create(req_type, u16::from(RequestCode::Uid)),
220 RawMessageCode::create(req_type, u16::from(RequestCode::ProgramSignature)),
221 RawMessageCode::create(req_type, u16::from(RequestCode::Version)),
222 RawMessageCode::create(req_type, u16::from(RequestCode::SerialNumber)),
223 RawMessageCode::create(req_type, u16::from(RequestCode::ModelName)),
224 RawMessageCode::create(req_type, u16::from(RequestCode::Status)),
225 RawMessageCode::create(req_type, u16::from(RequestCode::Reset)),
226 RawMessageCode::create(req_type, u16::from(RequestCode::Inhibit)),
227 RawMessageCode::create(req_type, u16::from(RequestCode::Collect)),
228 RawMessageCode::create(req_type, u16::from(RequestCode::Key)),
229 RawMessageCode::create(req_type, u16::from(RequestCode::EventResendInterval)),
230 RawMessageCode::create(req_type, u16::from(RequestCode::Idle)),
231 RawMessageCode::create(req_type, u16::from(RequestCode::Stack)),
232 RawMessageCode::create(req_type, u16::from(RequestCode::Reject)),
233 RawMessageCode::create(req_type, u16::from(RequestCode::Hold)),
234 RawMessageCode::create(req_type, u16::from(RequestCode::AcceptorCollect)),
235 RawMessageCode::create(req_type, u16::from(RequestCode::DenominationDisable)),
236 RawMessageCode::create(req_type, u16::from(RequestCode::DirectionDisable)),
237 RawMessageCode::create(req_type, u16::from(RequestCode::CurrencyAssign)),
238 RawMessageCode::create(req_type, u16::from(RequestCode::CashBoxSize)),
239 RawMessageCode::create(req_type, u16::from(RequestCode::NearFull)),
240 RawMessageCode::create(req_type, u16::from(RequestCode::BarCode)),
241 RawMessageCode::create(req_type, u16::from(RequestCode::Insert)),
242 RawMessageCode::create(req_type, u16::from(RequestCode::ConditionalVend)),
243 RawMessageCode::create(req_type, u16::from(RequestCode::Pause)),
244 RawMessageCode::create(req_type, u16::from(RequestCode::NoteDataInfo)),
245 RawMessageCode::create(req_type, u16::from(RequestCode::RecyclerCollect)),
246 RawMessageCode::create(event_type, u16::from(EventCode::PowerUp)),
247 RawMessageCode::create(event_type, u16::from(EventCode::PowerUpAcceptor)),
248 RawMessageCode::create(event_type, u16::from(EventCode::PowerUpStacker)),
249 RawMessageCode::create(event_type, u16::from(EventCode::Inhibit)),
250 RawMessageCode::create(event_type, u16::from(EventCode::ProgramSignature)),
251 RawMessageCode::create(event_type, u16::from(EventCode::Rejected)),
252 RawMessageCode::create(event_type, u16::from(EventCode::Collected)),
253 RawMessageCode::create(event_type, u16::from(EventCode::Clear)),
254 RawMessageCode::create(event_type, u16::from(EventCode::OperationError)),
255 RawMessageCode::create(event_type, u16::from(EventCode::Failure)),
256 RawMessageCode::create(event_type, u16::from(EventCode::NoteStay)),
257 RawMessageCode::create(event_type, u16::from(EventCode::PowerUpAcceptorAccepting)),
258 RawMessageCode::create(event_type, u16::from(EventCode::PowerUpStackerAccepting)),
259 RawMessageCode::create(event_type, u16::from(EventCode::Idle)),
260 RawMessageCode::create(event_type, u16::from(EventCode::Escrow)),
261 RawMessageCode::create(event_type, u16::from(EventCode::VendValid)),
262 RawMessageCode::create(event_type, u16::from(EventCode::AcceptorRejected)),
263 RawMessageCode::create(event_type, u16::from(EventCode::Returned)),
264 RawMessageCode::create(event_type, u16::from(EventCode::AcceptorCollected)),
265 RawMessageCode::create(event_type, u16::from(EventCode::Insert)),
266 RawMessageCode::create(event_type, u16::from(EventCode::ConditionalVend)),
267 RawMessageCode::create(event_type, u16::from(EventCode::Pause)),
268 RawMessageCode::create(event_type, u16::from(EventCode::Resume)),
269 RawMessageCode::create(event_type, u16::from(EventCode::AcceptorClear)),
270 RawMessageCode::create(event_type, u16::from(EventCode::AcceptorOperationError)),
271 RawMessageCode::create(event_type, u16::from(EventCode::AcceptorFailure)),
272 RawMessageCode::create(event_type, u16::from(EventCode::AcceptorNoteStay)),
273 RawMessageCode::create(event_type, u16::from(EventCode::FunctionAbeyance)),
274 ];
275 let expected = [
276 MessageCode::Request(RequestCode::Uid),
277 MessageCode::Request(RequestCode::ProgramSignature),
278 MessageCode::Request(RequestCode::Version),
279 MessageCode::Request(RequestCode::SerialNumber),
280 MessageCode::Request(RequestCode::ModelName),
281 MessageCode::Request(RequestCode::Status),
282 MessageCode::Request(RequestCode::Reset),
283 MessageCode::Request(RequestCode::Inhibit),
284 MessageCode::Request(RequestCode::Collect),
285 MessageCode::Request(RequestCode::Key),
286 MessageCode::Request(RequestCode::EventResendInterval),
287 MessageCode::Request(RequestCode::Idle),
288 MessageCode::Request(RequestCode::Stack),
289 MessageCode::Request(RequestCode::Reject),
290 MessageCode::Request(RequestCode::Hold),
291 MessageCode::Request(RequestCode::AcceptorCollect),
292 MessageCode::Request(RequestCode::DenominationDisable),
293 MessageCode::Request(RequestCode::DirectionDisable),
294 MessageCode::Request(RequestCode::CurrencyAssign),
295 MessageCode::Request(RequestCode::CashBoxSize),
296 MessageCode::Request(RequestCode::NearFull),
297 MessageCode::Request(RequestCode::BarCode),
298 MessageCode::Request(RequestCode::Insert),
299 MessageCode::Request(RequestCode::ConditionalVend),
300 MessageCode::Request(RequestCode::Pause),
301 MessageCode::Request(RequestCode::NoteDataInfo),
302 MessageCode::Request(RequestCode::RecyclerCollect),
303 MessageCode::Event(EventCode::PowerUp),
304 MessageCode::Event(EventCode::PowerUpAcceptor),
305 MessageCode::Event(EventCode::PowerUpStacker),
306 MessageCode::Event(EventCode::Inhibit),
307 MessageCode::Event(EventCode::ProgramSignature),
308 MessageCode::Event(EventCode::Rejected),
309 MessageCode::Event(EventCode::Collected),
310 MessageCode::Event(EventCode::Clear),
311 MessageCode::Event(EventCode::OperationError),
312 MessageCode::Event(EventCode::Failure),
313 MessageCode::Event(EventCode::NoteStay),
314 MessageCode::Event(EventCode::PowerUpAcceptorAccepting),
315 MessageCode::Event(EventCode::PowerUpStackerAccepting),
316 MessageCode::Event(EventCode::Idle),
317 MessageCode::Event(EventCode::Escrow),
318 MessageCode::Event(EventCode::VendValid),
319 MessageCode::Event(EventCode::AcceptorRejected),
320 MessageCode::Event(EventCode::Returned),
321 MessageCode::Event(EventCode::AcceptorCollected),
322 MessageCode::Event(EventCode::Insert),
323 MessageCode::Event(EventCode::ConditionalVend),
324 MessageCode::Event(EventCode::Pause),
325 MessageCode::Event(EventCode::Resume),
326 MessageCode::Event(EventCode::AcceptorClear),
327 MessageCode::Event(EventCode::AcceptorOperationError),
328 MessageCode::Event(EventCode::AcceptorFailure),
329 MessageCode::Event(EventCode::AcceptorNoteStay),
330 MessageCode::Event(EventCode::FunctionAbeyance),
331 ];
332
333 for (raw, exp) in raw_vals.into_iter().zip(expected.into_iter()) {
334 assert_eq!(MessageCode::try_from(raw), Ok(exp));
335 assert_eq!(u16::from(exp), raw.code);
336
337 assert!(exp.is_valid());
338 assert!(!exp.is_empty());
339
340 if exp.is_request_code() {
341 assert_eq!(exp.request_code(), Ok(RequestCode::from_u16(raw.code)));
342 }
343
344 if exp.is_event_code() {
345 assert_eq!(exp.event_code(), Ok(EventCode::from_u16(raw.code)));
346 }
347 }
348
349 for val in (0..=0x1fffu16).filter(|s| !raw_vals.iter().any(|d| d.code == *s)) {
350 let req_code = RawMessageCode::create(req_type, val);
351 let event_code = RawMessageCode::create(event_type, val);
352
353 assert!(MessageCode::try_from(req_code).is_err());
354 assert!(MessageCode::try_from(event_code).is_err());
355
356 let res_req = MessageCode::create(req_code.msg_type, req_code.code);
357 let res_event = MessageCode::create(event_code.msg_type, event_code.code);
358
359 assert_eq!(res_req, MessageCode::Request(RequestCode::Reserved));
360 assert_eq!(res_event, MessageCode::Event(EventCode::Reserved));
361
362 assert!(res_req.is_empty());
363 assert!(!res_req.is_valid());
364
365 assert!(res_event.is_empty());
366 assert!(!res_event.is_valid());
367 }
368 }
369}