musli_descriptive/
error.rs1use 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#[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}