use std::fmt;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct JsonError {
kind: JsonErrorKind,
offset: Option<usize>,
}
impl JsonError {
#[must_use]
pub const fn new(kind: JsonErrorKind) -> Self {
Self { kind, offset: None }
}
#[must_use]
pub const fn at(kind: JsonErrorKind, offset: usize) -> Self {
Self {
kind,
offset: Some(offset),
}
}
#[must_use]
pub const fn kind(&self) -> &JsonErrorKind {
&self.kind
}
#[must_use]
pub const fn offset(&self) -> Option<usize> {
self.offset
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub enum JsonErrorKind {
UnexpectedEnd,
UnexpectedByte(u8),
UnexpectedToken(&'static str),
InvalidEscape,
ControlCharacterInString,
InvalidUtf8,
InvalidNumber,
SerializationFailure,
DeserializationFailure,
TrailingValue,
InputBufferLimitExceeded(usize),
EmptyPath,
MissingRoot,
UnsupportedJsonPath(&'static str),
UnsupportedRewrite(&'static str),
InvalidJsonPath(&'static str),
CaptureLimitExceeded(usize),
}
impl fmt::Display for JsonError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match &self.kind {
JsonErrorKind::UnexpectedEnd => f.write_str("unexpected end of JSON input")?,
JsonErrorKind::UnexpectedByte(b) => write!(f, "unexpected byte {b:#04x}")?,
JsonErrorKind::UnexpectedToken(token) => write!(f, "unexpected JSON token {token}")?,
JsonErrorKind::InvalidEscape => f.write_str("invalid JSON string escape")?,
JsonErrorKind::ControlCharacterInString => {
f.write_str("control character in JSON string")?
}
JsonErrorKind::InvalidUtf8 => f.write_str("JSON string is not valid UTF-8")?,
JsonErrorKind::InvalidNumber => f.write_str("invalid JSON number")?,
JsonErrorKind::SerializationFailure => f.write_str("JSON serialization failure")?,
JsonErrorKind::DeserializationFailure => f.write_str("JSON deserialization failure")?,
JsonErrorKind::TrailingValue => f.write_str("trailing top-level JSON value")?,
JsonErrorKind::InputBufferLimitExceeded(limit) => {
write!(f, "buffered JSON input exceeded limit of {limit} bytes")?
}
JsonErrorKind::EmptyPath => f.write_str("empty JSONPath expression")?,
JsonErrorKind::MissingRoot => f.write_str("JSONPath expression must start with `$`")?,
JsonErrorKind::UnsupportedJsonPath(feature) => {
write!(f, "unsupported JSONPath feature: {feature}")?
}
JsonErrorKind::UnsupportedRewrite(feature) => {
write!(f, "unsupported JSON rewrite operation: {feature}")?
}
JsonErrorKind::InvalidJsonPath(reason) => write!(f, "invalid JSONPath: {reason}")?,
JsonErrorKind::CaptureLimitExceeded(limit) => write!(
f,
"selected JSON value exceeded capture limit of {limit} bytes"
)?,
}
if let Some(offset) = self.offset {
write!(f, " at byte offset {offset}")?;
}
Ok(())
}
}
impl std::error::Error for JsonError {}