osdp/command/
local_status.rs1use crate::error::Error;
11use crate::payload_util::require_exact_len;
12use alloc::vec::Vec;
13
14macro_rules! empty_status {
15 ($Ty:ident, $code:expr, $name:literal) => {
16 #[doc = concat!("`", $name, "` body (empty).")]
17 #[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
18 pub struct $Ty;
19
20 impl $Ty {
21 pub fn encode(&self) -> Result<Vec<u8>, Error> {
23 Ok(Vec::new())
24 }
25
26 pub fn decode(data: &[u8]) -> Result<Self, Error> {
28 require_exact_len(data, 0, $code)?;
29 Ok(Self)
30 }
31 }
32 };
33}
34
35empty_status!(LocalStatus, 0x64, "osdp_LSTAT");
36empty_status!(InputStatus, 0x65, "osdp_ISTAT");
37empty_status!(OutputStatus, 0x66, "osdp_OSTAT");
38empty_status!(ReaderStatus, 0x67, "osdp_RSTAT");
39
40#[cfg(test)]
41mod tests {
42 use super::*;
43
44 #[test]
45 fn lstat_roundtrip_empty() {
46 assert!(LocalStatus.encode().unwrap().is_empty());
47 assert_eq!(LocalStatus::decode(&[]).unwrap(), LocalStatus);
48 }
49
50 #[test]
51 fn lstat_rejects_payload() {
52 assert!(matches!(
53 LocalStatus::decode(&[0x00]),
54 Err(Error::PayloadLength { code: 0x64, .. })
55 ));
56 }
57
58 #[test]
59 fn istat_rejects_payload() {
60 assert!(matches!(
61 InputStatus::decode(&[0x00]),
62 Err(Error::PayloadLength { code: 0x65, .. })
63 ));
64 }
65
66 #[test]
67 fn ostat_rejects_payload() {
68 assert!(matches!(
69 OutputStatus::decode(&[0x00]),
70 Err(Error::PayloadLength { code: 0x66, .. })
71 ));
72 }
73
74 #[test]
75 fn rstat_rejects_payload() {
76 assert!(matches!(
77 ReaderStatus::decode(&[0x00]),
78 Err(Error::PayloadLength { code: 0x67, .. })
79 ));
80 }
81}