diff: rely on compacted unchanged regions when iterating hunks
Some checks are pending
binaries / Build binary artifacts (linux-aarch64-gnu, ubuntu-24.04, aarch64-unknown-linux-gnu) (push) Waiting to run
binaries / Build binary artifacts (linux-aarch64-musl, ubuntu-24.04, aarch64-unknown-linux-musl) (push) Waiting to run
binaries / Build binary artifacts (linux-x86_64-gnu, ubuntu-24.04, x86_64-unknown-linux-gnu) (push) Waiting to run
binaries / Build binary artifacts (linux-x86_64-musl, ubuntu-24.04, x86_64-unknown-linux-musl) (push) Waiting to run
binaries / Build binary artifacts (macos-aarch64, macos-14, aarch64-apple-darwin) (push) Waiting to run
binaries / Build binary artifacts (macos-x86_64, macos-13, x86_64-apple-darwin) (push) Waiting to run
binaries / Build binary artifacts (win-x86_64, windows-2022, x86_64-pc-windows-msvc) (push) Waiting to run
nix / flake check (macos-14) (push) Waiting to run
nix / flake check (ubuntu-latest) (push) Waiting to run
build / build (, macos-13) (push) Waiting to run
build / build (, macos-14) (push) Waiting to run
build / build (, ubuntu-latest) (push) Waiting to run
build / build (, windows-latest) (push) Waiting to run
build / build (--all-features, ubuntu-latest) (push) Waiting to run
build / Build jj-lib without Git support (push) Waiting to run
build / Check protos (push) Waiting to run
build / Check formatting (push) Waiting to run
build / Check that MkDocs can build the docs (push) Waiting to run
build / Check that MkDocs can build the docs with Poetry 1.8 (push) Waiting to run
build / cargo-deny (advisories) (push) Waiting to run
build / cargo-deny (bans licenses sources) (push) Waiting to run
build / Clippy check (push) Waiting to run
Codespell / Codespell (push) Waiting to run
website / prerelease-docs-build-deploy (ubuntu-latest) (push) Waiting to run
Scorecards supply-chain security / Scorecards analysis (push) Waiting to run

We don't have to test emptiness of contents between unchanged regions.
This commit is contained in:
Yuya Nishihara 2024-10-12 14:35:25 +09:00
parent e15c7a8662
commit a9433784b0

View file

@ -527,6 +527,10 @@ impl UnchangedRange {
.collect();
UnchangedRange { base, others }
}
fn is_all_empty(&self) -> bool {
self.base.is_empty() && self.others.iter().all(|r| r.is_empty())
}
}
/// Takes any number of inputs and finds regions that are them same between all
@ -702,14 +706,8 @@ impl<'input> Diff<'input> {
diff
}
pub fn hunks<'diff>(&'diff self) -> DiffHunkIterator<'diff, 'input> {
let mut unchanged_iter = self.unchanged_regions.iter();
DiffHunkIterator {
diff: self,
previous: unchanged_iter.next().unwrap(),
unchanged_emitted: false,
unchanged_iter,
}
pub fn hunks(&self) -> DiffHunkIterator<'_, 'input> {
DiffHunkIterator::new(self)
}
/// Returns contents at the unchanged `range`.
@ -833,35 +831,39 @@ pub struct DiffHunkIterator<'diff, 'input> {
unchanged_iter: slice::Iter<'diff, UnchangedRange>,
}
impl<'diff, 'input> DiffHunkIterator<'diff, 'input> {
fn new(diff: &'diff Diff<'input>) -> Self {
let mut unchanged_iter = diff.unchanged_regions.iter();
let previous = unchanged_iter.next().unwrap();
DiffHunkIterator {
diff,
previous,
unchanged_emitted: previous.is_all_empty(),
unchanged_iter,
}
}
}
impl<'diff, 'input> Iterator for DiffHunkIterator<'diff, 'input> {
type Item = DiffHunk<'input>;
fn next(&mut self) -> Option<Self::Item> {
loop {
if !self.unchanged_emitted {
self.unchanged_emitted = true;
let contents = self.diff.hunk_at(self.previous).collect_vec();
if contents.iter().any(|content| !content.is_empty()) {
let kind = DiffHunkKind::Matching;
return Some(DiffHunk { kind, contents });
}
}
if let Some(current) = self.unchanged_iter.next() {
let contents = self
.diff
.hunk_between(self.previous, current)
.collect_vec();
self.previous = current;
self.unchanged_emitted = false;
if contents.iter().any(|content| !content.is_empty()) {
let kind = DiffHunkKind::Different;
return Some(DiffHunk { kind, contents });
}
} else {
break;
}
if !self.unchanged_emitted {
self.unchanged_emitted = true;
let contents = self.diff.hunk_at(self.previous).collect_vec();
let kind = DiffHunkKind::Matching;
return Some(DiffHunk { kind, contents });
}
None
let current = self.unchanged_iter.next()?;
let contents = self.diff.hunk_between(self.previous, current).collect_vec();
debug_assert!(
contents.iter().any(|content| !content.is_empty()),
"unchanged regions should have been compacted"
);
self.previous = current;
self.unchanged_emitted = self.previous.is_all_empty();
let kind = DiffHunkKind::Different;
Some(DiffHunk { kind, contents })
}
}