1use foldhash::HashSet;
2
3use crate::differ::compute_file_diff;
4use crate::metadata::CodebaseMetadata;
5use crate::symbol::SymbolIdentifier;
6
7#[derive(Default, Debug, Clone, PartialEq, Eq)]
14#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
15pub struct CodebaseDiff {
16 keep: HashSet<SymbolIdentifier>,
20
21 changed: HashSet<SymbolIdentifier>,
25}
26
27impl CodebaseDiff {
28 #[inline]
29 #[must_use]
30 pub fn new() -> Self {
31 Self::default()
32 }
33
34 #[must_use]
41 pub fn between(old_metadata: &CodebaseMetadata, new_metadata: &CodebaseMetadata) -> Self {
42 let mut aggregate_diff = CodebaseDiff::new();
43
44 let mut all_file_ids = old_metadata.get_all_file_ids();
45 all_file_ids.extend(new_metadata.get_all_file_ids());
46 all_file_ids.sort();
47 all_file_ids.dedup();
48
49 for file_id in all_file_ids {
50 let old_sig = old_metadata.get_file_signature(&file_id);
51 let new_sig = new_metadata.get_file_signature(&file_id);
52
53 let file_diff = compute_file_diff(file_id, old_sig, new_sig);
54
55 aggregate_diff.extend(file_diff);
56 }
57
58 aggregate_diff
59 }
60
61 #[inline]
63 pub fn extend(&mut self, other: Self) {
64 self.keep.extend(other.keep);
65 self.changed.extend(other.changed);
66 }
67
68 #[inline]
70 #[must_use]
71 pub fn get_keep(&self) -> &HashSet<SymbolIdentifier> {
72 &self.keep
73 }
74
75 #[inline]
77 #[must_use]
78 pub fn get_changed(&self) -> &HashSet<SymbolIdentifier> {
79 &self.changed
80 }
81
82 #[inline]
84 #[must_use]
85 pub fn with_keep(mut self, keep_set: impl IntoIterator<Item = SymbolIdentifier>) -> Self {
86 self.keep = keep_set.into_iter().collect();
87 self
88 }
89
90 #[inline]
92 pub fn add_keep_entry(&mut self, entry: SymbolIdentifier) -> bool {
93 self.keep.insert(entry)
94 }
95
96 #[inline]
98 #[must_use]
99 pub fn with_changed(mut self, change_set: impl IntoIterator<Item = SymbolIdentifier>) -> Self {
100 self.changed = change_set.into_iter().collect();
101 self
102 }
103
104 #[inline]
106 #[must_use]
107 pub fn contains_changed_entry(&self, entry: &SymbolIdentifier) -> bool {
108 self.changed.contains(entry)
109 }
110}