msd/de/
error.rs

1use crate::de::Position;
2use serde::{
3    de,
4    de::{Expected, Unexpected},
5};
6use std::{fmt, fmt::Display};
7
8#[derive(Clone, Debug, PartialEq, Eq)]
9pub enum Kind {
10    // Formatting errors.
11    EndOfFile,
12    ExpectedTag,
13    UnexpectedTag,
14    EndOfTag,
15    UnexpectedValues,
16    UnexpectedValue,
17    EndOfValues,
18
19    // Value errors.
20    ExpectedBool,
21    ExpectedI8,
22    ExpectedI16,
23    ExpectedI32,
24    ExpectedI64,
25    ExpectedI128,
26    ExpectedU8,
27    ExpectedU16,
28    ExpectedU32,
29    ExpectedU64,
30    ExpectedU128,
31    ExpectedF32,
32    ExpectedF64,
33    ExpectedChar,
34    ExpectedString,
35    ExpectedUnit,
36    ExpectedIdentifier,
37
38    // IO-related errors.
39    Io,
40
41    // User-provided errors (provided through `serde::de::Error` trait methods).
42    Custom(String),
43    InvalidType(String, String),
44    InvalidValue(String, String),
45    InvalidLength(usize, String),
46    UnknownVariant(String, &'static [&'static str]),
47    UnknownField(String, &'static [&'static str]),
48    MissingField(&'static str),
49    DuplicateField(&'static str),
50
51    // Unrepresentable type errors.
52    CannotDeserializeAsSelfDescribing,
53    CannotDeserializeAsOptionInTuple,
54    CannotDeserializeAsSeqInTuple,
55    CannotDeserializeAsMapInTuple,
56    CannotDeserializeAsStructInTuple,
57    CannotDeserializeNestedStruct,
58    MustDeserializeStructFieldAsIdentifier,
59    CannotDeserializeAsOptionInSeq,
60    CannotDeserializeNestedSeq,
61    MustDeserializeEnumVariantAsIdentifier,
62}
63
64impl Display for Kind {
65    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
66        match self {
67            Kind::EndOfFile => formatter.write_str("unexpected end of file"),
68            Kind::ExpectedTag => formatter.write_str("expected tag"),
69            Kind::UnexpectedTag => formatter.write_str("unexpected tag"),
70            Kind::EndOfTag => formatter.write_str("unexpected end of tag"),
71            Kind::UnexpectedValues => formatter.write_str("unexpected values"),
72            Kind::UnexpectedValue => formatter.write_str("unexpected value"),
73            Kind::EndOfValues => formatter.write_str("unexpected end of values"),
74            Kind::ExpectedBool => formatter.write_str("expected bool"),
75            Kind::ExpectedI8 => formatter.write_str("expected i8"),
76            Kind::ExpectedI16 => formatter.write_str("expected i16"),
77            Kind::ExpectedI32 => formatter.write_str("expected i32"),
78            Kind::ExpectedI64 => formatter.write_str("expected i64"),
79            Kind::ExpectedI128 => formatter.write_str("expected i128"),
80            Kind::ExpectedU8 => formatter.write_str("expected u8"),
81            Kind::ExpectedU16 => formatter.write_str("expected u16"),
82            Kind::ExpectedU32 => formatter.write_str("expected u32"),
83            Kind::ExpectedU64 => formatter.write_str("expected u64"),
84            Kind::ExpectedU128 => formatter.write_str("expected u128"),
85            Kind::ExpectedF32 => formatter.write_str("expected f32"),
86            Kind::ExpectedF64 => formatter.write_str("expected f64"),
87            Kind::ExpectedChar => formatter.write_str("expected char"),
88            Kind::ExpectedString => formatter.write_str("expected string"),
89            Kind::ExpectedUnit => formatter.write_str("expected unit value"),
90            Kind::ExpectedIdentifier => formatter.write_str("expected identifier"),
91            Kind::Io => formatter.write_str("io error"),
92            Kind::Custom(msg) => formatter.write_str(msg),
93            Kind::InvalidType(unexpected, expected) => {
94                write!(
95                    formatter,
96                    "invalid type: expected {}, found {}",
97                    expected, unexpected
98                )
99            }
100            Kind::InvalidValue(unexpected, expected) => {
101                write!(
102                    formatter,
103                    "invalid value: expected {}, found {}",
104                    expected, unexpected
105                )
106            }
107            Kind::InvalidLength(length, expected) => {
108                write!(
109                    formatter,
110                    "invalid length {}, expected {}",
111                    length, expected
112                )
113            }
114            Kind::UnknownVariant(variant, expected) => {
115                write!(
116                    formatter,
117                    "unknown variant {}, expected one of {:?}",
118                    variant, expected
119                )
120            }
121
122            Kind::UnknownField(field, expected) => {
123                write!(
124                    formatter,
125                    "unknown field {}, expected one of {:?}",
126                    field, expected
127                )
128            }
129            Kind::MissingField(field) => {
130                write!(formatter, "missing field {}", field)
131            }
132
133            Kind::DuplicateField(field) => {
134                write!(formatter, "duplicate field {}", field)
135            }
136            Kind::CannotDeserializeAsSelfDescribing => {
137                formatter.write_str("cannot deserialize as self-describing")
138            }
139            Kind::CannotDeserializeAsOptionInTuple => {
140                formatter.write_str("cannot deserialize as option in tuple")
141            }
142            Kind::CannotDeserializeAsSeqInTuple => {
143                formatter.write_str("cannot deserialize as seq in tuple")
144            }
145            Kind::CannotDeserializeAsMapInTuple => {
146                formatter.write_str("cannot deserialize as map in tuple")
147            }
148            Kind::CannotDeserializeAsStructInTuple => {
149                formatter.write_str("cannot deserialize as struct in tuple")
150            }
151            Kind::CannotDeserializeNestedStruct => {
152                formatter.write_str("cannot deserialize nested struct")
153            }
154            Kind::MustDeserializeStructFieldAsIdentifier => {
155                formatter.write_str("must deserialize struct field as identifier")
156            }
157            Kind::CannotDeserializeAsOptionInSeq => {
158                formatter.write_str("cannot deserialize as option in seq")
159            }
160            Kind::CannotDeserializeNestedSeq => {
161                formatter.write_str("cannot deserialize nested seq")
162            }
163            Kind::MustDeserializeEnumVariantAsIdentifier => {
164                formatter.write_str("must deserialize enum variant as identifier")
165            }
166        }
167    }
168}
169
170/// An error that may occur during deserialization.
171#[derive(Clone, Debug, PartialEq, Eq)]
172pub struct Error {
173    position: Position,
174    kind: Kind,
175}
176
177impl Error {
178    pub(super) fn new(kind: Kind, position: Position) -> Self {
179        Self { position, kind }
180    }
181
182    pub(in crate::de) fn set_position(&mut self, position: Position) {
183        self.position = position;
184    }
185}
186
187impl de::Error for Error {
188    fn custom<T>(msg: T) -> Self
189    where
190        T: Display,
191    {
192        Self::new(Kind::Custom(msg.to_string()), Position::new(0, 0))
193    }
194
195    fn invalid_type(unexpected: Unexpected, expected: &dyn Expected) -> Self {
196        Self::new(
197            Kind::InvalidType(unexpected.to_string(), expected.to_string()),
198            Position::new(0, 0),
199        )
200    }
201
202    fn invalid_value(unexpected: Unexpected, expected: &dyn Expected) -> Self {
203        Self::new(
204            Kind::InvalidValue(unexpected.to_string(), expected.to_string()),
205            Position::new(0, 0),
206        )
207    }
208
209    fn invalid_length(len: usize, expected: &dyn Expected) -> Self {
210        Self::new(
211            Kind::InvalidLength(len, expected.to_string()),
212            Position::new(0, 0),
213        )
214    }
215
216    fn unknown_variant(variant: &str, expected: &'static [&'static str]) -> Self {
217        Self::new(
218            Kind::UnknownVariant(variant.to_owned(), expected),
219            Position::new(0, 0),
220        )
221    }
222
223    fn unknown_field(field: &str, expected: &'static [&'static str]) -> Self {
224        Self::new(
225            Kind::UnknownField(field.to_owned(), expected),
226            Position::new(0, 0),
227        )
228    }
229
230    fn missing_field(field: &'static str) -> Self {
231        Self::new(Kind::MissingField(field), Position::new(0, 0))
232    }
233
234    fn duplicate_field(field: &'static str) -> Self {
235        Self::new(Kind::DuplicateField(field), Position::new(0, 0))
236    }
237}
238
239impl Display for Error {
240    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
241        write!(
242            formatter,
243            "{} at line {} column {}",
244            self.kind,
245            self.position.line(),
246            self.position.column()
247        )
248    }
249}
250
251impl std::error::Error for Error {}
252
253/// An alias for a [`Result`] with the error type [`Error`].
254///
255/// [`Result`]: std::result::Result
256pub type Result<T> = core::result::Result<T, Error>;
257
258#[cfg(test)]
259mod tests {
260    use super::{Error, Kind};
261    use crate::de::Position;
262    use serde::de::Error as SerdeError;
263    use serde::de::Unexpected;
264
265    #[test]
266    fn end_of_file() {
267        assert_eq!(
268            format!("{}", Error::new(Kind::EndOfFile, Position::new(1, 2))),
269            "unexpected end of file at line 1 column 2"
270        );
271    }
272
273    #[test]
274    fn expected_tag() {
275        assert_eq!(
276            format!("{}", Error::new(Kind::ExpectedTag, Position::new(2, 3))),
277            "expected tag at line 2 column 3"
278        );
279    }
280
281    #[test]
282    fn unexpected_tag() {
283        assert_eq!(
284            format!("{}", Error::new(Kind::UnexpectedTag, Position::new(3, 4))),
285            "unexpected tag at line 3 column 4"
286        );
287    }
288
289    #[test]
290    fn end_of_tag() {
291        assert_eq!(
292            format!("{}", Error::new(Kind::EndOfTag, Position::new(4, 5))),
293            "unexpected end of tag at line 4 column 5"
294        );
295    }
296
297    #[test]
298    fn unexpected_values() {
299        assert_eq!(
300            format!(
301                "{}",
302                Error::new(Kind::UnexpectedValues, Position::new(5, 6))
303            ),
304            "unexpected values at line 5 column 6"
305        );
306    }
307
308    #[test]
309    fn unexpected_value() {
310        assert_eq!(
311            format!("{}", Error::new(Kind::UnexpectedValue, Position::new(6, 7))),
312            "unexpected value at line 6 column 7"
313        );
314    }
315
316    #[test]
317    fn end_of_values() {
318        assert_eq!(
319            format!("{}", Error::new(Kind::EndOfValues, Position::new(7, 8))),
320            "unexpected end of values at line 7 column 8"
321        );
322    }
323
324    #[test]
325    fn expected_bool() {
326        assert_eq!(
327            format!("{}", Error::new(Kind::ExpectedBool, Position::new(8, 9))),
328            "expected bool at line 8 column 9"
329        );
330    }
331
332    #[test]
333    fn expected_i8() {
334        assert_eq!(
335            format!("{}", Error::new(Kind::ExpectedI8, Position::new(9, 10))),
336            "expected i8 at line 9 column 10"
337        );
338    }
339
340    #[test]
341    fn expected_i16() {
342        assert_eq!(
343            format!("{}", Error::new(Kind::ExpectedI16, Position::new(10, 11))),
344            "expected i16 at line 10 column 11"
345        );
346    }
347
348    #[test]
349    fn expected_i32() {
350        assert_eq!(
351            format!("{}", Error::new(Kind::ExpectedI32, Position::new(11, 12))),
352            "expected i32 at line 11 column 12"
353        );
354    }
355
356    #[test]
357    fn expected_i64() {
358        assert_eq!(
359            format!("{}", Error::new(Kind::ExpectedI64, Position::new(12, 13))),
360            "expected i64 at line 12 column 13"
361        );
362    }
363
364    #[test]
365    fn expected_i128() {
366        assert_eq!(
367            format!("{}", Error::new(Kind::ExpectedI128, Position::new(13, 14))),
368            "expected i128 at line 13 column 14"
369        );
370    }
371
372    #[test]
373    fn expected_u8() {
374        assert_eq!(
375            format!("{}", Error::new(Kind::ExpectedU8, Position::new(14, 15))),
376            "expected u8 at line 14 column 15"
377        );
378    }
379
380    #[test]
381    fn expected_u16() {
382        assert_eq!(
383            format!("{}", Error::new(Kind::ExpectedU16, Position::new(15, 16))),
384            "expected u16 at line 15 column 16"
385        );
386    }
387
388    #[test]
389    fn expected_u32() {
390        assert_eq!(
391            format!("{}", Error::new(Kind::ExpectedU32, Position::new(16, 17))),
392            "expected u32 at line 16 column 17"
393        );
394    }
395
396    #[test]
397    fn expected_u64() {
398        assert_eq!(
399            format!("{}", Error::new(Kind::ExpectedU64, Position::new(17, 18))),
400            "expected u64 at line 17 column 18"
401        );
402    }
403
404    #[test]
405    fn expected_u128() {
406        assert_eq!(
407            format!("{}", Error::new(Kind::ExpectedU128, Position::new(18, 19))),
408            "expected u128 at line 18 column 19"
409        );
410    }
411
412    #[test]
413    fn expected_f32() {
414        assert_eq!(
415            format!("{}", Error::new(Kind::ExpectedF32, Position::new(19, 20))),
416            "expected f32 at line 19 column 20"
417        );
418    }
419
420    #[test]
421    fn expected_f64() {
422        assert_eq!(
423            format!("{}", Error::new(Kind::ExpectedF64, Position::new(20, 21))),
424            "expected f64 at line 20 column 21"
425        );
426    }
427
428    #[test]
429    fn expected_char() {
430        assert_eq!(
431            format!("{}", Error::new(Kind::ExpectedChar, Position::new(21, 22))),
432            "expected char at line 21 column 22"
433        );
434    }
435
436    #[test]
437    fn expected_string() {
438        assert_eq!(
439            format!(
440                "{}",
441                Error::new(Kind::ExpectedString, Position::new(22, 23))
442            ),
443            "expected string at line 22 column 23"
444        );
445    }
446
447    #[test]
448    fn expected_unit() {
449        assert_eq!(
450            format!("{}", Error::new(Kind::ExpectedUnit, Position::new(23, 24))),
451            "expected unit value at line 23 column 24"
452        );
453    }
454
455    #[test]
456    fn expected_identifier() {
457        assert_eq!(
458            format!(
459                "{}",
460                Error::new(Kind::ExpectedIdentifier, Position::new(24, 25))
461            ),
462            "expected identifier at line 24 column 25"
463        );
464    }
465
466    #[test]
467    fn io() {
468        assert_eq!(
469            format!("{}", Error::new(Kind::Io, Position::new(25, 26))),
470            "io error at line 25 column 26"
471        );
472    }
473
474    #[test]
475    fn custom() {
476        let mut error = Error::custom("foo");
477        error.set_position(Position::new(26, 27));
478
479        assert_eq!(format!("{}", error), "foo at line 26 column 27");
480    }
481
482    #[test]
483    fn invalid_type() {
484        let mut error = Error::invalid_type(Unexpected::Bool(true), &"foo");
485        error.set_position(Position::new(27, 28));
486
487        assert_eq!(
488            format!("{}", error),
489            "invalid type: expected foo, found boolean `true` at line 27 column 28"
490        );
491    }
492
493    #[test]
494    fn invalid_value() {
495        let mut error = Error::invalid_value(Unexpected::Bool(true), &"foo");
496        error.set_position(Position::new(28, 29));
497
498        assert_eq!(
499            format!("{}", error),
500            "invalid value: expected foo, found boolean `true` at line 28 column 29"
501        );
502    }
503
504    #[test]
505    fn invalid_length() {
506        let mut error = Error::invalid_length(42, &"foo");
507        error.set_position(Position::new(29, 30));
508
509        assert_eq!(
510            format!("{}", error),
511            "invalid length 42, expected foo at line 29 column 30"
512        );
513    }
514
515    #[test]
516    fn unknown_variant() {
517        static EXPECTED: &'static [&'static str] = &["foo", "bar"];
518        let mut error = Error::unknown_variant("baz", EXPECTED);
519        error.set_position(Position::new(30, 31));
520
521        assert_eq!(
522            format!("{}", error),
523            "unknown variant baz, expected one of [\"foo\", \"bar\"] at line 30 column 31"
524        );
525    }
526
527    #[test]
528    fn unknown_field() {
529        let mut error = Error::unknown_field("baz", &["foo", "bar"]);
530        error.set_position(Position::new(31, 32));
531
532        assert_eq!(
533            format!("{}", error),
534            "unknown field baz, expected one of [\"foo\", \"bar\"] at line 31 column 32"
535        );
536    }
537
538    #[test]
539    fn missing_field() {
540        let mut error = Error::missing_field("foo");
541        error.set_position(Position::new(32, 33));
542
543        assert_eq!(
544            format!("{}", error),
545            "missing field foo at line 32 column 33"
546        );
547    }
548
549    #[test]
550    fn duplicate_field() {
551        let mut error = Error::duplicate_field("foo");
552        error.set_position(Position::new(33, 34));
553
554        assert_eq!(
555            format!("{}", error),
556            "duplicate field foo at line 33 column 34"
557        );
558    }
559
560    #[test]
561    fn cannot_deserialize_as_self_describing() {
562        assert_eq!(
563            format!(
564                "{}",
565                Error::new(
566                    Kind::CannotDeserializeAsSelfDescribing,
567                    Position::new(34, 35)
568                )
569            ),
570            "cannot deserialize as self-describing at line 34 column 35"
571        );
572    }
573
574    #[test]
575    fn cannot_deserialize_as_option_in_tuple() {
576        assert_eq!(
577            format!(
578                "{}",
579                Error::new(
580                    Kind::CannotDeserializeAsOptionInTuple,
581                    Position::new(35, 36)
582                )
583            ),
584            "cannot deserialize as option in tuple at line 35 column 36"
585        );
586    }
587
588    #[test]
589    fn cannot_deserialize_as_seq_in_tuple() {
590        assert_eq!(
591            format!(
592                "{}",
593                Error::new(Kind::CannotDeserializeAsSeqInTuple, Position::new(36, 37))
594            ),
595            "cannot deserialize as seq in tuple at line 36 column 37"
596        );
597    }
598
599    #[test]
600    fn cannot_deserialize_as_map_in_tuple() {
601        assert_eq!(
602            format!(
603                "{}",
604                Error::new(Kind::CannotDeserializeAsMapInTuple, Position::new(37, 38))
605            ),
606            "cannot deserialize as map in tuple at line 37 column 38"
607        );
608    }
609
610    #[test]
611    fn cannot_deserialize_as_struct_in_tuple() {
612        assert_eq!(
613            format!(
614                "{}",
615                Error::new(
616                    Kind::CannotDeserializeAsStructInTuple,
617                    Position::new(38, 39)
618                )
619            ),
620            "cannot deserialize as struct in tuple at line 38 column 39"
621        );
622    }
623
624    #[test]
625    fn cannot_deserialize_nested_struct() {
626        assert_eq!(
627            format!(
628                "{}",
629                Error::new(Kind::CannotDeserializeNestedStruct, Position::new(39, 40))
630            ),
631            "cannot deserialize nested struct at line 39 column 40"
632        );
633    }
634
635    #[test]
636    fn must_deserialize_struct_field_as_identifier() {
637        assert_eq!(
638            format!(
639                "{}",
640                Error::new(
641                    Kind::MustDeserializeStructFieldAsIdentifier,
642                    Position::new(40, 41)
643                )
644            ),
645            "must deserialize struct field as identifier at line 40 column 41"
646        );
647    }
648
649    #[test]
650    fn cannot_deserialize_as_option_in_seq() {
651        assert_eq!(
652            format!(
653                "{}",
654                Error::new(Kind::CannotDeserializeAsOptionInSeq, Position::new(41, 42))
655            ),
656            "cannot deserialize as option in seq at line 41 column 42"
657        );
658    }
659
660    #[test]
661    fn cannot_deserialize_nested_seq() {
662        assert_eq!(
663            format!(
664                "{}",
665                Error::new(Kind::CannotDeserializeNestedSeq, Position::new(42, 43))
666            ),
667            "cannot deserialize nested seq at line 42 column 43"
668        );
669    }
670
671    #[test]
672    fn must_deserialize_enum_variant_as_identifier() {
673        assert_eq!(
674            format!(
675                "{}",
676                Error::new(
677                    Kind::MustDeserializeEnumVariantAsIdentifier,
678                    Position::new(43, 44)
679                )
680            ),
681            "must deserialize enum variant as identifier at line 43 column 44"
682        );
683    }
684
685    #[test]
686    fn set_position() {
687        let mut error = Error::new(Kind::EndOfFile, Position::new(0, 0));
688
689        error.set_position(Position::new(1, 2));
690
691        assert_eq!(error.position, Position::new(1, 2));
692    }
693}