dlt_parse/verbose/values/
array_i8.rs

1use crate::verbose::{ArrayDimensions, Scaling, VariableInfoUnit};
2
3#[cfg(feature = "serde")]
4use super::ArrayItDimension;
5use arrayvec::{ArrayVec, CapacityError};
6#[cfg(feature = "serde")]
7use serde::ser::{Serialize, SerializeSeq, SerializeStruct, Serializer};
8
9#[derive(Debug, PartialEq, Clone)]
10pub struct ArrayI8<'a> {
11    pub dimensions: ArrayDimensions<'a>,
12    pub variable_info: Option<VariableInfoUnit<'a>>,
13    pub scaling: Option<Scaling<i32>>,
14    pub(crate) data: &'a [u8],
15}
16
17impl<'a> ArrayI8<'a> {
18    pub fn data(&self) -> &'a [u8] {
19        self.data
20    }
21    pub fn iter(&'a self) -> ArrayI8Iterator<'a> {
22        ArrayI8Iterator { rest: self.data }
23    }
24    /// Adds the verbose value to the given dlt mesage buffer.
25    pub fn add_to_msg<const CAP: usize>(
26        &self,
27        buf: &mut ArrayVec<u8, CAP>,
28        is_big_endian: bool,
29    ) -> Result<(), CapacityError> {
30        if let Some(var_info) = &self.variable_info {
31            let (name_len, unit_len, number_of_dimensions) = if is_big_endian {
32                (
33                    (var_info.name.len() as u16 + 1).to_be_bytes(),
34                    (var_info.unit.len() as u16 + 1).to_be_bytes(),
35                    (self.dimensions.dimensions.len() as u16 / 2).to_be_bytes(),
36                )
37            } else {
38                (
39                    (var_info.name.len() as u16 + 1).to_le_bytes(),
40                    (var_info.unit.len() as u16 + 1).to_le_bytes(),
41                    (self.dimensions.dimensions.len() as u16 / 2).to_le_bytes(),
42                )
43            };
44
45            if let Some(scaler) = &self.scaling {
46                let type_info = [0b0010_0001, 0b0001_1001, 0b0000_0000, 0b0000_0000];
47                let quantization;
48                let offset: [u8; 4];
49
50                if is_big_endian {
51                    quantization = scaler.quantization.to_be_bytes();
52                    offset = scaler.offset.to_be_bytes();
53                } else {
54                    quantization = scaler.quantization.to_le_bytes();
55                    offset = scaler.offset.to_le_bytes();
56                }
57
58                buf.try_extend_from_slice(&type_info)?;
59
60                buf.try_extend_from_slice(&number_of_dimensions)?;
61                buf.try_extend_from_slice(self.dimensions.dimensions)?;
62                buf.try_extend_from_slice(&[name_len[0], name_len[1], unit_len[0], unit_len[1]])?;
63                buf.try_extend_from_slice(var_info.name.as_bytes())?;
64                if buf.remaining_capacity() > var_info.unit.len() + 2 {
65                    // Safe as capacity is checked earlier
66                    unsafe { buf.push_unchecked(0) };
67                    let _ = buf.try_extend_from_slice(var_info.unit.as_bytes());
68                    unsafe { buf.push_unchecked(0) };
69                } else {
70                    return Err(CapacityError::new(()));
71                }
72                buf.try_extend_from_slice(&quantization)?;
73                buf.try_extend_from_slice(&offset)?;
74                buf.try_extend_from_slice(self.data)?;
75                Ok(())
76            } else {
77                let type_info: [u8; 4] = [0b0010_0001, 0b0000_1001, 0b0000_0000, 0b0000_0000];
78                buf.try_extend_from_slice(&type_info)?;
79
80                buf.try_extend_from_slice(&number_of_dimensions)?;
81                buf.try_extend_from_slice(self.dimensions.dimensions)?;
82                buf.try_extend_from_slice(&[name_len[0], name_len[1], unit_len[0], unit_len[1]])?;
83                buf.try_extend_from_slice(var_info.name.as_bytes())?;
84                if buf.remaining_capacity() > var_info.unit.len() + 2 {
85                    // Safe as capacity is checked earlier
86                    unsafe { buf.push_unchecked(0) };
87                    let _ = buf.try_extend_from_slice(var_info.unit.as_bytes());
88                    unsafe { buf.push_unchecked(0) };
89                } else {
90                    return Err(CapacityError::new(()));
91                }
92                buf.try_extend_from_slice(self.data)?;
93                Ok(())
94            }
95        } else {
96            let number_of_dimensions = if is_big_endian {
97                (self.dimensions.dimensions.len() as u16 / 2).to_be_bytes()
98            } else {
99                (self.dimensions.dimensions.len() as u16 / 2).to_le_bytes()
100            };
101
102            if let Some(scaler) = &self.scaling {
103                let type_info: [u8; 4] = [0b0010_0001, 0b0001_0001, 0b0000_0000, 0b0000_0000];
104
105                let quantization;
106                let offset: [u8; 4];
107
108                if is_big_endian {
109                    quantization = scaler.quantization.to_be_bytes();
110                    offset = scaler.offset.to_be_bytes();
111                } else {
112                    quantization = scaler.quantization.to_le_bytes();
113                    offset = scaler.offset.to_le_bytes();
114                }
115
116                buf.try_extend_from_slice(&type_info)?;
117                buf.try_extend_from_slice(&number_of_dimensions)?;
118                buf.try_extend_from_slice(self.dimensions.dimensions)?;
119                buf.try_extend_from_slice(&quantization)?;
120                buf.try_extend_from_slice(&offset)?;
121                buf.try_extend_from_slice(self.data)?;
122            } else {
123                let type_info: [u8; 4] = [0b0010_0001, 0b0000_0001, 0b0000_0000, 0b0000_0000];
124                buf.try_extend_from_slice(&type_info)?;
125                buf.try_extend_from_slice(&number_of_dimensions)?;
126                buf.try_extend_from_slice(self.dimensions.dimensions)?;
127                buf.try_extend_from_slice(self.data)?;
128            }
129            Ok(())
130        }
131    }
132}
133
134#[cfg(feature = "serde")]
135impl<'a> Serialize for ArrayI8<'a> {
136    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
137    where
138        S: Serializer,
139    {
140        let mut state = serializer.serialize_struct("ArrayI8", 4)?;
141        state.serialize_field("variable_info", &self.variable_info)?;
142        state.serialize_field("scaling", &self.scaling)?;
143
144        let iter = ArrayItDimension::<i8> {
145            is_big_endian: self.dimensions.is_big_endian,
146            dimensions: self.dimensions.dimensions,
147            data: self.data,
148            phantom: Default::default(),
149        };
150        state.serialize_field("data", &iter)?;
151        state.end()
152    }
153}
154
155#[derive(Debug, Clone)]
156pub struct ArrayI8Iterator<'a> {
157    pub(crate) rest: &'a [u8],
158}
159
160impl Iterator for ArrayI8Iterator<'_> {
161    type Item = i8;
162
163    #[inline]
164    fn next(&mut self) -> Option<Self::Item> {
165        if self.rest.is_empty() {
166            None
167        } else {
168            let result = i8::from_ne_bytes([self.rest[0]]);
169            self.rest = &self.rest[1..];
170            Some(result)
171        }
172    }
173
174    #[inline]
175    fn size_hint(&self) -> (usize, Option<usize>) {
176        (self.rest.len(), Some(self.rest.len()))
177    }
178
179    #[inline]
180    fn count(self) -> usize {
181        self.rest.len()
182    }
183
184    #[inline]
185    fn last(self) -> Option<Self::Item> {
186        self.rest.last().map(|v| i8::from_ne_bytes([*v]))
187    }
188
189    #[inline]
190    fn nth(&mut self, n: usize) -> Option<Self::Item> {
191        if n < self.rest.len() {
192            let result = i8::from_ne_bytes([unsafe {
193                // SAFETY: Safe as the length is checked beforehand to be at least n + 1
194                *self.rest.get_unchecked(n)
195            }]);
196            self.rest = unsafe {
197                // SAFETY: Safe as the length is checked beforehand to be at least n + 1
198                core::slice::from_raw_parts(self.rest.as_ptr().add(n + 1), self.rest.len() - n - 1)
199            };
200            Some(result)
201        } else {
202            self.rest = unsafe {
203                // SAFETY: Safe as the length is checked beforehand to be at least n + 1
204                core::slice::from_raw_parts(self.rest.as_ptr().add(self.rest.len()), 0)
205            };
206            None
207        }
208    }
209}
210
211impl ExactSizeIterator for ArrayI8Iterator<'_> {
212    #[inline]
213    fn len(&self) -> usize {
214        self.rest.len()
215    }
216}
217
218impl<'a> IntoIterator for &'a ArrayI8<'a> {
219    type Item = i8;
220    type IntoIter = ArrayI8Iterator<'a>;
221
222    fn into_iter(self) -> Self::IntoIter {
223        self.iter()
224    }
225}
226
227#[cfg(feature = "serde")]
228impl<'a> Serialize for ArrayI8Iterator<'a> {
229    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
230    where
231        S: Serializer,
232    {
233        let mut seq = serializer.serialize_seq(Some(self.rest.len()))?;
234        for e in self.clone() {
235            seq.serialize_element(&e)?;
236        }
237        seq.end()
238    }
239}
240
241#[cfg(test)]
242mod test {
243    use super::*;
244    use crate::error::UnexpectedEndOfSliceError;
245    use crate::error::VerboseDecodeError::UnexpectedEndOfSlice;
246    use crate::verbose::VerboseValue;
247    use crate::verbose::VerboseValue::ArrI8;
248    use alloc::vec::Vec;
249    use proptest::prelude::*;
250    use std::format;
251
252    type InternalTypes = i8;
253
254    proptest! {
255        #[test]
256        fn write_read(ref name in "\\pc{0,20}", ref unit in "\\pc{0,20}", quantization in any::<f32>(), offset in any::<i32>(), dim_count in 0u16..5) {
257            const TYPE_INFO_RAW: [u8; 4] = [0b0010_0001, 0b0000_0001, 0b0000_0000, 0b0000_0000];
258            const VAR_INFO_FLAG: u8 = 0b0000_1000;
259            const FIXED_POINT_FLAG: u8 = 0b0001_0000;
260
261            const BUFFER_SIZE: usize = 400;
262
263               // test big endian with name & scaling
264               {
265                let mut msg_buff: ArrayVec<u8, BUFFER_SIZE> = ArrayVec::new();
266                let is_big_endian = true;
267
268                let variable_info = Some(VariableInfoUnit {
269                    name,
270                    unit,
271                });
272                let scaling = Some(Scaling {
273                    quantization,
274                    offset,
275                });
276
277                let mut dimensions = Vec::with_capacity(dim_count as usize);
278                let mut content = Vec::with_capacity(dim_count as usize);
279
280                for i in 0..dim_count {
281                    dimensions.extend_from_slice(&(i + 1).to_be_bytes());
282                    for x in 0..=i as InternalTypes {
283                        if x % 2 == 1 {
284                            content.push(x as u8); // Sample I8s
285                        }
286                        else {
287                            content.push((-1 * x) as u8); // Sample I8s
288                        }
289
290                    }
291                }
292
293                let arr_dim = ArrayDimensions {
294                    is_big_endian,
295                    dimensions: &dimensions,
296                };
297                let arr_u = ArrayI8 {
298                    variable_info,
299                    dimensions: arr_dim,
300                    data: &content,
301                    scaling,
302                };
303                arr_u.add_to_msg(&mut msg_buff, is_big_endian)?;
304
305                let len_name = (name.len() as u16 + 1).to_be_bytes();
306                let len_unit = (unit.len() as u16 + 1).to_be_bytes();
307
308                let mut content_buff = Vec::new();
309
310                content_buff.extend_from_slice(&[
311                    TYPE_INFO_RAW[0], TYPE_INFO_RAW[1] | VAR_INFO_FLAG | FIXED_POINT_FLAG, TYPE_INFO_RAW[2], TYPE_INFO_RAW[3]
312                ]);
313                content_buff.extend_from_slice(&dim_count.to_be_bytes());
314                content_buff.extend_from_slice(&dimensions);
315                content_buff.extend_from_slice(&[
316                    len_name[0],
317                    len_name[1],
318                    len_unit[0],
319                    len_unit[1],
320                ]);
321                content_buff.extend_from_slice(name.as_bytes());
322                content_buff.push(0);
323                content_buff.extend_from_slice(unit.as_bytes());
324                content_buff.push(0);
325                content_buff.extend_from_slice(&quantization.to_be_bytes());
326                content_buff.extend_from_slice(&offset.to_be_bytes());
327                content_buff.extend_from_slice(&content);
328
329                prop_assert_eq!(&msg_buff[..], &content_buff[..]);
330
331                // Now wrap back
332                let parsed_back = VerboseValue::from_slice(&msg_buff, is_big_endian);
333                prop_assert_eq!(parsed_back, Ok((ArrI8(arr_u), &[] as &[u8])));
334            }
335
336               // test little endian with name & scaling
337               {
338                let mut msg_buff: ArrayVec<u8, BUFFER_SIZE> = ArrayVec::new();
339                let is_big_endian = false;
340
341                let variable_info = Some(VariableInfoUnit {
342                    name,
343                    unit,
344                });
345                let scaling = Some(Scaling {
346                    quantization,
347                    offset,
348                });
349
350                let mut dimensions = Vec::with_capacity(dim_count as usize);
351                let mut content = Vec::with_capacity(dim_count as usize);
352
353                for i in 0..dim_count {
354                    dimensions.extend_from_slice(&(i + 1).to_le_bytes());
355                    for x in 0..=i as InternalTypes {
356                        if x % 2 == 1 {
357                            content.push(x as u8); // Sample I8s
358                        }
359                        else {
360                            content.push((-1 * x) as u8); // Sample I8s
361                        }
362                    }
363                }
364
365                let arr_dim = ArrayDimensions {
366                    is_big_endian,
367                    dimensions: &dimensions,
368                };
369                let arr_u = ArrayI8 {
370                    variable_info,
371                    dimensions: arr_dim,
372                    data: &content,
373                    scaling,
374                };
375                arr_u.add_to_msg(&mut msg_buff, is_big_endian)?;
376
377                let len_name = (name.len() as u16 + 1).to_le_bytes();
378                let len_unit = (unit.len() as u16 + 1).to_le_bytes();
379
380                let mut content_buff = Vec::new();
381
382                content_buff.extend_from_slice(&[
383                    TYPE_INFO_RAW[0], TYPE_INFO_RAW[1] | VAR_INFO_FLAG | FIXED_POINT_FLAG, TYPE_INFO_RAW[2], TYPE_INFO_RAW[3]
384                ]);
385                content_buff.extend_from_slice(&dim_count.to_le_bytes());
386                content_buff.extend_from_slice(&dimensions);
387                content_buff.extend_from_slice(&[
388                    len_name[0],
389                    len_name[1],
390                    len_unit[0],
391                    len_unit[1],
392                ]);
393                content_buff.extend_from_slice(name.as_bytes());
394                content_buff.push(0);
395                content_buff.extend_from_slice(unit.as_bytes());
396                content_buff.push(0);
397                content_buff.extend_from_slice(&quantization.to_le_bytes());
398                content_buff.extend_from_slice(&offset.to_le_bytes());
399                content_buff.extend_from_slice(&content);
400
401                prop_assert_eq!(&msg_buff[..], &content_buff[..]);
402
403                // Now wrap back
404                let parsed_back = VerboseValue::from_slice(&msg_buff, is_big_endian);
405                prop_assert_eq!(parsed_back, Ok((ArrI8(arr_u), &[] as &[u8])));
406            }
407
408            // test big endian with name without scaling
409            {
410                let mut msg_buff: ArrayVec<u8, BUFFER_SIZE> = ArrayVec::new();
411                let is_big_endian = true;
412
413                let variable_info = Some(VariableInfoUnit { name , unit });
414                let scaling = None;
415
416                let mut dimensions = Vec::with_capacity(dim_count as usize);
417                let mut content = Vec::with_capacity(dim_count as usize);
418
419                for i in 0..dim_count {
420                        dimensions.extend_from_slice(&(i+1).to_be_bytes());
421                    for x in 0..=i as InternalTypes {
422                        if x % 2 == 1 {
423                            content.push(x as u8); // Sample I8s
424                        }
425                        else {
426                            content.push((-1 * x) as u8); // Sample I8s
427                        }
428                }
429            }
430
431                let arr_dim = ArrayDimensions { is_big_endian, dimensions: &dimensions };
432
433                let arr_i8 = ArrayI8 {variable_info, dimensions:arr_dim,data: &content, scaling };
434                arr_i8.add_to_msg(&mut msg_buff, is_big_endian)?;
435
436                let len_name = (name.len() as u16 + 1).to_be_bytes();
437                let len_unit = (unit.len() as u16 + 1).to_be_bytes();
438
439                let mut content_buff = Vec::new();
440
441                content_buff.extend_from_slice(&[TYPE_INFO_RAW[0], TYPE_INFO_RAW[1] | VAR_INFO_FLAG, TYPE_INFO_RAW[2], TYPE_INFO_RAW[3]]);
442                content_buff.extend_from_slice(&dim_count.to_be_bytes());
443                content_buff.extend_from_slice(&dimensions);
444                content_buff.extend_from_slice(&[len_name[0], len_name[1], len_unit[0], len_unit[1]]);
445                content_buff.extend_from_slice(name.as_bytes());
446                content_buff.push(0);
447                content_buff.extend_from_slice(unit.as_bytes());
448                content_buff.push(0);
449                content_buff.extend_from_slice(&content);
450
451                prop_assert_eq!(&msg_buff[..], &content_buff[..]);
452
453                // Now wrap back
454                let parsed_back = VerboseValue::from_slice(&msg_buff, is_big_endian);
455                prop_assert_eq!(parsed_back, Ok((ArrI8(arr_i8),&[] as &[u8])));
456
457                }
458
459            // test little endian with name without scaling
460            {
461                let mut msg_buff: ArrayVec<u8, BUFFER_SIZE> = ArrayVec::new();
462                let is_big_endian = false;
463
464                let variable_info = Some(VariableInfoUnit { name , unit });
465                let scaling = None;
466
467                let mut dimensions = Vec::with_capacity(dim_count as usize);
468                let mut content = Vec::with_capacity(dim_count as usize);
469
470                for i in 0..dim_count {
471                        dimensions.extend_from_slice(&(i+1).to_le_bytes());
472                    for x in 0..=i as InternalTypes {
473                        if x % 2 == 1 {
474                            content.push(x as u8); // Sample I8s
475                        }
476                        else {
477                            content.push((-1 * x) as u8); // Sample I8s
478                        }
479                }
480            }
481
482                let arr_dim = ArrayDimensions { is_big_endian, dimensions: &dimensions };
483                let arr_u = ArrayI8 {variable_info, dimensions:arr_dim,data: &content, scaling };
484                arr_u.add_to_msg(&mut msg_buff, is_big_endian)?;
485
486                let len_name = (name.len() as u16 + 1).to_le_bytes();
487                let len_unit = (unit.len() as u16 + 1).to_le_bytes();
488
489                let mut content_buff = Vec::new();
490
491                content_buff.extend_from_slice(&[TYPE_INFO_RAW[0], TYPE_INFO_RAW[1] | VAR_INFO_FLAG, TYPE_INFO_RAW[2], TYPE_INFO_RAW[3]]);
492                content_buff.extend_from_slice(&dim_count.to_le_bytes());
493                content_buff.extend_from_slice(&dimensions);
494                content_buff.extend_from_slice(&[len_name[0], len_name[1], len_unit[0], len_unit[1]]);
495                content_buff.extend_from_slice(name.as_bytes());
496                content_buff.push(0);
497                content_buff.extend_from_slice(unit.as_bytes());
498                content_buff.push(0);
499                content_buff.extend_from_slice(&content);
500
501                prop_assert_eq!(&msg_buff[..], &content_buff[..]);
502
503                // Now wrap back
504                let parsed_back = VerboseValue::from_slice(&msg_buff, is_big_endian);
505                prop_assert_eq!(parsed_back, Ok((ArrI8(arr_u),&[] as &[u8])));
506
507                }
508
509            // test big endian without name & scaling
510            {
511                let mut msg_buff: ArrayVec<u8, BUFFER_SIZE> = ArrayVec::new();
512                let is_big_endian = true;
513
514                let variable_info = None;
515                let scaling = None;
516
517                let mut dimensions = Vec::with_capacity(dim_count as usize);
518                let mut content = Vec::with_capacity(dim_count as usize);
519
520                for i in 0..dim_count {
521                        dimensions.extend_from_slice(&(i+1).to_be_bytes());
522                    for x in 0..=i as InternalTypes {
523                        if x % 2 == 1 {
524                            content.push(x as u8); // Sample I8s
525                        }
526                        else {
527                            content.push((-1 * x) as u8); // Sample I8s
528                        }
529                }
530            }
531
532                let arr_dim = ArrayDimensions { is_big_endian, dimensions: &dimensions };
533                let arr_i8 = ArrayI8 {variable_info, dimensions:arr_dim,data: &content, scaling };
534                arr_i8.add_to_msg(&mut msg_buff, is_big_endian)?;
535                let mut content_buff = Vec::new();
536
537                content_buff.extend_from_slice(&[TYPE_INFO_RAW[0], TYPE_INFO_RAW[1], TYPE_INFO_RAW[2], TYPE_INFO_RAW[3]]);
538                content_buff.extend_from_slice(&dim_count.to_be_bytes());
539                content_buff.extend_from_slice(&dimensions);
540                content_buff.extend_from_slice(&content);
541
542                prop_assert_eq!(&msg_buff[..], &content_buff[..]);
543
544                // Now wrap back
545                let parsed_back = VerboseValue::from_slice(&msg_buff, is_big_endian);
546                prop_assert_eq!(parsed_back, Ok((ArrI8(arr_i8),&[] as &[u8])));
547
548                }
549
550            // test little endian without name & scaling
551            {
552                let mut msg_buff: ArrayVec<u8, BUFFER_SIZE> = ArrayVec::new();
553                let is_big_endian = false;
554
555                let variable_info = None;
556                let scaling = None;
557
558                let mut dimensions = Vec::with_capacity(dim_count as usize);
559                let mut content = Vec::with_capacity(dim_count as usize);
560
561                for i in 0..dim_count {
562                        dimensions.extend_from_slice(&(i+1).to_le_bytes());
563                    for x in 0..=i as InternalTypes {
564                        if x % 2 == 1 {
565                            content.push(x as u8); // Sample I8s
566                        }
567                        else {
568                            content.push((-1 * x) as u8); // Sample I8s
569                        }
570                    }
571                }
572
573                let arr_dim = ArrayDimensions { is_big_endian, dimensions: &dimensions };
574                let arr_i8 = ArrayI8 {variable_info, dimensions:arr_dim,data: &content, scaling };
575                arr_i8.add_to_msg(&mut msg_buff, is_big_endian)?;
576
577                let mut content_buff = Vec::new();
578                content_buff.extend_from_slice(&[TYPE_INFO_RAW[0], TYPE_INFO_RAW[1], TYPE_INFO_RAW[2], TYPE_INFO_RAW[3]]);
579                content_buff.extend_from_slice(&dim_count.to_le_bytes());
580                content_buff.extend_from_slice(&dimensions);
581                content_buff.extend_from_slice(&content);
582
583                prop_assert_eq!(&msg_buff[..], &content_buff[..]);
584
585                // Now wrap back
586                let parsed_back = VerboseValue::from_slice(&msg_buff, is_big_endian);
587                prop_assert_eq!(parsed_back, Ok((ArrI8(arr_i8),&[] as &[u8])));
588
589                }
590
591             // test big endian with scaling and without name
592             {
593                let mut msg_buff: ArrayVec<u8, BUFFER_SIZE> = ArrayVec::new();
594                let is_big_endian = true;
595
596                let variable_info = None;
597                let scaling = Some(Scaling { quantization, offset });
598
599                let mut dimensions = Vec::with_capacity(dim_count as usize);
600                let mut content = Vec::with_capacity(dim_count as usize);
601
602                for i in 0..dim_count {
603                        dimensions.extend_from_slice(&(i+1).to_be_bytes());
604                    for x in 0..=i as InternalTypes {
605                        if x % 2 == 1 {
606                            content.push(x as u8); // Sample I8s
607                        }
608                        else {
609                            content.push((-1 * x) as u8); // Sample I8s
610                        }
611                }
612            }
613
614                let arr_dim = ArrayDimensions { is_big_endian, dimensions: &dimensions };
615                let arr_i8 = ArrayI8 {variable_info, dimensions:arr_dim,data: &content, scaling };
616                arr_i8.add_to_msg(&mut msg_buff, is_big_endian)?;
617                let mut content_buff = Vec::new();
618
619                content_buff.extend_from_slice(&[TYPE_INFO_RAW[0], TYPE_INFO_RAW[1] | FIXED_POINT_FLAG, TYPE_INFO_RAW[2], TYPE_INFO_RAW[3]]);
620                content_buff.extend_from_slice(&dim_count.to_be_bytes());
621                content_buff.extend_from_slice(&dimensions);
622                content_buff.extend_from_slice(&quantization.to_be_bytes());
623                content_buff.extend_from_slice(&offset.to_be_bytes());
624                content_buff.extend_from_slice(&content);
625
626                prop_assert_eq!(&msg_buff[..], &content_buff[..]);
627
628                // Now wrap back
629                let parsed_back = VerboseValue::from_slice(&msg_buff, is_big_endian);
630                prop_assert_eq!(parsed_back, Ok((ArrI8(arr_i8),&[] as &[u8])));
631
632                }
633
634            // test little endian with scaling and without name
635            {
636                let mut msg_buff: ArrayVec<u8, BUFFER_SIZE> = ArrayVec::new();
637                let is_big_endian = false;
638
639                let variable_info = None;
640                let scaling = Some(Scaling { quantization, offset });
641
642                let mut dimensions = Vec::with_capacity(dim_count as usize);
643                let mut content = Vec::with_capacity(dim_count as usize);
644
645                for i in 0..dim_count {
646                        dimensions.extend_from_slice(&(i+1).to_le_bytes());
647                    for x in 0..=i as InternalTypes {
648                        if x % 2 == 1 {
649                            content.push(x as u8); // Sample I8s
650                        }
651                        else {
652                            content.push((-1 * x) as u8); // Sample I8s
653                        }
654                }
655            }
656
657                let arr_dim = ArrayDimensions { is_big_endian, dimensions: &dimensions };
658                let arr_i8 = ArrayI8 {variable_info, dimensions:arr_dim,data: &content, scaling };
659                arr_i8.add_to_msg(&mut msg_buff, is_big_endian)?;
660                let mut content_buff = Vec::new();
661
662                content_buff.extend_from_slice(&[TYPE_INFO_RAW[0], TYPE_INFO_RAW[1] | FIXED_POINT_FLAG, TYPE_INFO_RAW[2], TYPE_INFO_RAW[3]]);
663                content_buff.extend_from_slice(&dim_count.to_le_bytes());
664                content_buff.extend_from_slice(&dimensions);
665                content_buff.extend_from_slice(&quantization.to_le_bytes());
666                content_buff.extend_from_slice(&offset.to_le_bytes());
667                content_buff.extend_from_slice(&content);
668
669                prop_assert_eq!(&msg_buff[..], &content_buff[..]);
670
671                // Now wrap back
672                let parsed_back = VerboseValue::from_slice(&msg_buff, is_big_endian);
673                prop_assert_eq!(parsed_back, Ok((ArrI8(arr_i8),&[] as &[u8])));
674
675                }
676
677             // Capacity error big endian with name & scaling
678             {
679                let dim_count = dim_count + 1;
680                let mut msg_buff: ArrayVec<u8, BUFFER_SIZE> = ArrayVec::new();
681                let is_big_endian = true;
682
683                let variable_info = Some(VariableInfoUnit { name , unit });
684                let scaling = Some(Scaling { quantization, offset });
685
686                let mut dimensions = Vec::with_capacity(dim_count as usize);
687                let mut content = Vec::with_capacity(dim_count as usize);
688
689                for i in 1u16..=dim_count {
690                    dimensions.extend_from_slice(&(i as u16).to_be_bytes());
691
692                    for x in 0..(i-1) as InternalTypes {
693                        if x % 2 == 0 {
694                            content.push(x as u8);
695                        }
696                        else {
697                            content.push((-1 * x) as u8);
698                        }
699
700                    }
701                }
702
703                let arr_dim = ArrayDimensions { is_big_endian, dimensions: &dimensions };
704                let arr = ArrayI8 {variable_info, dimensions: arr_dim, data: &content, scaling };
705                arr.add_to_msg(&mut msg_buff, is_big_endian)?;
706
707                // Now wrap back
708                let parsed_back = VerboseValue::from_slice(&msg_buff, is_big_endian);
709                prop_assert_eq!(parsed_back, Err(UnexpectedEndOfSlice(UnexpectedEndOfSliceError { layer: crate::error::Layer::VerboseValue, minimum_size: msg_buff.len() + dim_count as usize, actual_size: msg_buff.len() })));
710
711            }
712
713             // Capacity error little endian with name & scaling
714             {
715                let dim_count = dim_count + 1;
716                let mut msg_buff: ArrayVec<u8, BUFFER_SIZE> = ArrayVec::new();
717                let is_big_endian = false;
718
719                let variable_info = Some(VariableInfoUnit { name , unit });
720                let scaling = Some( Scaling { quantization, offset });
721
722                let mut dimensions = Vec::with_capacity(dim_count as usize);
723                let mut content = Vec::with_capacity(dim_count as usize);
724
725                for i in 1u16..=dim_count {
726                    dimensions.extend_from_slice(&(i as u16).to_le_bytes());
727
728                    for x in 0..(i-1) as InternalTypes {
729                        if x % 2 == 0 {
730                            content.push(x as u8);
731                        }
732                        else {
733                            content.push((-1 * x) as u8);
734                        }
735                    }
736                }
737
738                let arr_dim = ArrayDimensions { is_big_endian, dimensions: &dimensions };
739                let arr = ArrayI8 {variable_info, dimensions: arr_dim, data: &content, scaling };
740                arr.add_to_msg(&mut msg_buff, is_big_endian)?;
741
742                // Now wrap back
743                let parsed_back = VerboseValue::from_slice(&msg_buff, is_big_endian);
744                prop_assert_eq!(parsed_back, Err(UnexpectedEndOfSlice(UnexpectedEndOfSliceError { layer: crate::error::Layer::VerboseValue, minimum_size: msg_buff.len() + dim_count as usize, actual_size: msg_buff.len() })));
745            }
746
747             // Capacity error big endian with name & no scaling
748             {
749                let dim_count = dim_count + 1;
750                let mut msg_buff: ArrayVec<u8, BUFFER_SIZE> = ArrayVec::new();
751                let is_big_endian = true;
752
753                let variable_info = Some(VariableInfoUnit { name , unit });
754                let scaling = None;
755
756                let mut dimensions = Vec::with_capacity(dim_count as usize);
757                let mut content = Vec::with_capacity(dim_count as usize);
758
759                for i in 1u16..=dim_count {
760                    dimensions.extend_from_slice(&(i as u16).to_be_bytes());
761
762                    for x in 0..(i-1) as InternalTypes {
763                        if x % 2 == 0 {
764                            content.push(x as u8);
765                        }
766                        else {
767                            content.push((-1 * x) as u8);
768                        }
769                    }
770                }
771
772                let arr_dim = ArrayDimensions { is_big_endian, dimensions: &dimensions };
773                let arr = ArrayI8 {variable_info, dimensions: arr_dim, data: &content, scaling };
774                arr.add_to_msg(&mut msg_buff, is_big_endian)?;
775
776                // Now wrap back
777                let parsed_back = VerboseValue::from_slice(&msg_buff, is_big_endian);
778                prop_assert_eq!(parsed_back, Err(UnexpectedEndOfSlice(UnexpectedEndOfSliceError { layer: crate::error::Layer::VerboseValue, minimum_size: msg_buff.len() + dim_count as usize, actual_size: msg_buff.len() })));
779
780            }
781
782             // Capacity error little endian with name & no scaling
783             {
784                let dim_count = dim_count + 1;
785                let mut msg_buff: ArrayVec<u8, BUFFER_SIZE> = ArrayVec::new();
786                let is_big_endian = false;
787
788                let variable_info = Some(VariableInfoUnit { name , unit });
789                let scaling = None;
790
791                let mut dimensions = Vec::with_capacity(dim_count as usize);
792                let mut content = Vec::with_capacity(dim_count as usize);
793
794                for i in 1u16..=dim_count {
795                    dimensions.extend_from_slice(&(i as u16).to_le_bytes());
796
797                    for x in 0..(i-1) as InternalTypes {
798                        if x % 2 == 0 {
799                            content.push(x as u8);
800                        }
801                        else {
802                            content.push((-1 * x) as u8);
803                        }
804                }
805            }
806
807                let arr_dim = ArrayDimensions { is_big_endian, dimensions: &dimensions };
808                let arr = ArrayI8 {variable_info, dimensions: arr_dim, data: &content, scaling };
809                arr.add_to_msg(&mut msg_buff, is_big_endian)?;
810
811                // Now wrap back
812                let parsed_back = VerboseValue::from_slice(&msg_buff, is_big_endian);
813                prop_assert_eq!(parsed_back, Err(UnexpectedEndOfSlice(UnexpectedEndOfSliceError { layer: crate::error::Layer::VerboseValue, minimum_size: msg_buff.len() + dim_count as usize, actual_size: msg_buff.len() })));
814            }
815
816             // Capacity error big endian with scaling & no name
817             {
818                let dim_count = dim_count + 1;
819                let mut msg_buff: ArrayVec<u8, BUFFER_SIZE> = ArrayVec::new();
820                let is_big_endian = true;
821
822                let variable_info = None;
823                let scaling = Some(Scaling { quantization, offset });
824
825                let mut dimensions = Vec::with_capacity(dim_count as usize);
826                let mut content = Vec::with_capacity(dim_count as usize);
827
828                for i in 1u16..=dim_count {
829                    dimensions.extend_from_slice(&(i as u16).to_be_bytes());
830
831                    for x in 0..(i-1) as InternalTypes {
832                        if x % 2 == 0 {
833                            content.push(x as u8);
834                        }
835                        else {
836                            content.push((-1 * x) as u8);
837                        }
838                }
839            }
840
841                let arr_dim = ArrayDimensions { is_big_endian, dimensions: &dimensions };
842                let arr = ArrayI8 {variable_info, dimensions: arr_dim, data: &content, scaling };
843                arr.add_to_msg(&mut msg_buff, is_big_endian)?;
844
845                // Now wrap back
846                let parsed_back = VerboseValue::from_slice(&msg_buff, is_big_endian);
847                prop_assert_eq!(parsed_back, Err(UnexpectedEndOfSlice(UnexpectedEndOfSliceError { layer: crate::error::Layer::VerboseValue, minimum_size: msg_buff.len() + dim_count as usize, actual_size: msg_buff.len() })));
848
849            }
850
851             // Capacity error little endian with scaling & no name
852             {
853                let dim_count = dim_count + 1;
854                let mut msg_buff: ArrayVec<u8, BUFFER_SIZE> = ArrayVec::new();
855                let is_big_endian = false;
856
857                let variable_info = None;
858                let scaling = Some( Scaling { quantization, offset });
859
860                let mut dimensions = Vec::with_capacity(dim_count as usize);
861                let mut content = Vec::with_capacity(dim_count as usize);
862
863                for i in 1u16..=dim_count {
864                    dimensions.extend_from_slice(&(i as u16).to_le_bytes());
865
866                    for x in 0..(i-1) as InternalTypes {
867                        if x % 2 == 0 {
868                            content.push(x as u8);
869                        }
870                        else {
871                            content.push((-1 * x) as u8);
872                        }
873                }
874            }
875
876                let arr_dim = ArrayDimensions { is_big_endian, dimensions: &dimensions };
877                let arr = ArrayI8 {variable_info, dimensions: arr_dim, data: &content, scaling };
878                arr.add_to_msg(&mut msg_buff, is_big_endian)?;
879
880                // Now wrap back
881                let parsed_back = VerboseValue::from_slice(&msg_buff, is_big_endian);
882                prop_assert_eq!(parsed_back, Err(UnexpectedEndOfSlice(UnexpectedEndOfSliceError { layer: crate::error::Layer::VerboseValue, minimum_size: msg_buff.len() + dim_count as usize, actual_size: msg_buff.len() })));
883            }
884
885             // Capacity error big endian without scaling & name
886             {
887                let dim_count = dim_count + 1;
888                let mut msg_buff: ArrayVec<u8, BUFFER_SIZE> = ArrayVec::new();
889                let is_big_endian = true;
890
891                let variable_info = None;
892                let scaling = None;
893
894                let mut dimensions = Vec::with_capacity(dim_count as usize);
895                let mut content = Vec::with_capacity(dim_count as usize);
896
897                for i in 1u16..=dim_count {
898                    dimensions.extend_from_slice(&(i as u16).to_be_bytes());
899
900                    for x in 0..(i-1) as InternalTypes {
901                        if x % 2 == 0 {
902                            content.push(x as u8);
903                        }
904                        else {
905                            content.push((-1 * x) as u8);
906                        }
907                }
908            }
909
910                let arr_dim = ArrayDimensions { is_big_endian, dimensions: &dimensions };
911                let arr = ArrayI8 {variable_info, dimensions: arr_dim, data: &content, scaling };
912                arr.add_to_msg(&mut msg_buff, is_big_endian)?;
913
914                // Now wrap back
915                let parsed_back = VerboseValue::from_slice(&msg_buff, is_big_endian);
916                prop_assert_eq!(parsed_back, Err(UnexpectedEndOfSlice(UnexpectedEndOfSliceError { layer: crate::error::Layer::VerboseValue, minimum_size: msg_buff.len() + dim_count as usize, actual_size: msg_buff.len() })));
917
918            }
919
920             // Capacity error little endian without scaling & name
921             {
922                let dim_count = dim_count + 1;
923                let mut msg_buff: ArrayVec<u8, BUFFER_SIZE> = ArrayVec::new();
924                let is_big_endian = false;
925
926                let variable_info = None;
927                let scaling = None;
928
929                let mut dimensions = Vec::with_capacity(dim_count as usize);
930                let mut content = Vec::with_capacity(dim_count as usize);
931
932                for i in 1u16..=dim_count {
933                    dimensions.extend_from_slice(&(i as u16).to_le_bytes());
934
935                    for x in 0..(i-1) as InternalTypes {
936                        if x % 2 == 0 {
937                            content.push(x as u8);
938                        }
939                        else {
940                            content.push((-1 * x) as u8);
941                        }
942                }
943            }
944
945                let arr_dim = ArrayDimensions { is_big_endian, dimensions: &dimensions };
946                let arr = ArrayI8 {variable_info, dimensions: arr_dim, data: &content, scaling };
947                arr.add_to_msg(&mut msg_buff, is_big_endian)?;
948
949                // Now wrap back
950                let parsed_back = VerboseValue::from_slice(&msg_buff, is_big_endian);
951                prop_assert_eq!(parsed_back, Err(UnexpectedEndOfSlice(UnexpectedEndOfSliceError { layer: crate::error::Layer::VerboseValue, minimum_size: msg_buff.len() + dim_count as usize, actual_size: msg_buff.len() })));
952            }
953
954
955             // capacity error big endian with name, without scaling
956             {
957                let name = "Abc";
958                let unit = "Xyz";
959                const DIM_COUNT: u16 = 5;
960                const BUFFER_SIZE: usize = DIM_COUNT as usize * 2 + 14;
961                let mut msg_buff: ArrayVec<u8, BUFFER_SIZE> = ArrayVec::new();
962                let is_big_endian = true;
963
964                let variable_info = Some(VariableInfoUnit { name , unit });
965                let scaling = None;
966
967                let mut dimensions = Vec::with_capacity(DIM_COUNT as usize);
968                let mut content = Vec::with_capacity(DIM_COUNT as usize);
969
970                for i in 0..DIM_COUNT as i8 {
971                        dimensions.extend_from_slice(&(1 as u16).to_be_bytes());
972                        if i % 2 == 0 {
973                            content.push(i as u8);
974                        }
975                        else {
976                            content.push((-1 * i) as u8);
977                        }
978
979                }
980
981                let arr_dim = ArrayDimensions { is_big_endian, dimensions: &dimensions };
982
983                let arr = ArrayI8 {variable_info,dimensions:arr_dim,data: &content, scaling };
984                let err = arr.add_to_msg(&mut msg_buff, is_big_endian);
985
986                prop_assert_eq!(err, Err(CapacityError::new(())));
987
988                }
989
990
991             // capacity error little endian with name, without scaling
992             {
993                let name = "Abc";
994                let unit = "Xyz";
995                const DIM_COUNT: u16 = 5;
996                const BUFFER_SIZE: usize = DIM_COUNT as usize * 2 + 15;
997                let mut msg_buff: ArrayVec<u8, BUFFER_SIZE> = ArrayVec::new();
998                let is_big_endian = false;
999
1000                let variable_info = Some(VariableInfoUnit { name , unit });
1001                let scaling = Some(Scaling { quantization, offset });
1002
1003                let mut dimensions = Vec::with_capacity(DIM_COUNT as usize);
1004                let mut content = Vec::with_capacity(DIM_COUNT as usize);
1005
1006                for i in 0..DIM_COUNT as i8 {
1007                        dimensions.extend_from_slice(&(1 as u16).to_be_bytes());
1008                        if i % 2 == 0 {
1009                            content.push(i as u8);
1010                        }
1011                        else {
1012                            content.push((-1 * i) as u8);
1013                        }
1014
1015                }
1016
1017                let arr_dim = ArrayDimensions { is_big_endian, dimensions: &dimensions };
1018
1019                let arr = ArrayI8 {variable_info,dimensions:arr_dim,data: &content, scaling };
1020                let err = arr.add_to_msg(&mut msg_buff, is_big_endian);
1021
1022                prop_assert_eq!(err, Err(CapacityError::new(())));
1023
1024                }
1025        }
1026    }
1027
1028    proptest! {
1029        #[test]
1030        fn data(ref data in "\\pc{0,100}", ref dimensions in "\\pc{0,100}", quantization in any::<f32>(), offset in any::<i32>()) {
1031
1032            let arr_dim = ArrayDimensions {dimensions: dimensions.as_bytes(), is_big_endian: true };
1033            let scaling = Some(Scaling { quantization, offset });
1034            let arr = ArrayI8 {dimensions:arr_dim,variable_info:None,data:data.as_bytes(), scaling };
1035            prop_assert_eq!(arr.data(), data.as_bytes());
1036        }
1037    }
1038
1039    proptest! {
1040        #[test]
1041        fn iterator(dim_count in 0u16..5) {
1042
1043            let is_big_endian = true;
1044
1045            let variable_info = None;
1046            let scaling = None;
1047
1048            let mut dimensions = Vec::with_capacity(dim_count as usize);
1049            let mut content = Vec::with_capacity(dim_count as usize);
1050
1051            for i in 0..dim_count {
1052                    dimensions.extend_from_slice(&(i+1).to_be_bytes());
1053                for x in 0..=i as i8 {
1054                    if x % 2 == 0 {
1055                        content.push(x as u8);       // Sample I8s
1056                    }
1057                    else {
1058                        content.push((-1 * x) as u8);       // Sample I8s
1059                    }
1060                }
1061            }
1062
1063            let arr_dim = ArrayDimensions { is_big_endian, dimensions: &dimensions };
1064            let arr = ArrayI8 {variable_info, dimensions:arr_dim,data: &content, scaling };
1065
1066            // normal iteration
1067            {
1068                let mut cnt = 0;
1069                for item in arr.iter() {
1070                    prop_assert_eq!(item, content[cnt] as i8);
1071                    cnt += 1;
1072                }
1073            }
1074
1075            // size_hint
1076            assert_eq!(arr.into_iter().size_hint(), (content.len(), Some(content.len())));
1077
1078            // count
1079            assert_eq!(arr.into_iter().count(), content.len());
1080
1081            // test last
1082            assert_eq!(arr.into_iter().last(), content.last().map(|v| i8::from_ne_bytes([*v])));
1083
1084            // test nth
1085            for i in 0..content.len() {
1086                let mut it = arr.into_iter();
1087                assert_eq!(it.nth(i), Some(i8::from_ne_bytes([content[i]])));
1088                assert_eq!(it.rest.len(), content.len() - i - 1);
1089            }
1090            assert_eq!(arr.into_iter().nth(content.len()), None);
1091
1092            // test len
1093            assert_eq!(arr.into_iter().len(), content.len());
1094        }
1095    }
1096
1097    #[cfg(feature = "serde")]
1098    #[test]
1099    fn serialization() {
1100        // test dim_count 0
1101
1102        use alloc::string::ToString;
1103        {
1104            let dim_count: u16 = 0;
1105            let is_big_endian = true;
1106
1107            let variable_info = None;
1108
1109            let mut dimensions = Vec::with_capacity(dim_count as usize);
1110            let mut content = Vec::with_capacity(dim_count as usize);
1111
1112            let mut elems: u8 = 1;
1113
1114            for i in 0..dim_count {
1115                dimensions.extend_from_slice(&(i + 1).to_be_bytes());
1116                elems *= (i + 1) as u8;
1117            }
1118
1119            for x in 0u8..elems as u8 {
1120                if x % 2 == 1 {
1121                    content.push((-1 * x as i8) as u8);
1122                } else {
1123                    content.push(x);
1124                }
1125            }
1126
1127            let arr_dim = ArrayDimensions {
1128                is_big_endian,
1129                dimensions: &dimensions,
1130            };
1131            let arr_i8 = ArrayI8 {
1132                variable_info,
1133                dimensions: arr_dim,
1134                data: &content,
1135                scaling: None,
1136            };
1137
1138            let mut cnt = 0;
1139            for item in arr_i8.iter() {
1140                assert_eq!(item, content[cnt] as i8);
1141                cnt += 1;
1142            }
1143
1144            let convert_content =
1145                "{\"variable_info\":null,\"scaling\":null,\"data\":[]}".to_string();
1146
1147            assert_eq!(convert_content, serde_json::to_string(&arr_i8).unwrap());
1148        }
1149
1150        // test dim_count 1
1151        {
1152            let dim_count: u16 = 1;
1153            let is_big_endian = true;
1154
1155            let variable_info = None;
1156
1157            let mut dimensions = Vec::with_capacity(dim_count as usize);
1158            let mut content = Vec::with_capacity(dim_count as usize);
1159
1160            let mut elems: u8 = 1;
1161
1162            for i in 0..dim_count {
1163                dimensions.extend_from_slice(&(i + 1).to_be_bytes());
1164                elems *= (i + 1) as u8;
1165            }
1166
1167            for x in 0u8..elems as u8 {
1168                if x % 2 == 1 {
1169                    content.push((-1 * x as i8) as u8);
1170                } else {
1171                    content.push(x);
1172                }
1173            }
1174
1175            let arr_dim = ArrayDimensions {
1176                is_big_endian,
1177                dimensions: &dimensions,
1178            };
1179            let arr_i8 = ArrayI8 {
1180                variable_info,
1181                dimensions: arr_dim,
1182                data: &content,
1183                scaling: None,
1184            };
1185
1186            let mut cnt = 0;
1187            for item in arr_i8.iter() {
1188                assert_eq!(item, content[cnt] as i8);
1189                cnt += 1;
1190            }
1191
1192            let convert_content =
1193                "{\"variable_info\":null,\"scaling\":null,\"data\":[0]}".to_string();
1194
1195            assert_eq!(convert_content, serde_json::to_string(&arr_i8).unwrap());
1196        }
1197
1198        // test dim_count 2
1199        {
1200            let dim_count: u16 = 2;
1201            let is_big_endian = true;
1202
1203            let variable_info = None;
1204
1205            let mut dimensions = Vec::with_capacity(dim_count as usize);
1206            let mut content = Vec::with_capacity(dim_count as usize);
1207
1208            let mut elems: u8 = 1;
1209
1210            for i in 0..dim_count {
1211                dimensions.extend_from_slice(&(i + 1).to_be_bytes());
1212                elems *= (i + 1) as u8;
1213            }
1214
1215            for x in 0u8..elems as u8 {
1216                if x % 2 == 1 {
1217                    content.push((-1 * x as i8) as u8);
1218                } else {
1219                    content.push(x);
1220                }
1221            }
1222
1223            let arr_dim = ArrayDimensions {
1224                is_big_endian,
1225                dimensions: &dimensions,
1226            };
1227            let arr_i8 = ArrayI8 {
1228                variable_info,
1229                dimensions: arr_dim,
1230                data: &content,
1231                scaling: None,
1232            };
1233
1234            let mut cnt = 0;
1235            for item in arr_i8.iter() {
1236                assert_eq!(item, content[cnt] as i8);
1237                cnt += 1;
1238            }
1239
1240            let convert_content =
1241                "{\"variable_info\":null,\"scaling\":null,\"data\":[[0,-1]]}".to_string();
1242
1243            assert_eq!(convert_content, serde_json::to_string(&arr_i8).unwrap());
1244        }
1245
1246        // test dim_count 3
1247        {
1248            let dim_count: u16 = 3;
1249            let is_big_endian = true;
1250
1251            let variable_info = None;
1252
1253            let mut dimensions = Vec::with_capacity(dim_count as usize);
1254            let mut content = Vec::with_capacity(dim_count as usize);
1255
1256            let mut elems: u8 = 1;
1257
1258            for i in 0..dim_count {
1259                dimensions.extend_from_slice(&(i + 1).to_be_bytes());
1260                elems *= (i + 1) as u8;
1261            }
1262
1263            for x in 0u8..elems as u8 {
1264                if x % 2 == 1 {
1265                    content.push((-1 * x as i8) as u8);
1266                } else {
1267                    content.push(x);
1268                }
1269            }
1270
1271            let arr_dim = ArrayDimensions {
1272                is_big_endian,
1273                dimensions: &dimensions,
1274            };
1275            let arr_i8 = ArrayI8 {
1276                variable_info,
1277                dimensions: arr_dim,
1278                data: &content,
1279                scaling: None,
1280            };
1281
1282            let mut cnt = 0;
1283            for item in arr_i8.iter() {
1284                assert_eq!(item, content[cnt] as i8);
1285                cnt += 1;
1286            }
1287
1288            let convert_content =
1289                "{\"variable_info\":null,\"scaling\":null,\"data\":[[[0,-1,2],[-3,4,-5]]]}"
1290                    .to_string();
1291            assert_eq!(convert_content, serde_json::to_string(&arr_i8).unwrap());
1292        }
1293
1294        // test dim_count 4
1295        {
1296            let dim_count: u16 = 4;
1297            let is_big_endian = true;
1298
1299            let variable_info = None;
1300
1301            let mut dimensions = Vec::with_capacity(dim_count as usize);
1302            let mut content = Vec::with_capacity(dim_count as usize);
1303
1304            let mut elems: u8 = 1;
1305
1306            for i in 0..dim_count {
1307                dimensions.extend_from_slice(&(i + 1).to_be_bytes());
1308                elems *= (i + 1) as u8;
1309            }
1310
1311            for x in 0u8..elems as u8 {
1312                if x % 2 == 1 {
1313                    content.push((-1 * x as i8) as u8);
1314                } else {
1315                    content.push(x);
1316                }
1317            }
1318
1319            let arr_dim = ArrayDimensions {
1320                is_big_endian,
1321                dimensions: &dimensions,
1322            };
1323            let arr_i8 = ArrayI8 {
1324                variable_info,
1325                dimensions: arr_dim,
1326                data: &content,
1327                scaling: None,
1328            };
1329
1330            let mut cnt = 0;
1331            for item in arr_i8.iter() {
1332                assert_eq!(item, content[cnt] as i8);
1333                cnt += 1;
1334            }
1335
1336            let convert_content = "{\"variable_info\":null,\"scaling\":null,\"data\":[[[[0,-1,2,-3],[4,-5,6,-7],[8,-9,10,-11]],[[12,-13,14,-15],[16,-17,18,-19],[20,-21,22,-23]]]]}".to_string();
1337            assert_eq!(convert_content, serde_json::to_string(&arr_i8).unwrap());
1338        }
1339
1340        // test dim_count 5
1341        {
1342            let dim_count: u16 = 5;
1343            let is_big_endian = true;
1344
1345            let variable_info = None;
1346
1347            let mut dimensions = Vec::with_capacity(dim_count as usize);
1348            let mut content = Vec::with_capacity(dim_count as usize);
1349
1350            let mut elems: u8 = 1;
1351
1352            for i in 0..dim_count {
1353                dimensions.extend_from_slice(&(i + 1).to_be_bytes());
1354                elems *= (i + 1) as u8;
1355            }
1356
1357            for x in 0u8..elems as u8 {
1358                if x % 2 == 1 {
1359                    content.push((-1 * x as i8) as u8);
1360                } else {
1361                    content.push(x);
1362                }
1363            }
1364
1365            let arr_dim = ArrayDimensions {
1366                is_big_endian,
1367                dimensions: &dimensions,
1368            };
1369            let arr_i8 = ArrayI8 {
1370                variable_info,
1371                dimensions: arr_dim,
1372                data: &content,
1373                scaling: None,
1374            };
1375
1376            let mut cnt = 0;
1377            for item in arr_i8.iter() {
1378                assert_eq!(item, content[cnt] as i8);
1379                cnt += 1;
1380            }
1381
1382            let convert_content = "{\"variable_info\":null,\"scaling\":null,\"data\":[[[[[0,-1,2,-3,4],[-5,6,-7,8,-9],[10,-11,12,-13,14],[-15,16,-17,18,-19]],[[20,-21,22,-23,24],[-25,26,-27,28,-29],[30,-31,32,-33,34],[-35,36,-37,38,-39]],[[40,-41,42,-43,44],[-45,46,-47,48,-49],[50,-51,52,-53,54],[-55,56,-57,58,-59]]],[[[60,-61,62,-63,64],[-65,66,-67,68,-69],[70,-71,72,-73,74],[-75,76,-77,78,-79]],[[80,-81,82,-83,84],[-85,86,-87,88,-89],[90,-91,92,-93,94],[-95,96,-97,98,-99]],[[100,-101,102,-103,104],[-105,106,-107,108,-109],[110,-111,112,-113,114],[-115,116,-117,118,-119]]]]]}".to_string();
1383            assert_eq!(convert_content, serde_json::to_string(&arr_i8).unwrap());
1384        }
1385    }
1386}