That way, the trait impls can optimize access to their data structures.
Showing the changes to git-diff/src (3 of 3 files). Show all
Unified · Split
| @@ -75,14 +75,14 @@ impl<'a> tree::Changes<'a> { · 74 unmodified lines | ||
| 75 | 75 | match (lhs_entries.next(), rhs_entries.next()) { |
| 76 | 76 | (None, None) => { |
| 77 | 77 | match state.trees.pop_front() { |
| 78 | − Some((None, Some(rhs))) => { | |
| 79 | − delegate.set_current_path(rhs.parent_path_id.clone()); | |
| 78 | + Some((None, Some(mut rhs))) => { | |
| 79 | + delegate.set_current_path(rhs.parent_path_id.take().expect("path-id is set")); | |
| 80 | 80 | rhs_entries = peekable( |
| 81 | 81 | locate(&rhs.tree_id, &mut state.buf2).ok_or(Error::NotFound { oid: rhs.tree_id })?, |
| 82 | 82 | ); |
| 83 | 83 | } |
| 84 | − Some((Some(lhs), Some(rhs))) => { | |
| 85 | − delegate.set_current_path(lhs.parent_path_id.clone()); | |
| 84 | + Some((Some(mut lhs), Some(rhs))) => { | |
| 85 | + delegate.set_current_path(lhs.parent_path_id.take().expect("path-id is set in lhs")); | |
| 86 | 86 | lhs_entries = peekable( |
| 87 | 87 | locate(&lhs.tree_id, &mut state.buf1).ok_or(Error::NotFound { oid: lhs.tree_id })?, |
| 88 | 88 | ); |
| @@ -90,8 +90,8 @@ impl<'a> tree::Changes<'a> { · 1 unmodified line | ||
| 90 | 90 | locate(&rhs.tree_id, &mut state.buf2).ok_or(Error::NotFound { oid: rhs.tree_id })?, |
| 91 | 91 | ); |
| 92 | 92 | } |
| 93 | − Some((Some(lhs), None)) => { | |
| 94 | − delegate.set_current_path(lhs.parent_path_id.clone()); | |
| 93 | + Some((Some(mut lhs), None)) => { | |
| 94 | + delegate.set_current_path(lhs.parent_path_id.take().expect("path-id is set")); | |
| 95 | 95 | lhs_entries = peekable( |
| 96 | 96 | locate(&lhs.tree_id, &mut state.buf1).ok_or(Error::NotFound { oid: lhs.tree_id })?, |
| 97 | 97 | ); |
| @@ -144,7 +144,7 @@ fn delete_entry_schedule_recursion<R: tree::Visit>( · 46 unmodified lines | ||
| 144 | 144 | queue.push_back(( |
| 145 | 145 | Some(TreeInfo { |
| 146 | 146 | tree_id: entry.oid.to_owned(), |
| 147 | − parent_path_id: path_id, | |
| 147 | + parent_path_id: Some(path_id), | |
| 148 | 148 | }), |
| 149 | 149 | None, |
| 150 | 150 | )); |
| @@ -174,7 +174,7 @@ fn add_entry_schedule_recursion<R: tree::Visit>( · 23 unmodified lines | ||
| 174 | 174 | None, |
| 175 | 175 | Some(TreeInfo { |
| 176 | 176 | tree_id: entry.oid.to_owned(), |
| 177 | − parent_path_id: path_id, | |
| 177 | + parent_path_id: Some(path_id), | |
| 178 | 178 | }), |
| 179 | 179 | )) |
| 180 | 180 | } |
| @@ -285,11 +285,11 @@ fn handle_lhs_and_rhs_with_equal_filenames<R: tree::Visit>( · 104 unmodified lines | ||
| 285 | 285 | queue.push_back(( |
| 286 | 286 | Some(TreeInfo { |
| 287 | 287 | tree_id: lhs.oid.to_owned(), |
| 288 | − parent_path_id: path_id.clone(), | |
| 288 | + parent_path_id: Some(path_id), | |
| 289 | 289 | }), |
| 290 | 290 | Some(TreeInfo { |
| 291 | 291 | tree_id: rhs.oid.to_owned(), |
| 292 | − parent_path_id: path_id, | |
| 292 | + parent_path_id: None, | |
| 293 | 293 | }), |
| 294 | 294 | )); |
| 295 | 295 | } |
| @@ -317,7 +317,7 @@ fn handle_lhs_and_rhs_with_equal_filenames<R: tree::Visit>( · 21 unmodified lines | ||
| 317 | 317 | None, |
| 318 | 318 | Some(TreeInfo { |
| 319 | 319 | tree_id: rhs.oid.to_owned(), |
| 320 | − parent_path_id: path_id, | |
| 320 | + parent_path_id: Some(path_id), | |
| 321 | 321 | }), |
| 322 | 322 | )); |
| 323 | 323 | } |
| @@ -344,7 +344,7 @@ fn handle_lhs_and_rhs_with_equal_filenames<R: tree::Visit>( · 20 unmodified lines | ||
| 344 | 344 | queue.push_back(( |
| 345 | 345 | Some(TreeInfo { |
| 346 | 346 | tree_id: lhs.oid.to_owned(), |
| 347 | − parent_path_id: path_id, | |
| 347 | + parent_path_id: Some(path_id), | |
| 348 | 348 | }), |
| 349 | 349 | None, |
| 350 | 350 | )); |
| @@ -3,8 +3,8 @@ use git_object::immutable; · 2 unmodified lines | ||
| 3 | 3 | use std::collections::VecDeque; |
| 4 | 4 | |
| 5 | 5 | /// The state required to visit [Changes] to be instantiated with `State::default()`. |
| 6 | −#[derive(Default, Clone)] | |
| 7 | −pub struct State<PathId: Default + Clone> { | |
| 6 | +#[derive(Default)] | |
| 7 | +pub struct State<PathId> { | |
| 8 | 8 | buf1: Vec<u8>, |
| 9 | 9 | buf2: Vec<u8>, |
| 10 | 10 | trees: VecDeque<TreeInfoPair<PathId>>, |
| @@ -12,13 +12,12 @@ pub struct State<PathId: Default + Clone> { · 1 unmodified line | ||
| 12 | 12 | |
| 13 | 13 | type TreeInfoPair<PathId> = (Option<TreeInfo<PathId>>, Option<TreeInfo<PathId>>); |
| 14 | 14 | |
| 15 | −#[derive(Clone)] | |
| 16 | −pub(crate) struct TreeInfo<PathId: Clone> { | |
| 15 | +pub(crate) struct TreeInfo<PathId> { | |
| 17 | 16 | pub tree_id: ObjectId, |
| 18 | − pub parent_path_id: PathId, | |
| 17 | + pub parent_path_id: Option<PathId>, | |
| 19 | 18 | } |
| 20 | 19 | |
| 21 | −impl<P: Clone + Default> State<P> { | |
| 20 | +impl<P> State<P> { | |
| 22 | 21 | fn clear(&mut self) { |
| 23 | 22 | self.trees.clear(); |
| 24 | 23 | self.buf1.clear(); |
| @@ -52,9 +52,10 @@ impl Action { · 51 unmodified lines | ||
| 52 | 52 | /// to turn tree A into tree B. |
| 53 | 53 | pub trait Visit { |
| 54 | 54 | /// A type capable of uniquely identifying paths in a tree. |
| 55 | − type PathId: Clone + Default; | |
| 55 | + type PathId; | |
| 56 | 56 | |
| 57 | 57 | /// Sets the path associated with the given `id` so future calls to push and pop components affect it instead. |
| 58 | + /// It will only ever be called once with a given `id`. | |
| 58 | 59 | fn set_current_path(&mut self, id: Self::PathId); |
| 59 | 60 | /// Append a `component` to the end of a path, which may be empty, and associate it with the returned path id. |
| 60 | 61 | fn push_tracked_path_component(&mut self, component: &BStr) -> Self::PathId; |