musli_descriptive/
error.rs

1use core::fmt;
2
3#[cfg(feature = "alloc")]
4use alloc::boxed::Box;
5#[cfg(feature = "alloc")]
6use alloc::string::ToString;
7
8use musli::context::StdError;
9
10/// Error raised during descriptive encoding.
11#[derive(Debug)]
12pub struct Error {
13    err: ErrorImpl,
14}
15
16impl fmt::Display for Error {
17    #[inline]
18    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
19        self.err.fmt(f)
20    }
21}
22
23#[derive(Debug)]
24enum ErrorImpl {
25    #[cfg(feature = "alloc")]
26    Message(Box<str>),
27    #[cfg(feature = "alloc")]
28    Custom(Box<dyn 'static + Send + Sync + StdError>),
29    #[cfg(not(feature = "alloc"))]
30    Empty,
31}
32
33impl fmt::Display for ErrorImpl {
34    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
35        match self {
36            #[cfg(feature = "alloc")]
37            ErrorImpl::Message(message) => message.fmt(f),
38            #[cfg(feature = "alloc")]
39            ErrorImpl::Custom(message) => message.fmt(f),
40            #[cfg(not(feature = "alloc"))]
41            ErrorImpl::Empty => write!(f, "Message error (see diagnostics)"),
42        }
43    }
44}
45
46#[cfg(all(feature = "std", feature = "alloc"))]
47impl std::error::Error for Error {
48    #[inline]
49    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
50        match &self.err {
51            ErrorImpl::Custom(err) => Some(&**err),
52            _ => None,
53        }
54    }
55}
56
57impl musli_utils::context::Error for Error {
58    #[inline]
59    #[allow(unused_variables)]
60    fn custom<T>(error: T) -> Self
61    where
62        T: 'static + Send + Sync + StdError,
63    {
64        Self {
65            #[cfg(feature = "alloc")]
66            err: ErrorImpl::Custom(Box::new(error)),
67            #[cfg(not(feature = "alloc"))]
68            err: ErrorImpl::Empty,
69        }
70    }
71
72    #[inline]
73    #[allow(unused_variables)]
74    fn message<T>(message: T) -> Self
75    where
76        T: fmt::Display,
77    {
78        Self {
79            #[cfg(feature = "alloc")]
80            err: ErrorImpl::Message(message.to_string().into()),
81            #[cfg(not(feature = "alloc"))]
82            err: ErrorImpl::Empty,
83        }
84    }
85}