Skip to main content

json_cursor/
error.rs

1//! What went wrong, and where.
2
3use core::fmt;
4
5/// Why the bytes are not JSON, and the byte where the cursor found out.
6#[derive(Clone, Copy, Debug, PartialEq, Eq)]
7pub struct Error {
8    kind: ErrorKind,
9    at: usize,
10}
11
12/// Why the bytes are not JSON.
13#[non_exhaustive]
14#[derive(Clone, Copy, Debug, PartialEq, Eq)]
15pub enum ErrorKind {
16    /// The input ended inside a value.
17    End,
18    /// A byte the grammar does not allow here. It names what was expected, such as "`,` or `}`".
19    Expected(&'static str),
20    /// A byte below 0x20 inside a string. JSON needs it escaped.
21    ControlCharacter,
22    /// A backslash followed by anything but `" \ / b f n r t u`, or `\u` without four hex digits.
23    Escape,
24    /// A `\u` escape of half a surrogate pair, with no other half.
25    Surrogate,
26    /// Bytes that are not UTF-8.
27    Utf8,
28    /// A number outside JSON's grammar, such as `-`, `1.` or `1e`.
29    Number,
30    /// Arrays and objects nested deeper than the cursor's depth limit.
31    TooDeep,
32    /// Bytes after the value, other than whitespace.
33    Trailing,
34}
35
36impl Error {
37    pub(crate) fn new(kind: ErrorKind, at: usize) -> Self {
38        Error { kind, at }
39    }
40
41    /// Why the bytes are not JSON.
42    pub fn kind(&self) -> ErrorKind {
43        self.kind
44    }
45
46    /// The offset of the byte where the cursor found out.
47    pub fn position(&self) -> usize {
48        self.at
49    }
50}
51
52impl fmt::Display for Error {
53    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
54        let what = match self.kind {
55            ErrorKind::End => "the input ended inside a value",
56            ErrorKind::Expected(what) => return write!(f, "expected {what} at byte {}", self.at),
57            ErrorKind::ControlCharacter => "a control character in a string, which JSON needs escaped,",
58            ErrorKind::Escape => "a bad escape",
59            ErrorKind::Surrogate => "half of a surrogate pair",
60            ErrorKind::Utf8 => "bytes that are not UTF-8",
61            ErrorKind::Number => "a number outside JSON's grammar",
62            ErrorKind::TooDeep => "arrays and objects nested deeper than the limit",
63            ErrorKind::Trailing => "bytes after the value",
64        };
65        write!(f, "{what} at byte {}", self.at)
66    }
67}
68
69impl core::error::Error for Error {}