nimbi_protocol/types/
id.rs1use microdot::{deserialize::Deserialize, serialize::Serialize, MicrodotError};
2
3pub const ID_SIZE: usize = 6;
4
5#[cfg_attr(feature = "defmt", derive(defmt::Format))]
6#[derive(Debug, PartialEq, Eq)]
7pub struct Id<'a>(&'a [u8; ID_SIZE]);
8
9impl<'a> Id<'a> {
10 pub fn from_str_unchecked(s: &'a str) -> Self {
11 let id = s.as_bytes()[..6].try_into().unwrap();
12
13 Id(id)
14 }
15}
16
17impl<'a> TryFrom<&'a str> for Id<'a> {
18 type Error = ParseIdError;
19
20 fn try_from(s: &'a str) -> Result<Id<'a>, Self::Error> {
21 let bytes = s.as_bytes();
22
23 if bytes.len() != 6 {
24 return Err(ParseIdError::IvalidLength);
25 }
26
27 let id = bytes.try_into().map_err(|_| ParseIdError::TryFromSlice)?;
28
29 Ok(Id(id))
30 }
31}
32
33#[derive(Debug)]
34pub enum ParseIdError {
35 IvalidLength,
36 TryFromSlice,
37}
38
39impl Serialize for Id<'_> {
40 fn serialize(&self, buf: &mut [u8]) -> Result<usize, MicrodotError> {
41 let bytes = &self.0[..];
42
43 bytes.serialize(buf)
44 }
45}
46
47impl<'a> Deserialize<'a> for Id<'a> {
48 fn deserialize(buf: &'a [u8]) -> Result<Id<'a>, MicrodotError> {
49 if buf.len() < ID_SIZE {
50 return Err(microdot::error::Error::invalid_length());
51 }
52
53 let id = buf[..6].try_into()?;
54
55 Ok(Self(id))
56 }
57}
58
59#[cfg(test)]
60mod tests {
61 use super::*;
62
63 #[test]
64 fn id_should_serialize() {
65 let id = Id(&[1, 1, 1, 1, 1, 1]);
66
67 let mut buf = [0u8; 6];
68
69 match id.serialize(&mut buf) {
70 Ok(bytes_written) => {
71 assert_eq!(bytes_written, 6);
72 assert_eq!(&buf[..], &[1, 1, 1, 1, 1, 1]);
73 }
74 Err(err) => {
75 dbg!(err);
76
77 unreachable!();
78 }
79 }
80 }
81}