Skip to main content

le_stream/
stream.rs

1use core::marker::PhantomData;
2
3use crate::FromLeStream;
4
5/// Extension trait for reading typed values from an iterator of bytes.
6pub trait LeStream: Sized {
7    /// Converts an iterator of little-endian bytes into an iterator of `T`.
8    ///
9    /// Iteration stops when `T::from_le_stream` returns [`None`], usually
10    /// because the underlying byte iterator is exhausted or ends with an
11    /// incomplete value.
12    fn le_stream<T>(self) -> LeStreamIterator<T, Self>;
13}
14
15impl<I> LeStream for I
16where
17    I: Iterator<Item = u8>,
18{
19    fn le_stream<T>(self) -> LeStreamIterator<T, Self> {
20        LeStreamIterator {
21            iterator: self,
22            _type: PhantomData,
23        }
24    }
25}
26
27/// Iterator adapter returned by [`LeStream::le_stream`].
28#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
29pub struct LeStreamIterator<T, I> {
30    iterator: I,
31    _type: PhantomData<T>,
32}
33
34impl<T, I> LeStreamIterator<T, I> {
35    /// Consumes the adapter and returns the underlying byte iterator.
36    #[must_use]
37    pub fn into_inner(self) -> I {
38        self.iterator
39    }
40}
41
42impl<T, I> Iterator for LeStreamIterator<T, I>
43where
44    T: FromLeStream,
45    I: Iterator<Item = u8>,
46{
47    type Item = T;
48
49    fn next(&mut self) -> Option<Self::Item> {
50        T::from_le_stream(&mut self.iterator)
51    }
52}