solana_nohash_hasher/
lib.rs1#![cfg_attr(not(feature = "std"), no_std)]
12
13use core::{
14 fmt,
15 hash::{BuildHasherDefault, Hasher},
16 marker::PhantomData,
17};
18
19#[cfg(feature = "std")]
37pub type IntMap<K, V> = std::collections::HashMap<K, V, BuildNoHashHasher<K>>;
38
39#[cfg(feature = "std")]
57pub type IntSet<T> = std::collections::HashSet<T, BuildNoHashHasher<T>>;
58
59pub type BuildNoHashHasher<T> = BuildHasherDefault<NoHashHasher<T>>;
79
80#[cfg(debug_assertions)]
111pub struct NoHashHasher<T>(u64, bool, PhantomData<T>);
112
113#[cfg(not(debug_assertions))]
114pub struct NoHashHasher<T>(u64, PhantomData<T>);
115
116impl<T> fmt::Debug for NoHashHasher<T> {
117 #[cfg(debug_assertions)]
118 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
119 f.debug_tuple("NoHashHasher")
120 .field(&self.0)
121 .field(&self.1)
122 .finish()
123 }
124
125 #[cfg(not(debug_assertions))]
126 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
127 f.debug_tuple("NoHashHasher").field(&self.0).finish()
128 }
129}
130
131impl<T> Default for NoHashHasher<T> {
132 #[cfg(debug_assertions)]
133 fn default() -> Self {
134 NoHashHasher(0, false, PhantomData)
135 }
136
137 #[cfg(not(debug_assertions))]
138 fn default() -> Self {
139 NoHashHasher(0, PhantomData)
140 }
141}
142
143impl<T> Clone for NoHashHasher<T> {
144 #[cfg(debug_assertions)]
145 fn clone(&self) -> Self {
146 *self
147 }
148
149 #[cfg(not(debug_assertions))]
150 fn clone(&self) -> Self {
151 *self
152 }
153}
154
155impl<T> Copy for NoHashHasher<T> {}
156
157pub trait IsEnabled {}
193
194impl IsEnabled for u8 {}
195impl IsEnabled for u16 {}
196impl IsEnabled for u32 {}
197impl IsEnabled for u64 {}
198impl IsEnabled for usize {}
199impl IsEnabled for i8 {}
200impl IsEnabled for i16 {}
201impl IsEnabled for i32 {}
202impl IsEnabled for i64 {}
203impl IsEnabled for isize {}
204
205#[cfg(not(debug_assertions))]
206impl<T: IsEnabled> Hasher for NoHashHasher<T> {
207 fn write(&mut self, _: &[u8]) {
208 panic!("Invalid use of NoHashHasher")
209 }
210
211 fn write_u8(&mut self, n: u8) {
212 self.0 = u64::from(n)
213 }
214 fn write_u16(&mut self, n: u16) {
215 self.0 = u64::from(n)
216 }
217 fn write_u32(&mut self, n: u32) {
218 self.0 = u64::from(n)
219 }
220 fn write_u64(&mut self, n: u64) {
221 self.0 = n
222 }
223 fn write_usize(&mut self, n: usize) {
224 self.0 = n as u64
225 }
226
227 fn write_i8(&mut self, n: i8) {
228 self.0 = n as u64
229 }
230 fn write_i16(&mut self, n: i16) {
231 self.0 = n as u64
232 }
233 fn write_i32(&mut self, n: i32) {
234 self.0 = n as u64
235 }
236 fn write_i64(&mut self, n: i64) {
237 self.0 = n as u64
238 }
239 fn write_isize(&mut self, n: isize) {
240 self.0 = n as u64
241 }
242
243 fn finish(&self) -> u64 {
244 self.0
245 }
246}
247
248#[cfg(debug_assertions)]
249impl<T: IsEnabled> Hasher for NoHashHasher<T> {
250 fn write(&mut self, _: &[u8]) {
251 panic!("Invalid use of NoHashHasher")
252 }
253
254 fn write_u8(&mut self, n: u8) {
255 assert!(!self.1, "NoHashHasher: second write attempt detected.");
256 self.0 = u64::from(n);
257 self.1 = true
258 }
259
260 fn write_u16(&mut self, n: u16) {
261 assert!(!self.1, "NoHashHasher: second write attempt detected.");
262 self.0 = u64::from(n);
263 self.1 = true
264 }
265
266 fn write_u32(&mut self, n: u32) {
267 assert!(!self.1, "NoHashHasher: second write attempt detected.");
268 self.0 = u64::from(n);
269 self.1 = true
270 }
271
272 fn write_u64(&mut self, n: u64) {
273 assert!(!self.1, "NoHashHasher: second write attempt detected.");
274 self.0 = n;
275 self.1 = true
276 }
277
278 fn write_usize(&mut self, n: usize) {
279 assert!(!self.1, "NoHashHasher: second write attempt detected.");
280 self.0 = n as u64;
281 self.1 = true
282 }
283
284 fn write_i8(&mut self, n: i8) {
285 assert!(!self.1, "NoHashHasher: second write attempt detected.");
286 self.0 = n as u64;
287 self.1 = true
288 }
289
290 fn write_i16(&mut self, n: i16) {
291 assert!(!self.1, "NoHashHasher: second write attempt detected.");
292 self.0 = n as u64;
293 self.1 = true
294 }
295
296 fn write_i32(&mut self, n: i32) {
297 assert!(!self.1, "NoHashHasher: second write attempt detected.");
298 self.0 = n as u64;
299 self.1 = true
300 }
301
302 fn write_i64(&mut self, n: i64) {
303 assert!(!self.1, "NoHashHasher: second write attempt detected.");
304 self.0 = n as u64;
305 self.1 = true
306 }
307
308 fn write_isize(&mut self, n: isize) {
309 assert!(!self.1, "NoHashHasher: second write attempt detected.");
310 self.0 = n as u64;
311 self.1 = true
312 }
313
314 fn finish(&self) -> u64 {
315 self.0
316 }
317}
318
319#[cfg(test)]
320mod tests {
321 use super::*;
322
323 #[test]
324 fn ok() {
325 let mut h1 = NoHashHasher::<u8>::default();
326 h1.write_u8(42);
327 assert_eq!(42, h1.finish());
328
329 let mut h2 = NoHashHasher::<u16>::default();
330 h2.write_u16(42);
331 assert_eq!(42, h2.finish());
332
333 let mut h3 = NoHashHasher::<u32>::default();
334 h3.write_u32(42);
335 assert_eq!(42, h3.finish());
336
337 let mut h4 = NoHashHasher::<u64>::default();
338 h4.write_u64(42);
339 assert_eq!(42, h4.finish());
340
341 let mut h5 = NoHashHasher::<usize>::default();
342 h5.write_usize(42);
343 assert_eq!(42, h5.finish());
344
345 let mut h6 = NoHashHasher::<i8>::default();
346 h6.write_i8(42);
347 assert_eq!(42, h6.finish());
348
349 let mut h7 = NoHashHasher::<i16>::default();
350 h7.write_i16(42);
351 assert_eq!(42, h7.finish());
352
353 let mut h8 = NoHashHasher::<i32>::default();
354 h8.write_i32(42);
355 assert_eq!(42, h8.finish());
356
357 let mut h9 = NoHashHasher::<i64>::default();
358 h9.write_i64(42);
359 assert_eq!(42, h9.finish());
360
361 let mut h10 = NoHashHasher::<isize>::default();
362 h10.write_isize(42);
363 assert_eq!(42, h10.finish())
364 }
365
366 #[cfg(debug_assertions)]
367 #[test]
368 #[should_panic]
369 fn u8_double_usage() {
370 let mut h = NoHashHasher::<u8>::default();
371 h.write_u8(42);
372 h.write_u8(43);
373 }
374
375 #[cfg(debug_assertions)]
376 #[test]
377 #[should_panic]
378 fn u16_double_usage() {
379 let mut h = NoHashHasher::<u16>::default();
380 h.write_u16(42);
381 h.write_u16(43);
382 }
383
384 #[cfg(debug_assertions)]
385 #[test]
386 #[should_panic]
387 fn u32_double_usage() {
388 let mut h = NoHashHasher::<u32>::default();
389 h.write_u32(42);
390 h.write_u32(43);
391 }
392
393 #[cfg(debug_assertions)]
394 #[test]
395 #[should_panic]
396 fn u64_double_usage() {
397 let mut h = NoHashHasher::<u64>::default();
398 h.write_u64(42);
399 h.write_u64(43);
400 }
401
402 #[cfg(debug_assertions)]
403 #[test]
404 #[should_panic]
405 fn usize_double_usage() {
406 let mut h = NoHashHasher::<usize>::default();
407 h.write_usize(42);
408 h.write_usize(43);
409 }
410
411 #[cfg(debug_assertions)]
412 #[test]
413 #[should_panic]
414 fn i8_double_usage() {
415 let mut h = NoHashHasher::<i8>::default();
416 h.write_i8(42);
417 h.write_i8(43);
418 }
419
420 #[cfg(debug_assertions)]
421 #[test]
422 #[should_panic]
423 fn i16_double_usage() {
424 let mut h = NoHashHasher::<i16>::default();
425 h.write_i16(42);
426 h.write_i16(43);
427 }
428
429 #[cfg(debug_assertions)]
430 #[test]
431 #[should_panic]
432 fn i32_double_usage() {
433 let mut h = NoHashHasher::<i32>::default();
434 h.write_i32(42);
435 h.write_i32(43);
436 }
437
438 #[cfg(debug_assertions)]
439 #[test]
440 #[should_panic]
441 fn i64_double_usage() {
442 let mut h = NoHashHasher::<i64>::default();
443 h.write_i64(42);
444 h.write_i64(43);
445 }
446
447 #[cfg(debug_assertions)]
448 #[test]
449 #[should_panic]
450 fn isize_double_usage() {
451 let mut h = NoHashHasher::<isize>::default();
452 h.write_isize(42);
453 h.write_isize(43);
454 }
455}