use std::any::TypeId;
use std::fmt::Display;
use std::fmt::Formatter;
use std::fmt::Result as FmtResult;
use std::hash::DefaultHasher;
use std::hash::Hash as _;
use std::hash::Hasher;
#[macro_export]
macro_rules! fork_id {
() => {{
struct _ForkId;
&std::string::ToString::to_string(&$crate::ForkId::of(::std::any::TypeId::of::<_ForkId>()))
}};
}
#[derive(Clone, Hash, PartialEq, Eq, Debug)]
pub struct ForkId(TypeId);
impl ForkId {
#[doc(hidden)]
pub fn of(id: TypeId) -> Self {
Self(id)
}
}
impl Display for ForkId {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
let mut hasher = DefaultHasher::default();
self.0.hash(&mut hasher);
write!(f, ":{:016X}", hasher.finish())
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn ids_for_same_type_are_equal() {
struct UniqueType;
let id1 = ForkId::of(TypeId::of::<UniqueType>());
let id2 = ForkId::of(TypeId::of::<UniqueType>());
assert_eq!(id1, id2);
assert_eq!(id1.to_string(), id2.to_string());
}
#[test]
fn ids_are_actually_distinct() {
let id1 = fork_id!();
let id2 = fork_id!();
assert_ne!(id1, id2);
assert_ne!(id1.to_string(), id2.to_string());
}
}