use std::{hash::Hash, marker::PhantomData}; use serde::{de::Visitor, Deserialize, Serialize}; #[derive(Debug)] pub struct Id(u64, PhantomData<&'static T>); impl Id { pub fn new(inner: u64) -> Self { Self(inner, PhantomData) } pub fn into_u64(self) -> u64 { self.0 } } impl Clone for Id { fn clone(&self) -> Self { Self(self.0, PhantomData) } } impl PartialEq for Id { fn eq(&self, other: &Self) -> bool { self.0 == other.0 } } impl Eq for Id {} impl Hash for Id { fn hash(&self, state: &mut H) { self.0.hash(state); } } impl Serialize for Id { fn serialize(&self, serializer: S) -> Result where S: serde::Serializer, { serializer.serialize_u64(self.0) } } pub struct IdVisitor { _phantom: PhantomData T>, } impl IdVisitor { pub fn new() -> Self { Self { _phantom: PhantomData, } } } impl<'de, T> Visitor<'de> for IdVisitor { type Value = Id; fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { formatter.write_str("an integer in the u64 range") } } impl<'de, T: 'static> Deserialize<'de> for Id { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de>, { deserializer.deserialize_u64(IdVisitor::new()) } } impl From for Id { fn from(input: u64) -> Self { Self::new(input) } } impl From> for u64 { fn from(input: Id) -> Self { let Id(inner, _) = input; inner } }