typed_container/
errors.rs

1use std::{
2    any::type_name,
3    fmt::{Debug, Display},
4    marker::PhantomData,
5    sync::PoisonError,
6};
7
8use derivative::Derivative;
9
10#[derive(Debug, PartialEq, Eq)]
11pub enum ErrorKind {
12    LockPoisoned,
13    Duplicated,
14    NotFound,
15    FailDowncast,
16    CircularReference,
17}
18
19impl Display for ErrorKind {
20    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
21        match self {
22            Self::Duplicated => write!(f, "Item duplicated"),
23            Self::LockPoisoned => write!(f, "Lock poisoned"),
24            Self::NotFound => write!(f, "Service not found"),
25            Self::FailDowncast => write!(f, "Failed to downcast"),
26            Self::CircularReference => write!(f, "Found circular reference"),
27        }
28    }
29}
30
31impl<E> From<PoisonError<E>> for ErrorKind {
32    fn from(_: PoisonError<E>) -> Self {
33        ErrorKind::LockPoisoned
34    }
35}
36
37#[derive(Derivative)]
38#[derivative(Debug)]
39pub struct Error<T> {
40    pub kind: ErrorKind,
41    #[derivative(Debug = "ignore")]
42    _marker: PhantomData<T>,
43}
44
45impl<T> Display for Error<T> {
46    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
47        write!(f, "{}: {}", self.kind, type_name::<T>())
48    }
49}
50
51impl<T> std::error::Error for Error<T> {}
52
53impl<T> From<ErrorKind> for Error<T> {
54    fn from(value: ErrorKind) -> Self {
55        Self {
56            kind: value,
57            _marker: PhantomData,
58        }
59    }
60}
61
62impl<T, E> From<PoisonError<E>> for Error<T> {
63    fn from(_: PoisonError<E>) -> Self {
64        Self {
65            kind: ErrorKind::LockPoisoned,
66            _marker: PhantomData,
67        }
68    }
69}