gix_diff/index/
change.rs

1use crate::index::{Change, ChangeRef};
2use crate::rewrites;
3use crate::rewrites::tracker::ChangeKind;
4use crate::tree::visit::Relation;
5use bstr::BStr;
6use gix_object::tree;
7use std::borrow::Cow;
8
9impl ChangeRef<'_, '_> {
10    /// Copy everything into an owned version of this instance.
11    pub fn into_owned(self) -> Change {
12        match self {
13            ChangeRef::Addition {
14                location,
15                index,
16                entry_mode,
17                id,
18            } => ChangeRef::Addition {
19                location: Cow::Owned(location.into_owned()),
20                index,
21                entry_mode,
22                id: Cow::Owned(id.into_owned()),
23            },
24            ChangeRef::Deletion {
25                location,
26                index,
27                entry_mode,
28                id,
29            } => ChangeRef::Deletion {
30                location: Cow::Owned(location.into_owned()),
31                index,
32                entry_mode,
33                id: Cow::Owned(id.into_owned()),
34            },
35            ChangeRef::Modification {
36                location,
37                previous_index,
38                previous_entry_mode,
39                previous_id,
40                index,
41                entry_mode,
42                id,
43            } => ChangeRef::Modification {
44                location: Cow::Owned(location.into_owned()),
45                previous_index,
46                previous_entry_mode,
47                previous_id: Cow::Owned(previous_id.into_owned()),
48                index,
49                entry_mode,
50                id: Cow::Owned(id.into_owned()),
51            },
52            ChangeRef::Rewrite {
53                source_location,
54                source_index,
55                source_entry_mode,
56                source_id,
57                location,
58                index,
59                entry_mode,
60                id,
61                copy,
62            } => ChangeRef::Rewrite {
63                source_location: Cow::Owned(source_location.into_owned()),
64                source_index,
65                source_entry_mode,
66                source_id: Cow::Owned(source_id.into_owned()),
67                location: Cow::Owned(location.into_owned()),
68                index,
69                entry_mode,
70                id: Cow::Owned(id.into_owned()),
71                copy,
72            },
73        }
74    }
75}
76
77impl ChangeRef<'_, '_> {
78    /// Return all shared fields among all variants: `(location, index, entry_mode, id)`
79    ///
80    /// In case of rewrites, the fields return to the current change.
81    pub fn fields(&self) -> (&BStr, usize, gix_index::entry::Mode, &gix_hash::oid) {
82        match self {
83            ChangeRef::Addition {
84                location,
85                index,
86                entry_mode,
87                id,
88                ..
89            }
90            | ChangeRef::Deletion {
91                location,
92                index,
93                entry_mode,
94                id,
95                ..
96            }
97            | ChangeRef::Modification {
98                location,
99                index,
100                entry_mode,
101                id,
102                ..
103            }
104            | ChangeRef::Rewrite {
105                location,
106                index,
107                entry_mode,
108                id,
109                ..
110            } => (location.as_ref(), *index, *entry_mode, id),
111        }
112    }
113}
114
115impl rewrites::tracker::Change for ChangeRef<'_, '_> {
116    fn id(&self) -> &gix_hash::oid {
117        match self {
118            ChangeRef::Addition { id, .. } | ChangeRef::Deletion { id, .. } | ChangeRef::Modification { id, .. } => {
119                id.as_ref()
120            }
121            ChangeRef::Rewrite { .. } => {
122                unreachable!("BUG")
123            }
124        }
125    }
126
127    fn relation(&self) -> Option<Relation> {
128        None
129    }
130
131    fn kind(&self) -> ChangeKind {
132        match self {
133            ChangeRef::Addition { .. } => ChangeKind::Addition,
134            ChangeRef::Deletion { .. } => ChangeKind::Deletion,
135            ChangeRef::Modification { .. } => ChangeKind::Modification,
136            ChangeRef::Rewrite { .. } => {
137                unreachable!("BUG: rewrites can't be determined ahead of time")
138            }
139        }
140    }
141
142    fn entry_mode(&self) -> tree::EntryMode {
143        match self {
144            ChangeRef::Addition { entry_mode, .. }
145            | ChangeRef::Deletion { entry_mode, .. }
146            | ChangeRef::Modification { entry_mode, .. }
147            | ChangeRef::Rewrite { entry_mode, .. } => {
148                entry_mode
149                    .to_tree_entry_mode()
150                    // Default is for the impossible case - just don't let it participate in rename tracking.
151                    .unwrap_or(tree::EntryKind::Tree.into())
152            }
153        }
154    }
155
156    fn id_and_entry_mode(&self) -> (&gix_hash::oid, tree::EntryMode) {
157        match self {
158            ChangeRef::Addition { id, entry_mode, .. }
159            | ChangeRef::Deletion { id, entry_mode, .. }
160            | ChangeRef::Modification { id, entry_mode, .. }
161            | ChangeRef::Rewrite { id, entry_mode, .. } => {
162                (
163                    id,
164                    entry_mode
165                        .to_tree_entry_mode()
166                        // Default is for the impossible case - just don't let it participate in rename tracking.
167                        .unwrap_or(tree::EntryKind::Tree.into()),
168                )
169            }
170        }
171    }
172}