use std::fmt;
#[derive(Debug)]
#[cfg_attr(
feature = "serde",
derive(serde::Serialize, serde::Deserialize),
serde(transparent)
)]
pub struct Id<T>([u8; 32], std::marker::PhantomData<T>);
impl<T> Clone for Id<T> {
fn clone(&self) -> Self {
*self
}
}
impl<T> Copy for Id<T> {}
impl<T> PartialEq for Id<T> {
fn eq(&self, other: &Self) -> bool {
self.0 == other.0
}
}
impl<T> Eq for Id<T> {}
impl<T> std::hash::Hash for Id<T> {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.0.hash(state);
}
}
impl<T> fmt::Display for Id<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
hex::encode(self.0).fmt(f)
}
}
impl<T> std::str::FromStr for Id<T> {
type Err = hex::FromHexError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut id = [0u8; 32];
hex::decode_to_slice(s, &mut id)?;
Ok(Self(id, std::marker::PhantomData))
}
}
impl<T> AsRef<[u8]> for Id<T> {
fn as_ref(&self) -> &[u8] {
&self.0
}
}
impl<T> std::ops::Deref for Id<T> {
type Target = [u8; 32];
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T> Id<T> {
#[must_use]
pub fn cast<U>(self) -> Id<U> {
Id::<U>(self.0, std::marker::PhantomData)
}
}
impl<T> From<[u8; 32]> for Id<T> {
fn from(value: [u8; 32]) -> Self {
Self(value, std::marker::PhantomData)
}
}