1use super::{HashKind, HashMapper};
7
8pub fn compute_binhash(s: &str) -> u32 {
12 s.to_ascii_lowercase().bytes()
13 .fold(0x811c9dc5_u32, |h, b| (h ^ b as u32).wrapping_mul(0x01000193))
14}
15
16pub const fn compute_binhash_const(s: &str) -> u32 {
20 let mut h = 0x811c9dc5_u32;
21 let bytes = s.as_bytes();
22 let mut i = 0usize;
23 while i < bytes.len() {
24 let b = bytes[i].to_ascii_lowercase();
25 h = (h ^ b as u32).wrapping_mul(0x01000193);
26 i += 1;
27 }
28 h
29}
30
31pub fn binhash_from_str(s: &str) -> u32 {
37 let hash = {
38 if s.len() == 8 {
39 u32::from_str_radix(s, 16).ok()
40 } else if s.len() == 10 && s.starts_with('{') & s.ends_with('}') {
41 u32::from_str_radix(&s[1..9], 16).ok()
42 } else {
43 None
44 }
45 };
46 hash.unwrap_or_else(|| compute_binhash(s))
47}
48
49
50pub type BinHashMapper = HashMapper<u32, 32>;
52
53#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)]
55pub enum BinHashKind {
56 EntryPath,
58 ClassName,
60 FieldName,
62 HashValue,
64}
65
66impl BinHashKind {
67 pub const VARIANTS: [Self; 4] = [
69 Self::EntryPath,
70 Self::ClassName,
71 Self::FieldName,
72 Self::HashValue,
73 ];
74}
75
76impl From<BinHashKind> for HashKind {
77 fn from(val: BinHashKind) -> Self {
78 match val {
79 BinHashKind::EntryPath => HashKind::BinEntryPath,
80 BinHashKind::ClassName => HashKind::BinClassName,
81 BinHashKind::FieldName => HashKind::BinFieldName,
82 BinHashKind::HashValue => HashKind::BinHashValue,
83 }
84 }
85}
86
87#[macro_export]
89macro_rules! binh {
90 ($e:expr) => { $crate::bin::compute_binhash_const($e).into() };
91 ($t:ident, $e:literal) => { $t { hash: $crate::bin::compute_binhash_const($e) } };
92}
93