1use core::fmt;
2
3#[cfg(feature = "alloc")]
4use alloc::boxed::Box;
5#[cfg(feature = "alloc")]
6use alloc::string::ToString;
7
8use crate::type_hint::{NumberHint, TypeHint};
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#[allow(missing_docs)]
24#[derive(Debug)]
25#[non_exhaustive]
26enum ErrorImpl {
27 #[cfg(feature = "alloc")]
28 Message(Box<str>),
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(not(feature = "alloc"))]
39 ErrorImpl::Empty => write!(f, "Message error (see diagnostics)"),
40 }
41 }
42}
43
44#[cfg(feature = "std")]
45impl std::error::Error for Error {}
46
47impl musli_utils::context::Error for Error {
48 #[inline]
49 fn custom<T>(error: T) -> Self
50 where
51 T: fmt::Display,
52 {
53 Self::message(error)
54 }
55
56 #[inline]
57 #[allow(unused_variables)]
58 fn message<T>(message: T) -> Self
59 where
60 T: fmt::Display,
61 {
62 Self {
63 #[cfg(feature = "alloc")]
64 err: ErrorImpl::Message(message.to_string().into()),
65 #[cfg(not(feature = "alloc"))]
66 err: ErrorImpl::Empty,
67 }
68 }
69}
70
71#[derive(Debug)]
73#[non_exhaustive]
74#[allow(missing_docs)]
75pub(crate) enum ErrorMessage {
76 #[cfg(feature = "alloc")]
77 ArrayOutOfBounds,
78 ExpectedPackValue,
79 ExpectedUnit(TypeHint),
80 ExpectedBool(TypeHint),
81 ExpectedChar(TypeHint),
82 ExpectedNumber(NumberHint, TypeHint),
83 ExpectedMapValue,
84 #[cfg(feature = "alloc")]
85 ExpectedBytes(TypeHint),
86 #[cfg(feature = "alloc")]
87 ExpectedString(TypeHint),
88 #[cfg(feature = "alloc")]
89 ExpectedStringAsNumber,
90 #[cfg(feature = "alloc")]
91 ExpectedOption(TypeHint),
92 #[cfg(feature = "alloc")]
93 ExpectedSequence(TypeHint),
94 #[cfg(feature = "alloc")]
95 ExpectedPack(TypeHint),
96 #[cfg(feature = "alloc")]
97 ExpectedMap(TypeHint),
98 #[cfg(feature = "alloc")]
99 ExpectedVariant(TypeHint),
100}
101
102impl fmt::Display for ErrorMessage {
103 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
104 match self {
105 #[cfg(feature = "alloc")]
106 ErrorMessage::ArrayOutOfBounds => {
107 write!(
108 f,
109 "Value buffer tried to decode array that is out-of-bounds"
110 )
111 }
112 ErrorMessage::ExpectedPackValue => write!(f, "Value buffer expected pack value"),
113 ErrorMessage::ExpectedUnit(hint) => {
114 write!(f, "Value buffer expected unit, but found {hint}")
115 }
116 ErrorMessage::ExpectedBool(hint) => {
117 write!(f, "Value buffer expected boolean, but found {hint}")
118 }
119 ErrorMessage::ExpectedChar(hint) => {
120 write!(f, "Value buffer expected character, but found {hint}")
121 }
122 ErrorMessage::ExpectedNumber(number, hint) => {
123 write!(f, "Value buffer expected {number}, but found {hint}")
124 }
125 ErrorMessage::ExpectedMapValue => write!(f, "Value buffer expected map value"),
126 #[cfg(feature = "alloc")]
127 ErrorMessage::ExpectedBytes(hint) => {
128 write!(f, "Value buffer expected bytes, but found {hint}")
129 }
130 #[cfg(feature = "alloc")]
131 ErrorMessage::ExpectedString(hint) => {
132 write!(f, "Value buffer expected string, but found {hint}")
133 }
134 #[cfg(feature = "alloc")]
135 ErrorMessage::ExpectedStringAsNumber => {
136 write!(f, "Value buffer expected string containing number")
137 }
138 #[cfg(feature = "alloc")]
139 ErrorMessage::ExpectedOption(hint) => {
140 write!(f, "Value buffer expected option, but found {hint}")
141 }
142 #[cfg(feature = "alloc")]
143 ErrorMessage::ExpectedSequence(hint) => {
144 write!(f, "Value buffer expected sequence, but found {hint}")
145 }
146 #[cfg(feature = "alloc")]
147 ErrorMessage::ExpectedPack(hint) => {
148 write!(f, "Value buffer expected pack of bytes, but found {hint}")
149 }
150 #[cfg(feature = "alloc")]
151 ErrorMessage::ExpectedMap(hint) => {
152 write!(f, "Value buffer expected map, but found {hint}")
153 }
154 #[cfg(feature = "alloc")]
155 ErrorMessage::ExpectedVariant(hint) => {
156 write!(f, "Value buffer expected struct, but found {hint}")
157 }
158 }
159 }
160}