Skip to main content

osdp/command/
cap.rs

1//! `osdp_CAP` (`0x62`) — request PD capabilities list.
2//!
3//! # Spec: §6.3
4
5use crate::error::Error;
6use crate::payload_util::require_exact_len;
7use alloc::vec::Vec;
8
9/// `osdp_CAP` body.
10#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
11pub struct Cap {
12    /// Reserved byte; spec mandates `0x00`.
13    pub reserved: u8,
14}
15
16impl Cap {
17    /// Standard request.
18    pub const fn standard() -> Self {
19        Self { reserved: 0 }
20    }
21
22    /// Encode.
23    pub fn encode(&self) -> Result<Vec<u8>, Error> {
24        Ok(alloc::vec![self.reserved])
25    }
26
27    /// Decode.
28    pub fn decode(data: &[u8]) -> Result<Self, Error> {
29        require_exact_len(data, 1, 0x62)?;
30        Ok(Self { reserved: data[0] })
31    }
32}
33
34#[cfg(test)]
35mod tests {
36    use super::*;
37
38    #[test]
39    fn standard_encodes_zero() {
40        assert_eq!(Cap::standard().encode().unwrap(), [0x00]);
41    }
42
43    #[test]
44    fn roundtrip_preserves_reserved() {
45        let body = Cap { reserved: 0x42 };
46        let bytes = body.encode().unwrap();
47        assert_eq!(bytes, [0x42]);
48        assert_eq!(Cap::decode(&bytes).unwrap(), body);
49    }
50
51    #[test]
52    fn decode_rejects_wrong_length() {
53        assert!(matches!(
54            Cap::decode(&[]),
55            Err(Error::PayloadLength { code: 0x62, .. })
56        ));
57        assert!(matches!(
58            Cap::decode(&[0x00, 0x00]),
59            Err(Error::PayloadLength { code: 0x62, .. })
60        ));
61    }
62}