1use std::{error::Error as StdError, fmt, io, str::Utf8Error, string::FromUtf8Error};
2
3use serde::{de, ser};
4
5use crate::parse::{is_ident_first_char, is_ident_other_char, is_ident_raw_char, BASE64_ENGINE};
6
7#[derive(Clone, Debug, PartialEq, Eq)]
10pub struct SpannedError {
11 pub code: Error,
12 pub position: Position,
13}
14
15pub type Result<T, E = Error> = std::result::Result<T, E>;
16pub type SpannedResult<T> = std::result::Result<T, SpannedError>;
17
18#[derive(Clone, Debug, PartialEq, Eq)]
19#[non_exhaustive]
20pub enum Error {
21 Io(String),
22 Message(String),
23 Base64Error(base64::DecodeError),
24 Eof,
25 ExpectedArray,
26 ExpectedArrayEnd,
27 ExpectedAttribute,
28 ExpectedAttributeEnd,
29 ExpectedBoolean,
30 ExpectedComma,
31 ExpectedChar,
32 ExpectedFloat,
33 FloatUnderscore,
34 ExpectedInteger,
35 ExpectedOption,
36 ExpectedOptionEnd,
37 ExpectedMap,
38 ExpectedMapColon,
39 ExpectedMapEnd,
40 ExpectedDifferentStructName {
41 expected: &'static str,
42 found: String,
43 },
44 ExpectedStructLike,
45 ExpectedNamedStructLike(&'static str),
46 ExpectedStructLikeEnd,
47 ExpectedUnit,
48 ExpectedString,
49 ExpectedStringEnd,
50 ExpectedIdentifier,
51
52 InvalidEscape(&'static str),
53
54 IntegerOutOfBounds,
55
56 NoSuchExtension(String),
57
58 UnclosedBlockComment,
59 UnderscoreAtBeginning,
60 UnexpectedByte(char),
61
62 Utf8Error(Utf8Error),
63 TrailingCharacters,
64
65 InvalidValueForType {
66 expected: String,
67 found: String,
68 },
69 ExpectedDifferentLength {
70 expected: String,
71 found: usize,
72 },
73 NoSuchEnumVariant {
74 expected: &'static [&'static str],
75 found: String,
76 outer: Option<String>,
77 },
78 NoSuchStructField {
79 expected: &'static [&'static str],
80 found: String,
81 outer: Option<String>,
82 },
83 MissingStructField {
84 field: &'static str,
85 outer: Option<String>,
86 },
87 DuplicateStructField {
88 field: &'static str,
89 outer: Option<String>,
90 },
91 InvalidIdentifier(String),
92 SuggestRawIdentifier(String),
93 ExceededRecursionLimit,
94}
95
96impl fmt::Display for SpannedError {
97 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
98 if (self.position == Position { line: 0, col: 0 }) {
99 write!(f, "{}", self.code)
100 } else {
101 write!(f, "{}: {}", self.position, self.code)
102 }
103 }
104}
105
106impl fmt::Display for Error {
107 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
108 match *self {
109 Error::Io(ref s) => f.write_str(s),
110 Error::Message(ref s) => f.write_str(s),
111 Error::Base64Error(ref e) => fmt::Display::fmt(e, f),
112 Error::Eof => f.write_str("Unexpected end of RON"),
113 Error::ExpectedArray => f.write_str("Expected opening `[`"),
114 Error::ExpectedArrayEnd => f.write_str("Expected closing `]`"),
115 Error::ExpectedAttribute => f.write_str("Expected an `#![enable(...)]` attribute"),
116 Error::ExpectedAttributeEnd => {
117 f.write_str("Expected closing `)]` after the enable attribute")
118 }
119 Error::ExpectedBoolean => f.write_str("Expected boolean"),
120 Error::ExpectedComma => f.write_str("Expected comma"),
121 Error::ExpectedChar => f.write_str("Expected char"),
122 Error::ExpectedFloat => f.write_str("Expected float"),
123 Error::FloatUnderscore => f.write_str("Unexpected underscore in float"),
124 Error::ExpectedInteger => f.write_str("Expected integer"),
125 Error::ExpectedOption => f.write_str("Expected option"),
126 Error::ExpectedOptionEnd => f.write_str("Expected closing `)`"),
127 Error::ExpectedMap => f.write_str("Expected opening `{`"),
128 Error::ExpectedMapColon => f.write_str("Expected colon"),
129 Error::ExpectedMapEnd => f.write_str("Expected closing `}`"),
130 Error::ExpectedDifferentStructName {
131 expected,
132 ref found,
133 } => write!(
134 f,
135 "Expected struct {} but found {}",
136 Identifier(expected),
137 Identifier(found)
138 ),
139 Error::ExpectedStructLike => f.write_str("Expected opening `(`"),
140 Error::ExpectedNamedStructLike(name) => {
141 if name.is_empty() {
142 f.write_str("Expected only opening `(`, no name, for un-nameable struct")
143 } else {
144 write!(f, "Expected opening `(` for struct {}", Identifier(name))
145 }
146 }
147 Error::ExpectedStructLikeEnd => f.write_str("Expected closing `)`"),
148 Error::ExpectedUnit => f.write_str("Expected unit"),
149 Error::ExpectedString => f.write_str("Expected string"),
150 Error::ExpectedStringEnd => f.write_str("Expected end of string"),
151 Error::ExpectedIdentifier => f.write_str("Expected identifier"),
152 Error::InvalidEscape(s) => f.write_str(s),
153 Error::IntegerOutOfBounds => f.write_str("Integer is out of bounds"),
154 Error::NoSuchExtension(ref name) => {
155 write!(f, "No RON extension named {}", Identifier(name))
156 }
157 Error::Utf8Error(ref e) => fmt::Display::fmt(e, f),
158 Error::UnclosedBlockComment => f.write_str("Unclosed block comment"),
159 Error::UnderscoreAtBeginning => {
160 f.write_str("Unexpected leading underscore in an integer")
161 }
162 Error::UnexpectedByte(ref byte) => write!(f, "Unexpected byte {:?}", byte),
163 Error::TrailingCharacters => f.write_str("Non-whitespace trailing characters"),
164 Error::InvalidValueForType {
165 ref expected,
166 ref found,
167 } => {
168 write!(f, "Expected {} but found {} instead", expected, found)
169 }
170 Error::ExpectedDifferentLength {
171 ref expected,
172 found,
173 } => {
174 write!(f, "Expected {} but found ", expected)?;
175
176 match found {
177 0 => f.write_str("zero elements")?,
178 1 => f.write_str("one element")?,
179 n => write!(f, "{} elements", n)?,
180 }
181
182 f.write_str(" instead")
183 }
184 Error::NoSuchEnumVariant {
185 expected,
186 ref found,
187 ref outer,
188 } => {
189 f.write_str("Unexpected ")?;
190
191 if outer.is_none() {
192 f.write_str("enum ")?;
193 }
194
195 write!(f, "variant named {}", Identifier(found))?;
196
197 if let Some(outer) = outer {
198 write!(f, "in enum {}", Identifier(outer))?;
199 }
200
201 write!(
202 f,
203 ", {}",
204 OneOf {
205 alts: expected,
206 none: "variants"
207 }
208 )
209 }
210 Error::NoSuchStructField {
211 expected,
212 ref found,
213 ref outer,
214 } => {
215 write!(f, "Unexpected field named {}", Identifier(found))?;
216
217 if let Some(outer) = outer {
218 write!(f, "in {}", Identifier(outer))?;
219 }
220
221 write!(
222 f,
223 ", {}",
224 OneOf {
225 alts: expected,
226 none: "fields"
227 }
228 )
229 }
230 Error::MissingStructField { field, ref outer } => {
231 write!(f, "Unexpected missing field {}", Identifier(field))?;
232
233 match outer {
234 Some(outer) => write!(f, " in {}", Identifier(outer)),
235 None => Ok(()),
236 }
237 }
238 Error::DuplicateStructField { field, ref outer } => {
239 write!(f, "Unexpected duplicate field {}", Identifier(field))?;
240
241 match outer {
242 Some(outer) => write!(f, " in {}", Identifier(outer)),
243 None => Ok(()),
244 }
245 }
246 Error::InvalidIdentifier(ref invalid) => write!(f, "Invalid identifier {:?}", invalid),
247 Error::SuggestRawIdentifier(ref identifier) => write!(
248 f,
249 "Found invalid std identifier `{}`, try the raw identifier `r#{}` instead",
250 identifier, identifier
251 ),
252 Error::ExceededRecursionLimit => f.write_str("Exceeded recursion limit, try increasing the limit and using `serde_stacker` to protect against a stack overflow"),
253 }
254 }
255}
256
257#[derive(Clone, Copy, Debug, PartialEq, Eq)]
258pub struct Position {
259 pub line: usize,
260 pub col: usize,
261}
262
263impl fmt::Display for Position {
264 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
265 write!(f, "{}:{}", self.line, self.col)
266 }
267}
268
269impl ser::Error for Error {
270 #[cold]
271 fn custom<T: fmt::Display>(msg: T) -> Self {
272 Error::Message(msg.to_string())
273 }
274}
275
276impl de::Error for Error {
277 #[cold]
278 fn custom<T: fmt::Display>(msg: T) -> Self {
279 Error::Message(msg.to_string())
280 }
281
282 #[cold]
283 fn invalid_type(unexp: de::Unexpected, exp: &dyn de::Expected) -> Self {
284 Self::invalid_value(unexp, exp)
286 }
287
288 #[cold]
289 fn invalid_value(unexp: de::Unexpected, exp: &dyn de::Expected) -> Self {
290 struct UnexpectedSerdeTypeValue<'a>(de::Unexpected<'a>);
291
292 impl<'a> fmt::Display for UnexpectedSerdeTypeValue<'a> {
293 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
294 use de::Unexpected::*;
295
296 match self.0 {
297 Bool(b) => write!(f, "the boolean `{}`", b),
298 Unsigned(i) => write!(f, "the unsigned integer `{}`", i),
299 Signed(i) => write!(f, "the signed integer `{}`", i),
300 Float(n) => write!(f, "the floating point number `{}`", n),
301 Char(c) => write!(f, "the UTF-8 character `{}`", c),
302 Str(s) => write!(f, "the string {:?}", s),
303 Bytes(b) => write!(f, "the bytes \"{}\"", {
304 base64::display::Base64Display::new(b, &BASE64_ENGINE)
305 }),
306 Unit => write!(f, "a unit value"),
307 Option => write!(f, "an optional value"),
308 NewtypeStruct => write!(f, "a newtype struct"),
309 Seq => write!(f, "a sequence"),
310 Map => write!(f, "a map"),
311 Enum => write!(f, "an enum"),
312 UnitVariant => write!(f, "a unit variant"),
313 NewtypeVariant => write!(f, "a newtype variant"),
314 TupleVariant => write!(f, "a tuple variant"),
315 StructVariant => write!(f, "a struct variant"),
316 Other(other) => f.write_str(other),
317 }
318 }
319 }
320
321 Error::InvalidValueForType {
322 expected: exp.to_string(),
323 found: UnexpectedSerdeTypeValue(unexp).to_string(),
324 }
325 }
326
327 #[cold]
328 fn invalid_length(len: usize, exp: &dyn de::Expected) -> Self {
329 Error::ExpectedDifferentLength {
330 expected: exp.to_string(),
331 found: len,
332 }
333 }
334
335 #[cold]
336 fn unknown_variant(variant: &str, expected: &'static [&'static str]) -> Self {
337 Error::NoSuchEnumVariant {
338 expected,
339 found: variant.to_string(),
340 outer: None,
341 }
342 }
343
344 #[cold]
345 fn unknown_field(field: &str, expected: &'static [&'static str]) -> Self {
346 Error::NoSuchStructField {
347 expected,
348 found: field.to_string(),
349 outer: None,
350 }
351 }
352
353 #[cold]
354 fn missing_field(field: &'static str) -> Self {
355 Error::MissingStructField { field, outer: None }
356 }
357
358 #[cold]
359 fn duplicate_field(field: &'static str) -> Self {
360 Error::DuplicateStructField { field, outer: None }
361 }
362}
363
364impl StdError for SpannedError {}
365impl StdError for Error {}
366
367impl From<Utf8Error> for Error {
368 fn from(e: Utf8Error) -> Self {
369 Error::Utf8Error(e)
370 }
371}
372
373impl From<FromUtf8Error> for Error {
374 fn from(e: FromUtf8Error) -> Self {
375 Error::Utf8Error(e.utf8_error())
376 }
377}
378
379impl From<io::Error> for Error {
380 fn from(e: io::Error) -> Self {
381 Error::Io(e.to_string())
382 }
383}
384
385impl From<io::Error> for SpannedError {
386 fn from(e: io::Error) -> Self {
387 SpannedError {
388 code: e.into(),
389 position: Position { line: 0, col: 0 },
390 }
391 }
392}
393
394impl From<SpannedError> for Error {
395 fn from(e: SpannedError) -> Self {
396 e.code
397 }
398}
399
400struct OneOf {
401 alts: &'static [&'static str],
402 none: &'static str,
403}
404
405impl fmt::Display for OneOf {
406 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
407 match self.alts {
408 [] => write!(f, "there are no {}", self.none),
409 [a1] => write!(f, "expected {} instead", Identifier(a1)),
410 [a1, a2] => write!(
411 f,
412 "expected either {} or {} instead",
413 Identifier(a1),
414 Identifier(a2)
415 ),
416 [a1, ref alts @ ..] => {
417 write!(f, "expected one of {}", Identifier(a1))?;
418
419 for alt in alts {
420 write!(f, ", {}", Identifier(alt))?;
421 }
422
423 f.write_str(" instead")
424 }
425 }
426 }
427}
428
429struct Identifier<'a>(&'a str);
430
431impl<'a> fmt::Display for Identifier<'a> {
432 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
433 if self.0.is_empty() || !self.0.as_bytes().iter().copied().all(is_ident_raw_char) {
434 return write!(f, "{:?}_[invalid identifier]", self.0);
435 }
436
437 let mut bytes = self.0.as_bytes().iter().copied();
438
439 if !bytes.next().map_or(false, is_ident_first_char) || !bytes.all(is_ident_other_char) {
440 write!(f, "`r#{}`", self.0)
441 } else {
442 write!(f, "`{}`", self.0)
443 }
444 }
445}