1pub(crate) trait Convert<To> {
2 fn convert(self) -> To;
3}
4
5macro_rules! convert {
6 ($a:ty, $b:ty) => {
7 impl Convert<$b> for $a {
8 #[inline(always)]
9 fn convert(self) -> $b {
10 zerocopy::transmute!(self)
11 }
12 }
13 impl Convert<$a> for $b {
14 #[inline(always)]
15 fn convert(self) -> $a {
16 zerocopy::transmute!(self)
17 }
18 }
19 };
20}
21
22macro_rules! convert_primitive_bytes {
23 ($a:ty, $b:ty) => {
24 impl Convert<$b> for $a {
25 #[inline(always)]
26 fn convert(self) -> $b {
27 self.to_ne_bytes()
28 }
29 }
30 impl Convert<$a> for $b {
31 #[inline(always)]
32 fn convert(self) -> $a {
33 <$a>::from_ne_bytes(self)
34 }
35 }
36 };
37}
38
39convert!([u128; 4], [u8; 64]);
40convert!([u128; 2], [u64; 4]);
41convert!([u128; 2], [u8; 32]);
42convert!(u128, [u64; 2]);
43convert_primitive_bytes!(u128, [u8; 16]);
44convert!([u64; 2], [u32; 4]);
45#[cfg(test)]
46convert!([u64; 2], [u8; 16]);
47convert_primitive_bytes!(u64, [u8; 8]);
48convert_primitive_bytes!(u32, [u8; 4]);
49convert_primitive_bytes!(u16, [u8; 2]);
50convert!([[u64; 4]; 2], [u8; 64]);
51
52macro_rules! as_array {
53 ($input:expr, $len:expr) => {{
54 {
55 #[inline(always)]
56 fn as_array<T>(slice: &[T]) -> &[T; $len] {
57 core::convert::TryFrom::try_from(slice).unwrap()
58 }
59 as_array($input)
60 }
61 }};
62}
63
64pub(crate) trait ReadFromSlice {
65 fn read_u16(&self) -> (u16, &[u8]);
66 fn read_u32(&self) -> (u32, &[u8]);
67 fn read_u64(&self) -> (u64, &[u8]);
68 fn read_u128(&self) -> (u128, &[u8]);
69 fn read_u128x2(&self) -> ([u128; 2], &[u8]);
70 fn read_u128x4(&self) -> ([u128; 4], &[u8]);
71 fn read_last_u16(&self) -> u16;
72 fn read_last_u32(&self) -> u32;
73 fn read_last_u64(&self) -> u64;
74 fn read_last_u128(&self) -> u128;
75 fn read_last_u128x2(&self) -> [u128; 2];
76 fn read_last_u128x4(&self) -> [u128; 4];
77}
78
79impl ReadFromSlice for [u8] {
80 #[inline(always)]
81 fn read_u16(&self) -> (u16, &[u8]) {
82 let (value, rest) = self.split_at(2);
83 (as_array!(value, 2).convert(), rest)
84 }
85
86 #[inline(always)]
87 fn read_u32(&self) -> (u32, &[u8]) {
88 let (value, rest) = self.split_at(4);
89 (as_array!(value, 4).convert(), rest)
90 }
91
92 #[inline(always)]
93 fn read_u64(&self) -> (u64, &[u8]) {
94 let (value, rest) = self.split_at(8);
95 (as_array!(value, 8).convert(), rest)
96 }
97
98 #[inline(always)]
99 fn read_u128(&self) -> (u128, &[u8]) {
100 let (value, rest) = self.split_at(16);
101 (as_array!(value, 16).convert(), rest)
102 }
103
104 #[inline(always)]
105 fn read_u128x2(&self) -> ([u128; 2], &[u8]) {
106 let (value, rest) = self.split_at(32);
107 (as_array!(value, 32).convert(), rest)
108 }
109
110 #[inline(always)]
111 fn read_u128x4(&self) -> ([u128; 4], &[u8]) {
112 let (value, rest) = self.split_at(64);
113 (as_array!(value, 64).convert(), rest)
114 }
115
116 #[inline(always)]
117 fn read_last_u16(&self) -> u16 {
118 let (_, value) = self.split_at(self.len() - 2);
119 as_array!(value, 2).convert()
120 }
121
122 #[inline(always)]
123 fn read_last_u32(&self) -> u32 {
124 let (_, value) = self.split_at(self.len() - 4);
125 as_array!(value, 4).convert()
126 }
127
128 #[inline(always)]
129 fn read_last_u64(&self) -> u64 {
130 let (_, value) = self.split_at(self.len() - 8);
131 as_array!(value, 8).convert()
132 }
133
134 #[inline(always)]
135 fn read_last_u128(&self) -> u128 {
136 let (_, value) = self.split_at(self.len() - 16);
137 as_array!(value, 16).convert()
138 }
139
140 #[inline(always)]
141 fn read_last_u128x2(&self) -> [u128; 2] {
142 let (_, value) = self.split_at(self.len() - 32);
143 as_array!(value, 32).convert()
144 }
145
146 #[inline(always)]
147 fn read_last_u128x4(&self) -> [u128; 4] {
148 let (_, value) = self.split_at(self.len() - 64);
149 as_array!(value, 64).convert()
150 }
151}