nu_json/
error.rs

1//! JSON Errors
2//!
3//! This module is centered around the `Error` and `ErrorCode` types, which represents all possible
4//! `serde_hjson` errors.
5
6use std::error;
7use std::fmt;
8use std::io;
9use std::result;
10use std::string::FromUtf8Error;
11
12use serde::de;
13use serde::ser;
14
15/// The errors that can arise while parsing a JSON stream.
16#[derive(Clone, PartialEq, Eq)]
17pub enum ErrorCode {
18    /// Catchall for syntax error messages
19    Custom(String),
20
21    /// EOF while parsing a list.
22    EofWhileParsingList,
23
24    /// EOF while parsing an object.
25    EofWhileParsingObject,
26
27    /// EOF while parsing a string.
28    EofWhileParsingString,
29
30    /// EOF while parsing a JSON value.
31    EofWhileParsingValue,
32
33    /// Expected this character to be a `':'`.
34    ExpectedColon,
35
36    /// Expected this character to be either a `','` or a `]`.
37    ExpectedListCommaOrEnd,
38
39    /// Expected this character to be either a `','` or a `}`.
40    ExpectedObjectCommaOrEnd,
41
42    /// Expected to parse either a `true`, `false`, or a `null`.
43    ExpectedSomeIdent,
44
45    /// Expected this character to start a JSON value.
46    ExpectedSomeValue,
47
48    /// Invalid hex escape code.
49    InvalidEscape,
50
51    /// Invalid number.
52    InvalidNumber,
53
54    /// Invalid Unicode code point.
55    InvalidUnicodeCodePoint,
56
57    /// Object key is not a string.
58    KeyMustBeAString,
59
60    /// Lone leading surrogate in hex escape.
61    LoneLeadingSurrogateInHexEscape,
62
63    /// JSON has non-whitespace trailing characters after the value.
64    TrailingCharacters,
65
66    /// Unexpected end of hex escape.
67    UnexpectedEndOfHexEscape,
68
69    /// Found a punctuator character when expecting a quoteless string.
70    PunctuatorInQlString,
71}
72
73impl fmt::Debug for ErrorCode {
74    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
75        //use std::fmt::Debug;
76
77        match *self {
78            ErrorCode::Custom(ref msg) => write!(f, "{msg}"),
79            ErrorCode::EofWhileParsingList => "EOF while parsing a list".fmt(f),
80            ErrorCode::EofWhileParsingObject => "EOF while parsing an object".fmt(f),
81            ErrorCode::EofWhileParsingString => "EOF while parsing a string".fmt(f),
82            ErrorCode::EofWhileParsingValue => "EOF while parsing a value".fmt(f),
83            ErrorCode::ExpectedColon => "expected `:`".fmt(f),
84            ErrorCode::ExpectedListCommaOrEnd => "expected `,` or `]`".fmt(f),
85            ErrorCode::ExpectedObjectCommaOrEnd => "expected `,` or `}`".fmt(f),
86            ErrorCode::ExpectedSomeIdent => "expected ident".fmt(f),
87            ErrorCode::ExpectedSomeValue => "expected value".fmt(f),
88            ErrorCode::InvalidEscape => "invalid escape".fmt(f),
89            ErrorCode::InvalidNumber => "invalid number".fmt(f),
90            ErrorCode::InvalidUnicodeCodePoint => "invalid Unicode code point".fmt(f),
91            ErrorCode::KeyMustBeAString => "key must be a string".fmt(f),
92            ErrorCode::LoneLeadingSurrogateInHexEscape => {
93                "lone leading surrogate in hex escape".fmt(f)
94            }
95            ErrorCode::TrailingCharacters => "trailing characters".fmt(f),
96            ErrorCode::UnexpectedEndOfHexEscape => "unexpected end of hex escape".fmt(f),
97            ErrorCode::PunctuatorInQlString => {
98                "found a punctuator character when expecting a quoteless string".fmt(f)
99            }
100        }
101    }
102}
103
104/// This type represents all possible errors that can occur when serializing or deserializing a
105/// value into JSON.
106#[derive(Debug)]
107pub enum Error {
108    /// The JSON value had some syntactic error.
109    Syntax(ErrorCode, usize, usize),
110
111    /// Some IO error occurred when serializing or deserializing a value.
112    Io(io::Error),
113
114    /// Some UTF8 error occurred while serializing or deserializing a value.
115    FromUtf8(FromUtf8Error),
116}
117
118impl error::Error for Error {
119    fn cause(&self) -> Option<&dyn error::Error> {
120        match *self {
121            Error::Io(ref error) => Some(error),
122            Error::FromUtf8(ref error) => Some(error),
123            _ => None,
124        }
125    }
126}
127
128impl fmt::Display for Error {
129    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
130        match *self {
131            Error::Syntax(ref code, line, col) => {
132                write!(fmt, "{code:?} at line {line} column {col}")
133            }
134            Error::Io(ref error) => fmt::Display::fmt(error, fmt),
135            Error::FromUtf8(ref error) => fmt::Display::fmt(error, fmt),
136        }
137    }
138}
139
140impl From<io::Error> for Error {
141    fn from(error: io::Error) -> Error {
142        Error::Io(error)
143    }
144}
145
146impl From<FromUtf8Error> for Error {
147    fn from(error: FromUtf8Error) -> Error {
148        Error::FromUtf8(error)
149    }
150}
151
152impl de::Error for Error {
153    fn custom<T: fmt::Display>(msg: T) -> Error {
154        Error::Syntax(ErrorCode::Custom(msg.to_string()), 0, 0)
155    }
156}
157
158impl ser::Error for Error {
159    /// Raised when there is general error when deserializing a type.
160    fn custom<T: fmt::Display>(msg: T) -> Error {
161        Error::Syntax(ErrorCode::Custom(msg.to_string()), 0, 0)
162    }
163}
164
165/// Helper alias for `Result` objects that return a JSON `Error`.
166pub type Result<T> = result::Result<T, Error>;