backhopper_core/model/
snapshot_diff.rs1use serde::{Deserialize, Serialize};
15
16use crate::model::names::{ModuleName, ProjectName, SeriesName, TagName};
17
18#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
22pub struct DiffPayload {
23 pub project: ProjectName,
24 pub from: TagName,
26 pub to: TagName,
28 pub modules_added: Vec<ModuleName>,
29 pub modules_removed: Vec<ModuleName>,
30 pub exports_added: Vec<QualifiedFunArity>,
31 pub exports_removed: Vec<QualifiedFunArity>,
32 pub types_added: Vec<QualifiedTypeArity>,
33 pub types_removed: Vec<QualifiedTypeArity>,
34 pub callbacks_added: Vec<QualifiedFunArity>,
35 pub callbacks_removed: Vec<QualifiedFunArity>,
36 pub headers_added: Vec<String>,
37 pub headers_removed: Vec<String>,
38 pub records_added: Vec<QualifiedRecord>,
39 pub records_removed: Vec<QualifiedRecord>,
40 #[serde(default, skip_serializing_if = "Vec::is_empty")]
41 pub versioned_machine_version_changes: Vec<VersionedMachineVersionChange>,
42 #[serde(default, skip_serializing_if = "Vec::is_empty")]
43 pub wire_constant_changes: Vec<WireConstantChange>,
44}
45
46impl DiffPayload {
47 #[must_use]
49 pub fn is_empty(&self) -> bool {
50 self.modules_added.is_empty()
51 && self.modules_removed.is_empty()
52 && self.exports_added.is_empty()
53 && self.exports_removed.is_empty()
54 && self.types_added.is_empty()
55 && self.types_removed.is_empty()
56 && self.callbacks_added.is_empty()
57 && self.callbacks_removed.is_empty()
58 && self.headers_added.is_empty()
59 && self.headers_removed.is_empty()
60 && self.records_added.is_empty()
61 && self.records_removed.is_empty()
62 && self.versioned_machine_version_changes.is_empty()
63 && self.wire_constant_changes.is_empty()
64 }
65
66 #[must_use]
68 pub fn breaking_removal_count(&self) -> usize {
69 self.modules_removed.len()
70 + self.exports_removed.len()
71 + self.callbacks_removed.len()
72 + self.types_removed.len()
73 + self.records_removed.len()
74 + self.headers_removed.len()
75 }
76}
77
78#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
80#[serde(rename_all = "snake_case", tag = "kind")]
81pub enum VersionedMachineVersionChange {
82 Missing {
83 module: ModuleName,
84 side: String,
85 },
86 Drift {
87 module: ModuleName,
88 from: Option<u64>,
89 to: Option<u64>,
90 },
91}
92
93#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
95#[serde(rename_all = "snake_case", tag = "kind")]
96pub enum WireConstantChange {
97 Missing {
98 module: ModuleName,
99 side: String,
100 macros: Vec<String>,
101 },
102 Drift {
103 module: ModuleName,
104 macro_name: String,
105 from: String,
106 to: String,
107 },
108}
109
110#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
112pub struct QualifiedFunArity {
113 pub module: ModuleName,
114 pub fun_arity: String,
115}
116
117#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
119pub struct QualifiedTypeArity {
120 pub module: ModuleName,
121 pub type_arity: String,
122}
123
124#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
126pub struct QualifiedRecord {
127 pub header: String,
128 pub record: String,
129}
130
131#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
135pub struct CrossSeriesDiffPayload {
136 pub from_series: SeriesName,
138 pub to_series: SeriesName,
140 pub projects: Vec<DiffPayload>,
142}