mirror of
https://github.com/martinvonz/jj.git
synced 2025-01-29 23:57:51 +00:00
index: add filter RevWalk adapter
FilterRevset will be built on top.
This commit is contained in:
parent
cfa067a0a9
commit
97e69d1dcc
1 changed files with 48 additions and 0 deletions
|
@ -39,6 +39,18 @@ pub(super) trait RevWalk<I: ?Sized> {
|
|||
// The following methods are provided for convenience. They are not supposed
|
||||
// to be reimplemented.
|
||||
|
||||
/// Wraps in adapter that will filter items by the given `predicate`.
|
||||
fn filter<P>(self, predicate: P) -> FilterRevWalk<Self, P>
|
||||
where
|
||||
Self: Sized,
|
||||
P: FnMut(&I, &Self::Item) -> bool,
|
||||
{
|
||||
FilterRevWalk {
|
||||
walk: self,
|
||||
predicate,
|
||||
}
|
||||
}
|
||||
|
||||
/// Wraps in adapter that can peek one more item without consuming.
|
||||
fn peekable(self) -> PeekableRevWalk<I, Self>
|
||||
where
|
||||
|
@ -82,6 +94,31 @@ impl<I: ?Sized, T: Iterator> RevWalk<I> for EagerRevWalk<T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
#[must_use]
|
||||
pub(super) struct FilterRevWalk<W, P> {
|
||||
walk: W,
|
||||
predicate: P,
|
||||
}
|
||||
|
||||
impl<I, W, P> RevWalk<I> for FilterRevWalk<W, P>
|
||||
where
|
||||
I: ?Sized,
|
||||
W: RevWalk<I>,
|
||||
P: FnMut(&I, &W::Item) -> bool,
|
||||
{
|
||||
type Item = W::Item;
|
||||
|
||||
fn next(&mut self, index: &I) -> Option<Self::Item> {
|
||||
while let Some(item) = self.walk.next(index) {
|
||||
if (self.predicate)(index, &item) {
|
||||
return Some(item);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
#[must_use]
|
||||
pub(super) struct PeekableRevWalk<I: ?Sized, W: RevWalk<I>> {
|
||||
|
@ -778,6 +815,17 @@ mod tests {
|
|||
assert_eq!(peekable.next(&()), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_filter_rev_walk() {
|
||||
let source = EagerRevWalk::new(vec![0, 1, 2, 3, 4].into_iter());
|
||||
let mut filtered = source.filter(|_, &v| v & 1 == 0);
|
||||
assert_eq!(filtered.next(&()), Some(0));
|
||||
assert_eq!(filtered.next(&()), Some(2));
|
||||
assert_eq!(filtered.next(&()), Some(4));
|
||||
assert_eq!(filtered.next(&()), None);
|
||||
assert_eq!(filtered.next(&()), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_walk_ancestors() {
|
||||
let mut new_change_id = change_id_generator();
|
||||
|
|
Loading…
Reference in a new issue