1use std::borrow::Cow;
2
3use bstr::BStr;
4use gix_object::tree;
5
6use crate::{
7 index::{Change, ChangeRef},
8 rewrites,
9 rewrites::tracker::ChangeKind,
10 tree::visit::Relation,
11};
12
13impl ChangeRef<'_, '_> {
14 pub fn into_owned(self) -> Change {
16 match self {
17 ChangeRef::Addition {
18 location,
19 index,
20 entry_mode,
21 id,
22 } => ChangeRef::Addition {
23 location: Cow::Owned(location.into_owned()),
24 index,
25 entry_mode,
26 id: Cow::Owned(id.into_owned()),
27 },
28 ChangeRef::Deletion {
29 location,
30 index,
31 entry_mode,
32 id,
33 } => ChangeRef::Deletion {
34 location: Cow::Owned(location.into_owned()),
35 index,
36 entry_mode,
37 id: Cow::Owned(id.into_owned()),
38 },
39 ChangeRef::Modification {
40 location,
41 previous_index,
42 previous_entry_mode,
43 previous_id,
44 index,
45 entry_mode,
46 id,
47 } => ChangeRef::Modification {
48 location: Cow::Owned(location.into_owned()),
49 previous_index,
50 previous_entry_mode,
51 previous_id: Cow::Owned(previous_id.into_owned()),
52 index,
53 entry_mode,
54 id: Cow::Owned(id.into_owned()),
55 },
56 ChangeRef::Rewrite {
57 source_location,
58 source_index,
59 source_entry_mode,
60 source_id,
61 location,
62 index,
63 entry_mode,
64 id,
65 copy,
66 } => ChangeRef::Rewrite {
67 source_location: Cow::Owned(source_location.into_owned()),
68 source_index,
69 source_entry_mode,
70 source_id: Cow::Owned(source_id.into_owned()),
71 location: Cow::Owned(location.into_owned()),
72 index,
73 entry_mode,
74 id: Cow::Owned(id.into_owned()),
75 copy,
76 },
77 }
78 }
79}
80
81impl ChangeRef<'_, '_> {
82 pub fn fields(&self) -> (&BStr, usize, gix_index::entry::Mode, &gix_hash::oid) {
92 match self {
93 ChangeRef::Addition {
94 location,
95 index,
96 entry_mode,
97 id,
98 ..
99 }
100 | ChangeRef::Deletion {
101 location,
102 index,
103 entry_mode,
104 id,
105 ..
106 }
107 | ChangeRef::Modification {
108 location,
109 index,
110 entry_mode,
111 id,
112 ..
113 }
114 | ChangeRef::Rewrite {
115 location,
116 index,
117 entry_mode,
118 id,
119 ..
120 } => (location.as_ref(), *index, *entry_mode, id),
121 }
122 }
123
124 pub fn location(&self) -> &BStr {
126 match self {
127 ChangeRef::Addition { location, .. }
128 | ChangeRef::Deletion { location, .. }
129 | ChangeRef::Modification { location, .. }
130 | ChangeRef::Rewrite { location, .. } => location.as_ref(),
131 }
132 }
133
134 pub fn index(&self) -> usize {
136 match self {
137 ChangeRef::Addition { index, .. }
138 | ChangeRef::Deletion { index, .. }
139 | ChangeRef::Modification { index, .. }
140 | ChangeRef::Rewrite { index, .. } => *index,
141 }
142 }
143
144 pub fn entry_mode(&self) -> gix_index::entry::Mode {
146 match self {
147 ChangeRef::Addition { entry_mode, .. }
148 | ChangeRef::Deletion { entry_mode, .. }
149 | ChangeRef::Modification { entry_mode, .. }
150 | ChangeRef::Rewrite { entry_mode, .. } => *entry_mode,
151 }
152 }
153
154 pub fn id(&self) -> &gix_hash::oid {
156 match self {
157 ChangeRef::Addition { id, .. }
158 | ChangeRef::Deletion { id, .. }
159 | ChangeRef::Modification { id, .. }
160 | ChangeRef::Rewrite { id, .. } => id,
161 }
162 }
163}
164
165impl rewrites::tracker::Change for ChangeRef<'_, '_> {
166 fn id(&self) -> &gix_hash::oid {
167 match self {
168 ChangeRef::Addition { id, .. } | ChangeRef::Deletion { id, .. } | ChangeRef::Modification { id, .. } => {
169 id.as_ref()
170 }
171 ChangeRef::Rewrite { .. } => {
172 unreachable!("BUG")
173 }
174 }
175 }
176
177 fn relation(&self) -> Option<Relation> {
178 None
179 }
180
181 fn kind(&self) -> ChangeKind {
182 match self {
183 ChangeRef::Addition { .. } => ChangeKind::Addition,
184 ChangeRef::Deletion { .. } => ChangeKind::Deletion,
185 ChangeRef::Modification { .. } => ChangeKind::Modification,
186 ChangeRef::Rewrite { .. } => {
187 unreachable!("BUG: rewrites can't be determined ahead of time")
188 }
189 }
190 }
191
192 fn entry_mode(&self) -> tree::EntryMode {
193 match self {
194 ChangeRef::Addition { entry_mode, .. }
195 | ChangeRef::Deletion { entry_mode, .. }
196 | ChangeRef::Modification { entry_mode, .. }
197 | ChangeRef::Rewrite { entry_mode, .. } => {
198 entry_mode
199 .to_tree_entry_mode()
200 .unwrap_or(tree::EntryKind::Tree.into())
202 }
203 }
204 }
205
206 fn id_and_entry_mode(&self) -> (&gix_hash::oid, tree::EntryMode) {
207 match self {
208 ChangeRef::Addition { id, entry_mode, .. }
209 | ChangeRef::Deletion { id, entry_mode, .. }
210 | ChangeRef::Modification { id, entry_mode, .. }
211 | ChangeRef::Rewrite { id, entry_mode, .. } => {
212 (
213 id,
214 entry_mode
215 .to_tree_entry_mode()
216 .unwrap_or(tree::EntryKind::Tree.into()),
218 )
219 }
220 }
221 }
222}