sen66_interface/data/
product_data.rs1use crate::{error::DataError, util::check_deserialization};
2
3#[derive(Clone, Copy)]
5pub struct ProductName(SmallString);
6
7impl TryFrom<&[u8]> for ProductName {
8 type Error = DataError;
9
10 fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
11 Ok(ProductName(value.try_into()?))
12 }
13}
14
15impl ProductName {
16 pub fn get_name_buffer(&self) -> &[u8] {
18 self.0.get_buffer()
19 }
20}
21
22#[cfg(feature = "defmt")]
23impl defmt::Format for ProductName {
24 fn format(&self, f: defmt::Formatter) {
26 defmt::write!(f, "{}", self.0)
27 }
28}
29
30#[derive(Clone, Copy)]
32pub struct SerialNumber(SmallString);
33
34impl SerialNumber {
35 pub fn get_serial_buffer(&self) -> &[u8] {
37 self.0.get_buffer()
38 }
39}
40
41impl TryFrom<&[u8]> for SerialNumber {
42 type Error = DataError;
43
44 fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
45 Ok(SerialNumber(value.try_into()?))
46 }
47}
48
49#[cfg(feature = "defmt")]
50impl defmt::Format for SerialNumber {
51 fn format(&self, f: defmt::Formatter) {
53 defmt::write!(f, "{}", self.0)
54 }
55}
56
57#[derive(Clone, Copy)]
58struct SmallString {
59 name: [u8; 32],
60 len: usize,
61}
62
63impl SmallString {
64 fn get_buffer(&self) -> &[u8] {
65 &self.name[0..self.len]
66 }
67}
68
69impl TryFrom<&[u8]> for SmallString {
70 type Error = DataError;
71
72 fn try_from(data: &[u8]) -> Result<Self, Self::Error> {
73 check_deserialization(data, 48)?;
74 let mut name = [0; 32];
75 let mut len = 0;
76 for (i, &c) in data.iter().enumerate() {
77 if (i + 1) % 3 == 0 {
79 continue;
80 }
81 if !c.is_ascii() {
82 return Err(Self::Error::NotASCIIString);
83 }
84 name[len] = c;
85 len += 1;
86 if c == 0x00 {
87 break;
88 }
89 }
90
91 Ok(Self { name, len })
92 }
93}
94
95#[cfg(feature = "defmt")]
96impl defmt::Format for SmallString {
97 fn format(&self, f: defmt::Formatter) {
99 let output = unsafe { core::str::from_utf8_unchecked(&self.name[0..self.len]) };
102 defmt::write!(f, "{}", output)
103 }
104}