use ::serde_json::error::Category;
use crate::{
fail::{Fail, Fault},
lane::{Fatal, FatalKind},
};
fn lane_table(e: &::serde_json::Error) -> Fault<crate::lanes!(Fatal)> {
match e.classify() {
Category::Io => Fatal::new(FatalKind::Dependency).into(),
Category::Syntax | Category::Data | Category::Eof => {
Fatal::new(FatalKind::Invariant).into()
}
}
}
fn classify_serde_json_fault(e: ::serde_json::Error) -> Fault<crate::lanes!(Fatal)> {
match lane_table(&e) {
Fault::Fatal(f) => f.with_source(e).into(),
}
}
pub(crate) fn classify_serde_json_ref(e: &::serde_json::Error) -> Fault<crate::lanes!(Fatal)> {
match lane_table(e) {
Fault::Fatal(f) => f.with_context(e.to_string()).into(),
}
}
impl crate::Classify for ::serde_json::Error {
type Rejected = core::convert::Infallible;
type Lanes = crate::lanes!(Fatal);
fn classify(self) -> Fail<Self::Rejected, Self::Lanes> {
match classify_serde_json_fault(self) {
Fault::Fatal(x) => Fail::Fatal(x),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::lane::Lane;
fn parse_error() -> ::serde_json::Error {
::serde_json::from_str::<serde_json::Value>("{ not json").unwrap_err()
}
#[test]
fn syntax_error_is_fatal_invariant() {
let f = classify_serde_json_fault(parse_error());
match f {
Fault::Fatal(fatal) => assert_eq!(fatal.kind, FatalKind::Invariant),
other => panic!("expected Fatal(Invariant), got {other:?}"),
}
}
#[test]
fn classify_serde_json_expands_into_any_rejection_type() {
#[derive(Debug)]
struct NeverRejects;
let f: Fail<NeverRejects> = parse_error().into();
assert_eq!(f.lane(), Lane::Fatal);
}
#[test]
fn classify_ref_folds_the_message_into_context() {
let e = parse_error();
let message = e.to_string();
match classify_serde_json_ref(&e) {
Fault::Fatal(f) => {
assert_eq!(f.context.as_deref(), Some(message.as_str()));
}
other => panic!("expected Fatal, got {other:?}"),
}
}
}