use std::io;
use crate::{Endian, read::ReadExt};
pub trait Readable: Sized {
fn read(reader: impl ReadExt, endian: Endian) -> io::Result<Self>;
}
macro_rules! int {
(impl $ty:ty) => {
impl Readable for $ty {
fn read(mut reader: impl ReadExt, endian: Endian) -> io::Result<Self> {
let mut bytes = [0; std::mem::size_of::<Self>()];
reader.read_exact(&mut bytes)?;
let value = match endian {
Endian::Big => Self::from_be_bytes(bytes),
Endian::Little => Self::from_le_bytes(bytes),
Endian::Native => Self::from_ne_bytes(bytes),
};
Ok(value)
}
}
};
($($ty:ty)+) => {
$( int!(impl $ty); )+
};
}
int!(u8 u16 u32 u64 u128);
int!(i8 i16 i32 i64 i128);
int!(f32 f64);
impl Readable for bool {
fn read(mut reader: impl ReadExt, endian: Endian) -> io::Result<Self> {
let raw = reader.read_type::<u8>(endian)?;
if raw != 0 && raw != 1 {
return Err(io::Error::from(io::ErrorKind::InvalidData));
}
let value = raw == 1;
Ok(value)
}
}