classifier_implementation/
lib.rs1#![deny(missing_docs)]
3#![forbid(unsafe_code)]
4
5use boxology_classifier::{Class, ClassificationReport, classify};
6use boxology_schema::SchemaDocument;
7
8mod contract;
9pub use contract::*;
10
11pub struct ClassifierService;
13
14#[boxology::implementation]
15impl ClassifierService {
16 pub async fn classify(
18 &self,
19 _context: boxology::CallContext,
20 request: ClassifyRequest,
21 ) -> Result<ClassifyOutcome, ClassifierError> {
22 let base = match request.base.as_deref() {
23 Some(bytes) => match SchemaDocument::parse(bytes) {
24 Ok(document) => Some(document),
25 Err(diagnostics) => {
26 return Ok(failure(ClassifyFailureStage::Base, diagnostics));
27 }
28 },
29 None => None,
30 };
31 let submitted = match SchemaDocument::parse(&request.submitted) {
32 Ok(document) => document,
33 Err(diagnostics) => {
34 return Ok(failure(ClassifyFailureStage::Submitted, diagnostics));
35 }
36 };
37 let report = match classify(base.as_ref(), Some(&submitted)) {
38 Ok(report) => report,
39 Err(diagnostics) => {
40 return Ok(failure(ClassifyFailureStage::Pairing, diagnostics));
41 }
42 };
43 Ok(ClassifyOutcome {
44 report: Some(boundary_report(&report)),
45 failure: None,
46 })
47 }
48}
49
50fn failure(
51 stage: ClassifyFailureStage,
52 diagnostics: boxology_schema::Diagnostics,
53) -> ClassifyOutcome {
54 ClassifyOutcome {
55 report: None,
56 failure: Some(ClassifyFailure {
57 stage,
58 diagnostics: diagnostics.to_string(),
59 }),
60 }
61}
62
63fn boundary_report(report: &ClassificationReport) -> ClassifyReport {
64 ClassifyReport {
65 verdict: boundary_class(report.verdict()),
66 findings: report
67 .findings()
68 .iter()
69 .map(|finding| ClassifyFinding {
70 code: finding.code().to_owned(),
71 path: finding.path().to_owned(),
72 kind: finding.kind().to_owned(),
73 class: boundary_class(finding.class()),
74 base_excerpt: finding.base_excerpt().map(str::to_owned),
75 submitted_excerpt: finding.submitted_excerpt().map(str::to_owned),
76 condition: finding.condition().map(str::to_owned),
77 })
78 .collect(),
79 rendered_text: boxology_classifier::render_text(report),
80 }
81}
82
83fn boundary_class(class: Class) -> CompatibilityClass {
84 match class {
85 Class::Unchanged => CompatibilityClass::Unchanged,
86 Class::Documentation => CompatibilityClass::Documentation,
87 Class::Deprecation => CompatibilityClass::Deprecation,
88 Class::Additive => CompatibilityClass::Additive,
89 Class::CompatibleWithConditions => CompatibilityClass::CompatibleWithConditions,
90 Class::Incompatible => CompatibilityClass::Incompatible,
91 }
92}
93
94#[doc(hidden)]
96pub mod generated {
97 include!("generated_adapter.rs");
98}