r-ex 1.0.1

Zero-bloat Rust core library extensions
Documentation
pub trait EndianAs<T> {
    fn as_be(&self) -> T;
    fn as_le(&self) -> T;
}

pub trait EndianFromRef<T, U> {
    fn from_be_ref(buf: &U) -> T;
    fn from_le_ref(buf: &U) -> T;
}

pub trait EndianSet<T> {
    fn set_be(&mut self, val: T);
    fn set_le(&mut self, val: T);
}

macro_rules! impl_endian_traits {
    ($typ:ty) => {
        impl EndianAs<$typ> for [u8; core::mem::size_of::<$typ>()] {
            #[inline]
            fn as_be(&self) -> $typ { <$typ>::from_be_bytes(*self) }

            #[inline]
            fn as_le(&self) -> $typ { <$typ>::from_le_bytes(*self) }
        }

        impl EndianFromRef<$typ, [u8; core::mem::size_of::<$typ>()]> for $typ {
            #[inline]
            fn from_be_ref(buf: &[u8; core::mem::size_of::<$typ>()]) -> $typ { <$typ>::from_be_bytes(*buf) }

            #[inline]
            fn from_le_ref(buf: &[u8; core::mem::size_of::<$typ>()]) -> $typ { <$typ>::from_le_bytes(*buf) }
        }

        impl EndianSet<$typ> for [u8; core::mem::size_of::<$typ>()] {
            #[inline]
            fn set_be(&mut self, val: $typ) { self.copy_from_slice(&val.to_be_bytes()); }

            #[inline]
            fn set_le(&mut self, val: $typ) { self.copy_from_slice(&val.to_le_bytes()); }
        }
    };
}

impl_endian_traits!(u16);
impl_endian_traits!(u32);
impl_endian_traits!(u64);
impl_endian_traits!(u128);

impl_endian_traits!(i16);
impl_endian_traits!(i32);
impl_endian_traits!(i64);
impl_endian_traits!(i128);

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

    macro_rules! test_endian_traits {
        ($typ:ty, $typ_ident:ident) => {

            #[test]
            fn $typ_ident() {
                let mut buf = [0u8; core::mem::size_of::<$typ>()];

                buf.set_be(1 as $typ);
                assert_eq!((1 as $typ).to_be_bytes(), buf);
                assert_eq!((1 as $typ), buf.as_be());
                assert_eq!((1 as $typ), <$typ>::from_be_ref(&buf));
                assert_eq!((1 as $typ), <$typ>::from_be_ref(&mut buf));

                buf.set_le(1 as $typ);
                assert_eq!((1 as $typ).to_le_bytes(), buf);
                assert_eq!((1 as $typ), buf.as_le());
                assert_eq!((1 as $typ), <$typ>::from_le_ref(&buf));
                assert_eq!((1 as $typ), <$typ>::from_le_ref(&mut buf));
            }
        }
    }

    test_endian_traits!(u16, u16);
    test_endian_traits!(u32, u32);
    test_endian_traits!(u64, u64);
    test_endian_traits!(u128, u128);

    test_endian_traits!(i16, i16);
    test_endian_traits!(i32, i32);
    test_endian_traits!(i64, i64);
    test_endian_traits!(i128, i128);
}