Skip to main content

le_stream/from_le_stream/
core.rs

1use core::iter::once;
2use core::marker::PhantomData;
3use core::ops::{Range, RangeInclusive};
4
5use crate::FromLeStream;
6
7macro_rules! impl_primitives {
8    ($($typ:ty,)+) => {
9        $(
10            impl FromLeStream for $typ {
11                fn from_le_stream<T>(bytes: T) -> Option<Self>
12                where
13                    T: Iterator<Item = u8>,
14                {
15                    <[u8; size_of::<Self>()]>::from_le_stream(bytes).map(Self::from_le_bytes)
16                }
17            }
18        )+
19    };
20}
21
22// Implement u8 separately, since all other conversions depend on it.
23impl_primitives!(
24    u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize, f32, f64,
25);
26
27impl FromLeStream for u8 {
28    fn from_le_stream<T>(mut bytes: T) -> Option<Self>
29    where
30        T: Iterator<Item = Self>,
31    {
32        bytes.next()
33    }
34}
35
36impl FromLeStream for () {
37    /// This is guaranteed to always return `Some(())`.
38    fn from_le_stream<T>(_: T) -> Option<Self>
39    where
40        T: Iterator<Item = u8>,
41    {
42        Some(())
43    }
44}
45
46impl<T> FromLeStream for PhantomData<T> {
47    /// This is guaranteed to always return `Some(PhantomData<T>)`.
48    fn from_le_stream<I>(_: I) -> Option<Self>
49    where
50        I: Iterator<Item = u8>,
51    {
52        Some(Self)
53    }
54}
55
56impl FromLeStream for bool {
57    fn from_le_stream<T>(mut bytes: T) -> Option<Self>
58    where
59        T: Iterator<Item = u8>,
60    {
61        bytes.next().map(|byte| byte != 0)
62    }
63}
64
65impl<T, const SIZE: usize> FromLeStream for [T; SIZE]
66where
67    T: FromLeStream,
68{
69    fn from_le_stream<I>(mut bytes: I) -> Option<Self>
70    where
71        I: Iterator<Item = u8>,
72    {
73        let mut array = [const { None }; SIZE];
74
75        for element in &mut array {
76            element.replace(T::from_le_stream(&mut bytes)?);
77        }
78
79        Some(array.map(|element| element.expect("All elements are initialized.")))
80    }
81}
82
83impl<T> FromLeStream for Option<T>
84where
85    T: FromLeStream,
86{
87    /// This is guaranteed to always return `Some(Option<T>)`.
88    fn from_le_stream<I>(mut bytes: I) -> Option<Self>
89    where
90        I: Iterator<Item = u8>,
91    {
92        bytes.next().map_or_else(
93            || Some(None),
94            |byte| T::from_le_stream(once(byte).chain(bytes)).map(Some),
95        )
96    }
97}
98
99impl<T> FromLeStream for Range<T>
100where
101    T: FromLeStream,
102{
103    fn from_le_stream<I>(mut bytes: I) -> Option<Self>
104    where
105        I: Iterator<Item = u8>,
106    {
107        let start = T::from_le_stream(&mut bytes)?;
108        let end = T::from_le_stream(&mut bytes)?;
109        Some(start..end)
110    }
111}
112
113impl<T> FromLeStream for RangeInclusive<T>
114where
115    T: FromLeStream,
116{
117    fn from_le_stream<I>(mut bytes: I) -> Option<Self>
118    where
119        I: Iterator<Item = u8>,
120    {
121        let start = T::from_le_stream(&mut bytes)?;
122        let end = T::from_le_stream(&mut bytes)?;
123        Some(start..=end)
124    }
125}