typed-container 0.1.2

A simple container for IoC
Documentation
use std::{
    any::type_name,
    fmt::{Debug, Display},
    marker::PhantomData,
    sync::PoisonError,
};

use derivative::Derivative;

#[derive(Debug, PartialEq, Eq)]
pub enum ErrorKind {
    LockPoisoned,
    Duplicated,
    NotFound,
    FailDowncast,
    CircularReference,
}

impl Display for ErrorKind {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            Self::Duplicated => write!(f, "Item duplicated"),
            Self::LockPoisoned => write!(f, "Lock poisoned"),
            Self::NotFound => write!(f, "Service not found"),
            Self::FailDowncast => write!(f, "Failed to downcast"),
            Self::CircularReference => write!(f, "Found circular reference"),
        }
    }
}

impl<E> From<PoisonError<E>> for ErrorKind {
    fn from(_: PoisonError<E>) -> Self {
        ErrorKind::LockPoisoned
    }
}

#[derive(Derivative)]
#[derivative(Debug)]
pub struct Error<T> {
    pub kind: ErrorKind,
    #[derivative(Debug = "ignore")]
    _marker: PhantomData<T>,
}

impl<T> Display for Error<T> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}: {}", self.kind, type_name::<T>())
    }
}

impl<T> std::error::Error for Error<T> {}

impl<T> From<ErrorKind> for Error<T> {
    fn from(value: ErrorKind) -> Self {
        Self {
            kind: value,
            _marker: PhantomData,
        }
    }
}

impl<T, E> From<PoisonError<E>> for Error<T> {
    fn from(_: PoisonError<E>) -> Self {
        Self {
            kind: ErrorKind::LockPoisoned,
            _marker: PhantomData,
        }
    }
}