slid 0.2.0

Simple labeled IDs
Documentation
use crate::Id;
use std::any::type_name;
use std::cmp::Ordering;
use std::fmt::{Debug, Display, Formatter};
use std::hash::{Hash, Hasher};
use std::marker::PhantomData;

impl<Label, const SIZE: usize> Debug for Id<Label, SIZE> {
    /// Formats the `Id` for debugging purposes
    ///
    /// ```
    /// # use slid::Id;
    /// let id: Id<String> = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255].into();
    /// assert_eq!(
    ///     format!("{:?}", id),
    ///     "Id<alloc::string::String>(000000000000000000000000000000ff)"
    /// );
    /// ```
    ///
    /// Note: the Debug representation may change in the future
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        write!(f, "Id<{}>(", type_name::<Label>())?;
        for byte in self.data {
            write!(f, "{:02x}", byte)?;
        }
        write!(f, ")")?;

        Ok(())
    }
}

impl<Label, const SIZE: usize> Display for Id<Label, SIZE> {
    /// Produces the hex representation of the Id
    ///
    /// ```
    /// # use slid::Id;
    /// let id: Id<String> = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255].into();
    /// assert_eq!(
    ///     format!("{:}", id),
    ///     "000000000000000000000000000000ff"
    /// );
    /// ```
    ///
    /// Note: the Display representation may change in the future
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        for byte in self.data {
            write!(f, "{:02x}", byte)?;
        }

        Ok(())
    }
}

impl<Label, const SIZE: usize> Hash for Id<Label, SIZE> {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.data.hash(state)
    }
}

impl<Label, const SIZE: usize> Copy for Id<Label, SIZE> {}

impl<Label, const SIZE: usize> Clone for Id<Label, SIZE> {
    fn clone(&self) -> Self {
        Id {
            data: self.data,
            _phantom: PhantomData,
        }
    }
}

impl<Label, const SIZE: usize> Eq for Id<Label, SIZE> {}

impl<Label, const SIZE: usize> PartialEq for Id<Label, SIZE> {
    fn eq(&self, other: &Self) -> bool {
        self.data.eq(&other.data)
    }
}

#[test]
fn test_eq() {
    let a: Id<()> = [0; 16].into();
    let b: Id<()> = [0; 16].into();
    let c: Id<()> = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0].into();

    assert_eq!(a, b);
    assert_ne!(a, c);
}

impl<Label, const SIZE: usize> PartialOrd for Id<Label, SIZE> {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        Some(self.data.cmp(&other.data))
    }
}

impl<Label, const SIZE: usize> Ord for Id<Label, SIZE> {
    fn cmp(&self, other: &Self) -> Ordering {
        self.data.cmp(&other.data)
    }
}