1 use core::iter::FusedIterator; 2 use std::fmt; 3 4 /// An iterator adaptor that consumes elements while the given predicate is 5 /// `true`, including the element for which the predicate first returned 6 /// `false`. 7 /// 8 /// See [`.take_while_inclusive()`](crate::Itertools::take_while_inclusive) 9 /// for more information. 10 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] 11 #[derive(Clone)] 12 pub struct TakeWhileInclusive<I, F> { 13 iter: I, 14 predicate: F, 15 done: bool, 16 } 17 18 impl<I, F> TakeWhileInclusive<I, F> 19 where 20 I: Iterator, 21 F: FnMut(&I::Item) -> bool, 22 { 23 /// Create a new [`TakeWhileInclusive`] from an iterator and a predicate. new(iter: I, predicate: F) -> Self24 pub(crate) fn new(iter: I, predicate: F) -> Self { 25 Self { 26 iter, 27 predicate, 28 done: false, 29 } 30 } 31 } 32 33 impl<I, F> fmt::Debug for TakeWhileInclusive<I, F> 34 where 35 I: Iterator + fmt::Debug, 36 { 37 debug_fmt_fields!(TakeWhileInclusive, iter, done); 38 } 39 40 impl<I, F> Iterator for TakeWhileInclusive<I, F> 41 where 42 I: Iterator, 43 F: FnMut(&I::Item) -> bool, 44 { 45 type Item = I::Item; 46 next(&mut self) -> Option<Self::Item>47 fn next(&mut self) -> Option<Self::Item> { 48 if self.done { 49 None 50 } else { 51 self.iter.next().map(|item| { 52 if !(self.predicate)(&item) { 53 self.done = true; 54 } 55 item 56 }) 57 } 58 } 59 size_hint(&self) -> (usize, Option<usize>)60 fn size_hint(&self) -> (usize, Option<usize>) { 61 if self.done { 62 (0, Some(0)) 63 } else { 64 (0, self.iter.size_hint().1) 65 } 66 } 67 fold<B, Fold>(mut self, init: B, mut f: Fold) -> B where Fold: FnMut(B, Self::Item) -> B,68 fn fold<B, Fold>(mut self, init: B, mut f: Fold) -> B 69 where 70 Fold: FnMut(B, Self::Item) -> B, 71 { 72 if self.done { 73 init 74 } else { 75 let predicate = &mut self.predicate; 76 self.iter 77 .try_fold(init, |mut acc, item| { 78 let is_ok = predicate(&item); 79 acc = f(acc, item); 80 if is_ok { 81 Ok(acc) 82 } else { 83 Err(acc) 84 } 85 }) 86 .unwrap_or_else(|err| err) 87 } 88 } 89 } 90 91 impl<I, F> FusedIterator for TakeWhileInclusive<I, F> 92 where 93 I: Iterator, 94 F: FnMut(&I::Item) -> bool, 95 { 96 } 97