1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
use crate::sealed; use core::num::Wrapping; pub trait Encoding<T>: Copy + From<T> + Sized + sealed::Sealed where T: From<Self>, { const ZERO: Self; fn into_raw_value(self) -> T; } pub fn as_bytes<E: Encoding<T>, T>(x: &[E]) -> &[u8] where T: From<E>, { unsafe { core::slice::from_raw_parts(x.as_ptr() as *const u8, x.len() * core::mem::size_of::<E>()) } } macro_rules! define_endian { ($endian:ident) => { #[repr(transparent)] #[derive(Copy, Clone)] pub struct $endian<T>(T) where T: Copy + Clone + Sized; impl<T> sealed::Sealed for $endian<T> where T: Copy + Clone + Sized {} }; } macro_rules! impl_endian { ($endian:ident, $base:ident, $to_endian:ident, $from_endian:ident) => { impl Encoding<$base> for $endian<$base> { const ZERO: Self = Self(0); #[inline] fn into_raw_value(self) -> $base { self.0 } } impl From<$base> for $endian<$base> { #[inline] fn from(value: $base) -> Self { Self($base::$to_endian(value)) } } impl From<Wrapping<$base>> for $endian<$base> { #[inline] fn from(Wrapping(value): Wrapping<$base>) -> Self { Self($base::$to_endian(value)) } } impl From<$endian<$base>> for $base { #[inline] fn from($endian(value): $endian<$base>) -> Self { $base::$from_endian(value) } } }; } define_endian!(BigEndian); define_endian!(LittleEndian); impl_endian!(BigEndian, u32, to_be, from_be); impl_endian!(BigEndian, u64, to_be, from_be); impl_endian!(LittleEndian, u32, to_le, from_le); impl_endian!(LittleEndian, u64, to_le, from_le); #[cfg(test)] mod tests { use super::*; #[test] fn test_big_endian() { let x = BigEndian::from(1u32); assert_eq!(u32::from(x), 1); } }