1#![deny(missing_docs)]
67#![deny(warnings)]
68#![no_std]
69
70extern crate byteorder;
71
72use core::marker::PhantomData;
73use core::{mem, slice, fmt};
74
75pub use fnv::Hasher as FnvHasher;
76pub use murmur3::Hasher as Murmur3Hasher;
77
78mod fnv;
79mod murmur3;
80
81pub struct BuildHasherDefault<H>
85{
86 _marker: PhantomData<H>,
87}
88
89impl<H> Default for BuildHasherDefault<H>
90where
91 H: Default + Hasher,
92{
93 fn default() -> Self {
94 BuildHasherDefault {
95 _marker: PhantomData,
96 }
97 }
98}
99
100impl<H> Clone for BuildHasherDefault<H>
101where
102 H: Default + Hasher,
103{
104 fn clone(&self) -> Self {
105 BuildHasherDefault::default()
106 }
107}
108
109impl<H> PartialEq for BuildHasherDefault<H>
110where
111 H: Default + Hasher,
112{
113 fn eq(&self, _other: &BuildHasherDefault<H>) -> bool {
114 true
115 }
116}
117
118impl<H: Default + Hasher> Eq for BuildHasherDefault<H> {}
119
120impl<H: Default + Hasher> fmt::Debug for BuildHasherDefault<H> {
121 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
122 f.pad("BuildHasherDefault")
123 }
124}
125
126impl<H> BuildHasherDefault<H>
127{
128 pub const fn new() -> Self {
130 BuildHasherDefault {
131 _marker: PhantomData,
132 }
133 }
134}
135
136impl<H> BuildHasher for BuildHasherDefault<H>
137where
138 H: Default + Hasher,
139{
140 type Hasher = H;
141
142 fn build_hasher(&self) -> Self::Hasher {
143 H::default()
144 }
145}
146
147pub trait BuildHasher {
151 type Hasher: Hasher;
155
156 fn build_hasher(&self) -> Self::Hasher;
160}
161
162pub trait Hasher {
171 fn finish(&self) -> u32;
175
176 fn write(&mut self, bytes: &[u8]);
180}
181
182pub trait Hash {
186 fn hash<H>(&self, state: &mut H)
188 where
189 H: Hasher;
190
191 fn hash_slice<H>(data: &[Self], state: &mut H)
193 where
194 H: Hasher,
195 Self: Sized,
196 {
197 for piece in data {
198 piece.hash(state);
199 }
200 }
201}
202
203macro_rules! int {
204 ($ty:ident) => {
205 impl Hash for $ty {
206 fn hash<H>(&self, state: &mut H)
207 where
208 H: Hasher,
209 {
210 unsafe { state.write(&mem::transmute::<$ty, [u8; mem::size_of::<$ty>()]>(*self)) }
211 }
212
213 fn hash_slice<H>(data: &[Self], state: &mut H)
214 where
215 H: Hasher,
216 {
217 let newlen = data.len() * mem::size_of::<$ty>();
218 let ptr = data.as_ptr() as *const u8;
219 unsafe { state.write(slice::from_raw_parts(ptr, newlen)) }
220 }
221 }
222 };
223}
224
225int!(i16);
226int!(i32);
227int!(i64);
228int!(i8);
229int!(isize);
230int!(u16);
231int!(u32);
232int!(u64);
233int!(u8);
234int!(usize);
235
236impl Hash for bool {
237 fn hash<H>(&self, state: &mut H)
238 where
239 H: Hasher,
240 {
241 (*self as u8).hash(state)
242 }
243}
244
245impl Hash for char {
246 fn hash<H>(&self, state: &mut H)
247 where
248 H: Hasher,
249 {
250 (*self as u32).hash(state)
251 }
252}
253
254impl Hash for str {
255 fn hash<H>(&self, state: &mut H)
256 where
257 H: Hasher,
258 {
259 state.write(self.as_bytes());
260 state.write(&[0xff]);
261 }
262}
263
264impl<T> Hash for [T]
265where
266 T: Hash,
267{
268 fn hash<H>(&self, state: &mut H)
269 where
270 H: Hasher,
271 {
272 self.len().hash(state);
273 T::hash_slice(self, state);
274 }
275}
276
277macro_rules! array {
278 ($($n:expr),+) => {
279 $(
280 impl<T> Hash for [T; $n]
281 where
282 T: Hash,
283 {
284 fn hash<H>(&self, state: &mut H)
285 where
286 H: Hasher,
287 {
288 Hash::hash(&self[..], state)
289 }
290 }
291 )+
292 };
293}
294
295array!(
296 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
297 26, 27, 28, 29, 30, 31, 32
298);
299
300impl<'a, T: ?Sized + Hash> Hash for &'a T {
301 fn hash<H: Hasher>(&self, state: &mut H) {
302 (**self).hash(state);
303 }
304}
305
306impl<'a, T: ?Sized + Hash> Hash for &'a mut T {
307 fn hash<H: Hasher>(&self, state: &mut H) {
308 (**self).hash(state);
309 }
310}
311
312impl Hash for () {
313 fn hash<H: Hasher>(&self, _state: &mut H) {}
314}
315
316macro_rules! tuple {
317 ( $($name:ident)+) => (
318 impl<$($name: Hash),*> Hash for ($($name,)*)
319 where
320 last_type!($($name,)+): ?Sized
321 {
322 #[allow(non_snake_case)]
323 fn hash<S: Hasher>(&self, state: &mut S) {
324 let ($(ref $name,)*) = *self;
325 $($name.hash(state);)*
326 }
327 }
328 );
329}
330
331macro_rules! last_type {
332 ($a:ident,) => { $a };
333 ($a:ident, $($rest_a:ident,)+) => { last_type!($($rest_a,)+) };
334}
335
336tuple! { A }
337tuple! { A B }
338tuple! { A B C }
339tuple! { A B C D }
340tuple! { A B C D E }
341tuple! { A B C D E F }
342tuple! { A B C D E F G }
343tuple! { A B C D E F G H }
344tuple! { A B C D E F G H I }
345tuple! { A B C D E F G H I J }
346tuple! { A B C D E F G H I J K }
347tuple! { A B C D E F G H I J K L }
348
349#[cfg(test)]
350mod test {
351 use super::{FnvHasher, Hash, Hasher};
352 #[test]
353 fn hashes_tuples() {
354 let mut h = FnvHasher::default();
355 ().hash(&mut h);
356 (1_usize,).hash(&mut h);
357 (1_u8, 2_i8).hash(&mut h);
358 (1_u16, 2_i16, 3_u32).hash(&mut h);
359 (1_i32, 2_u64, 3_i64, true).hash(&mut h);
360 (1_isize, 'a', "abc", [1u32, 2, 3, 4], false).hash(&mut h);
361 h.finish();
362 }
363}