merge: implement IntoIterator for references of Merge<T>
Some checks are pending
binaries / Build binary artifacts (push) Waiting to run
website / prerelease-docs-build-deploy (ubuntu-24.04) (push) Waiting to run
Scorecards supply-chain security / Scorecards analysis (push) Waiting to run

It seemed odd that owned values can be looped over with "for", but borrowed
values can't.
This commit is contained in:
Yuya Nishihara 2025-12-09 14:56:48 +09:00
parent cfb6509e38
commit 3890c28493
8 changed files with 33 additions and 14 deletions

View file

@ -802,7 +802,7 @@ fn show_color_words_conflict_hunks(
) -> io::Result<DiffLineNumber> {
let num_lefts = contents.before.as_slice().len();
let line_diff = diff_by_line(
contents.before.iter().chain(contents.after.iter()),
itertools::chain(contents.before, contents.after),
&options.line_diff.compare_mode,
);
// Matching entries shouldn't appear consecutively in diff of two inputs.

View file

@ -964,7 +964,7 @@ pub async fn update_from_content(
.and_then(|hunks| hunks.last_mut())
.filter(|hunk| !hunk.is_resolved())
{
for (original_content, term) in old_contents.iter().zip_eq(last_hunk.iter_mut()) {
for (original_content, term) in itertools::zip_eq(&old_contents, last_hunk) {
if term.last() == Some(&b'\n') && has_no_eol(original_content) {
term.pop();
}
@ -991,11 +991,11 @@ pub async fn update_from_content(
let mut contents = simplified_file_ids.map(|_| vec![]);
for hunk in hunks {
if let Some(slice) = hunk.as_resolved() {
for content in contents.iter_mut() {
for content in &mut contents {
content.extend_from_slice(slice);
}
} else {
for (content, slice) in zip(contents.iter_mut(), hunk.into_iter()) {
for (content, slice) in zip(&mut contents, hunk) {
content.extend(Vec::from(slice));
}
}
@ -1003,7 +1003,7 @@ pub async fn update_from_content(
// If the user edited the empty placeholder for an absent side, we consider the
// conflict resolved.
if zip(contents.iter(), simplified_file_ids.iter())
if zip(&contents, &simplified_file_ids)
.any(|(content, file_id)| file_id.is_none() && !content.is_empty())
{
let file_id = store.write_file(path, &mut &content[..]).await?;
@ -1013,7 +1013,7 @@ pub async fn update_from_content(
// Now write the new files contents we found by parsing the file with conflict
// markers.
// TODO: Write these concurrently
let new_file_ids: Vec<Option<FileId>> = zip(contents.iter(), simplified_file_ids.iter())
let new_file_ids: Vec<Option<FileId>> = zip(&contents, &simplified_file_ids)
.map(|(content, file_id)| -> BackendResult<Option<FileId>> {
match file_id {
Some(_) => {

View file

@ -1412,7 +1412,7 @@ fn diff_match_lines(
let rights: Merge<BString> = rights.map(|text| match_lines(text, matcher).collect());
let lefts = files::merge(&lefts, merge_options);
let rights = files::merge(&rights, merge_options);
let diff = ContentDiff::by_line(lefts.iter().chain(rights.iter()));
let diff = ContentDiff::by_line(itertools::chain(&lefts, &rights));
let different = files::conflict_diff_hunks(diff.hunks(), lefts.as_slice().len())
.any(|hunk| hunk.kind == DiffHunkKind::Different);
Ok(different)

View file

@ -437,7 +437,7 @@ fn collect_merged<'input>(hunks: impl IntoIterator<Item = MergeHunk<'input>>) ->
let mut maybe_resolved = Merge::resolved(BString::default());
for hunk in hunks {
if let Some(content) = hunk.as_resolved() {
for buf in maybe_resolved.iter_mut() {
for buf in &mut maybe_resolved {
buf.extend_from_slice(content);
}
} else {
@ -446,7 +446,7 @@ fn collect_merged<'input>(hunks: impl IntoIterator<Item = MergeHunk<'input>>) ->
Err(conflict) => conflict,
};
assert_eq!(maybe_resolved.as_slice().len(), hunk.len());
for (buf, s) in iter::zip(maybe_resolved.iter_mut(), hunk.iter()) {
for (buf, s) in iter::zip(&mut maybe_resolved, hunk.iter()) {
buf.extend_from_slice(s);
}
}

View file

@ -536,6 +536,24 @@ impl<T> IntoIterator for Merge<T> {
}
}
impl<'a, T> IntoIterator for &'a Merge<T> {
type Item = &'a T;
type IntoIter = slice::Iter<'a, T>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<'a, T> IntoIterator for &'a mut Merge<T> {
type Item = &'a mut T;
type IntoIter = slice::IterMut<'a, T>;
fn into_iter(self) -> Self::IntoIter {
self.iter_mut()
}
}
impl<T> FromIterator<T> for MergeBuilder<T> {
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
let mut builder = Self::default();
@ -761,7 +779,7 @@ where
/// `FileId` values may differ.
pub fn with_new_file_ids(&self, file_ids: &Merge<Option<FileId>>) -> Merge<Option<TreeValue>> {
assert_eq!(self.values.len(), file_ids.values.len());
let values = zip(self.iter(), file_ids.iter().cloned())
let values = zip(self, file_ids.iter().cloned())
.map(
|(tree_value, file_id)| match (borrow_tree_value(tree_value.as_ref()), file_id) {
(

View file

@ -1048,7 +1048,7 @@ impl MergedTreeBuilder {
Ok(value) => {
// This path was overridden with a resolved value. Apply that to all
// builders.
for builder in tree_builders.iter_mut() {
for builder in &mut tree_builders {
builder.set_or_remove(path.clone(), value.clone());
}
}
@ -1056,7 +1056,7 @@ impl MergedTreeBuilder {
values.pad_to(num_sides, &None);
// This path was overridden with a conflicted value. Apply each term to
// its corresponding builder.
for (builder, value) in zip(tree_builders.iter_mut(), values) {
for (builder, value) in zip(&mut tree_builders, values) {
builder.set_or_remove(path.clone(), value);
}
}

View file

@ -17,6 +17,7 @@
use std::borrow::Borrow;
use std::collections::BTreeMap;
use std::collections::HashSet;
use std::iter::zip;
use std::sync::Arc;
use std::vec;
@ -144,7 +145,7 @@ impl MergedTreeInput {
let mut conflict_entries = self.conflicts.first_key_value().unwrap().1.map(|_| vec![]);
for (basename, value) in self.conflicts {
assert_eq!(value.num_sides(), conflict_entries.num_sides());
for (entries, value) in conflict_entries.iter_mut().zip(value.into_iter()) {
for (entries, value) in zip(&mut conflict_entries, value) {
if let Some(value) = value {
entries.push((basename.clone(), value));
}

View file

@ -564,7 +564,7 @@ pub fn dump_tree(merged_tree: &MergedTree) -> String {
let mut buf = String::new();
let trees = merged_tree.trees().unwrap();
writeln!(&mut buf, "merged tree (sides: {})", trees.num_sides()).unwrap();
for tree in trees.iter() {
for tree in &trees {
writeln!(&mut buf, " tree {}", tree.id()).unwrap();
for (path, entry) in tree.entries_matching(&EverythingMatcher) {
match entry {