]>
Commit | Line | Data |
---|---|---|
c1a9b12d SL |
1 | mod sip; |
2 | ||
1a4d82fc | 3 | use std::default::Default; |
136023e0 | 4 | use std::hash::{BuildHasher, Hash, Hasher}; |
ea8adc8c | 5 | use std::rc::Rc; |
1a4d82fc JJ |
6 | |
7 | struct MyHasher { | |
8 | hash: u64, | |
9 | } | |
10 | ||
11 | impl Default for MyHasher { | |
12 | fn default() -> MyHasher { | |
13 | MyHasher { hash: 0 } | |
14 | } | |
15 | } | |
16 | ||
85aaf69f | 17 | impl Hasher for MyHasher { |
1a4d82fc | 18 | fn write(&mut self, buf: &[u8]) { |
85aaf69f | 19 | for byte in buf { |
1a4d82fc JJ |
20 | self.hash += *byte as u64; |
21 | } | |
22 | } | |
60c5eb7d XL |
23 | fn finish(&self) -> u64 { |
24 | self.hash | |
25 | } | |
1a4d82fc JJ |
26 | } |
27 | ||
1a4d82fc JJ |
28 | #[test] |
29 | fn test_writer_hasher() { | |
85aaf69f | 30 | fn hash<T: Hash>(t: &T) -> u64 { |
e9174d1e SL |
31 | let mut s = MyHasher { hash: 0 }; |
32 | t.hash(&mut s); | |
33 | s.finish() | |
1a4d82fc JJ |
34 | } |
35 | ||
36 | assert_eq!(hash(&()), 0); | |
37 | ||
85aaf69f SL |
38 | assert_eq!(hash(&5_u8), 5); |
39 | assert_eq!(hash(&5_u16), 5); | |
40 | assert_eq!(hash(&5_u32), 5); | |
41 | assert_eq!(hash(&5_u64), 5); | |
42 | assert_eq!(hash(&5_usize), 5); | |
1a4d82fc | 43 | |
85aaf69f SL |
44 | assert_eq!(hash(&5_i8), 5); |
45 | assert_eq!(hash(&5_i16), 5); | |
46 | assert_eq!(hash(&5_i32), 5); | |
47 | assert_eq!(hash(&5_i64), 5); | |
48 | assert_eq!(hash(&5_isize), 5); | |
1a4d82fc JJ |
49 | |
50 | assert_eq!(hash(&false), 0); | |
51 | assert_eq!(hash(&true), 1); | |
52 | ||
53 | assert_eq!(hash(&'a'), 97); | |
54 | ||
55 | let s: &str = "a"; | |
60c5eb7d | 56 | assert_eq!(hash(&s), 97 + 0xFF); |
32a655c1 | 57 | let s: Box<str> = String::from("a").into_boxed_str(); |
60c5eb7d | 58 | assert_eq!(hash(&s), 97 + 0xFF); |
ea8adc8c XL |
59 | let s: Rc<&str> = Rc::new("a"); |
60 | assert_eq!(hash(&s), 97 + 0xFF); | |
c34b1796 | 61 | let cs: &[u8] = &[1, 2, 3]; |
60c5eb7d | 62 | assert_eq!(hash(&cs), 9); |
c34b1796 | 63 | let cs: Box<[u8]> = Box::new([1, 2, 3]); |
60c5eb7d | 64 | assert_eq!(hash(&cs), 9); |
ea8adc8c | 65 | let cs: Rc<[u8]> = Rc::new([1, 2, 3]); |
60c5eb7d | 66 | assert_eq!(hash(&cs), 9); |
1a4d82fc | 67 | |
e9174d1e SL |
68 | let ptr = 5_usize as *const i32; |
69 | assert_eq!(hash(&ptr), 5); | |
1a4d82fc | 70 | |
e9174d1e SL |
71 | let ptr = 5_usize as *mut i32; |
72 | assert_eq!(hash(&ptr), 5); | |
abe05a73 | 73 | |
dfeec247 XL |
74 | if cfg!(miri) { |
75 | // Miri cannot hash pointers | |
60c5eb7d XL |
76 | return; |
77 | } | |
78 | ||
abe05a73 XL |
79 | let cs: &mut [u8] = &mut [1, 2, 3]; |
80 | let ptr = cs.as_ptr(); | |
81 | let slice_ptr = cs as *const [u8]; | |
82 | assert_eq!(hash(&slice_ptr), hash(&ptr) + cs.len() as u64); | |
83 | ||
84 | let slice_ptr = cs as *mut [u8]; | |
85 | assert_eq!(hash(&slice_ptr), hash(&ptr) + cs.len() as u64); | |
1a4d82fc JJ |
86 | } |
87 | ||
60c5eb7d XL |
88 | struct Custom { |
89 | hash: u64, | |
90 | } | |
91 | struct CustomHasher { | |
92 | output: u64, | |
93 | } | |
1a4d82fc JJ |
94 | |
95 | impl Hasher for CustomHasher { | |
60c5eb7d XL |
96 | fn finish(&self) -> u64 { |
97 | self.output | |
98 | } | |
99 | fn write(&mut self, _: &[u8]) { | |
100 | panic!() | |
101 | } | |
102 | fn write_u64(&mut self, data: u64) { | |
103 | self.output = data; | |
104 | } | |
1a4d82fc JJ |
105 | } |
106 | ||
107 | impl Default for CustomHasher { | |
108 | fn default() -> CustomHasher { | |
109 | CustomHasher { output: 0 } | |
110 | } | |
111 | } | |
112 | ||
85aaf69f SL |
113 | impl Hash for Custom { |
114 | fn hash<H: Hasher>(&self, state: &mut H) { | |
115 | state.write_u64(self.hash); | |
1a4d82fc JJ |
116 | } |
117 | } | |
118 | ||
119 | #[test] | |
120 | fn test_custom_state() { | |
85aaf69f | 121 | fn hash<T: Hash>(t: &T) -> u64 { |
e9174d1e SL |
122 | let mut c = CustomHasher { output: 0 }; |
123 | t.hash(&mut c); | |
124 | c.finish() | |
1a4d82fc JJ |
125 | } |
126 | ||
127 | assert_eq!(hash(&Custom { hash: 5 }), 5); | |
128 | } | |
ea8adc8c XL |
129 | |
130 | // FIXME: Instantiated functions with i128 in the signature is not supported in Emscripten. | |
131 | // See https://github.com/kripken/emscripten-fastcomp/issues/169 | |
132 | #[cfg(not(target_os = "emscripten"))] | |
133 | #[test] | |
134 | fn test_indirect_hasher() { | |
135 | let mut hasher = MyHasher { hash: 0 }; | |
136 | { | |
8faf50e0 | 137 | let mut indirect_hasher: &mut dyn Hasher = &mut hasher; |
ea8adc8c XL |
138 | 5u32.hash(&mut indirect_hasher); |
139 | } | |
140 | assert_eq!(hasher.hash, 5); | |
141 | } | |
136023e0 XL |
142 | |
143 | #[test] | |
144 | fn test_build_hasher_object_safe() { | |
145 | use std::collections::hash_map::{DefaultHasher, RandomState}; | |
146 | ||
147 | let _: &dyn BuildHasher<Hasher = DefaultHasher> = &RandomState::new(); | |
148 | } |