1use gix_hash::ObjectId;
2use gix_object::{tree, tree::EntryMode};
3
4pub type ChangeId = u32;
8
9#[derive(Debug, Copy, Clone, PartialOrd, PartialEq, Ord, Eq, Hash)]
11pub enum Relation {
12 Parent(ChangeId),
18 ChildOfParent(ChangeId),
20}
21
22#[derive(Debug, Clone, PartialOrd, PartialEq, Ord, Eq, Hash)]
24pub enum Change {
25 Addition {
27 entry_mode: tree::EntryMode,
29 oid: ObjectId,
31 relation: Option<Relation>,
33 },
34 Deletion {
36 entry_mode: tree::EntryMode,
38 oid: ObjectId,
40 relation: Option<Relation>,
42 },
43 Modification {
46 previous_entry_mode: tree::EntryMode,
48 previous_oid: ObjectId,
50
51 entry_mode: tree::EntryMode,
53 oid: ObjectId,
55 },
56}
57
58impl Change {
59 pub fn oid(&self) -> &gix_hash::oid {
61 match self {
62 Change::Addition { oid, .. } | Change::Deletion { oid, .. } | Change::Modification { oid, .. } => oid,
63 }
64 }
65 pub fn entry_mode(&self) -> EntryMode {
67 match self {
68 Change::Addition { entry_mode, .. }
69 | Change::Deletion { entry_mode, .. }
70 | Change::Modification { entry_mode, .. } => *entry_mode,
71 }
72 }
73 pub fn oid_and_entry_mode(&self) -> (&gix_hash::oid, EntryMode) {
75 match self {
76 Change::Addition {
77 oid,
78 entry_mode,
79 relation: _,
80 }
81 | Change::Deletion {
82 oid,
83 entry_mode,
84 relation: _,
85 }
86 | Change::Modification { oid, entry_mode, .. } => (oid, *entry_mode),
87 }
88 }
89}
90
91#[derive(Default, Clone, Copy, PartialOrd, PartialEq, Ord, Eq, Hash)]
93pub enum Action {
94 #[default]
96 Continue,
97 Cancel,
99}
100
101impl Action {
102 pub fn cancelled(&self) -> bool {
104 matches!(self, Action::Cancel)
105 }
106}
107
108#[cfg(feature = "blob")]
109mod change_impls {
110 use gix_hash::oid;
111 use gix_object::tree::EntryMode;
112
113 use crate::tree::visit::Relation;
114 use crate::{rewrites::tracker::ChangeKind, tree::visit::Change};
115
116 impl crate::rewrites::tracker::Change for crate::tree::visit::Change {
117 fn id(&self) -> &oid {
118 match self {
119 Change::Addition { oid, .. } | Change::Deletion { oid, .. } | Change::Modification { oid, .. } => oid,
120 }
121 }
122
123 fn relation(&self) -> Option<Relation> {
124 match self {
125 Change::Addition { relation, .. } | Change::Deletion { relation, .. } => *relation,
126 Change::Modification { .. } => None,
127 }
128 }
129
130 fn kind(&self) -> ChangeKind {
131 match self {
132 Change::Addition { .. } => ChangeKind::Addition,
133 Change::Deletion { .. } => ChangeKind::Deletion,
134 Change::Modification { .. } => ChangeKind::Modification,
135 }
136 }
137
138 fn entry_mode(&self) -> EntryMode {
139 match self {
140 Change::Addition { entry_mode, .. }
141 | Change::Deletion { entry_mode, .. }
142 | Change::Modification { entry_mode, .. } => *entry_mode,
143 }
144 }
145
146 fn id_and_entry_mode(&self) -> (&oid, EntryMode) {
147 match self {
148 Change::Addition { entry_mode, oid, .. }
149 | Change::Deletion { entry_mode, oid, .. }
150 | Change::Modification { entry_mode, oid, .. } => (oid, *entry_mode),
151 }
152 }
153 }
154}
155
156#[cfg(test)]
157mod tests {
158 use super::*;
159
160 #[test]
161 fn size_of_change() {
162 let actual = std::mem::size_of::<Change>();
163 assert!(
164 actual <= 48,
165 "{actual} <= 48: this type shouldn't grow without us knowing"
166 );
167 }
168}