use crate::util::fnv::Key;
use std::{
fmt::{Debug, Formatter, Result},
hash::{Hash, Hasher},
ops::Deref,
};
#[derive(Clone, Eq, Default)]
#[cfg_attr(not(debug_assertions), repr(transparent))]
pub(crate) struct Id {
#[cfg(debug_assertions)]
name: String,
id: u64,
}
macro_rules! precomputed_hashes {
($($fn_name:ident, $const:expr, $name:expr;)*) => {
impl Id {
$(
pub(crate) fn $fn_name() -> Self {
Id {
#[cfg(debug_assertions)]
name: $name.into(),
id: $const,
}
}
)*
}
};
}
precomputed_hashes! {
empty_hash, 0x1C9D_3ADB_639F_298E, "";
help_hash, 0x5963_6393_CFFB_FE5F, "help";
version_hash, 0x30FF_0B7C_4D07_9478, "version";
}
impl Id {
pub(crate) fn from_ref<T: Key>(val: T) -> Self {
Id {
#[cfg(debug_assertions)]
name: val.to_string(),
id: val.key(),
}
}
}
impl Debug for Id {
fn fmt(&self, f: &mut Formatter) -> Result {
#[cfg(debug_assertions)]
write!(f, "{}", self.name)?;
#[cfg(not(debug_assertions))]
write!(f, "[hash: {:X}]", self.id)?;
Ok(())
}
}
impl Deref for Id {
type Target = u64;
fn deref(&self) -> &Self::Target {
&self.id
}
}
impl<T: Key> From<T> for Id {
fn from(val: T) -> Self {
Id {
#[cfg(debug_assertions)]
name: val.to_string(),
id: val.key(),
}
}
}
impl Hash for Id {
fn hash<H>(&self, state: &mut H)
where
H: Hasher,
{
self.id.hash(state)
}
}
impl PartialEq for Id {
fn eq(&self, other: &Id) -> bool {
self.id == other.id
}
}