dlt_parse/verbose/values/
array_f128.rs

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