use core::iter::once;
use core::marker::PhantomData;
use core::ops::{Range, RangeInclusive};
use crate::FromLeStream;
macro_rules! impl_primitives {
($($typ:ty,)+) => {
$(
impl FromLeStream for $typ {
fn from_le_stream<T>(bytes: T) -> Option<Self>
where
T: Iterator<Item = u8>,
{
<[u8; size_of::<Self>()]>::from_le_stream(bytes).map(Self::from_le_bytes)
}
}
)+
};
}
impl_primitives!(
u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize, f32, f64,
);
impl FromLeStream for u8 {
fn from_le_stream<T>(mut bytes: T) -> Option<Self>
where
T: Iterator<Item = Self>,
{
bytes.next()
}
}
impl FromLeStream for () {
fn from_le_stream<T>(_: T) -> Option<Self>
where
T: Iterator<Item = u8>,
{
Some(())
}
}
impl<T> FromLeStream for PhantomData<T> {
fn from_le_stream<I>(_: I) -> Option<Self>
where
I: Iterator<Item = u8>,
{
Some(Self)
}
}
impl FromLeStream for bool {
fn from_le_stream<T>(mut bytes: T) -> Option<Self>
where
T: Iterator<Item = u8>,
{
bytes.next().map(|byte| byte != 0)
}
}
impl<T, const SIZE: usize> FromLeStream for [T; SIZE]
where
T: FromLeStream,
{
fn from_le_stream<I>(mut bytes: I) -> Option<Self>
where
I: Iterator<Item = u8>,
{
let mut array = [const { None }; SIZE];
for element in &mut array {
element.replace(T::from_le_stream(&mut bytes)?);
}
Some(array.map(|element| element.expect("All elements are initialized.")))
}
}
impl<T> FromLeStream for Option<T>
where
T: FromLeStream,
{
fn from_le_stream<I>(mut bytes: I) -> Option<Self>
where
I: Iterator<Item = u8>,
{
bytes.next().map_or_else(
|| Some(None),
|byte| T::from_le_stream(once(byte).chain(bytes)).map(Some),
)
}
}
impl<T> FromLeStream for Range<T>
where
T: FromLeStream,
{
fn from_le_stream<I>(mut bytes: I) -> Option<Self>
where
I: Iterator<Item = u8>,
{
let start = T::from_le_stream(&mut bytes)?;
let end = T::from_le_stream(&mut bytes)?;
Some(start..end)
}
}
impl<T> FromLeStream for RangeInclusive<T>
where
T: FromLeStream,
{
fn from_le_stream<I>(mut bytes: I) -> Option<Self>
where
I: Iterator<Item = u8>,
{
let start = T::from_le_stream(&mut bytes)?;
let end = T::from_le_stream(&mut bytes)?;
Some(start..=end)
}
}