diff --git a/cli/src/diff_util.rs b/cli/src/diff_util.rs index c09871a4e8..8b11f78efa 100644 --- a/cli/src/diff_util.rs +++ b/cli/src/diff_util.rs @@ -25,8 +25,8 @@ use jj_lib::commit::Commit; use jj_lib::conflicts::{ materialized_diff_stream, MaterializedTreeDiffEntry, MaterializedTreeValue, }; -use jj_lib::diff::{Diff, DiffHunk}; -use jj_lib::files::DiffLine; +use jj_lib::diff::{self, Diff, DiffHunk}; +use jj_lib::files::{DiffLine, DiffLineIterator}; use jj_lib::matchers::Matcher; use jj_lib::merge::MergedTreeValue; use jj_lib::merged_tree::{MergedTree, TreeDiffEntry, TreeDiffStream}; @@ -35,7 +35,6 @@ use jj_lib::repo::Repo; use jj_lib::repo_path::{RepoPath, RepoPathUiConverter}; use jj_lib::settings::{ConfigResultExt as _, UserSettings}; use jj_lib::store::Store; -use jj_lib::{diff, files}; use pollster::FutureExt; use thiserror::Error; use tracing::instrument; @@ -401,7 +400,7 @@ fn show_color_words_diff_hunks( let mut skipped_context = false; // Are the lines in `context` to be printed before the next modified line? let mut context_before = true; - for diff_line in files::diff(left, right) { + for diff_line in DiffLineIterator::new(Diff::default_refinement([left, right]).hunks()) { if diff_line.is_unmodified() { context.push_back(diff_line.clone()); let mut start_skipping_context = false; diff --git a/lib/src/files.rs b/lib/src/files.rs index d00ad379bd..72f49a8eed 100644 --- a/lib/src/files.rs +++ b/lib/src/files.rs @@ -14,11 +14,11 @@ #![allow(missing_docs)] +use std::borrow::Borrow; use std::collections::VecDeque; use std::fmt::{Debug, Error, Formatter}; -use std::{iter, vec}; +use std::iter; -use crate::diff; use crate::diff::{Diff, DiffHunk}; use crate::merge::{trivial_merge, Merge}; @@ -45,19 +45,19 @@ impl DiffLine<'_> { } } -pub fn diff<'a>(left: &'a [u8], right: &'a [u8]) -> DiffLineIterator<'a> { - let diff_hunks = diff::diff(left, right); - DiffLineIterator::new(diff_hunks) -} - -pub struct DiffLineIterator<'a> { - diff_hunks: iter::Fuse>>, +pub struct DiffLineIterator<'a, I> { + diff_hunks: iter::Fuse, current_line: DiffLine<'a>, queued_lines: VecDeque>, } -impl<'a> DiffLineIterator<'a> { - fn new(diff_hunks: Vec>) -> Self { +impl<'a, I> DiffLineIterator<'a, I> +where + I: Iterator, + I::Item: Borrow>, +{ + /// Iterates `diff_hunks` by line. Each hunk should have exactly two inputs. + pub fn new(diff_hunks: I) -> Self { let current_line = DiffLine { left_line_number: 1, right_line_number: 1, @@ -66,14 +66,18 @@ impl<'a> DiffLineIterator<'a> { hunks: vec![], }; DiffLineIterator { - diff_hunks: diff_hunks.into_iter().fuse(), + diff_hunks: diff_hunks.fuse(), current_line, queued_lines: VecDeque::new(), } } } -impl<'a> Iterator for DiffLineIterator<'a> { +impl<'a, I> Iterator for DiffLineIterator<'a, I> +where + I: Iterator, + I::Item: Borrow>, +{ type Item = DiffLine<'a>; fn next(&mut self) -> Option { @@ -83,7 +87,7 @@ impl<'a> Iterator for DiffLineIterator<'a> { let Some(hunk) = self.diff_hunks.next() else { break; }; - match &hunk { + match hunk.borrow() { DiffHunk::Matching(text) => { let lines = text.split_inclusive(|b| *b == b'\n'); for line in lines {