ron/
error.rs

1use std::{
2    error::Error as StdError,
3    fmt, io,
4    str::{self, Utf8Error},
5};
6
7use serde::{de, ser};
8use unicode_ident::is_xid_continue;
9
10use crate::parse::{is_ident_first_char, is_ident_raw_char};
11
12/// This type represents all possible errors that can occur when
13/// serializing or deserializing RON data.
14#[allow(clippy::module_name_repetitions)]
15#[derive(Clone, Debug, PartialEq, Eq)]
16pub struct SpannedError {
17    pub code: Error,
18    pub position: Position,
19}
20
21pub type Result<T, E = Error> = std::result::Result<T, E>;
22pub type SpannedResult<T> = std::result::Result<T, SpannedError>;
23
24#[derive(Clone, Debug, PartialEq, Eq)]
25#[non_exhaustive]
26pub enum Error {
27    Fmt,
28    Io(String),
29    Message(String),
30    #[deprecated(
31        since = "0.9.0",
32        note = "ambiguous base64 byte strings are replaced by strongly typed Rusty b\"byte strings\""
33    )]
34    Base64Error(base64::DecodeError),
35    Eof,
36    ExpectedArray,
37    ExpectedArrayEnd,
38    ExpectedAttribute,
39    ExpectedAttributeEnd,
40    ExpectedBoolean,
41    ExpectedComma,
42    ExpectedChar,
43    ExpectedByteLiteral,
44    ExpectedFloat,
45    FloatUnderscore,
46    ExpectedInteger,
47    ExpectedOption,
48    ExpectedOptionEnd,
49    ExpectedMap,
50    ExpectedMapColon,
51    ExpectedMapEnd,
52    ExpectedDifferentStructName {
53        expected: &'static str,
54        found: String,
55    },
56    ExpectedStructLike,
57    ExpectedNamedStructLike(&'static str),
58    ExpectedStructLikeEnd,
59    ExpectedUnit,
60    ExpectedString,
61    ExpectedByteString,
62    ExpectedStringEnd,
63    ExpectedIdentifier,
64
65    InvalidEscape(&'static str),
66
67    IntegerOutOfBounds,
68    InvalidIntegerDigit {
69        digit: char,
70        base: u8,
71    },
72
73    NoSuchExtension(String),
74
75    UnclosedBlockComment,
76    UnclosedLineComment,
77    UnderscoreAtBeginning,
78    UnexpectedChar(char),
79
80    Utf8Error(Utf8Error),
81    TrailingCharacters,
82
83    InvalidValueForType {
84        expected: String,
85        found: String,
86    },
87    ExpectedDifferentLength {
88        expected: String,
89        found: usize,
90    },
91    NoSuchEnumVariant {
92        expected: &'static [&'static str],
93        found: String,
94        outer: Option<String>,
95    },
96    NoSuchStructField {
97        expected: &'static [&'static str],
98        found: String,
99        outer: Option<String>,
100    },
101    MissingStructField {
102        field: &'static str,
103        outer: Option<String>,
104    },
105    DuplicateStructField {
106        field: &'static str,
107        outer: Option<String>,
108    },
109    InvalidIdentifier(String),
110    SuggestRawIdentifier(String),
111    ExpectedRawValue,
112    ExceededRecursionLimit,
113    ExpectedStructName(String),
114}
115
116impl fmt::Display for SpannedError {
117    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
118        write!(f, "{}: {}", self.position, self.code)
119    }
120}
121
122impl fmt::Display for Error {
123    #[allow(clippy::too_many_lines)]
124    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
125        match *self {
126            Error::Fmt => f.write_str("Formatting RON failed"),
127            Error::Io(ref s) | Error::Message(ref s) => f.write_str(s),
128            #[allow(deprecated)]
129            Error::Base64Error(ref e) => write!(f, "Invalid base64: {}", e),
130            Error::Eof => f.write_str("Unexpected end of RON"),
131            Error::ExpectedArray => f.write_str("Expected opening `[`"),
132            Error::ExpectedArrayEnd => f.write_str("Expected closing `]`"),
133            Error::ExpectedAttribute => f.write_str("Expected an `#![enable(...)]` attribute"),
134            Error::ExpectedAttributeEnd => {
135                f.write_str("Expected closing `)]` after the enable attribute")
136            }
137            Error::ExpectedBoolean => f.write_str("Expected boolean"),
138            Error::ExpectedComma => f.write_str("Expected comma"),
139            Error::ExpectedChar => f.write_str("Expected char"),
140            Error::ExpectedByteLiteral => f.write_str("Expected byte literal"),
141            Error::ExpectedFloat => f.write_str("Expected float"),
142            Error::FloatUnderscore => f.write_str("Unexpected underscore in float"),
143            Error::ExpectedInteger => f.write_str("Expected integer"),
144            Error::ExpectedOption => f.write_str("Expected option"),
145            Error::ExpectedOptionEnd | Error::ExpectedStructLikeEnd => {
146                f.write_str("Expected closing `)`")
147            }
148            Error::ExpectedMap => f.write_str("Expected opening `{`"),
149            Error::ExpectedMapColon => f.write_str("Expected colon"),
150            Error::ExpectedMapEnd => f.write_str("Expected closing `}`"),
151            Error::ExpectedDifferentStructName {
152                expected,
153                ref found,
154            } => write!(
155                f,
156                "Expected struct {} but found {}",
157                Identifier(expected),
158                Identifier(found)
159            ),
160            Error::ExpectedStructLike => f.write_str("Expected opening `(`"),
161            Error::ExpectedNamedStructLike(name) => {
162                if name.is_empty() {
163                    f.write_str("Expected only opening `(`, no name, for un-nameable struct")
164                } else {
165                    write!(f, "Expected opening `(` for struct {}", Identifier(name))
166                }
167            }
168            Error::ExpectedUnit => f.write_str("Expected unit"),
169            Error::ExpectedString => f.write_str("Expected string"),
170            Error::ExpectedByteString => f.write_str("Expected byte string"),
171            Error::ExpectedStringEnd => f.write_str("Expected end of string"),
172            Error::ExpectedIdentifier => f.write_str("Expected identifier"),
173            Error::InvalidEscape(s) => f.write_str(s),
174            Error::IntegerOutOfBounds => f.write_str("Integer is out of bounds"),
175            Error::InvalidIntegerDigit { digit, base } => {
176                write!(f, "Invalid digit {:?} for base {} integers", digit, base)
177            }
178            Error::NoSuchExtension(ref name) => {
179                write!(f, "No RON extension named {}", Identifier(name))
180            }
181            Error::Utf8Error(ref e) => fmt::Display::fmt(e, f),
182            Error::UnclosedBlockComment => f.write_str("Unclosed block comment"),
183            Error::UnclosedLineComment => f.write_str(
184                "`ron::value::RawValue` cannot end in unclosed line comment, \
185                try using a block comment or adding a newline",
186            ),
187            Error::UnderscoreAtBeginning => {
188                f.write_str("Unexpected leading underscore in a number")
189            }
190            Error::UnexpectedChar(c) => write!(f, "Unexpected char {:?}", c),
191            Error::TrailingCharacters => f.write_str("Non-whitespace trailing characters"),
192            Error::InvalidValueForType {
193                ref expected,
194                ref found,
195            } => {
196                write!(f, "Expected {} but found {} instead", expected, found)
197            }
198            Error::ExpectedDifferentLength {
199                ref expected,
200                found,
201            } => {
202                write!(f, "Expected {} but found ", expected)?;
203
204                match found {
205                    0 => f.write_str("zero elements")?,
206                    1 => f.write_str("one element")?,
207                    n => write!(f, "{} elements", n)?,
208                }
209
210                f.write_str(" instead")
211            }
212            Error::NoSuchEnumVariant {
213                expected,
214                ref found,
215                ref outer,
216            } => {
217                f.write_str("Unexpected ")?;
218
219                if outer.is_none() {
220                    f.write_str("enum ")?;
221                }
222
223                write!(f, "variant named {}", Identifier(found))?;
224
225                if let Some(outer) = outer {
226                    write!(f, " in enum {}", Identifier(outer))?;
227                }
228
229                write!(
230                    f,
231                    ", {}",
232                    OneOf {
233                        alts: expected,
234                        none: "variants"
235                    }
236                )
237            }
238            Error::NoSuchStructField {
239                expected,
240                ref found,
241                ref outer,
242            } => {
243                write!(f, "Unexpected field named {}", Identifier(found))?;
244
245                if let Some(outer) = outer {
246                    write!(f, " in {}", Identifier(outer))?;
247                }
248
249                write!(
250                    f,
251                    ", {}",
252                    OneOf {
253                        alts: expected,
254                        none: "fields"
255                    }
256                )
257            }
258            Error::MissingStructField { field, ref outer } => {
259                write!(f, "Unexpected missing field named {}", Identifier(field))?;
260
261                match outer {
262                    Some(outer) => write!(f, " in {}", Identifier(outer)),
263                    None => Ok(()),
264                }
265            }
266            Error::DuplicateStructField { field, ref outer } => {
267                write!(f, "Unexpected duplicate field named {}", Identifier(field))?;
268
269                match outer {
270                    Some(outer) => write!(f, " in {}", Identifier(outer)),
271                    None => Ok(()),
272                }
273            }
274            Error::InvalidIdentifier(ref invalid) => write!(f, "Invalid identifier {:?}", invalid),
275            Error::SuggestRawIdentifier(ref identifier) => write!(
276                f,
277                "Found invalid std identifier {:?}, try the raw identifier `r#{}` instead",
278                identifier, identifier
279            ),
280            Error::ExpectedRawValue => f.write_str("Expected a `ron::value::RawValue`"),
281            Error::ExceededRecursionLimit => f.write_str(
282                "Exceeded recursion limit, try increasing `ron::Options::recursion_limit` \
283                and using `serde_stacker` to protect against a stack overflow",
284            ),
285            Error::ExpectedStructName(ref name) => write!(
286                f,
287                "Expected the explicit struct name {}, but none was found",
288                Identifier(name)
289            ),
290        }
291    }
292}
293
294#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
295pub struct Position {
296    pub line: usize,
297    pub col: usize,
298}
299
300impl Position {
301    pub(crate) fn from_src_end(src: &str) -> Position {
302        let line = 1 + src.chars().filter(|&c| c == '\n').count();
303        let col = 1 + src.chars().rev().take_while(|&c| c != '\n').count();
304
305        Self { line, col }
306    }
307}
308
309impl fmt::Display for Position {
310    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
311        write!(f, "{}:{}", self.line, self.col)
312    }
313}
314
315impl ser::Error for Error {
316    #[cold]
317    fn custom<T: fmt::Display>(msg: T) -> Self {
318        Error::Message(msg.to_string())
319    }
320}
321
322impl de::Error for Error {
323    #[cold]
324    fn custom<T: fmt::Display>(msg: T) -> Self {
325        Error::Message(msg.to_string())
326    }
327
328    #[cold]
329    fn invalid_type(unexp: de::Unexpected, exp: &dyn de::Expected) -> Self {
330        // Invalid type and invalid value are merged given their similarity in ron
331        Self::invalid_value(unexp, exp)
332    }
333
334    #[cold]
335    fn invalid_value(unexp: de::Unexpected, exp: &dyn de::Expected) -> Self {
336        struct UnexpectedSerdeTypeValue<'a>(de::Unexpected<'a>);
337
338        impl<'a> fmt::Display for UnexpectedSerdeTypeValue<'a> {
339            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
340                match self.0 {
341                    de::Unexpected::Bool(b) => write!(f, "the boolean `{}`", b),
342                    de::Unexpected::Unsigned(i) => write!(f, "the unsigned integer `{}`", i),
343                    de::Unexpected::Signed(i) => write!(f, "the signed integer `{}`", i),
344                    de::Unexpected::Float(n) => write!(f, "the floating point number `{}`", n),
345                    de::Unexpected::Char(c) => write!(f, "the UTF-8 character `{}`", c),
346                    de::Unexpected::Str(s) => write!(f, "the string {:?}", s),
347                    de::Unexpected::Bytes(b) => write!(f, "the byte string b\"{}\"", {
348                        b.iter()
349                            .flat_map(|c| std::ascii::escape_default(*c))
350                            .map(char::from)
351                            .collect::<String>()
352                    }),
353                    de::Unexpected::Unit => write!(f, "a unit value"),
354                    de::Unexpected::Option => write!(f, "an optional value"),
355                    de::Unexpected::NewtypeStruct => write!(f, "a newtype struct"),
356                    de::Unexpected::Seq => write!(f, "a sequence"),
357                    de::Unexpected::Map => write!(f, "a map"),
358                    de::Unexpected::Enum => write!(f, "an enum"),
359                    de::Unexpected::UnitVariant => write!(f, "a unit variant"),
360                    de::Unexpected::NewtypeVariant => write!(f, "a newtype variant"),
361                    de::Unexpected::TupleVariant => write!(f, "a tuple variant"),
362                    de::Unexpected::StructVariant => write!(f, "a struct variant"),
363                    de::Unexpected::Other(other) => f.write_str(other),
364                }
365            }
366        }
367
368        Error::InvalidValueForType {
369            expected: exp.to_string(),
370            found: UnexpectedSerdeTypeValue(unexp).to_string(),
371        }
372    }
373
374    #[cold]
375    fn invalid_length(len: usize, exp: &dyn de::Expected) -> Self {
376        Error::ExpectedDifferentLength {
377            expected: exp.to_string(),
378            found: len,
379        }
380    }
381
382    #[cold]
383    fn unknown_variant(variant: &str, expected: &'static [&'static str]) -> Self {
384        Error::NoSuchEnumVariant {
385            expected,
386            found: variant.to_string(),
387            outer: None,
388        }
389    }
390
391    #[cold]
392    fn unknown_field(field: &str, expected: &'static [&'static str]) -> Self {
393        Error::NoSuchStructField {
394            expected,
395            found: field.to_string(),
396            outer: None,
397        }
398    }
399
400    #[cold]
401    fn missing_field(field: &'static str) -> Self {
402        Error::MissingStructField { field, outer: None }
403    }
404
405    #[cold]
406    fn duplicate_field(field: &'static str) -> Self {
407        Error::DuplicateStructField { field, outer: None }
408    }
409}
410
411impl StdError for SpannedError {}
412impl StdError for Error {}
413
414impl From<Utf8Error> for Error {
415    fn from(e: Utf8Error) -> Self {
416        Error::Utf8Error(e)
417    }
418}
419
420impl From<fmt::Error> for Error {
421    fn from(_: fmt::Error) -> Self {
422        Error::Fmt
423    }
424}
425
426impl From<io::Error> for Error {
427    fn from(e: io::Error) -> Self {
428        Error::Io(e.to_string())
429    }
430}
431
432impl From<SpannedError> for Error {
433    fn from(e: SpannedError) -> Self {
434        e.code
435    }
436}
437
438struct OneOf {
439    alts: &'static [&'static str],
440    none: &'static str,
441}
442
443impl fmt::Display for OneOf {
444    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
445        match self.alts {
446            [] => write!(f, "there are no {}", self.none),
447            [a1] => write!(f, "expected {} instead", Identifier(a1)),
448            [a1, a2] => write!(
449                f,
450                "expected either {} or {} instead",
451                Identifier(a1),
452                Identifier(a2)
453            ),
454            [a1, ref alts @ .., an] => {
455                write!(f, "expected one of {}", Identifier(a1))?;
456
457                for alt in alts {
458                    write!(f, ", {}", Identifier(alt))?;
459                }
460
461                write!(f, ", or {} instead", Identifier(an))
462            }
463        }
464    }
465}
466
467struct Identifier<'a>(&'a str);
468
469impl<'a> fmt::Display for Identifier<'a> {
470    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
471        if self.0.is_empty() || !self.0.chars().all(is_ident_raw_char) {
472            return write!(f, "{:?}_[invalid identifier]", self.0);
473        }
474
475        let mut chars = self.0.chars();
476
477        if !chars.next().map_or(false, is_ident_first_char) || !chars.all(is_xid_continue) {
478            write!(f, "`r#{}`", self.0)
479        } else {
480            write!(f, "`{}`", self.0)
481        }
482    }
483}
484
485#[cfg(test)]
486mod tests {
487    use serde::{de::Error as DeError, de::Unexpected, ser::Error as SerError};
488
489    use super::{Error, Position, SpannedError};
490
491    #[test]
492    fn error_messages() {
493        check_error_message(&Error::from(std::fmt::Error), "Formatting RON failed");
494        check_error_message(
495            &Error::from(std::io::Error::new(
496                std::io::ErrorKind::InvalidData,
497                "my-error",
498            )),
499            "my-error",
500        );
501        check_error_message(&<Error as SerError>::custom("my-ser-error"), "my-ser-error");
502        check_error_message(&<Error as DeError>::custom("my-de-error"), "my-de-error");
503        #[allow(deprecated)]
504        check_error_message(
505            &Error::Base64Error(base64::DecodeError::InvalidPadding),
506            "Invalid base64: Invalid padding",
507        );
508        check_error_message(&Error::Eof, "Unexpected end of RON");
509        check_error_message(&Error::ExpectedArray, "Expected opening `[`");
510        check_error_message(&Error::ExpectedArrayEnd, "Expected closing `]`");
511        check_error_message(
512            &Error::ExpectedAttribute,
513            "Expected an `#![enable(...)]` attribute",
514        );
515        check_error_message(
516            &Error::ExpectedAttributeEnd,
517            "Expected closing `)]` after the enable attribute",
518        );
519        check_error_message(&Error::ExpectedBoolean, "Expected boolean");
520        check_error_message(&Error::ExpectedComma, "Expected comma");
521        check_error_message(&Error::ExpectedChar, "Expected char");
522        check_error_message(&Error::ExpectedByteLiteral, "Expected byte literal");
523        check_error_message(&Error::ExpectedFloat, "Expected float");
524        check_error_message(&Error::FloatUnderscore, "Unexpected underscore in float");
525        check_error_message(&Error::ExpectedInteger, "Expected integer");
526        check_error_message(&Error::ExpectedOption, "Expected option");
527        check_error_message(&Error::ExpectedOptionEnd, "Expected closing `)`");
528        check_error_message(&Error::ExpectedStructLikeEnd, "Expected closing `)`");
529        check_error_message(&Error::ExpectedMap, "Expected opening `{`");
530        check_error_message(&Error::ExpectedMapColon, "Expected colon");
531        check_error_message(&Error::ExpectedMapEnd, "Expected closing `}`");
532        check_error_message(
533            &Error::ExpectedDifferentStructName {
534                expected: "raw+identifier",
535                found: String::from("identifier"),
536            },
537            "Expected struct `r#raw+identifier` but found `identifier`",
538        );
539        check_error_message(&Error::ExpectedStructLike, "Expected opening `(`");
540        check_error_message(
541            &Error::ExpectedNamedStructLike(""),
542            "Expected only opening `(`, no name, for un-nameable struct",
543        );
544        check_error_message(
545            &Error::ExpectedNamedStructLike("_ident"),
546            "Expected opening `(` for struct `_ident`",
547        );
548        check_error_message(&Error::ExpectedUnit, "Expected unit");
549        check_error_message(&Error::ExpectedString, "Expected string");
550        check_error_message(&Error::ExpectedByteString, "Expected byte string");
551        check_error_message(&Error::ExpectedStringEnd, "Expected end of string");
552        check_error_message(&Error::ExpectedIdentifier, "Expected identifier");
553        check_error_message(&Error::InvalidEscape("Invalid escape"), "Invalid escape");
554        check_error_message(&Error::IntegerOutOfBounds, "Integer is out of bounds");
555        check_error_message(
556            &Error::InvalidIntegerDigit {
557                digit: 'q',
558                base: 16,
559            },
560            "Invalid digit 'q' for base 16 integers",
561        );
562        check_error_message(
563            &Error::NoSuchExtension(String::from("unknown")),
564            "No RON extension named `unknown`",
565        );
566        check_error_message(&Error::UnclosedBlockComment, "Unclosed block comment");
567        check_error_message(
568            &Error::UnclosedLineComment,
569            "`ron::value::RawValue` cannot end in unclosed line comment, \
570        try using a block comment or adding a newline",
571        );
572        check_error_message(
573            &Error::UnderscoreAtBeginning,
574            "Unexpected leading underscore in a number",
575        );
576        check_error_message(&Error::UnexpectedChar('🦀'), "Unexpected char \'🦀\'");
577        #[allow(invalid_from_utf8)]
578        check_error_message(
579            &Error::Utf8Error(std::str::from_utf8(b"error: \xff\xff\xff\xff").unwrap_err()),
580            "invalid utf-8 sequence of 1 bytes from index 7",
581        );
582        check_error_message(
583            &Error::TrailingCharacters,
584            "Non-whitespace trailing characters",
585        );
586        check_error_message(
587            &Error::invalid_value(Unexpected::Enum, &"struct `Hi`"),
588            "Expected struct `Hi` but found an enum instead",
589        );
590        check_error_message(
591            &Error::invalid_length(0, &"two bees"),
592            "Expected two bees but found zero elements instead",
593        );
594        check_error_message(
595            &Error::invalid_length(1, &"two bees"),
596            "Expected two bees but found one element instead",
597        );
598        check_error_message(
599            &Error::invalid_length(3, &"two bees"),
600            "Expected two bees but found 3 elements instead",
601        );
602        check_error_message(
603            &Error::unknown_variant("unknown", &[]),
604            "Unexpected enum variant named `unknown`, there are no variants",
605        );
606        check_error_message(
607            &Error::NoSuchEnumVariant {
608                expected: &["A", "B+C"],
609                found: String::from("D"),
610                outer: Some(String::from("E")),
611            },
612            "Unexpected variant named `D` in enum `E`, \
613            expected either `A` or `r#B+C` instead",
614        );
615        check_error_message(
616            &Error::unknown_field("unknown", &[]),
617            "Unexpected field named `unknown`, there are no fields",
618        );
619        check_error_message(
620            &Error::NoSuchStructField {
621                expected: &["a"],
622                found: String::from("b"),
623                outer: Some(String::from("S")),
624            },
625            "Unexpected field named `b` in `S`, expected `a` instead",
626        );
627        check_error_message(
628            &Error::NoSuchStructField {
629                expected: &["a", "b+c", "d"],
630                found: String::from("e"),
631                outer: Some(String::from("S")),
632            },
633            "Unexpected field named `e` in `S`, \
634            expected one of `a`, `r#b+c`, or `d` instead",
635        );
636        check_error_message(
637            &Error::missing_field("a"),
638            "Unexpected missing field named `a`",
639        );
640        check_error_message(
641            &Error::MissingStructField {
642                field: "",
643                outer: Some(String::from("S+T")),
644            },
645            "Unexpected missing field named \"\"_[invalid identifier] in `r#S+T`",
646        );
647        check_error_message(
648            &Error::duplicate_field("a"),
649            "Unexpected duplicate field named `a`",
650        );
651        check_error_message(
652            &Error::DuplicateStructField {
653                field: "b+c",
654                outer: Some(String::from("S+T")),
655            },
656            "Unexpected duplicate field named `r#b+c` in `r#S+T`",
657        );
658        check_error_message(
659            &Error::InvalidIdentifier(String::from("why+🦀+not")),
660            "Invalid identifier \"why+🦀+not\"",
661        );
662        check_error_message(
663            &Error::SuggestRawIdentifier(String::from("raw+ident")),
664            "Found invalid std identifier \"raw+ident\", \
665            try the raw identifier `r#raw+ident` instead",
666        );
667        check_error_message(
668            &Error::ExpectedRawValue,
669            "Expected a `ron::value::RawValue`",
670        );
671        check_error_message(
672            &Error::ExceededRecursionLimit,
673            "Exceeded recursion limit, try increasing `ron::Options::recursion_limit` \
674            and using `serde_stacker` to protect against a stack overflow",
675        );
676        check_error_message(
677            &Error::ExpectedStructName(String::from("Struct")),
678            "Expected the explicit struct name `Struct`, but none was found",
679        );
680    }
681
682    fn check_error_message<T: std::fmt::Display>(err: &T, msg: &str) {
683        assert_eq!(format!("{}", err), msg);
684    }
685
686    #[test]
687    fn spanned_error_into_code() {
688        assert_eq!(
689            Error::from(SpannedError {
690                code: Error::Eof,
691                position: Position { line: 1, col: 1 }
692            }),
693            Error::Eof
694        );
695        assert_eq!(
696            Error::from(SpannedError {
697                code: Error::ExpectedRawValue,
698                position: Position { line: 1, col: 1 }
699            }),
700            Error::ExpectedRawValue
701        );
702    }
703}