97 lines
2.2 KiB
Rust
97 lines
2.2 KiB
Rust
use core::iter::FusedIterator;
|
|
use std::fmt;
|
|
|
|
/// An iterator adaptor that consumes elements while the given predicate is
|
|
/// `true`, including the element for which the predicate first returned
|
|
/// `false`.
|
|
///
|
|
/// See [`.take_while_inclusive()`](crate::Itertools::take_while_inclusive)
|
|
/// for more information.
|
|
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
|
|
#[derive(Clone)]
|
|
pub struct TakeWhileInclusive<I, F> {
|
|
iter: I,
|
|
predicate: F,
|
|
done: bool,
|
|
}
|
|
|
|
impl<I, F> TakeWhileInclusive<I, F>
|
|
where
|
|
I: Iterator,
|
|
F: FnMut(&I::Item) -> bool,
|
|
{
|
|
/// Create a new [`TakeWhileInclusive`] from an iterator and a predicate.
|
|
pub(crate) fn new(iter: I, predicate: F) -> Self {
|
|
Self {
|
|
iter,
|
|
predicate,
|
|
done: false,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<I, F> fmt::Debug for TakeWhileInclusive<I, F>
|
|
where
|
|
I: Iterator + fmt::Debug,
|
|
{
|
|
debug_fmt_fields!(TakeWhileInclusive, iter, done);
|
|
}
|
|
|
|
impl<I, F> Iterator for TakeWhileInclusive<I, F>
|
|
where
|
|
I: Iterator,
|
|
F: FnMut(&I::Item) -> bool,
|
|
{
|
|
type Item = I::Item;
|
|
|
|
fn next(&mut self) -> Option<Self::Item> {
|
|
if self.done {
|
|
None
|
|
} else {
|
|
self.iter.next().map(|item| {
|
|
if !(self.predicate)(&item) {
|
|
self.done = true;
|
|
}
|
|
item
|
|
})
|
|
}
|
|
}
|
|
|
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
|
if self.done {
|
|
(0, Some(0))
|
|
} else {
|
|
(0, self.iter.size_hint().1)
|
|
}
|
|
}
|
|
|
|
fn fold<B, Fold>(mut self, init: B, mut f: Fold) -> B
|
|
where
|
|
Fold: FnMut(B, Self::Item) -> B,
|
|
{
|
|
if self.done {
|
|
init
|
|
} else {
|
|
let predicate = &mut self.predicate;
|
|
self.iter
|
|
.try_fold(init, |mut acc, item| {
|
|
let is_ok = predicate(&item);
|
|
acc = f(acc, item);
|
|
if is_ok {
|
|
Ok(acc)
|
|
} else {
|
|
Err(acc)
|
|
}
|
|
})
|
|
.unwrap_or_else(|err| err)
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<I, F> FusedIterator for TakeWhileInclusive<I, F>
|
|
where
|
|
I: Iterator,
|
|
F: FnMut(&I::Item) -> bool,
|
|
{
|
|
}
|