1 use core::convert::TryInto;
2 
3 pub trait ByteOrder {
read_u16(buf: &[u8]) -> u164     fn read_u16(buf: &[u8]) -> u16;
read_u32(buf: &[u8]) -> u325     fn read_u32(buf: &[u8]) -> u32;
read_u64(buf: &[u8]) -> u646     fn read_u64(buf: &[u8]) -> u64;
read_uint(buf: &[u8], nbytes: usize) -> u647     fn read_uint(buf: &[u8], nbytes: usize) -> u64;
write_u16(buf: &mut [u8], n: u16)8     fn write_u16(buf: &mut [u8], n: u16);
write_u32(buf: &mut [u8], n: u32)9     fn write_u32(buf: &mut [u8], n: u32);
write_u64(buf: &mut [u8], n: u64)10     fn write_u64(buf: &mut [u8], n: u64);
write_uint(buf: &mut [u8], n: u64, nbytes: usize)11     fn write_uint(buf: &mut [u8], n: u64, nbytes: usize);
12 }
13 
14 pub enum BigEndian {}
15 pub enum LittleEndian {}
16 pub enum NativeEndian {}
17 
18 macro_rules! impl_endian {
19     ($t:ty, $from_endian:ident, $to_endian:ident) => {
20         impl ByteOrder for $t {
21             #[inline]
22             fn read_u16(buf: &[u8]) -> u16 {
23                 u16::$from_endian(buf[0..2].try_into().unwrap())
24             }
25 
26             #[inline]
27             fn read_u32(buf: &[u8]) -> u32 {
28                 u32::$from_endian(buf[0..4].try_into().unwrap())
29             }
30 
31             #[inline]
32             fn read_u64(buf: &[u8]) -> u64 {
33                 u64::$from_endian(buf[0..8].try_into().unwrap())
34             }
35 
36             #[inline]
37             fn read_uint(buf: &[u8], nbytes: usize) -> u64 {
38                 let mut dst = [0u8; 8];
39                 dst[..nbytes].copy_from_slice(&buf[..nbytes]);
40                 u64::$from_endian(dst)
41             }
42 
43             #[inline]
44             fn write_u16(buf: &mut [u8], n: u16) {
45                 buf[0..2].copy_from_slice(&n.$to_endian()[..]);
46             }
47 
48             #[inline]
49             fn write_u32(buf: &mut [u8], n: u32) {
50                 buf[0..4].copy_from_slice(&n.$to_endian()[..]);
51             }
52 
53             #[inline]
54             fn write_u64(buf: &mut [u8], n: u64) {
55                 buf[0..8].copy_from_slice(&n.$to_endian()[..]);
56             }
57 
58             #[inline]
59             fn write_uint(buf: &mut [u8], n: u64, nbytes: usize) {
60                 buf[..nbytes].copy_from_slice(&n.$to_endian()[..nbytes]);
61             }
62         }
63     };
64 }
65 
66 impl_endian! {
67     BigEndian, from_be_bytes, to_be_bytes
68 }
69 
70 impl_endian! {
71     LittleEndian, from_le_bytes, to_le_bytes
72 }
73 
74 impl_endian! {
75     NativeEndian, from_ne_bytes, to_ne_bytes
76 }
77