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 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 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 [*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 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 [
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 if self.rest.len() >= 2 && n <= (self.rest.len() - 2) / 2 {
187 let index = n * 2;
188 let bytes = unsafe {
189 [
190 *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 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 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 {
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 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 {
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 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 {
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 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 {
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 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 {
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 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 {
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 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 {
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 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 {
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 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 {
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 {
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 {
638 let mut iter = ArrayF16Iterator{
639 is_big_endian: false,
640 rest: &[],
641 };
642 assert!(iter.next().is_none());
643 }
644
645 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 {
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 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 {
737 let iter = ArrayF16Iterator{
738 is_big_endian: false,
739 rest: &[],
740 };
741 assert!(iter.last().is_none());
742 }
743
744 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 {
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 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 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 {
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 {
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 {
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}