ahash/
convert.rs

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}