1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
4#[serde(rename_all = "snake_case")]
5pub enum EntityChangeKind {
6 Added,
7 Removed,
8 Renamed,
9 Deprecated,
10}
11
12#[derive(Debug, Clone, Serialize, Deserialize)]
13pub struct EntityChange {
14 pub kind: EntityChangeKind,
15 pub iri: String,
16 #[serde(skip_serializing_if = "Option::is_none")]
17 pub previous_iri: Option<String>,
18 #[serde(default, skip_serializing_if = "Vec::is_empty")]
19 pub labels: Vec<String>,
20}
21
22#[derive(Debug, Clone, Serialize, Deserialize)]
23pub struct AxiomChange {
24 pub change: String,
25 pub subject: String,
26 pub predicate: String,
27 pub object: String,
28 pub axiom_kind: String,
29}
30
31#[derive(Debug, Clone, Serialize, Deserialize)]
32pub struct AnnotationChange {
33 pub change: String,
34 pub subject: String,
35 pub predicate: String,
36 pub object: String,
37}
38
39#[derive(Debug, Clone, Serialize, Deserialize)]
40pub struct ImportChange {
41 pub change: String,
42 pub ontology_id: String,
43 pub import_iri: String,
44}
45
46#[derive(Debug, Clone, Serialize, Deserialize)]
47pub struct InferenceChange {
48 pub class_iri: String,
49 pub change: String,
50 pub detail: String,
51}
52
53#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
54#[serde(rename_all = "snake_case")]
55pub enum BreakingReason {
56 RemovedEntity,
57 RenamedIri,
58 RemovedSuperclass,
59 RemovedImport,
60 UnsatisfiableClass,
61 DomainRangeChange,
62}
63
64#[derive(Debug, Clone, Serialize, Deserialize)]
65pub struct BreakingChange {
66 pub reason: BreakingReason,
67 pub message: String,
68 #[serde(skip_serializing_if = "Option::is_none")]
69 pub entity_iri: Option<String>,
70}
71
72#[derive(Debug, Clone, Default, Serialize, Deserialize)]
73pub struct DiffResult {
74 pub entity_changes: Vec<EntityChange>,
75 pub axiom_changes: Vec<AxiomChange>,
76 pub annotation_changes: Vec<AnnotationChange>,
77 pub import_changes: Vec<ImportChange>,
78 pub inference_changes: Vec<InferenceChange>,
79 pub breaking_changes: Vec<BreakingChange>,
80}
81
82impl DiffResult {
83 pub fn is_empty(&self) -> bool {
84 self.entity_changes.is_empty()
85 && self.axiom_changes.is_empty()
86 && self.annotation_changes.is_empty()
87 && self.import_changes.is_empty()
88 && self.inference_changes.is_empty()
89 && self.breaking_changes.is_empty()
90 }
91
92 pub fn summary_counts(&self) -> DiffSummaryCounts {
93 DiffSummaryCounts {
94 entities: self.entity_changes.len(),
95 axioms: self.axiom_changes.len(),
96 annotations: self.annotation_changes.len(),
97 imports: self.import_changes.len(),
98 inferences: self.inference_changes.len(),
99 breaking: self.breaking_changes.len(),
100 }
101 }
102}
103
104#[derive(Debug, Clone, Serialize, Deserialize)]
105pub struct DiffSummaryCounts {
106 pub entities: usize,
107 pub axioms: usize,
108 pub annotations: usize,
109 pub imports: usize,
110 pub inferences: usize,
111 pub breaking: usize,
112}