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
91pub type Action = std::ops::ControlFlow<()>;
96
97#[cfg(feature = "blob")]
98mod change_impls {
99 use gix_hash::oid;
100 use gix_object::tree::EntryMode;
101
102 use crate::{
103 rewrites::tracker::ChangeKind,
104 tree::visit::{Change, Relation},
105 };
106
107 impl crate::rewrites::tracker::Change for crate::tree::visit::Change {
108 fn id(&self) -> &oid {
109 match self {
110 Change::Addition { oid, .. } | Change::Deletion { oid, .. } | Change::Modification { oid, .. } => oid,
111 }
112 }
113
114 fn relation(&self) -> Option<Relation> {
115 match self {
116 Change::Addition { relation, .. } | Change::Deletion { relation, .. } => *relation,
117 Change::Modification { .. } => None,
118 }
119 }
120
121 fn kind(&self) -> ChangeKind {
122 match self {
123 Change::Addition { .. } => ChangeKind::Addition,
124 Change::Deletion { .. } => ChangeKind::Deletion,
125 Change::Modification { .. } => ChangeKind::Modification,
126 }
127 }
128
129 fn entry_mode(&self) -> EntryMode {
130 match self {
131 Change::Addition { entry_mode, .. }
132 | Change::Deletion { entry_mode, .. }
133 | Change::Modification { entry_mode, .. } => *entry_mode,
134 }
135 }
136
137 fn id_and_entry_mode(&self) -> (&oid, EntryMode) {
138 match self {
139 Change::Addition { entry_mode, oid, .. }
140 | Change::Deletion { entry_mode, oid, .. }
141 | Change::Modification { entry_mode, oid, .. } => (oid, *entry_mode),
142 }
143 }
144 }
145}
146
147#[cfg(test)]
148mod tests {
149 use super::*;
150
151 #[test]
152 fn size_of_change() {
153 let actual = std::mem::size_of::<Change>();
154 assert!(
155 actual <= 48,
156 "{actual} <= 48: this type shouldn't grow without us knowing"
157 );
158 }
159}