Skip to main content

lumen/
error.rs

1//! The crate's single error type, carrying the conformance check that failed.
2
3use crate::check::Check;
4
5/// Result alias for every fallible operation in this crate.
6pub type Result<T, E = Error> = core::result::Result<T, E>;
7
8/// A conformance failure: which check failed, and the bytes that caused it.
9///
10/// The [`Check`] travels with the error rather than being reconstructed by the
11/// caller, so a failure can be compared against the conformance corpus'
12/// `expected_failure` name verbatim.
13#[derive(Debug, Clone, PartialEq, Eq)]
14pub struct Error {
15    check: Check,
16    detail: String,
17}
18
19impl Error {
20    /// Build an error for `check` with a human-readable explanation.
21    pub fn new(check: Check, detail: impl Into<String>) -> Self {
22        Error {
23            check,
24            detail: detail.into(),
25        }
26    }
27
28    /// The check that failed.
29    pub fn check(&self) -> Check {
30        self.check
31    }
32
33    /// The `<group>.<rule>` name of the failed check.
34    pub fn check_name(&self) -> &'static str {
35        self.check.name()
36    }
37
38    /// The explanation, without the check name.
39    pub fn detail(&self) -> &str {
40        &self.detail
41    }
42}
43
44impl core::fmt::Display for Error {
45    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
46        write!(f, "{}: {}", self.check.name(), self.detail)
47    }
48}
49
50impl std::error::Error for Error {}
51
52impl From<core::str::Utf8Error> for Error {
53    fn from(err: core::str::Utf8Error) -> Self {
54        Error::new(Check::MetaJson, err.to_string())
55    }
56}
57
58impl From<serde_json::Error> for Error {
59    fn from(err: serde_json::Error) -> Self {
60        Error::new(Check::MetaJson, err.to_string())
61    }
62}