1use super::data_information::{self};
2use super::{DataRecords, LongTplHeader};
3
4#[cfg_attr(feature = "serde", derive(serde::Serialize))]
5#[derive(Debug, Clone, Copy, PartialEq)]
6#[cfg_attr(feature = "defmt", derive(defmt::Format))]
7#[non_exhaustive]
8pub enum DataRecordError {
9 DataInformationError(data_information::DataInformationError),
10 InsufficientData,
11}
12
13#[cfg(feature = "std")]
14impl std::fmt::Display for DataRecordError {
15 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
16 match self {
17 DataRecordError::DataInformationError(e) => write!(f, "{}", e),
18 DataRecordError::InsufficientData => write!(f, "Insufficient data"),
19 }
20 }
21}
22
23#[cfg(feature = "std")]
24impl std::error::Error for DataRecordError {}
25
26#[cfg_attr(feature = "serde", derive(serde::Serialize))]
27#[derive(Debug, Clone, Copy, PartialEq)]
28#[cfg_attr(feature = "defmt", derive(defmt::Format))]
29#[non_exhaustive]
30pub enum VariableUserDataError {
31 DataInformationError(DataRecordError),
32}
33
34#[cfg(feature = "std")]
35impl std::fmt::Display for VariableUserDataError {
36 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
37 match self {
38 VariableUserDataError::DataInformationError(e) => write!(f, "{}", e),
39 }
40 }
41}
42
43#[cfg(feature = "std")]
44impl std::error::Error for VariableUserDataError {}
45
46impl From<DataRecordError> for VariableUserDataError {
47 fn from(error: DataRecordError) -> Self {
48 Self::DataInformationError(error)
49 }
50}
51
52impl<'a> From<&'a [u8]> for DataRecords<'a> {
53 fn from(data: &'a [u8]) -> Self {
54 DataRecords::new(data, None)
55 }
56}
57
58impl<'a> From<(&'a [u8], &'a LongTplHeader)> for DataRecords<'a> {
59 fn from((data, fixed_data_header): (&'a [u8], &'a LongTplHeader)) -> Self {
60 DataRecords::new(data, Some(fixed_data_header))
61 }
62}
63
64#[cfg(all(test, feature = "std"))]
65mod tests {
66 use crate::{data_information::DataFieldCoding, data_record::DataRecord};
67
68 #[test]
69 fn test_parse_variable_data_length() {
70 use crate::data_information::DataFieldCoding;
71 use crate::data_information::DataType;
72 use crate::data_information::TextUnit;
73 use crate::DataRecords;
74
75 let data: &[u8] = &[
76 0x0D, 0x06, 0xC1, 0x12, 0x0D, 0x06, 0xD3, 0x12, 0x34, 0x56, 0x0D, 0x06, 0x02, 0x31,
77 0x32, 0x0D, 0x06, 0xE1, 0xFF, 0x0D, 0x06, 0x00,
78 ];
79
80 let records: Vec<DataRecord<'_>> = DataRecords::from(data).flatten().collect();
81
82 assert_eq!(records.len(), 5);
83 {
84 let record = records.first().unwrap();
85 let code = get_data_field_coding(record);
86 assert_eq!(code, DataFieldCoding::VariableLength);
87 let value = record.data.value.clone().unwrap();
88 assert_eq!(value, DataType::Number(12.0))
89 }
90 {
91 let record = records.get(1).unwrap();
92 let code = get_data_field_coding(record);
93 assert_eq!(code, DataFieldCoding::VariableLength);
94 let value = record.data.value.clone().unwrap();
95 assert_eq!(value, DataType::Number(-563412.0))
96 }
97 {
98 let record = records.get(2).unwrap();
99 let code = get_data_field_coding(record);
100 assert_eq!(code, DataFieldCoding::VariableLength);
101 let value = record.data.value.clone().unwrap();
102 assert_eq!(value, DataType::Text(TextUnit::new(&[0x31, 0x32])))
103 }
104 {
105 let record = records.get(3).unwrap();
106 let code = get_data_field_coding(record);
107 assert_eq!(code, DataFieldCoding::VariableLength);
108 let value = record.data.value.clone().unwrap();
109 assert_eq!(value, DataType::Number(-1.0))
110 }
111 {
112 let record = records.get(4).unwrap();
113 let code = get_data_field_coding(record);
114 assert_eq!(code, DataFieldCoding::VariableLength);
115 let value = record.data.value.clone().unwrap();
116 assert_eq!(value, DataType::Text(TextUnit::new(&[])))
117 }
118 }
119
120 #[test]
121 fn test_parse_variable_lossy_data_length() {
122 use crate::data_information::DataFieldCoding;
123 use crate::data_information::DataType;
124 use crate::data_information::TextUnit;
125 use crate::DataRecords;
126
127 let data: &[u8] = &[
128 0x0D, 0x06, 0xE9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0D, 0x06,
129 0x00, 0x0D, 0x06, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
130 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0D, 0x06, 0x00, 0x0D, 0x06, 0xF4, 0xFF, 0xFF, 0xFF,
131 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
132 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
133 0xFF, 0x0D, 0x06, 0x00, 0x0D, 0x06, 0xF5, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
134 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
135 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
136 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0D,
137 0x06, 0x00, 0x0D, 0x06, 0xF6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
138 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
139 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
140 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
141 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0D,
142 0x06, 0x00,
143 ];
144
145 let records: Vec<DataRecord<'_>> = DataRecords::from(data).flatten().collect();
146
147 assert_eq!(records.len(), 10);
148 {
149 let record = records.first().unwrap();
150 let code = get_data_field_coding(record);
151 assert_eq!(code, DataFieldCoding::VariableLength);
152 let value = record.data.value.clone().unwrap();
153 assert_eq!(value, DataType::LossyNumber(-1.0))
154 }
155 {
156 let record = records.get(1).unwrap();
157 let code = get_data_field_coding(record);
158 assert_eq!(code, DataFieldCoding::VariableLength);
159 let value = record.data.value.clone().unwrap();
160 assert_eq!(value, DataType::Text(TextUnit::new(&[])))
161 }
162 {
163 let record = records.get(2).unwrap();
164 let code = get_data_field_coding(record);
165 assert_eq!(code, DataFieldCoding::VariableLength);
166 let value = record.data.value.clone().unwrap();
167 assert_eq!(value, DataType::LossyNumber(-1.0))
168 }
169 {
170 let record = records.get(3).unwrap();
171 let code = get_data_field_coding(record);
172 assert_eq!(code, DataFieldCoding::VariableLength);
173 let value = record.data.value.clone().unwrap();
174 assert_eq!(value, DataType::Text(TextUnit::new(&[])))
175 }
176 {
177 let record = records.get(4).unwrap();
178 let code = get_data_field_coding(record);
179 assert_eq!(code, DataFieldCoding::VariableLength);
180 let value = record.data.value.clone().unwrap();
181 assert_eq!(value, DataType::LossyNumber(-1.0))
182 }
183 {
184 let record = records.get(5).unwrap();
185 let code = get_data_field_coding(record);
186 assert_eq!(code, DataFieldCoding::VariableLength);
187 let value = record.data.value.clone().unwrap();
188 assert_eq!(value, DataType::Text(TextUnit::new(&[])))
189 }
190 {
191 let record = records.get(6).unwrap();
192 let code = get_data_field_coding(record);
193 assert_eq!(code, DataFieldCoding::VariableLength);
194 let value = record.data.value.clone().unwrap();
195 assert_eq!(value, DataType::LossyNumber(-1.0))
196 }
197 {
198 let record = records.get(7).unwrap();
199 let code = get_data_field_coding(record);
200 assert_eq!(code, DataFieldCoding::VariableLength);
201 let value = record.data.value.clone().unwrap();
202 assert_eq!(value, DataType::Text(TextUnit::new(&[])))
203 }
204 {
205 let record = records.get(8).unwrap();
206 let code = get_data_field_coding(record);
207 assert_eq!(code, DataFieldCoding::VariableLength);
208 let value = record.data.value.clone().unwrap();
209 assert_eq!(value, DataType::LossyNumber(-1.0))
210 }
211 {
212 let record = records.get(9).unwrap();
213 let code = get_data_field_coding(record);
214 assert_eq!(code, DataFieldCoding::VariableLength);
215 let value = record.data.value.clone().unwrap();
216 assert_eq!(value, DataType::Text(TextUnit::new(&[])))
217 }
218 }
219
220 #[test]
221 fn test_parse_variable_data() {
222 use crate::DataRecords;
223
224 let data = &[0x03, 0x13, 0x15, 0x31, 0x00];
227
228 let _result = DataRecords::from(data.as_slice());
229 }
230
231 #[test]
232 fn test_parse_variable_data2() {
233 let _data = &[0x01, 0xFD, 0x1B, 0x00];
235 }
236
237 #[cfg(feature = "plaintext-before-extension")]
240 #[test]
241 fn test_parse_variable_data3() {
242 use crate::DataRecords;
243 let data = &[0x02, 0xFC, 0x03, 0x48, 0x52, 0x25, 0x74, 0x44, 0x0D];
245 let _data = DataRecords::try_from(data.as_slice());
246 }
247
248 #[cfg(not(feature = "plaintext-before-extension"))]
251 #[test]
252 fn test_parse_variable_data3() {
253 use crate::DataRecords;
254 let data = &[0x02, 0xFC, 0x74, 0x03, 0x48, 0x52, 0x25, 0x44, 0x0D];
256 let _data = DataRecords::from(data.as_slice());
257 }
258
259 const fn _test_parse_variable_data2() {
260 let _data = &[0xDA, 0x02, 0x3B, 0x13, 0x01];
262 }
263
264 const fn _test_parse_variable_data3() {
265 let _data = &[0x8B, 0x60, 0x04, 0x37, 0x18, 0x02];
267 }
268
269 fn get_data_field_coding(record: &DataRecord) -> DataFieldCoding {
270 record
271 .data_record_header
272 .processed_data_record_header
273 .data_information
274 .clone()
275 .unwrap()
276 .data_field_coding
277 }
278}