diff --git a/lib/src/files.rs b/lib/src/files.rs index d18fcc381..62346c65f 100644 --- a/lib/src/files.rs +++ b/lib/src/files.rs @@ -193,12 +193,10 @@ pub fn merge(slices: &Merge<&[u8]>) -> MergeResult { merge_hunks.push(Merge::from_removes_adds( parts[..num_diffs] .iter() - .map(|part| ContentHunk(part.to_vec())) - .collect_vec(), + .map(|part| ContentHunk(part.to_vec())), parts[num_diffs..] .iter() - .map(|part| ContentHunk(part.to_vec())) - .collect_vec(), + .map(|part| ContentHunk(part.to_vec())), )); } } diff --git a/lib/src/merge.rs b/lib/src/merge.rs index f8f6ff6a1..4ec729bb6 100644 --- a/lib/src/merge.rs +++ b/lib/src/merge.rs @@ -144,10 +144,18 @@ impl Merge { } /// Creates a new merge object from the given removes and adds. - pub fn from_removes_adds(removes: Vec, adds: Vec) -> Self { - // TODO: removes and adds can be just IntoIterator. - assert_eq!(adds.len(), removes.len() + 1); - let values = itertools::interleave(adds, removes).collect(); + pub fn from_removes_adds( + removes: impl IntoIterator, + adds: impl IntoIterator, + ) -> Self { + let removes = removes.into_iter(); + let mut adds = adds.into_iter(); + let mut values = SmallVec::with_capacity(removes.size_hint().0 * 2 + 1); + values.push(adds.next().expect("must have at least one add")); + for diff in removes.zip_longest(adds) { + let (remove, add) = diff.both().expect("must have one more adds than removes"); + values.extend([remove, add]); + } Merge { values } } diff --git a/lib/src/simple_op_store.rs b/lib/src/simple_op_store.rs index d690fbbbd..9a5d1225e 100644 --- a/lib/src/simple_op_store.rs +++ b/lib/src/simple_op_store.rs @@ -505,8 +505,8 @@ fn ref_target_from_proto(maybe_proto: Option crate::protos::op_store::ref_target::Value::Conflict(conflict) => { let term_from_proto = |term: crate::protos::op_store::ref_conflict::Term| term.value.map(CommitId::new); - let removes = conflict.removes.into_iter().map(term_from_proto).collect(); - let adds = conflict.adds.into_iter().map(term_from_proto).collect(); + let removes = conflict.removes.into_iter().map(term_from_proto); + let adds = conflict.adds.into_iter().map(term_from_proto); RefTarget::from_merge(Merge::from_removes_adds(removes, adds)) } }