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