1use crate::Pod;
2
3use core::{mem, marker};
4
5#[repr(packed(1))]
7pub(crate) struct Out<T>(pub T);
8
9#[derive(Copy, Clone)]
10pub struct Read<'a, OUT> {
31 bytes: &'a [u8],
32 cursor: usize,
33 _out: marker::PhantomData<OUT>
34}
35
36impl<'a, OUT: Pod> Read<'a, OUT> {
37 pub const fn new(bytes: &'a [u8]) -> Self {
39 Self {
40 bytes,
41 cursor: 0,
42 _out: marker::PhantomData,
43 }
44 }
45
46 const fn internal_read_unchecked(&self) -> &Out<OUT> {
47 unsafe {
48 let ptr = self.bytes.as_ptr().add(self.cursor) as *const _;
49 &*ptr
50 }
51 }
52
53 #[inline(always)]
54 pub const unsafe fn read_unchecked(&self) -> OUT {
56 self.internal_read_unchecked().0
57 }
58
59 #[inline(always)]
60 pub const fn read(&self) -> Option<OUT> {
62 if self.bytes.len().saturating_sub(self.cursor) >= mem::size_of::<OUT>() {
63 unsafe {
64 Some(self.read_unchecked())
65 }
66 } else {
67 None
68 }
69 }
70
71 #[inline(always)]
72 pub const fn advance(mut self, add: usize) -> Self {
74 self.cursor = self.cursor.saturating_add(add);
75 self
76 }
77
78 #[inline(always)]
79 pub const fn remaining(&self) -> usize {
81 let remain = self.bytes.len().saturating_sub(self.cursor);
82 remain / mem::size_of::<OUT>()
83 }
84}
85
86impl<'a, OUT: Pod> Iterator for Read<'a, OUT> {
87 type Item = OUT;
88
89 #[inline(always)]
90 fn next(&mut self) -> Option<Self::Item> {
91 match self.read() {
92 Some(res) => {
93 *self = self.advance(mem::size_of::<OUT>());
94 Some(res)
95 },
96 None => None
97 }
98 }
99
100 #[inline(always)]
101 fn size_hint(&self) -> (usize, Option<usize>) {
102 let len = self.remaining();
103 (len, Some(len))
104 }
105}