use std::fmt;
use crate::{JsonDecodeErrorKind, JsonTopLevelKind};
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct JsonDecodeError {
pub kind: JsonDecodeErrorKind,
pub message: String,
pub expected_top_level: Option<JsonTopLevelKind>,
pub actual_top_level: Option<JsonTopLevelKind>,
pub line: Option<usize>,
pub column: Option<usize>,
}
impl JsonDecodeError {
#[inline]
pub(crate) fn empty_input() -> Self {
Self {
kind: JsonDecodeErrorKind::EmptyInput,
message: "JSON input is empty after normalization".to_string(),
expected_top_level: None,
actual_top_level: None,
line: None,
column: None,
}
}
#[inline]
pub(crate) fn invalid_json(error: serde_json::Error) -> Self {
let line = error.line();
let column = error.column();
Self {
kind: JsonDecodeErrorKind::InvalidJson,
message: format!("Failed to parse JSON: {error}"),
expected_top_level: None,
actual_top_level: None,
line: (line > 0).then_some(line),
column: (column > 0).then_some(column),
}
}
#[inline]
pub(crate) fn unexpected_top_level(
expected: JsonTopLevelKind,
actual: JsonTopLevelKind,
) -> Self {
Self {
kind: JsonDecodeErrorKind::UnexpectedTopLevel,
message: format!("Unexpected JSON top-level type: expected {expected}, got {actual}"),
expected_top_level: Some(expected),
actual_top_level: Some(actual),
line: None,
column: None,
}
}
#[inline]
pub(crate) fn deserialize(error: serde_json::Error) -> Self {
let line = error.line();
let column = error.column();
Self {
kind: JsonDecodeErrorKind::Deserialize,
message: format!("Failed to deserialize JSON value: {error}"),
expected_top_level: None,
actual_top_level: None,
line: (line > 0).then_some(line),
column: (column > 0).then_some(column),
}
}
}
impl fmt::Display for JsonDecodeError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.kind {
JsonDecodeErrorKind::EmptyInput => f.write_str(&self.message),
JsonDecodeErrorKind::UnexpectedTopLevel => f.write_str(&self.message),
JsonDecodeErrorKind::InvalidJson | JsonDecodeErrorKind::Deserialize => {
match (self.line, self.column) {
(Some(line), Some(column)) => {
write!(f, "{} (line {}, column {})", self.message, line, column)
}
_ => f.write_str(&self.message),
}
}
}
}
}
impl std::error::Error for JsonDecodeError {}