1use crate::model::DiffResult;
2
3pub fn format_diff_text(diff: &DiffResult, breaking_only: bool) -> String {
4 let mut out = String::new();
5 if !breaking_only {
6 out.push_str(&format!(
7 "Summary: {} entity, {} axiom, {} annotation, {} import, {} inference, {} breaking\n\n",
8 diff.entity_changes.len(),
9 diff.axiom_changes.len(),
10 diff.annotation_changes.len(),
11 diff.import_changes.len(),
12 diff.inference_changes.len(),
13 diff.breaking_changes.len(),
14 ));
15 }
16 if !diff.breaking_changes.is_empty() {
17 out.push_str("Breaking changes:\n");
18 for b in &diff.breaking_changes {
19 out.push_str(&format!(" - [{}] {}\n", reason_label(b.reason), b.message));
20 }
21 out.push('\n');
22 }
23 if breaking_only {
24 return out;
25 }
26 if !diff.entity_changes.is_empty() {
27 out.push_str("Entity changes:\n");
28 for e in &diff.entity_changes {
29 out.push_str(&format!(" - {:?} {}\n", e.kind, e.iri));
30 }
31 out.push('\n');
32 }
33 if !diff.axiom_changes.is_empty() {
34 out.push_str("Axiom changes:\n");
35 for a in &diff.axiom_changes {
36 out.push_str(&format!(
37 " - {} {} {} {} {}\n",
38 a.change, a.axiom_kind, a.subject, a.predicate, a.object
39 ));
40 }
41 out.push('\n');
42 }
43 if !diff.annotation_changes.is_empty() {
44 out.push_str("Annotation changes:\n");
45 for a in &diff.annotation_changes {
46 out.push_str(&format!(" - {} {} {} {}\n", a.change, a.subject, a.predicate, a.object));
47 }
48 out.push('\n');
49 }
50 if !diff.import_changes.is_empty() {
51 out.push_str("Import changes:\n");
52 for i in &diff.import_changes {
53 out.push_str(&format!(" - {} {}\n", i.change, i.import_iri));
54 }
55 out.push('\n');
56 }
57 out
58}
59
60pub fn format_diff_markdown(diff: &DiffResult, breaking_only: bool) -> String {
61 let mut out = String::from("# Ontology semantic diff\n\n");
62 if !diff.breaking_changes.is_empty() {
63 out.push_str("## Breaking changes\n\n");
64 for b in &diff.breaking_changes {
65 out.push_str(&format!("- **{}**: {}\n", reason_label(b.reason), b.message));
66 }
67 out.push('\n');
68 }
69 if breaking_only {
70 return out;
71 }
72 out.push_str(&format!(
73 "## Summary\n\n| Category | Count |\n|---|---|\n| Entities | {} |\n| Axioms | {} |\n| Annotations | {} |\n| Imports | {} |\n| Inferences | {} |\n| Breaking | {} |\n\n",
74 diff.entity_changes.len(),
75 diff.axiom_changes.len(),
76 diff.annotation_changes.len(),
77 diff.import_changes.len(),
78 diff.inference_changes.len(),
79 diff.breaking_changes.len(),
80 ));
81 out
82}
83
84pub fn format_diff_json(diff: &DiffResult) -> String {
85 serde_json::to_string_pretty(diff).unwrap_or_else(|_| "{}".to_string())
86}
87
88fn reason_label(reason: crate::model::BreakingReason) -> &'static str {
89 use crate::model::BreakingReason::*;
90 match reason {
91 RemovedEntity => "removed_entity",
92 RenamedIri => "renamed_iri",
93 RemovedSuperclass => "removed_superclass",
94 RemovedImport => "removed_import",
95 UnsatisfiableClass => "unsatisfiable_class",
96 DomainRangeChange => "domain_range_change",
97 }
98}