From 0349d9ead3c35df00334a529ff0da29db430834a Mon Sep 17 00:00:00 2001 From: Matt Kulukundis Date: Tue, 6 Aug 2024 14:04:58 -0400 Subject: [PATCH] copy-tracking: extract next_impl from next in diff iter/stream --- lib/src/merged_tree.rs | 111 ++++++++++++++++++++++------------------- 1 file changed, 61 insertions(+), 50 deletions(-) diff --git a/lib/src/merged_tree.rs b/lib/src/merged_tree.rs index e6ed59ec16..c4540b110d 100644 --- a/lib/src/merged_tree.rs +++ b/lib/src/merged_tree.rs @@ -663,52 +663,8 @@ impl<'matcher> TreeDiffIterator<'matcher> { Ok(Merge::resolved(Tree::empty(store.clone(), dir.to_owned()))) } } -} - -impl TreeDiffDirItem { - fn from_trees( - dir: &RepoPath, - trees1: &Merge, - trees2: &Merge, - matcher: &dyn Matcher, - ) -> Self { - let mut entries = vec![]; - for (name, before, after) in merged_tree_entry_diff(trees1, trees2) { - let path = dir.join(name); - let before = before.to_merge(); - let after = after.to_merge(); - let tree_before = before.is_tree(); - let tree_after = after.is_tree(); - // Check if trees and files match, but only if either side is a tree or a file - // (don't query the matcher unnecessarily). - let tree_matches = (tree_before || tree_after) && !matcher.visit(&path).is_nothing(); - let file_matches = (!tree_before || !tree_after) && matcher.matches(&path); - - // Replace trees or files that don't match by `Merge::absent()` - let before = if (tree_before && tree_matches) || (!tree_before && file_matches) { - before - } else { - Merge::absent() - }; - let after = if (tree_after && tree_matches) || (!tree_after && file_matches) { - after - } else { - Merge::absent() - }; - if before.is_absent() && after.is_absent() { - continue; - } - entries.push((path, before, after)); - } - entries.reverse(); - Self { entries } - } -} -impl Iterator for TreeDiffIterator<'_> { - type Item = TreeDiffEntry; - - fn next(&mut self) -> Option { + fn next_impl(&mut self) -> Option { while let Some(top) = self.stack.last_mut() { let (path, before, after) = match top { TreeDiffItem::Dir(dir) => match dir.entries.pop() { @@ -788,6 +744,54 @@ impl Iterator for TreeDiffIterator<'_> { } } +impl TreeDiffDirItem { + fn from_trees( + dir: &RepoPath, + trees1: &Merge, + trees2: &Merge, + matcher: &dyn Matcher, + ) -> Self { + let mut entries = vec![]; + for (name, before, after) in merged_tree_entry_diff(trees1, trees2) { + let path = dir.join(name); + let before = before.to_merge(); + let after = after.to_merge(); + let tree_before = before.is_tree(); + let tree_after = after.is_tree(); + // Check if trees and files match, but only if either side is a tree or a file + // (don't query the matcher unnecessarily). + let tree_matches = (tree_before || tree_after) && !matcher.visit(&path).is_nothing(); + let file_matches = (!tree_before || !tree_after) && matcher.matches(&path); + + // Replace trees or files that don't match by `Merge::absent()` + let before = if (tree_before && tree_matches) || (!tree_before && file_matches) { + before + } else { + Merge::absent() + }; + let after = if (tree_after && tree_matches) || (!tree_after && file_matches) { + after + } else { + Merge::absent() + }; + if before.is_absent() && after.is_absent() { + continue; + } + entries.push((path, before, after)); + } + entries.reverse(); + Self { entries } + } +} + +impl Iterator for TreeDiffIterator<'_> { + type Item = TreeDiffEntry; + + fn next(&mut self) -> Option { + self.next_impl() + } +} + /// Stream of differences between two trees. pub struct TreeDiffStreamImpl<'matcher> { matcher: &'matcher dyn Matcher, @@ -997,12 +1001,11 @@ impl<'matcher> TreeDiffStreamImpl<'matcher> { } } } -} -impl Stream for TreeDiffStreamImpl<'_> { - type Item = TreeDiffEntry; - - fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + fn poll_next_impl( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> Poll> { // Go through all pending tree futures and poll them. self.poll_tree_futures(cx); @@ -1054,6 +1057,14 @@ impl Stream for TreeDiffStreamImpl<'_> { } } +impl Stream for TreeDiffStreamImpl<'_> { + type Item = TreeDiffEntry; + + fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + self.as_mut().poll_next_impl(cx) + } +} + /// Helps with writing trees with conflicts. You start by creating an instance /// of this type with one or more base trees. You then add overrides on top. The /// overrides may be conflicts. Then you can write the result as a legacy tree