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                     let mut result: $b = core::mem::zeroed();
12                     core::ptr::copy_nonoverlapping(
13                         &self as *const $a as *const u8,
14                         &mut result as *mut $b as *mut u8,
15                         core::mem::size_of::<$b>(),
16                     );
17                     return result;
18                 }
19             }
20         }
21         impl Convert<$a> for $b {
22             #[inline(always)]
23             fn convert(self) -> $a {
24                 unsafe {
25                     let mut result: $a = core::mem::zeroed();
26                     core::ptr::copy_nonoverlapping(
27                         &self as *const $b as *const u8,
28                         &mut result as *mut $a as *mut u8,
29                         core::mem::size_of::<$a>(),
30                     );
31                     return result;
32                 }
33             }
34         }
35     };
36 }
37 
38 convert!([u128; 4], [u64; 8]);
39 convert!([u128; 4], [u32; 16]);
40 convert!([u128; 4], [u16; 32]);
41 convert!([u128; 4], [u8; 64]);
42 convert!([u128; 2], [u64; 4]);
43 convert!([u128; 2], [u32; 8]);
44 convert!([u128; 2], [u16; 16]);
45 convert!([u128; 2], [u8; 32]);
46 convert!(u128, [u64; 2]);
47 convert!(u128, [u32; 4]);
48 convert!(u128, [u16; 8]);
49 convert!(u128, [u8; 16]);
50 convert!([u64; 8], [u32; 16]);
51 convert!([u64; 8], [u16; 32]);
52 convert!([u64; 8], [u8; 64]);
53 convert!([u64; 4], [u32; 8]);
54 convert!([u64; 4], [u16; 16]);
55 convert!([u64; 4], [u8; 32]);
56 convert!([u64; 2], [u32; 4]);
57 convert!([u64; 2], [u16; 8]);
58 convert!([u64; 2], [u8; 16]);
59 convert!([u32; 4], [u16; 8]);
60 convert!([u32; 4], [u8; 16]);
61 convert!([u16; 8], [u8; 16]);
62 convert!(u64, [u32; 2]);
63 convert!(u64, [u16; 4]);
64 convert!(u64, [u8; 8]);
65 convert!([u32; 2], [u16; 4]);
66 convert!([u32; 2], [u8; 8]);
67 convert!(u32, [u16; 2]);
68 convert!(u32, [u8; 4]);
69 convert!([u16; 2], [u8; 4]);
70 convert!(u16, [u8; 2]);
71 convert!([[u64; 4]; 2], [u8; 64]);
72 
73 convert!([f64; 2], [u8; 16]);
74 convert!([f32; 4], [u8; 16]);
75 convert!(f64, [u8; 8]);
76 convert!([f32; 2], [u8; 8]);
77 convert!(f32, [u8; 4]);
78 
79 macro_rules! as_array {
80     ($input:expr, $len:expr) => {{
81         {
82             #[inline(always)]
83             fn as_array<T>(slice: &[T]) -> &[T; $len] {
84                 assert_eq!(slice.len(), $len);
85                 unsafe { &*(slice.as_ptr() as *const [_; $len]) }
86             }
87             as_array($input)
88         }
89     }};
90 }
91 
92 pub(crate) trait ReadFromSlice {
read_u16(&self) -> (u16, &[u8])93     fn read_u16(&self) -> (u16, &[u8]);
read_u32(&self) -> (u32, &[u8])94     fn read_u32(&self) -> (u32, &[u8]);
read_u64(&self) -> (u64, &[u8])95     fn read_u64(&self) -> (u64, &[u8]);
read_u128(&self) -> (u128, &[u8])96     fn read_u128(&self) -> (u128, &[u8]);
read_u128x2(&self) -> ([u128; 2], &[u8])97     fn read_u128x2(&self) -> ([u128; 2], &[u8]);
read_u128x4(&self) -> ([u128; 4], &[u8])98     fn read_u128x4(&self) -> ([u128; 4], &[u8]);
read_last_u16(&self) -> u1699     fn read_last_u16(&self) -> u16;
read_last_u32(&self) -> u32100     fn read_last_u32(&self) -> u32;
read_last_u64(&self) -> u64101     fn read_last_u64(&self) -> u64;
read_last_u128(&self) -> u128102     fn read_last_u128(&self) -> u128;
read_last_u128x2(&self) -> [u128; 2]103     fn read_last_u128x2(&self) -> [u128; 2];
read_last_u128x4(&self) -> [u128; 4]104     fn read_last_u128x4(&self) -> [u128; 4];
105 }
106 
107 impl ReadFromSlice for [u8] {
108     #[inline(always)]
read_u16(&self) -> (u16, &[u8])109     fn read_u16(&self) -> (u16, &[u8]) {
110         let (value, rest) = self.split_at(2);
111         (as_array!(value, 2).convert(), rest)
112     }
113 
114     #[inline(always)]
read_u32(&self) -> (u32, &[u8])115     fn read_u32(&self) -> (u32, &[u8]) {
116         let (value, rest) = self.split_at(4);
117         (as_array!(value, 4).convert(), rest)
118     }
119 
120     #[inline(always)]
read_u64(&self) -> (u64, &[u8])121     fn read_u64(&self) -> (u64, &[u8]) {
122         let (value, rest) = self.split_at(8);
123         (as_array!(value, 8).convert(), rest)
124     }
125 
126     #[inline(always)]
read_u128(&self) -> (u128, &[u8])127     fn read_u128(&self) -> (u128, &[u8]) {
128         let (value, rest) = self.split_at(16);
129         (as_array!(value, 16).convert(), rest)
130     }
131 
132     #[inline(always)]
read_u128x2(&self) -> ([u128; 2], &[u8])133     fn read_u128x2(&self) -> ([u128; 2], &[u8]) {
134         let (value, rest) = self.split_at(32);
135         (as_array!(value, 32).convert(), rest)
136     }
137 
138     #[inline(always)]
read_u128x4(&self) -> ([u128; 4], &[u8])139     fn read_u128x4(&self) -> ([u128; 4], &[u8]) {
140         let (value, rest) = self.split_at(64);
141         (as_array!(value, 64).convert(), rest)
142     }
143 
144     #[inline(always)]
read_last_u16(&self) -> u16145     fn read_last_u16(&self) -> u16 {
146         let (_, value) = self.split_at(self.len() - 2);
147         as_array!(value, 2).convert()
148     }
149 
150     #[inline(always)]
read_last_u32(&self) -> u32151     fn read_last_u32(&self) -> u32 {
152         let (_, value) = self.split_at(self.len() - 4);
153         as_array!(value, 4).convert()
154     }
155 
156     #[inline(always)]
read_last_u64(&self) -> u64157     fn read_last_u64(&self) -> u64 {
158         let (_, value) = self.split_at(self.len() - 8);
159         as_array!(value, 8).convert()
160     }
161 
162     #[inline(always)]
read_last_u128(&self) -> u128163     fn read_last_u128(&self) -> u128 {
164         let (_, value) = self.split_at(self.len() - 16);
165         as_array!(value, 16).convert()
166     }
167 
168     #[inline(always)]
read_last_u128x2(&self) -> [u128; 2]169     fn read_last_u128x2(&self) -> [u128; 2] {
170         let (_, value) = self.split_at(self.len() - 32);
171         as_array!(value, 32).convert()
172     }
173 
174     #[inline(always)]
read_last_u128x4(&self) -> [u128; 4]175     fn read_last_u128x4(&self) -> [u128; 4] {
176         let (_, value) = self.split_at(self.len() - 64);
177         as_array!(value, 64).convert()
178     }
179 }
180