lunar-lib 0.11.0

Common utilities for lunar applications
Documentation
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)
    }
}