From 59eb03eec51c0fce31749d93e5a59855f558f3b1 Mon Sep 17 00:00:00 2001 From: Yuya Nishihara Date: Sat, 21 Oct 2023 07:37:57 +0900 Subject: [PATCH] refs: add helper function to iterate local/remote ref pairs This partially reverts the change in 30fb7995c22b "view: make local/remote branches iterator yield RemoteRef instead of RefTarget." As I'm going to add diff function for RemoteRef pairs, we'll need a generic version of merge-join iterator anyway. --- lib/src/refs.rs | 42 +++++++++++++++++++++++++++++++----------- lib/src/view.rs | 35 ++++++++++------------------------- 2 files changed, 41 insertions(+), 36 deletions(-) diff --git a/lib/src/refs.rs b/lib/src/refs.rs index 6b68cd94b..508e1bb57 100644 --- a/lib/src/refs.rs +++ b/lib/src/refs.rs @@ -28,23 +28,43 @@ pub fn diff_named_refs<'a, 'b, K: Ord>( refs1: impl IntoIterator, refs2: impl IntoIterator, ) -> impl Iterator { - iter_named_ref_pairs(refs1, refs2).filter(|(_, (target1, target2))| target1 != target2) + iter_named_pairs( + refs1, + refs2, + || RefTarget::absent_ref(), + || RefTarget::absent_ref(), + ) + .filter(|(_, (target1, target2))| target1 != target2) } -/// Iterates `refs1` and `refs2` target pairs by name. +/// Iterates local `refs1` and remote `refs2` pairs by name. /// /// `refs1` and `refs2` must be sorted by `K`. -fn iter_named_ref_pairs<'a, 'b, K: Ord>( +pub fn iter_named_local_remote_refs<'a, 'b, K: Ord>( refs1: impl IntoIterator, - refs2: impl IntoIterator, -) -> impl Iterator { - itertools::merge_join_by(refs1, refs2, |(name1, _), (name2, _)| name1.cmp(name2)).map(|entry| { - match entry { + refs2: impl IntoIterator, +) -> impl Iterator { + iter_named_pairs( + refs1, + refs2, + || RefTarget::absent_ref(), + || RemoteRef::absent_ref(), + ) +} + +fn iter_named_pairs( + refs1: impl IntoIterator, + refs2: impl IntoIterator, + absent_ref1: impl Fn() -> V1, + absent_ref2: impl Fn() -> V2, +) -> impl Iterator { + itertools::merge_join_by(refs1, refs2, |(name1, _), (name2, _)| name1.cmp(name2)).map( + move |entry| match entry { EitherOrBoth::Both((name, target1), (_, target2)) => (name, (target1, target2)), - EitherOrBoth::Left((name, target1)) => (name, (target1, RefTarget::absent_ref())), - EitherOrBoth::Right((name, target2)) => (name, (RefTarget::absent_ref(), target2)), - } - }) + EitherOrBoth::Left((name, target1)) => (name, (target1, absent_ref2())), + EitherOrBoth::Right((name, target2)) => (name, (absent_ref1(), target2)), + }, + ) } pub fn merge_ref_targets( diff --git a/lib/src/view.rs b/lib/src/view.rs index beb9a0b20..6d34f4578 100644 --- a/lib/src/view.rs +++ b/lib/src/view.rs @@ -17,16 +17,16 @@ use std::collections::{BTreeMap, HashMap, HashSet}; use std::fmt; -use itertools::{EitherOrBoth, Itertools}; +use itertools::Itertools; use crate::backend::CommitId; use crate::index::Index; -use crate::op_store; use crate::op_store::{ BranchTarget, RefTarget, RefTargetOptionExt as _, RemoteRef, RemoteRefState, WorkspaceId, }; use crate::refs::{merge_ref_targets, TrackingRefPair}; use crate::str_util::StringPattern; +use crate::{op_store, refs}; #[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Hash, Debug)] pub enum RefName { @@ -302,29 +302,14 @@ impl View { &'a self, remote_name: &str, ) -> impl Iterator)> + 'a { - itertools::merge_join_by( - self.local_branches(), - self.remote_branches(remote_name), - |(name1, _), (name2, _)| name1.cmp(name2), - ) - .map(|entry| match entry { - EitherOrBoth::Both((name, local_target), (_, remote_ref)) => { - (name, (local_target, remote_ref)) - } - EitherOrBoth::Left((name, local_target)) => { - (name, (local_target, RemoteRef::absent_ref())) - } - EitherOrBoth::Right((name, remote_ref)) => { - (name, (RefTarget::absent_ref(), remote_ref)) - } - }) - .map(|(name, (local_target, remote_ref))| { - let targets = TrackingRefPair { - local_target, - remote_ref, - }; - (name, targets) - }) + refs::iter_named_local_remote_refs(self.local_branches(), self.remote_branches(remote_name)) + .map(|(name, (local_target, remote_ref))| { + let targets = TrackingRefPair { + local_target, + remote_ref, + }; + (name, targets) + }) } pub fn remove_remote(&mut self, remote_name: &str) {