1use heapless::Vec;
11
12use crate::error::ScllError;
13use crate::limits::AID_MAX;
14
15const AID_MIN: usize = 5;
17
18#[derive(Clone, PartialEq, Eq, Hash)]
20pub struct Aid(Vec<u8, AID_MAX>);
21
22impl core::fmt::Debug for Aid {
23 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
26 write!(f, "Aid({:?})", crate::hexfmt::HexBytes(&self.0))
27 }
28}
29
30impl Aid {
31 pub fn new(bytes: &[u8]) -> Result<Self, ScllError> {
37 if !(AID_MIN..=AID_MAX).contains(&bytes.len()) {
38 return Err(ScllError::InvalidAid { len: bytes.len() });
39 }
40 let mut v = Vec::new();
42 v.extend_from_slice(bytes)
43 .map_err(|()| ScllError::InvalidAid { len: bytes.len() })?;
44 Ok(Self(v))
45 }
46
47 #[must_use]
49 pub fn as_bytes(&self) -> &[u8] {
50 &self.0
51 }
52}
53
54#[cfg(test)]
55mod tests {
56 use super::*;
57 use scll_test_util::HexSlice;
58
59 #[test]
60 fn accepts_every_length_in_range() {
61 for len in AID_MIN..=AID_MAX {
62 let n = u8::try_from(len).expect("len <= AID_MAX fits u8");
63 let raw: heapless::Vec<u8, AID_MAX> = (0..n).collect();
64 let aid = Aid::new(&raw).expect("5..=16 bytes must be accepted");
65 assert_eq!(HexSlice(aid.as_bytes()), HexSlice(&raw));
66 }
67 }
68
69 #[test]
70 fn rejects_too_short() {
71 for len in 0..AID_MIN {
72 let n = u8::try_from(len).expect("len < AID_MIN fits u8");
73 let raw: heapless::Vec<u8, AID_MAX> = (0..n).collect();
74 assert!(
75 matches!(Aid::new(&raw), Err(ScllError::InvalidAid { len: got }) if got == len),
76 "len {len} must be rejected"
77 );
78 }
79 }
80
81 #[test]
82 fn rejects_too_long() {
83 for len in (AID_MAX + 1)..=(AID_MAX + 4) {
84 let raw: [u8; AID_MAX + 4] =
86 core::array::from_fn(|i| u8::try_from(i).expect("index < 20 fits u8"));
87 assert!(
88 matches!(Aid::new(&raw[..len]), Err(ScllError::InvalidAid { len: got }) if got == len),
89 "len {len} must be rejected"
90 );
91 }
92 }
93
94 #[test]
95 fn as_bytes_round_trips_a_realistic_rid() {
96 let raw = [0xA0, 0x00, 0x00, 0x01, 0x51, 0x00, 0x00, 0x00, 0x00];
98 let aid = Aid::new(&raw).unwrap();
99 assert_eq!(HexSlice(aid.as_bytes()), HexSlice(&raw));
100 }
101}