1 use crate::util::fnv::Key; 2 3 use std::{ 4 fmt::{Debug, Formatter, Result}, 5 hash::{Hash, Hasher}, 6 ops::Deref, 7 }; 8 9 #[derive(Clone, Eq, Default)] 10 #[cfg_attr(not(debug_assertions), repr(transparent))] 11 pub(crate) struct Id { 12 #[cfg(debug_assertions)] 13 name: String, 14 id: u64, 15 } 16 17 macro_rules! precomputed_hashes { 18 ($($fn_name:ident, $const:expr, $name:expr;)*) => { 19 impl Id { 20 $( 21 pub(crate) fn $fn_name() -> Self { 22 Id { 23 #[cfg(debug_assertions)] 24 name: $name.into(), 25 id: $const, 26 } 27 } 28 )* 29 } 30 }; 31 } 32 33 // precompute some common values 34 precomputed_hashes! { 35 empty_hash, 0x1C9D_3ADB_639F_298E, ""; 36 help_hash, 0x5963_6393_CFFB_FE5F, "help"; 37 version_hash, 0x30FF_0B7C_4D07_9478, "version"; 38 } 39 40 impl Id { from_ref<T: Key>(val: T) -> Self41 pub(crate) fn from_ref<T: Key>(val: T) -> Self { 42 Id { 43 #[cfg(debug_assertions)] 44 name: val.to_string(), 45 id: val.key(), 46 } 47 } 48 } 49 50 impl Debug for Id { fmt(&self, f: &mut Formatter) -> Result51 fn fmt(&self, f: &mut Formatter) -> Result { 52 #[cfg(debug_assertions)] 53 write!(f, "{}", self.name)?; 54 #[cfg(not(debug_assertions))] 55 write!(f, "[hash: {:X}]", self.id)?; 56 57 Ok(()) 58 } 59 } 60 61 impl Deref for Id { 62 type Target = u64; 63 deref(&self) -> &Self::Target64 fn deref(&self) -> &Self::Target { 65 &self.id 66 } 67 } 68 69 impl<T: Key> From<T> for Id { from(val: T) -> Self70 fn from(val: T) -> Self { 71 Id { 72 #[cfg(debug_assertions)] 73 name: val.to_string(), 74 id: val.key(), 75 } 76 } 77 } 78 79 impl Hash for Id { hash<H>(&self, state: &mut H) where H: Hasher,80 fn hash<H>(&self, state: &mut H) 81 where 82 H: Hasher, 83 { 84 self.id.hash(state) 85 } 86 } 87 88 impl PartialEq for Id { eq(&self, other: &Id) -> bool89 fn eq(&self, other: &Id) -> bool { 90 self.id == other.id 91 } 92 } 93