#![deny(
dead_code,
irrefutable_let_patterns,
missing_docs,
unused_variables,
unused_imports,
unused_import_braces,
rustdoc::broken_intra_doc_links,
missing_debug_implementations,
unreachable_pub
)]
#![warn(rust_2018_idioms)]
use std::{fmt, hash::Hash, marker::PhantomData, ops::Deref};
#[cfg(feature = "serde")]
mod serde;
#[macro_export]
macro_rules! id_type {
($id_type:ty, $name_type:ident) => {
paste::paste! { type [< $name_type Id >] = typed_id::TypedId<$id_type, $name_type>; }
};
($where:vis, $id_type:ty, $name_type:ident) => {
paste::paste! { $where type [< $name_type Id >] = typed_id::TypedId<$id_type, $name_type>; }
};
}
pub struct TypedId<I, T>(pub I, PhantomData<T>);
impl<I, T> TypedId<I, T> {
pub fn new(id: I) -> Self {
Self(id, PhantomData)
}
pub fn convert<B: From<I>>(self) -> B {
B::from(self.0)
}
}
impl<I: Default, T> Default for TypedId<I, T> {
fn default() -> Self {
Self(Default::default(), Default::default())
}
}
impl<I: fmt::Debug, T> fmt::Debug for TypedId<I, T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("TypedId").field(&self.0).finish()
}
}
impl<I: fmt::Display, T> fmt::Display for TypedId<I, T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
impl<I: Clone, T> Clone for TypedId<I, T> {
fn clone(&self) -> Self {
Self(self.0.clone(), PhantomData)
}
}
impl<I: Copy, T> Copy for TypedId<I, T> {}
impl<I: Hash, T> Hash for TypedId<I, T> {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.0.hash(state)
}
}
impl<I: PartialEq, T> PartialEq for TypedId<I, T> {
fn eq(&self, other: &Self) -> bool {
self.0.eq(&other.0)
}
}
impl<I: Eq, T> Eq for TypedId<I, T> {}
impl<I: PartialOrd, T> PartialOrd for TypedId<I, T> {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
self.0.partial_cmp(&other.0)
}
}
impl<I: Ord, T> Ord for TypedId<I, T> {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.0.cmp(&other.0)
}
}
impl<I, T> Deref for TypedId<I, T> {
type Target = I;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<I, T> From<I> for TypedId<I, T> {
fn from(other: I) -> TypedId<I, T> {
TypedId(other, PhantomData)
}
}