use std::mem::size_of as sof;
use std::io::{Read, Result};
macro_rules! impl_read {
($($type:ty),*) => {
$(
paste::paste! {
#[inline]
fn [<read_ $type _ne>](&mut self) -> $type {
let mut buf: [u8; sof::<$type>()] = unsafe { std::mem::MaybeUninit::uninit().assume_init() };
self.read_exact(&mut buf).expect("Read failed");
<$type>::from_ne_bytes(buf)
}
#[inline]
fn [<read_ $type _ne_checked>](&mut self) -> Result<$type> {
let mut buf: [u8; sof::<$type>()] = unsafe { std::mem::MaybeUninit::uninit().assume_init() };
self.read_exact(&mut buf)?;
Ok(<$type>::from_ne_bytes(buf))
}
#[inline]
fn [<read_ $type>](&mut self) -> $type {
let mut buf: [u8; sof::<$type>()] = unsafe { std::mem::MaybeUninit::uninit().assume_init() };
self.read_exact(&mut buf).expect("Read failed");
<$type>::from_be_bytes(buf)
}
#[inline]
fn [<read_ $type _checked>](&mut self) -> Result<$type> {
let mut buf: [u8; sof::<$type>()] = unsafe { std::mem::MaybeUninit::uninit().assume_init() };
self.read_exact(&mut buf)?;
Ok(<$type>::from_be_bytes(buf))
}
#[inline]
fn [<read_ $type _le>](&mut self) -> $type {
let mut buf: [u8; sof::<$type>()] = unsafe { std::mem::MaybeUninit::uninit().assume_init() };
self.read_exact(&mut buf).expect("Read failed");
<$type>::from_le_bytes(buf)
}
#[inline]
fn [<read_ $type _le_checked>](&mut self) -> Result<$type> {
let mut buf: [u8; sof::<$type>()] = unsafe { std::mem::MaybeUninit::uninit().assume_init() };
self.read_exact(&mut buf)?;
Ok(<$type>::from_le_bytes(buf))
}
}
)*
};
}
pub trait ReadExt: Read {
#[inline]
fn read_u8(&mut self) -> u8 {
let mut v = 0u8;
self.read_exact(std::slice::from_mut(&mut v)).expect("Read failed");
v
}
#[inline]
fn read_u8_checked(&mut self) -> Result<u8> {
let mut v = 0u8;
self.read_exact(std::slice::from_mut(&mut v))?;
Ok(v)
}
impl_read!(f32, f64, u16, i16, u32, i32, u64, i64, u128, i128);
}
impl<R> ReadExt for R
where
R: Read
{ }