deser_hjson/
error.rs

1use {
2    serde::de,
3    std::{
4        fmt,
5        io,
6        str::Utf8Error,
7    },
8};
9
10pub type Result<T> = std::result::Result<T, Error>;
11
12/// The types of errors which can happen in our code
13/// during deserialization
14#[derive(Debug, Clone, PartialEq)]
15pub enum ErrorCode {
16    Eof,
17    ExpectedBoolean,
18    ExpectedInteger,
19    ExpectedI8,
20    ExpectedI16,
21    ExpectedI32,
22    ExpectedI64,
23    ExpectedU8,
24    ExpectedU16,
25    ExpectedU32,
26    ExpectedU64,
27    ExpectedF32,
28    ExpectedF64,
29    ExpectedPositiveInteger,
30    ExpectedString,
31    ExpectedNull,
32    ExpectedArray,
33    ExpectedArrayComma,
34    ExpectedArrayEnd,
35    ExpectedMap,
36    ExpectedMapColon,
37    ExpectedMapComma,
38    ExpectedMapEnd,
39    ExpectedEnum,
40    ExpectedSingleChar,
41    InvalidEscapeSequence,
42    TrailingCharacters,
43    UnexpectedChar,
44}
45
46#[derive(Debug)]
47#[non_exhaustive]
48pub enum Error {
49
50    /// a Hjson syntax error raised in our code,
51    /// with location
52    Syntax {
53        line: usize,
54        col: usize, // in chars (tab is one char)
55        code: ErrorCode,
56        at: String, // next few chars
57    },
58
59    /// A Serde error, with approximate location
60    Serde {
61        line: usize,
62        col: usize, // in chars (tab is one char)
63        message: String,
64    },
65
66    /// a raw Serde error. We should try to
67    /// convert them to Serde located errors as
68    /// much as possible
69    RawSerde(String),
70
71    /// an UTF8 error, raised when using from_slice
72    /// with an invalid UTF8 slice
73    Utf8(Utf8Error),
74
75    /// an IO error, raised when using from_reader
76    Io(io::Error),
77}
78
79impl Error {
80    pub fn is_eof(&self) -> bool {
81        matches!(self, Error::Syntax { code: ErrorCode::Eof, .. })
82    }
83}
84
85impl de::Error for Error {
86    fn custom<T: fmt::Display>(msg: T) -> Self {
87        Error::RawSerde(msg.to_string())
88    }
89}
90
91impl From<Utf8Error> for Error {
92    fn from(source: Utf8Error) -> Self {
93        Self::Utf8(source)
94    }
95}
96
97impl From<io::Error> for Error {
98    fn from(source: io::Error) -> Self {
99        Self::Io(source)
100    }
101}
102
103impl fmt::Display for Error {
104    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
105        match self {
106            Self::Syntax { line, col, code, at } => {
107                write!(formatter, "{:?} at {}:{} at {:?}", code, line, col, at)
108            }
109            Self::Serde { line, col, message } => {
110                write!(formatter, "{:?} near {}:{}", message, line, col)
111            }
112            Self::RawSerde(msg) => {
113                write!(formatter, "error message: {:?}", msg)
114            }
115            Self::Utf8(source) => {
116                source.fmt(formatter)
117            }
118            Self::Io(source) => {
119                source.fmt(formatter)
120            }
121        }
122    }
123}
124
125impl std::error::Error for Error {}