1use crate::packets::CrsfPacket;
2use crate::packets::PacketType;
3use crate::CrsfParsingError;
4use heapless::Vec;
5
6#[derive(Clone, Debug, PartialEq)]
12pub struct Temp {
13 pub temp_source_id: u8,
15 temperatures: Vec<i16, 20>,
17}
18
19impl Temp {
20 pub fn new(temp_source_id: u8, temperatures: &[i16]) -> Result<Self, CrsfParsingError> {
24 if temperatures.len() > 20 {
25 return Err(CrsfParsingError::InvalidPayloadLength);
26 }
27 let mut temps = Vec::new();
28 temps
29 .extend_from_slice(temperatures)
30 .map_err(|_| CrsfParsingError::InvalidPayloadLength)?;
31 Ok(Self {
32 temp_source_id,
33 temperatures: temps,
34 })
35 }
36
37 pub fn temperatures(&self) -> &[i16] {
39 &self.temperatures
40 }
41}
42
43#[cfg(feature = "defmt")]
44impl defmt::Format for Temp {
45 fn format(&self, fmt: defmt::Formatter) {
46 defmt::write!(
47 fmt,
48 "Temp {{ temp_source_id: {}, temperatures: {} }}",
49 self.temp_source_id,
50 self.temperatures(),
51 )
52 }
53}
54
55impl CrsfPacket for Temp {
56 const PACKET_TYPE: PacketType = PacketType::Temp;
57 const MIN_PAYLOAD_SIZE: usize = 3;
58
59 fn to_bytes(&self, buffer: &mut [u8]) -> Result<usize, CrsfParsingError> {
60 let required_len = 1 + self.temperatures.len() * 2;
61 if buffer.len() < required_len {
62 return Err(CrsfParsingError::BufferOverflow);
63 }
64 buffer[0] = self.temp_source_id;
65 let mut i = 1;
66 for &temp in self.temperatures() {
67 let bytes = temp.to_be_bytes();
68 buffer[i..i + 2].copy_from_slice(&bytes);
69 i += 2;
70 }
71 Ok(i)
72 }
73
74 fn from_bytes(data: &[u8]) -> Result<Self, CrsfParsingError> {
75 if data.len() < Self::MIN_PAYLOAD_SIZE {
76 return Err(CrsfParsingError::InvalidPayloadLength);
77 }
78
79 let temp_source_id = data[0];
80 let temperatures: Vec<i16, 20> = data[1..]
81 .chunks_exact(2)
82 .map(|chunk| {
83 let bytes = [chunk[0], chunk[1]];
84 i16::from_be_bytes(bytes)
85 })
86 .collect();
87
88 Ok(Self {
89 temp_source_id,
90 temperatures,
91 })
92 }
93}
94
95#[cfg(test)]
96mod tests {
97 use super::*;
98
99 #[test]
100 fn test_temp_to_bytes() {
101 let temperatures = [250, -50];
102 let temp = Temp::new(1, &temperatures).unwrap();
103
104 let mut buffer = [0u8; 60];
105 let len = temp.to_bytes(&mut buffer).unwrap();
106
107 let expected_bytes: [u8; 5] = [
108 1, 0x00, 0xfa, 0xff, 0xce, ];
112
113 assert_eq!(len, 5);
114 assert_eq!(&buffer[..len], &expected_bytes);
115 }
116
117 #[test]
118 fn test_temp_from_bytes() {
119 let data: [u8; 5] = [
120 1, 0x00, 0xfa, 0xff, 0xce, ];
124
125 let temp = Temp::from_bytes(&data).unwrap();
126
127 let expected_temperatures = [250, -50];
128 assert_eq!(temp.temp_source_id, 1);
129 assert_eq!(temp.temperatures(), &expected_temperatures);
130 }
131
132 #[test]
133 fn test_temp_round_trip() {
134 let temperatures = [1234, -5678];
135 let temp = Temp::new(2, &temperatures).unwrap();
136
137 let mut buffer = [0u8; 60];
138 let len = temp.to_bytes(&mut buffer).unwrap();
139
140 let round_trip_temp = Temp::from_bytes(&buffer[..len]).unwrap();
141
142 assert_eq!(temp, round_trip_temp);
143 }
144
145 #[test]
146 fn test_edge_cases() {
147 let temperatures = [0, 32767, -32768];
148 let temp = Temp::new(3, &temperatures).unwrap();
149
150 let mut buffer = [0u8; 60];
151 let len = temp.to_bytes(&mut buffer).unwrap();
152 let round_trip_temp = Temp::from_bytes(&buffer[..len]).unwrap();
153 assert_eq!(temp, round_trip_temp);
154 }
155}