Skip to content

Commit

Permalink
Merge pull request #21 from equas/master
Browse files Browse the repository at this point in the history
Implement take_while
  • Loading branch information
Crazytieguy authored Dec 9, 2023
2 parents 7998665 + ba3da16 commit 3a283e3
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 1 deletion.
2 changes: 2 additions & 0 deletions src/adapters/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ mod filter_map;
mod map;
mod step_by;
mod take;
mod take_while;
mod zip;
pub use self::chain::Chain;
pub use self::cloned::Cloned;
Expand All @@ -15,4 +16,5 @@ pub use self::filter_map::FilterMap;
pub use self::map::{IntoIter, Map};
pub use self::step_by::StepBy;
pub use self::take::Take;
pub use self::take_while::TakeWhile;
pub use self::zip::Zip;
51 changes: 51 additions & 0 deletions src/adapters/take_while.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
use crate::LendingIterator;

/// A lending iterator that yields items based on a predicate.
///
/// This iterator is fused.
#[derive(Clone)]
pub struct TakeWhile<I, P> {
iter: I,
predicate: P,
done: bool,
}

impl<I, P> TakeWhile<I, P> {
pub(crate) fn new(iter: I, predicate: P) -> Self {
Self {
iter,
predicate,
done: false,
}
}
}

impl<I, P> LendingIterator for TakeWhile<I, P>
where
I: LendingIterator,
P: for<'a> FnMut(&I::Item<'a>) -> bool
{
type Item<'a> = I::Item<'a> where I: 'a, P: 'a;

fn next(&mut self) -> Option<Self::Item<'_>> {
if self.done {
None
} else {
let item = self.iter.next()?;
if (self.predicate)(&item) {
Some(item)
} else {
self.done = true;
None
}
}
}

fn size_hint(&self) -> (usize, Option<usize>) {
if self.done {
(0, Some(0))
} else {
(0, self.iter.size_hint().1)
}
}
}
16 changes: 15 additions & 1 deletion src/traits/lending_iterator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::{num::NonZeroUsize, ops::Deref};

use crate::{
Chain, Cloned, Enumerate, Filter, FilterMap, Map, OptionTrait, SingleArgFnMut, SingleArgFnOnce,
StepBy, Take, Zip,
StepBy, Take, Zip, TakeWhile,
};

/// Like [`Iterator`], but items may borrow from `&mut self`.
Expand Down Expand Up @@ -82,6 +82,20 @@ pub trait LendingIterator {
Take::new(self, n)
}

/// Creates a lending iterator that lends items matching a predicate.
///
/// The predicate is called once for every item.
/// Once it returns false once, `None` is returned for all subsequent calls to [`next`].
///
/// [`next`]: Self::next
fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>
where
Self: Sized,
P: for <'a> FnMut(&Self::Item<'a>) -> bool
{
TakeWhile::new(self, predicate)
}

/// Takes two lending iterators and creates a new lending iterator over both in sequence.
///
/// See [`Iterator::chain`].
Expand Down

0 comments on commit 3a283e3

Please sign in to comment.