Skip to main content

dlt_parse/verbose/values/
array_f16.rs

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