1use core::fmt;
4
5#[derive(Clone, Copy, Debug, PartialEq, Eq)]
7pub struct Error {
8 kind: ErrorKind,
9 at: usize,
10}
11
12#[non_exhaustive]
14#[derive(Clone, Copy, Debug, PartialEq, Eq)]
15pub enum ErrorKind {
16 End,
18 Expected(&'static str),
20 ControlCharacter,
22 Escape,
24 Surrogate,
26 Utf8,
28 Number,
30 TooDeep,
32 Trailing,
34}
35
36impl Error {
37 pub(crate) fn new(kind: ErrorKind, at: usize) -> Self {
38 Error { kind, at }
39 }
40
41 pub fn kind(&self) -> ErrorKind {
43 self.kind
44 }
45
46 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 {}