werkzeug/src/iter.rs

62 lines
1.7 KiB
Rust

/// Trait for only yielding the next item in the Iterator if it tests true for some predicate
pub trait NextIf<I>: Iterator<Item = I> + Clone {
/// Yield next item if `pred` returns `true`.
/// If `pred` returns `false` the Iterator is not advanced.
#[must_use]
fn next_if<F>(&mut self, pred: F) -> Option<I>
where
F: FnOnce(&Self::Item) -> bool,
{
let old = self.clone();
match self.next() {
Some(item) => {
if pred(&item) {
Some(item)
} else {
*self = old;
None
}
}
None => None,
}
}
/// Yield next item if `pred` returns `Some(T)`.
/// If `pred` returns `None` the Iterator is not advanced.
#[must_use]
fn next_if_map<F, T>(&mut self, pred: F) -> Option<T>
where
F: FnOnce(Self::Item) -> Option<T>,
{
let old = self.clone();
match self.next() {
Some(item) => match pred(item) {
None => {
*self = old;
None
}
some => some,
},
None => None,
}
}
}
impl<I, T> NextIf<I> for T where T: Iterator<Item = I> + Clone {}
pub trait AdvanceWhile<I>: Iterator<Item = I> + Clone {
/// Advance the iterator while `pred` returns true.
fn advance_while<F>(&mut self, mut pred: F)
where
F: FnMut(&Self::Item) -> bool,
{
loop {
match self.next_if(&mut pred) {
Some(_) => {}
None => break,
}
}
}
}
impl<I, T> AdvanceWhile<I> for T where T: Iterator<Item = I> + Clone {}