1use std::fmt;
2
3#[derive(Debug, Clone, PartialEq, Eq)]
5pub struct JsonError {
6 kind: JsonErrorKind,
7 offset: Option<usize>,
8}
9
10impl JsonError {
11 #[must_use]
13 pub const fn new(kind: JsonErrorKind) -> Self {
14 Self { kind, offset: None }
15 }
16
17 #[must_use]
19 pub const fn at(kind: JsonErrorKind, offset: usize) -> Self {
20 Self {
21 kind,
22 offset: Some(offset),
23 }
24 }
25
26 #[must_use]
28 pub const fn kind(&self) -> &JsonErrorKind {
29 &self.kind
30 }
31
32 #[must_use]
34 pub const fn offset(&self) -> Option<usize> {
35 self.offset
36 }
37}
38
39#[derive(Debug, Clone, PartialEq, Eq)]
41#[non_exhaustive]
42pub enum JsonErrorKind {
43 UnexpectedEnd,
45 UnexpectedByte(u8),
47 UnexpectedToken(&'static str),
49 InvalidEscape,
51 ControlCharacterInString,
53 InvalidUtf8,
55 InvalidNumber,
57 SerializationFailure,
59 DeserializationFailure,
61 TrailingValue,
63 InputBufferLimitExceeded(usize),
65 EmptyPath,
67 MissingRoot,
69 UnsupportedJsonPath(&'static str),
71 UnsupportedRewrite(&'static str),
73 InvalidJsonPath(&'static str),
75 CaptureLimitExceeded(usize),
77}
78
79impl fmt::Display for JsonError {
80 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
81 match &self.kind {
82 JsonErrorKind::UnexpectedEnd => f.write_str("unexpected end of JSON input")?,
83 JsonErrorKind::UnexpectedByte(b) => write!(f, "unexpected byte {b:#04x}")?,
84 JsonErrorKind::UnexpectedToken(token) => write!(f, "unexpected JSON token {token}")?,
85 JsonErrorKind::InvalidEscape => f.write_str("invalid JSON string escape")?,
86 JsonErrorKind::ControlCharacterInString => {
87 f.write_str("control character in JSON string")?
88 }
89 JsonErrorKind::InvalidUtf8 => f.write_str("JSON string is not valid UTF-8")?,
90 JsonErrorKind::InvalidNumber => f.write_str("invalid JSON number")?,
91 JsonErrorKind::SerializationFailure => f.write_str("JSON serialization failure")?,
92 JsonErrorKind::DeserializationFailure => f.write_str("JSON deserialization failure")?,
93 JsonErrorKind::TrailingValue => f.write_str("trailing top-level JSON value")?,
94 JsonErrorKind::InputBufferLimitExceeded(limit) => {
95 write!(f, "buffered JSON input exceeded limit of {limit} bytes")?
96 }
97 JsonErrorKind::EmptyPath => f.write_str("empty JSONPath expression")?,
98 JsonErrorKind::MissingRoot => f.write_str("JSONPath expression must start with `$`")?,
99 JsonErrorKind::UnsupportedJsonPath(feature) => {
100 write!(f, "unsupported JSONPath feature: {feature}")?
101 }
102 JsonErrorKind::UnsupportedRewrite(feature) => {
103 write!(f, "unsupported JSON rewrite operation: {feature}")?
104 }
105 JsonErrorKind::InvalidJsonPath(reason) => write!(f, "invalid JSONPath: {reason}")?,
106 JsonErrorKind::CaptureLimitExceeded(limit) => write!(
107 f,
108 "selected JSON value exceeded capture limit of {limit} bytes"
109 )?,
110 }
111
112 if let Some(offset) = self.offset {
113 write!(f, " at byte offset {offset}")?;
114 }
115 Ok(())
116 }
117}
118
119impl std::error::Error for JsonError {}