1use byteorder::{BigEndian, ByteOrder};
6use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout, Unaligned};
7
8macro_rules! big_endian_inttype {
9 ($struct_name:ident, $inttype:ty, $read_fn:ident, $write_fn:ident, $width:expr) => {
10 #[repr(C)]
11 #[derive(
12 Clone,
13 Copy,
14 Debug,
15 Default,
16 IntoBytes,
17 FromBytes,
18 KnownLayout,
19 Immutable,
20 Unaligned,
21 PartialEq,
22 Eq,
23 )]
24 pub struct $struct_name(pub [u8; $width]);
25 impl $struct_name {
26 pub fn from_native(native: $inttype) -> Self {
27 let mut buf = [0u8; $width];
28 BigEndian::$write_fn(&mut buf, native);
29 $struct_name(buf)
30 }
31
32 pub fn to_native(&self) -> $inttype {
33 BigEndian::$read_fn(&self.0)
34 }
35
36 pub fn set_from_native(&mut self, value: $inttype) {
37 BigEndian::$write_fn(&mut self.0, value);
38 }
39 }
40 };
41}
42
43big_endian_inttype!(BigEndianU16, u16, read_u16, write_u16, 2);
44big_endian_inttype!(BigEndianU32, u32, read_u32, write_u32, 4);
45big_endian_inttype!(BigEndianU64, u64, read_u64, write_u64, 8);
46big_endian_inttype!(BigEndianU128, u128, read_u128, write_u128, 16);
47
48#[cfg(test)]
49mod tests {
50 use super::*;
51
52 #[test]
53 fn big_endian_u16() {
54 let mut x = BigEndianU16::from_native(0x1234);
55 assert_eq!([0x12, 0x34], x.0);
56 assert_eq!(0x1234, x.to_native());
57
58 x.set_from_native(0x5678);
59 assert_eq!([0x56, 0x78], x.0);
60 assert_eq!(0x5678, x.to_native());
61 }
62
63 #[test]
64 fn big_endian_u32() {
65 let mut x = BigEndianU32::from_native(0x12345678);
66 assert_eq!([0x12, 0x34, 0x56, 0x78], x.0);
67 assert_eq!(0x12345678, x.to_native());
68
69 x.set_from_native(0x12345678);
70 assert_eq!([0x12, 0x34, 0x56, 0x78], x.0);
71 assert_eq!(0x12345678, x.to_native());
72 }
73
74 #[test]
75 fn big_endian_u64() {
76 let mut x = BigEndianU64::from_native(0x0123456789abcdef);
77 assert_eq!([0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef], x.0);
78 assert_eq!(0x0123456789abcdef, x.to_native());
79
80 x.set_from_native(0x0123456789abcdef);
81 assert_eq!([0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef], x.0);
82 assert_eq!(0x0123456789abcdef, x.to_native());
83 }
84
85 #[test]
86 fn big_endian_u128() {
87 let mut x = BigEndianU128::from_native(0x0123456789abcdef0000111122223333);
88 assert_eq!(
89 [
90 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x00, 0x00, 0x11, 0x11, 0x22, 0x22,
91 0x33, 0x33,
92 ],
93 x.0
94 );
95 assert_eq!(0x0123456789abcdef0000111122223333, x.to_native());
96
97 x.set_from_native(0x0123456789abcdef0000111122223333);
98 assert_eq!(
99 [
100 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x00, 0x00, 0x11, 0x11, 0x22, 0x22,
101 0x33, 0x33,
102 ],
103 x.0
104 );
105 assert_eq!(0x0123456789abcdef0000111122223333, x.to_native());
106 }
107}