use super::*;
pub trait DeriveIdent<I,> {
fn derive_ident(value: &Self) -> I;
}
impl<T: DeriveIdent<I,>, I,> From<T> for WithIdent<T, I,> {
fn from(from: T) -> Self {
Self::new(DeriveIdent::derive_ident(&from), from)
}
}
impl<T: DeriveIdent<I,> + Default, I,> Default for WithIdent<T, I,> {
fn default() -> Self { T::default().into() }
}
impl<T: DeriveIdent<I,>, I,> WithIdent<T, I,> {
#[inline]
pub fn update_ident(mut wi: Self) -> Self {
wi.identifier = DeriveIdent::derive_ident(&wi.value); wi
}
}
#[macro_export]
macro_rules! impl_identity {
($type:ty) => {
impl DeriveIdent<$type> for $type {
fn derive_ident(value: &Self) -> $type {
value.clone()
}
}
};
($type:tt $($t:tt)*) => {
impl_identity!($type);
impl_identity!($($t)*);
};
}
impl_identity! { usize isize u8 i8 u16 i16 u32 i32 u64 i64 }
#[macro_export]
macro_rules! impl_hash_identity {
(($type:tt, $hasher:tt)) => {
impl DeriveIdent<u64> for $type {
fn derive_ident(value: &Self) -> u64 {
use std::hash::{Hash, Hasher};
let mut hasher = $hasher::default();
value.hash(&mut hasher);
hasher.finish()
}
}
};
(($type:tt, $hasher:tt) $($t:tt)*) => {
impl_hash_identity!(($type, $hasher));
impl_hash_identity!($($t)*);
};
($type:tt, $hasher:tt) => (impl_hash_identity!(($type, $hasher)););
}