use arrayvec::ArrayString; #[derive(Debug, PartialEq, Eq, Clone)] pub struct Identification { pub icon: u16, pub callsign: ArrayString<252>, pub ssid: u8, } impl Identification { pub fn new(icon: u16, call: &str, ssid: u8) -> Option<Self> { let callsign = ArrayString::from(call).ok()?; Some(Self { icon, callsign, ssid, }) } /// Returns none if there is not enough space in the buffer pub fn encode<'a>(&self, buf: &'a mut [u8]) -> Option<&'a [u8]> { // safe to unwrap because we know the length is <= 252 let len: u8 = self.callsign.as_bytes().len().try_into().unwrap(); *buf.get_mut(0)? = len + 3; buf.get_mut(1..3)?.copy_from_slice(&self.icon.to_le_bytes()); let mut len = 3; for (i, b) in self.callsign.as_bytes().iter().enumerate() { *buf.get_mut(i + 3)? = *b; len += 1 } *buf.get_mut(len)? = self.ssid; len += 1; Some(&buf[0..len]) } pub fn decode(data: &[u8]) -> Option<Self> { let len = (*data.first()?).into(); let icon = u16::from_le_bytes([*data.get(1)?, *data.get(2)?]); let callsign = core::str::from_utf8(data.get(3..len)?).ok()?; let callsign = ArrayString::from(callsign).ok()?; let ssid = *data.get(len)?; Some(Self { icon, callsign, ssid, }) } }