1use crate::error::Error;
9use crate::payload_util::require_at_least;
10use alloc::vec::Vec;
11
12#[derive(Debug, Clone, PartialEq, Eq)]
14pub struct Xrd {
15 pub mode: u8,
17 pub payload: Vec<u8>,
19}
20
21impl Xrd {
22 pub fn encode(&self) -> Result<Vec<u8>, Error> {
24 let mut out = Vec::with_capacity(1 + self.payload.len());
25 out.push(self.mode);
26 out.extend_from_slice(&self.payload);
27 Ok(out)
28 }
29
30 pub fn decode(data: &[u8]) -> Result<Self, Error> {
32 require_at_least(data, 1, 0xB1)?;
33 Ok(Self {
34 mode: data[0],
35 payload: data[1..].to_vec(),
36 })
37 }
38}
39
40#[cfg(test)]
41mod tests {
42 use super::*;
43
44 #[test]
45 fn roundtrip() {
46 let body = Xrd {
47 mode: 0x01,
48 payload: alloc::vec![0xCA, 0xFE],
49 };
50 let bytes = body.encode().unwrap();
51 assert_eq!(bytes, [0x01, 0xCA, 0xFE]);
52 assert_eq!(Xrd::decode(&bytes).unwrap(), body);
53 }
54
55 #[test]
56 fn mode_only_is_valid() {
57 let body = Xrd {
58 mode: 0x00,
59 payload: Vec::new(),
60 };
61 let bytes = body.encode().unwrap();
62 assert_eq!(bytes, [0x00]);
63 assert_eq!(Xrd::decode(&bytes).unwrap(), body);
64 }
65
66 #[test]
67 fn empty_decode_rejected() {
68 assert!(matches!(
69 Xrd::decode(&[]),
70 Err(Error::PayloadTooShort { code: 0xB1, .. })
71 ));
72 }
73}