deser_incomplete/
error.rs1use std::fmt::Display;
2
3use serde::de::{Expected, Unexpected};
4
5#[cfg(doc)]
6use serde::de::{DeserializeSeed, Deserializer};
7
8#[derive(Debug, thiserror::Error)]
12#[error(transparent)]
13pub struct Error<DeserializerErr> {
14 err: Box<ErrorImpl<DeserializerErr>>,
19}
20
21#[derive(Debug, thiserror::Error)]
22pub(crate) enum ErrorImpl<DeserializerErr> {
23 #[error(transparent)]
25 Deserializer(DeserializerErr),
26 #[error(transparent)]
27 Internal(InternalError),
28 #[error(transparent)]
30 InconsistentDeserializer(InconsistentDeserializerError),
31}
32
33#[derive(Debug, thiserror::Error)]
34#[non_exhaustive]
35pub enum InternalError {
36 #[error(
37 "the maximum number of backtracks has been exceeded (see tracing logs for pointers to avoid a high number of backtracks)"
38 )]
39 TooManyBacktracks,
40 #[error(
41 "could not find a potential backtrack point (do you have #[serde(default)] on your top-level type? are your settings too strict?) (after {after_backtracks} backtracks)"
42 )]
43 NoPotentialBacktrackPoint { after_backtracks: usize },
44 #[error("bug in {pkg} (please report): {0}", pkg = std::env!("CARGO_PKG_NAME"))]
45 Bug(BugError),
46}
47
48#[derive(Debug, thiserror::Error)]
49#[error(transparent)]
50pub struct BugError(BugEnum);
51
52#[derive(Debug, thiserror::Error)]
53pub(crate) enum BugEnum {
54 #[error("our visitor should store the obtained value on the stack, but it's missing")]
55 OkButValueMissingFromStack,
56}
57
58#[derive(Debug, thiserror::Error)]
59#[non_exhaustive]
60pub enum InconsistentDeserializerError {}
61
62#[derive(Debug, thiserror::Error)]
63pub enum FallbackError {
64 #[error("The fallback took the visitor to compute a value, but didn't return a Result.")]
65 FallbackDidntCompute,
66 #[error("While constructing a fallback value: {0}")]
67 FallbackVisitor(serde::de::value::Error),
68}
69
70impl<DeserializerErr> Error<DeserializerErr> {
71 pub(crate) fn from_de(err: DeserializerErr) -> Self {
72 Self {
73 err: Box::new(ErrorImpl::Deserializer(err)),
74 }
75 }
76
77 pub fn as_deserializer_error(&self) -> Option<&DeserializerErr> {
79 match &*self.err {
80 ErrorImpl::Deserializer(err) => Some(err),
81 _ => None,
82 }
83 }
84
85 pub fn into_deserializer_error(self) -> Option<DeserializerErr> {
86 match *self.err {
87 ErrorImpl::Deserializer(err) => Some(err),
88 _ => None,
89 }
90 }
91
92 pub fn as_internal_error(&self) -> Option<&InternalError> {
93 match &*self.err {
94 ErrorImpl::Internal(err) => Some(err),
95 _ => None,
96 }
97 }
98
99 pub fn into_internal_error(self) -> Option<InternalError> {
100 match *self.err {
101 ErrorImpl::Internal(err) => Some(err),
102 _ => None,
103 }
104 }
105
106 pub fn as_inconsistent_deserializer_error(&self) -> Option<&InconsistentDeserializerError> {
108 match &*self.err {
109 ErrorImpl::InconsistentDeserializer(err) => Some(err),
110 _ => None,
111 }
112 }
113
114 pub fn into_inconsistent_deserializer_error(self) -> Option<InconsistentDeserializerError> {
115 match *self.err {
116 ErrorImpl::InconsistentDeserializer(err) => Some(err),
117 _ => None,
118 }
119 }
120}
121
122impl<DeserializerErr> Error<DeserializerErr>
123where
124 DeserializerErr: serde::de::Error,
125{
126 pub fn unpack_or_make_custom(self) -> DeserializerErr {
132 match *self.err {
133 ErrorImpl::Deserializer(err) => err,
134 _ => DeserializerErr::custom(format!("{}: {self}", std::env!("CARGO_PKG_NAME"))),
135 }
136 }
137}
138
139impl<DeserializerErr> From<InternalError> for Error<DeserializerErr> {
140 fn from(err: InternalError) -> Self {
141 Self {
142 err: Box::new(ErrorImpl::Internal(err)),
143 }
144 }
145}
146
147impl From<BugEnum> for InternalError {
148 fn from(err: BugEnum) -> Self {
149 InternalError::Bug(BugError(err))
150 }
151}
152
153impl<DeserializerErr> From<BugEnum> for Error<DeserializerErr> {
154 fn from(err: BugEnum) -> Self {
155 Self {
156 err: Box::new(ErrorImpl::Internal(err.into())),
157 }
158 }
159}
160
161impl<DeserializerErr> From<InconsistentDeserializerError> for Error<DeserializerErr> {
162 fn from(err: InconsistentDeserializerError) -> Self {
163 Self {
164 err: Box::new(ErrorImpl::InconsistentDeserializer(err)),
165 }
166 }
167}
168
169impl<DeserializerErr> serde::de::Error for Error<DeserializerErr>
170where
171 DeserializerErr: serde::de::Error,
172{
173 fn custom<T>(msg: T) -> Self
174 where
175 T: Display,
176 {
177 Self::from_de(DeserializerErr::custom(msg))
178 }
179
180 #[cold]
181 fn invalid_type(unexp: Unexpected, exp: &dyn Expected) -> Self {
182 Self::from_de(DeserializerErr::invalid_type(unexp, exp))
183 }
184
185 #[cold]
186 fn invalid_value(unexp: Unexpected, exp: &dyn Expected) -> Self {
187 Self::from_de(DeserializerErr::invalid_value(unexp, exp))
188 }
189
190 #[cold]
191 fn invalid_length(len: usize, exp: &dyn Expected) -> Self {
192 Self::from_de(DeserializerErr::invalid_length(len, exp))
193 }
194
195 #[cold]
196 fn unknown_variant(variant: &str, expected: &'static [&'static str]) -> Self {
197 Self::from_de(DeserializerErr::unknown_variant(variant, expected))
198 }
199
200 #[cold]
201 fn unknown_field(field: &str, expected: &'static [&'static str]) -> Self {
202 Self::from_de(DeserializerErr::unknown_field(field, expected))
203 }
204
205 #[cold]
206 fn missing_field(field: &'static str) -> Self {
207 Self::from_de(DeserializerErr::missing_field(field))
208 }
209
210 #[cold]
211 fn duplicate_field(field: &'static str) -> Self {
212 Self::from_de(DeserializerErr::duplicate_field(field))
213 }
214}
215
216impl<DeserializerErr> Error<DeserializerErr>
217where
218 DeserializerErr: std::error::Error + Send + Sync + 'static,
219{
220 pub fn erase(self) -> Error<Box<dyn std::error::Error + Send + Sync>> {
221 let inner = *self.err;
222
223 let err = Box::new(match inner {
224 ErrorImpl::Deserializer(err) => {
225 ErrorImpl::Deserializer(Box::new(err) as Box<dyn std::error::Error + Send + Sync>)
226 }
227 ErrorImpl::Internal(err) => ErrorImpl::Internal(err),
228 ErrorImpl::InconsistentDeserializer(err) => ErrorImpl::InconsistentDeserializer(err),
229 });
230
231 Error { err }
232 }
233}