bin-layout 7.1.0

This library used to serialize and deserialize data in binary format.
Documentation
use crate::*;

impl Encoder for bool {
    #[inline]
    fn encoder(&self, writer: &mut impl Write) -> io::Result<()> {
        writer.write_all(&[*self as u8])
    }
}

impl Decoder<'_> for bool {
    #[inline]
    fn decoder(c: &mut &[u8]) -> Result<Self> {
        u8::decoder(c).map(|byte| byte != 0)
    }
}

impl Encoder for char {
    #[inline]
    fn encoder(&self, c: &mut impl Write) -> io::Result<()> {
        u32::from(*self).encoder(c)
    }
}
impl Decoder<'_> for char {
    #[inline]
    fn decoder(c: &mut &[u8]) -> Result<Self> {
        let num = u32::decoder(c)?;
        char::from_u32(num).ok_or_else(|| format!("{num} is not a valid char").into())
    }
}

// ----------------------------------------------------------------------------------------------

impl Encoder for u8 {
    #[inline]
    fn encoder(&self, writer: &mut impl Write) -> io::Result<()> {
        writer.write_all(&[*self])
    }
}

impl Decoder<'_> for u8 {
    #[inline]
    fn decoder(reader: &mut &[u8]) -> Result<Self> {
        if !reader.is_empty() {
            unsafe {
                let slice = reader.get_unchecked(0);
                *reader = reader.get_unchecked(1..);
                Ok(*slice)
            }
        } else {
            Err("Insufficient bytes".into())
        }
    }
}

impl Encoder for i8 {
    #[inline]
    fn encoder(&self, writer: &mut impl Write) -> io::Result<()> {
        writer.write_all(&[*self as u8])
    }
}
impl Decoder<'_> for i8 {
    #[inline]
    fn decoder(c: &mut &[u8]) -> Result<Self> {
        u8::decoder(c).map(|byte| byte as i8)
    }
}
macro_rules! impl_data_type_for {
    [$($rty:ty)*] => ($(
        impl Encoder for $rty {
            #[inline] fn encoder(&self, writer: &mut impl Write) -> io::Result<()> {
                #[cfg(not(any(feature = "BE", feature = "NE")))]
                return writer.write_all(&self.to_le_bytes());
                #[cfg(feature = "BE")]
                return writer.write_all(&self.to_be_bytes());
                #[cfg(feature = "NE")]
                return writer.write_all(&self.to_ne_bytes());
            }
        }
        impl Decoder<'_> for $rty {
            #[inline] fn decoder(c: &mut &[u8]) -> Result<Self> {
                let arr = <&[u8; std::mem::size_of::<Self>()]>::decoder(c)?;
                #[cfg(not(any(feature = "BE", feature = "NE")))]
                return Ok(Self::from_le_bytes(*arr));
                #[cfg(feature = "BE")]
                return Ok(Self::from_be_bytes(*arr));
                #[cfg(feature = "NE")]
                return Ok(Self::from_ne_bytes(*arr));
            }
        }
    )*);
}

impl_data_type_for!(
    u16 u32 u64 u128
    i16 i32 i64 i128
    usize isize
    f32 f64
);

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_scaler_type() {
        for word in [0x_A5C11, 0x_C0DE, 0x_DEC0DE, 0x_ADDED, 0x_AB0DE, 0x_CAFE] {
            assert_eq!(word, u32::decode(&word.encode()).unwrap());
        }
        for word in [
            0x_DEAD_BEEF,
            0x_Faded_Face,
            0x_BAD_F00D,
            0x_C01D_C0FFEE,
            0x_C0CA_C01A,
        ] {
            assert_eq!(word, u64::decode(&word.encode()).unwrap());
        }
    }
}