#![deny(missing_docs)]
#![forbid(unsafe_code)]
use boxology_classifier::{Class, ClassificationReport, classify};
use boxology_schema::SchemaDocument;
mod contract;
pub use contract::*;
pub struct ClassifierService;
#[boxology::implementation]
impl ClassifierService {
pub async fn classify(
&self,
_context: boxology::CallContext,
request: ClassifyRequest,
) -> Result<ClassifyOutcome, ClassifierError> {
let base = match request.base.as_deref() {
Some(bytes) => match SchemaDocument::parse(bytes) {
Ok(document) => Some(document),
Err(diagnostics) => {
return Ok(failure(ClassifyFailureStage::Base, diagnostics));
}
},
None => None,
};
let submitted = match SchemaDocument::parse(&request.submitted) {
Ok(document) => document,
Err(diagnostics) => {
return Ok(failure(ClassifyFailureStage::Submitted, diagnostics));
}
};
let report = match classify(base.as_ref(), Some(&submitted)) {
Ok(report) => report,
Err(diagnostics) => {
return Ok(failure(ClassifyFailureStage::Pairing, diagnostics));
}
};
Ok(ClassifyOutcome {
report: Some(boundary_report(&report)),
failure: None,
})
}
}
fn failure(
stage: ClassifyFailureStage,
diagnostics: boxology_schema::Diagnostics,
) -> ClassifyOutcome {
ClassifyOutcome {
report: None,
failure: Some(ClassifyFailure {
stage,
diagnostics: diagnostics.to_string(),
}),
}
}
fn boundary_report(report: &ClassificationReport) -> ClassifyReport {
ClassifyReport {
verdict: boundary_class(report.verdict()),
findings: report
.findings()
.iter()
.map(|finding| ClassifyFinding {
code: finding.code().to_owned(),
path: finding.path().to_owned(),
kind: finding.kind().to_owned(),
class: boundary_class(finding.class()),
base_excerpt: finding.base_excerpt().map(str::to_owned),
submitted_excerpt: finding.submitted_excerpt().map(str::to_owned),
condition: finding.condition().map(str::to_owned),
})
.collect(),
rendered_text: boxology_classifier::render_text(report),
}
}
fn boundary_class(class: Class) -> CompatibilityClass {
match class {
Class::Unchanged => CompatibilityClass::Unchanged,
Class::Documentation => CompatibilityClass::Documentation,
Class::Deprecation => CompatibilityClass::Deprecation,
Class::Additive => CompatibilityClass::Additive,
Class::CompatibleWithConditions => CompatibilityClass::CompatibleWithConditions,
Class::Incompatible => CompatibilityClass::Incompatible,
}
}
#[doc(hidden)]
pub mod generated {
include!("generated_adapter.rs");
}