1use core::fmt;
2
3#[cfg(feature = "alloc")]
4use alloc::boxed::Box;
5#[cfg(feature = "alloc")]
6use alloc::string::ToString;
7
8#[derive(Debug)]
10pub struct Error {
11 err: ErrorImpl,
12}
13
14impl fmt::Display for Error {
15 #[inline]
16 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
17 self.err.fmt(f)
18 }
19}
20
21#[derive(Debug)]
22enum ErrorImpl {
23 #[cfg(feature = "alloc")]
24 Message(Box<str>),
25 #[cfg(not(feature = "alloc"))]
26 Empty,
27}
28
29impl fmt::Display for ErrorImpl {
30 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
31 match self {
32 #[cfg(feature = "alloc")]
33 ErrorImpl::Message(message) => message.fmt(f),
34 #[cfg(not(feature = "alloc"))]
35 ErrorImpl::Empty => write!(f, "Message error (see diagnostics)"),
36 }
37 }
38}
39
40#[cfg(feature = "std")]
41impl std::error::Error for Error {}
42
43impl musli_utils::context::Error for Error {
44 #[inline]
45 fn custom<T>(error: T) -> Self
46 where
47 T: fmt::Display,
48 {
49 Self::message(error)
50 }
51
52 #[inline]
53 #[allow(unused_variables)]
54 fn message<T>(message: T) -> Self
55 where
56 T: fmt::Display,
57 {
58 Self {
59 #[cfg(feature = "alloc")]
60 err: ErrorImpl::Message(message.to_string().into()),
61 #[cfg(not(feature = "alloc"))]
62 err: ErrorImpl::Empty,
63 }
64 }
65}