use std::io::{Read, Result as IOResult}; macro_rules! archive_datatype { { $vis:vis struct $struct_name:ident { $( $($fix_field_name:ident: $fix_field_type:ty)? $([const] $const_field_name:ident: $const_field_type:ty = $const_field_value:expr)? , )* } } => { #[derive(Debug)] $vis struct $struct_name { $($(pub $fix_field_name: $fix_field_type,)?)* } #[allow(unused)] impl $struct_name { $($(pub const $const_field_name: $const_field_type = $const_field_value;)?)* } impl ArchiveDatatype<{$($((<$fix_field_type>::BITS as usize / 8)+)?)* 0}> for $struct_name { fn parse(buf: [u8; Self::SIZE]) -> Self { let mut byte = 0; $($( byte += (<$fix_field_type>::BITS / 8) as usize; let $fix_field_name = <$fix_field_type>::from_le_bytes(buf[byte - (<$fix_field_type>::BITS as usize / 8)..byte].try_into().unwrap()); )?)* Self { $($($fix_field_name,)?)* } } fn dump(&self) -> [u8; Self::SIZE] { [$($(&self.$fix_field_name.to_le_bytes()[..],)?)*] .concat() .try_into() .unwrap() } } } } pub(crate) use archive_datatype; pub trait ReadHelper: Read { fn read2buf(&mut self) -> IOResult<[u8; SIZE]> { let mut buf = [0; SIZE]; self.read(&mut buf)?; Ok(buf) } fn read2vec(&mut self, size: usize) -> IOResult> { let mut buf = vec![0; size]; self.read(&mut buf)?; Ok(buf) } } impl ReadHelper for R {}