#![deny(missing_docs)]
#![forbid(unsafe_code)]
use boxology_classifier::ClassificationReport;
use boxology_schema::{Diagnostics, SchemaDocument};
use std::fmt;
type Rule = (&'static str, &'static str, &'static str);
const D1_SOURCE: &str =
"specs/s4-contract-change-classification.md D1; specs/s5-manifest-and-validation.md D5";
const PAIRING_SOURCE: &str =
"specs/s4-contract-change-classification.md D2 D6; specs/s5-manifest-and-validation.md D5";
const BASE_TEXT: &str = "the checked-in schema document must satisfy the strict format-1 reader";
const SUBMITTED_TEXT: &str =
"the regenerated schema document must satisfy the strict format-1 reader";
const PAIRING_TEXT: &str =
"the checked-in and regenerated schema documents must pair and satisfy classifier integrity";
const BASE: Rule = ("BXW0077", BASE_TEXT, D1_SOURCE);
const SUBMITTED: Rule = ("BXW0078", SUBMITTED_TEXT, D1_SOURCE);
const PAIRING: Rule = ("BXW0079", PAIRING_TEXT, PAIRING_SOURCE);
#[derive(Debug)]
pub struct ClassifyError {
code: &'static str,
side: &'static str,
detail: &'static str,
diagnostics: Diagnostics,
}
impl ClassifyError {
pub fn code(&self) -> &'static str {
self.code
}
pub fn side(&self) -> &'static str {
self.side
}
pub fn detail(&self) -> &'static str {
self.detail
}
pub fn diagnostics(&self) -> &Diagnostics {
&self.diagnostics
}
fn base(diagnostics: Diagnostics) -> Self {
Self {
code: BASE.0,
side: "base",
detail: BASE.1,
diagnostics,
}
}
fn submitted(diagnostics: Diagnostics) -> Self {
Self {
code: SUBMITTED.0,
side: "submitted",
detail: SUBMITTED.1,
diagnostics,
}
}
fn pairing(diagnostics: Diagnostics) -> Self {
Self {
code: PAIRING.0,
side: "pairing",
detail: PAIRING.1,
diagnostics,
}
}
}
impl fmt::Display for ClassifyError {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
formatter,
"{} {}: {}: {}",
self.code, self.side, self.detail, self.diagnostics
)
}
}
impl std::error::Error for ClassifyError {}
pub fn classify(
base: Option<&[u8]>,
submitted: &[u8],
) -> Result<ClassificationReport, ClassifyError> {
let base = match base {
Some(bytes) => Some(SchemaDocument::parse(bytes).map_err(ClassifyError::base)?),
None => None,
};
let submitted = SchemaDocument::parse(submitted).map_err(ClassifyError::submitted)?;
boxology_classifier::classify(base.as_ref(), Some(&submitted)).map_err(ClassifyError::pairing)
}