diff --git a/src/lib.rs b/src/lib.rs index e0ae2e1..1180b33 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -72,11 +72,7 @@ pub trait PopFromNE { // // Impl PopFromNE, PopFromLE, PopFromBE for core primitive types -// TODO: Create macro(s) for impls. Most of these impls are the same except for the the type name. -// TODO: Impl for u128 and i128 -// TODO: Impl for usize and isize // - impl PopFromNE for u8 { fn pop_ne_from(source: &mut &[u8]) -> Result where @@ -113,7 +109,8 @@ impl PopFromBE for u8 { where Self: Sized, { - u8::pop_ne_from(source) + let x = u8::from_be(u8::pop_ne_from(source)?); + Ok(x) } fn push_be_into(&self, dest: &mut T) -> Result<()> { @@ -121,423 +118,121 @@ impl PopFromBE for u8 { } } -// Impls for u16 -impl PopFromNE for u16 { - fn pop_ne_from(source: &mut &[u8]) -> Result - where - Self: Sized, - { - const SIZE: usize = std::mem::size_of::(); - if source.len() < SIZE { - anyhow::bail!("Buffer too small to pop u16"); +macro_rules! core_impl_pop_ne { + ($int_type: ident) => { + impl PopFromNE for $int_type { + fn pop_ne_from(source: &mut &[u8]) -> Result + where + Self: Sized, + { + const SIZE: usize = std::mem::size_of::<$int_type>(); + if source.len() < SIZE { + anyhow::bail!("Buffer too small to pop {}", stringify!($int_type)); + } + let value = $int_type::from_ne_bytes(source[..SIZE].try_into()?); + *source = &source[SIZE..]; + Ok(value) + } + + fn push_ne_into(&self, dest: &mut T) -> Result<()> { + dest.push_slice(&self.to_ne_bytes()) + } } - let value = u16::from_be_bytes(source[..SIZE].try_into()?); - *source = &source[SIZE..]; - Ok(value) - } - - fn push_ne_into(&self, dest: &mut T) -> Result<()> { - dest.push_slice(&self.to_ne_bytes()) - } + }; } -impl PopFromLE for u16 { - fn pop_le_from(source: &mut &[u8]) -> Result - where - Self: Sized, - { - Ok(Self::from_le(Self::pop_ne_from(source)?)) - } +macro_rules! int_impl_pop_non_ne { + ($int_type: ident) => { + impl PopFromLE for $int_type { + fn pop_le_from(source: &mut &[u8]) -> Result + where + Self: Sized, + { + Ok(Self::from_le(Self::pop_ne_from(source)?)) + } - fn push_le_into(&self, dest: &mut T) -> Result<()> { - dest.push_slice(&self.to_le_bytes()) - } -} -impl PopFromBE for u16 { - fn pop_be_from(source: &mut &[u8]) -> Result - where - Self: Sized, - { - Ok(Self::from_be(Self::pop_ne_from(source)?)) - } - - fn push_be_into(&self, dest: &mut T) -> Result<()> { - dest.push_slice(&self.to_be_bytes()) - } -} - -//Impls for u32 -impl PopFromNE for u32 { - fn pop_ne_from(source: &mut &[u8]) -> Result - where - Self: Sized, - { - const SIZE: usize = std::mem::size_of::(); - if source.len() < SIZE { - anyhow::bail!("Buffer too small to pop u32"); + fn push_le_into(&self, dest: &mut T) -> Result<()> { + dest.push_slice(&self.to_le_bytes()) + } } - let value = u32::from_be_bytes(source[..SIZE].try_into()?); - *source = &source[SIZE..]; - Ok(value) - } + impl PopFromBE for $int_type { + fn pop_be_from(source: &mut &[u8]) -> Result + where + Self: Sized, + { + Ok(Self::from_be(Self::pop_ne_from(source)?)) + } - fn push_ne_into(&self, dest: &mut T) -> Result<()> { - dest.push_slice(&self.to_ne_bytes()) - } -} -impl PopFromLE for u32 { - fn pop_le_from(source: &mut &[u8]) -> Result - where - Self: Sized, - { - Ok(Self::from_le(Self::pop_ne_from(source)?)) - } - - fn push_le_into(&self, dest: &mut T) -> Result<()> { - dest.push_slice(&self.to_le_bytes()) - } -} -impl PopFromBE for u32 { - fn pop_be_from(source: &mut &[u8]) -> Result - where - Self: Sized, - { - Ok(Self::from_be(Self::pop_ne_from(source)?)) - } - - fn push_be_into(&self, dest: &mut T) -> Result<()> { - dest.push_slice(&self.to_be_bytes()) - } -} - -//Impls for u64 -impl PopFromNE for u64 { - fn pop_ne_from(source: &mut &[u8]) -> Result - where - Self: Sized, - { - const SIZE: usize = std::mem::size_of::(); - if source.len() < SIZE { - anyhow::bail!("Buffer too small to pop u64"); + fn push_be_into(&self, dest: &mut T) -> Result<()> { + dest.push_slice(&self.to_be_bytes()) + } } - let value = u64::from_be_bytes(source[..SIZE].try_into()?); - *source = &source[SIZE..]; - Ok(value) - } - - fn push_ne_into(&self, dest: &mut T) -> Result<()> { - dest.push_slice(&self.to_ne_bytes()) - } + }; } -impl PopFromLE for u64 { - fn pop_le_from(source: &mut &[u8]) -> Result - where - Self: Sized, - { - Ok(Self::from_le(Self::pop_ne_from(source)?)) - } +macro_rules! flt_impl_pop_non_ne { + ($flt_type: ident) => { + impl PopFromLE for $flt_type { + fn pop_le_from(source: &mut &[u8]) -> Result + where + Self: Sized, + { + const SIZE: usize = std::mem::size_of::<$flt_type>(); + if source.len() < SIZE { + anyhow::bail!("Buffer to small to pop $flt_type"); + } + let value = $flt_type::from_le_bytes(source[..SIZE].try_into()?); + *source = &source[SIZE..]; + Ok(value) + } - fn push_le_into(&self, dest: &mut T) -> Result<()> { - dest.push_slice(&self.to_le_bytes()) - } -} -impl PopFromBE for u64 { - fn pop_be_from(source: &mut &[u8]) -> Result - where - Self: Sized, - { - Ok(Self::from_be(Self::pop_ne_from(source)?)) - } - - fn push_be_into(&self, dest: &mut T) -> Result<()> { - dest.push_slice(&self.to_be_bytes()) - } -} - -impl PopFromNE for i8 { - fn pop_ne_from(source: &mut &[u8]) -> Result - where - Self: Sized, - { - const SIZE: usize = std::mem::size_of::(); - if source.len() < SIZE { - anyhow::bail!("Buffer too small to pop i8"); + fn push_le_into(&self, dest: &mut T) -> Result<()> { + dest.push_slice(&self.to_le_bytes()) + } } + impl PopFromBE for $flt_type { + fn pop_be_from(source: &mut &[u8]) -> Result + where + Self: Sized, + { + const SIZE: usize = std::mem::size_of::<$flt_type>(); + if source.len() < SIZE { + anyhow::bail!("Buffer to small to pop $flt_type"); + } + let value = $flt_type::from_be_bytes(source[..SIZE].try_into()?); + *source = &source[SIZE..]; + Ok(value) + } - let value = source[0] as i8; - *source = &source[SIZE..]; - Ok(value) - } - - fn push_ne_into(&self, dest: &mut T) -> Result<()> { - dest.push_u8(&(*self as u8)) - } -} -impl PopFromLE for i8 { - fn pop_le_from(source: &mut &[u8]) -> Result - where - Self: Sized, - { - i8::pop_ne_from(source) - } - - fn push_le_into(&self, dest: &mut T) -> Result<()> { - self.push_ne_into(dest) - } -} -impl PopFromBE for i8 { - fn pop_be_from(source: &mut &[u8]) -> Result - where - Self: Sized, - { - i8::pop_ne_from(source) - } - - fn push_be_into(&self, dest: &mut T) -> Result<()> { - self.push_ne_into(dest) - } -} - -impl PopFromNE for i16 { - fn pop_ne_from(source: &mut &[u8]) -> Result - where - Self: Sized, - { - const SIZE: usize = std::mem::size_of::(); - if source.len() < SIZE { - anyhow::bail!("Buffer too small to pop i16"); + fn push_be_into(&self, dest: &mut T) -> Result<()> { + dest.push_slice(&self.to_be_bytes()) + } } - - let value = i16::from_be_bytes(source[..SIZE].try_into()?); - *source = &source[SIZE..]; - Ok(value) - } - - fn push_ne_into(&self, dest: &mut T) -> Result<()> { - dest.push_slice(&self.to_ne_bytes()) - } -} -impl PopFromNE for i32 { - fn pop_ne_from(source: &mut &[u8]) -> Result - where - Self: Sized, - { - const SIZE: usize = std::mem::size_of::(); - if source.len() < SIZE { - anyhow::bail!("Buffer too small to pop i32"); - } - - let value = i32::from_be_bytes(source[..SIZE].try_into()?); - *source = &source[SIZE..]; - Ok(value) - } - - fn push_ne_into(&self, dest: &mut T) -> Result<()> { - dest.push_slice(&self.to_ne_bytes()) - } -} -impl PopFromNE for i64 { - fn pop_ne_from(source: &mut &[u8]) -> Result - where - Self: Sized, - { - const SIZE: usize = std::mem::size_of::(); - if source.len() < SIZE { - anyhow::bail!("Buffer too small to pop i64"); - } - - let value = i64::from_be_bytes(source[..SIZE].try_into()?); - *source = &source[SIZE..]; - Ok(value) - } - - fn push_ne_into(&self, dest: &mut T) -> Result<()> { - dest.push_slice(&self.to_ne_bytes()) - } + }; } -impl PopFromLE for i16 { - fn pop_le_from(source: &mut &[u8]) -> Result - where - Self: Sized, - { - Ok(Self::from_le(Self::pop_ne_from(source)?)) - } +core_impl_pop_ne!(u16); +core_impl_pop_ne!(u32); +core_impl_pop_ne!(u64); +core_impl_pop_ne!(u128); +core_impl_pop_ne!(usize); +core_impl_pop_ne!(i16); +core_impl_pop_ne!(i32); +core_impl_pop_ne!(i64); +core_impl_pop_ne!(i128); +core_impl_pop_ne!(isize); - fn push_le_into(&self, dest: &mut T) -> Result<()> { - dest.push_slice(&self.to_le_bytes()) - } -} -impl PopFromLE for i32 { - fn pop_le_from(source: &mut &[u8]) -> Result - where - Self: Sized, - { - Ok(Self::from_le(Self::pop_ne_from(source)?)) - } +int_impl_pop_non_ne!(u16); +int_impl_pop_non_ne!(u32); +int_impl_pop_non_ne!(u64); +int_impl_pop_non_ne!(u128); +int_impl_pop_non_ne!(usize); +int_impl_pop_non_ne!(i16); +int_impl_pop_non_ne!(i32); +int_impl_pop_non_ne!(i64); +int_impl_pop_non_ne!(i128); +int_impl_pop_non_ne!(isize); - fn push_le_into(&self, dest: &mut T) -> Result<()> { - dest.push_slice(&self.to_le_bytes()) - } -} -impl PopFromLE for i64 { - fn pop_le_from(source: &mut &[u8]) -> Result - where - Self: Sized, - { - Ok(Self::from_le(Self::pop_ne_from(source)?)) - } +core_impl_pop_ne!(f32); +flt_impl_pop_non_ne!(f32); - fn push_le_into(&self, dest: &mut T) -> Result<()> { - dest.push_slice(&self.to_le_bytes()) - } -} - -impl PopFromBE for i16 { - fn pop_be_from(source: &mut &[u8]) -> Result - where - Self: Sized, - { - Ok(Self::from_be(Self::pop_ne_from(source)?)) - } - - fn push_be_into(&self, dest: &mut T) -> Result<()> { - dest.push_slice(&self.to_be_bytes()) - } -} -impl PopFromBE for i32 { - fn pop_be_from(source: &mut &[u8]) -> Result - where - Self: Sized, - { - Ok(Self::from_be(Self::pop_ne_from(source)?)) - } - - fn push_be_into(&self, dest: &mut T) -> Result<()> { - dest.push_slice(&self.to_be_bytes()) - } -} -impl PopFromBE for i64 { - fn pop_be_from(source: &mut &[u8]) -> Result - where - Self: Sized, - { - Ok(Self::from_be(Self::pop_ne_from(source)?)) - } - - fn push_be_into(&self, dest: &mut T) -> Result<()> { - dest.push_slice(&self.to_be_bytes()) - } -} - -// -// Floating Point -// -impl PopFromNE for f32 { - fn pop_ne_from(source: &mut &[u8]) -> Result - where - Self: Sized, - { - const SIZE: usize = std::mem::size_of::(); - if source.len() < SIZE { - anyhow::bail!("Buffer to small to pop f32"); - } - let value = f32::from_ne_bytes(source[..SIZE].try_into()?); - *source = &source[SIZE..]; - Ok(value) - } - - fn push_ne_into(&self, dest: &mut T) -> Result<()> { - dest.push_slice(&self.to_ne_bytes()) - } -} -impl PopFromLE for f32 { - fn pop_le_from(source: &mut &[u8]) -> Result - where - Self: Sized, - { - const SIZE: usize = std::mem::size_of::(); - if source.len() < SIZE { - anyhow::bail!("Buffer to small to pop f32"); - } - let value = f32::from_le_bytes(source[..SIZE].try_into()?); - *source = &source[SIZE..]; - Ok(value) - } - - fn push_le_into(&self, dest: &mut T) -> Result<()> { - dest.push_slice(&self.to_le_bytes()) - } -} -impl PopFromBE for f32 { - fn pop_be_from(source: &mut &[u8]) -> Result - where - Self: Sized, - { - const SIZE: usize = std::mem::size_of::(); - if source.len() < SIZE { - anyhow::bail!("Buffer to small to pop f32"); - } - let value = f32::from_be_bytes(source[..SIZE].try_into()?); - *source = &source[SIZE..]; - Ok(value) - } - - fn push_be_into(&self, dest: &mut T) -> Result<()> { - dest.push_slice(&self.to_be_bytes()) - } -} - -impl PopFromNE for f64 { - fn pop_ne_from(source: &mut &[u8]) -> Result - where - Self: Sized, - { - const SIZE: usize = std::mem::size_of::(); - if source.len() < SIZE { - anyhow::bail!("Buffer to small to pop f64"); - } - let value = f64::from_ne_bytes(source[..SIZE].try_into()?); - *source = &source[SIZE..]; - Ok(value) - } - - fn push_ne_into(&self, dest: &mut T) -> Result<()> { - dest.push_slice(&self.to_ne_bytes()) - } -} -impl PopFromLE for f64 { - fn pop_le_from(source: &mut &[u8]) -> Result - where - Self: Sized, - { - const SIZE: usize = std::mem::size_of::(); - if source.len() < SIZE { - anyhow::bail!("Buffer to small to pop f64"); - } - let value = f64::from_le_bytes(source[..SIZE].try_into()?); - *source = &source[SIZE..]; - Ok(value) - } - - fn push_le_into(&self, dest: &mut T) -> Result<()> { - dest.push_slice(&self.to_le_bytes()) - } -} -impl PopFromBE for f64 { - fn pop_be_from(source: &mut &[u8]) -> Result - where - Self: Sized, - { - const SIZE: usize = std::mem::size_of::(); - if source.len() < SIZE { - anyhow::bail!("Buffer to small to pop f64"); - } - let value = f64::from_be_bytes(source[..SIZE].try_into()?); - *source = &source[SIZE..]; - Ok(value) - } - - fn push_be_into(&self, dest: &mut T) -> Result<()> { - dest.push_slice(&self.to_be_bytes()) - } -} +core_impl_pop_ne!(f64); +flt_impl_pop_non_ne!(f64);