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