Skip to main content

rw_types/read/
readable.rs

1use std::io;
2
3use crate::{Endian, read::ReadExt};
4
5/// A trait for objects that can be read.
6pub trait Readable: Sized {
7    /// Reads this object with the specified writer and endian.
8    fn read(reader: impl ReadExt, endian: Endian) -> io::Result<Self>;
9}
10
11macro_rules! num {
12    (impl $ty:ty) => {
13        impl Readable for $ty {
14            fn read(mut reader: impl ReadExt, endian: Endian) -> io::Result<Self> {
15                let mut bytes = [0; std::mem::size_of::<Self>()];
16                reader.read_exact(&mut bytes)?;
17                let value = match endian {
18                    Endian::Big => Self::from_be_bytes(bytes),
19                    Endian::Little => Self::from_le_bytes(bytes),
20                    Endian::Native => Self::from_ne_bytes(bytes),
21                };
22                Ok(value)
23            }
24        }
25    };
26    ($($ty:ty)+) => {
27        $( num!(impl $ty); )+
28    };
29}
30
31num!(u8 u16 u32 u64 u128);
32num!(i8 i16 i32 i64 i128);
33num!(f32 f64);
34
35impl Readable for bool {
36    fn read(mut reader: impl ReadExt, endian: Endian) -> io::Result<Self> {
37        let raw = reader.read_ty::<u8>(endian)?;
38        if raw != 0 && raw != 1 {
39            return Err(io::Error::from(io::ErrorKind::InvalidData));
40        }
41        let value = raw == 1;
42        Ok(value)
43    }
44}