1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
use core::fmt;
use mycelium_util::error::Error;

pub(crate) fn unexpected<T>(value: T) -> UnexpectedValue<T>
where
    T: fmt::LowerHex + fmt::Debug,
{
    UnexpectedValue { value, name: None }
}

#[derive(Clone, Debug, Eq, PartialEq)]
pub struct UnexpectedValue<T> {
    value: T,
    name: Option<&'static str>,
}

impl<T> UnexpectedValue<T> {
    pub(crate) fn named(self, name: &'static str) -> Self {
        Self {
            name: Some(name),
            ..self
        }
    }
}

impl<T> fmt::Display for UnexpectedValue<T>
where
    T: fmt::LowerHex + fmt::Debug,
{
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let ty = core::any::type_name::<T>();
        match self {
            Self {
                value,
                name: Some(name),
            } => write!(f, "unexpected {ty} value for {name}: {value:#x}",),
            Self { value, name: None } => write!(f, "unexpected {ty} value: {value:#x}",),
        }
    }
}

impl<T> Error for UnexpectedValue<T> where T: fmt::LowerHex + fmt::Debug {}