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 pub struct TakeWhileInclusive<'a, I: 'a, F> { 12 iter: &'a mut I, 13 predicate: F, 14 done: bool, 15 } 16 17 impl<'a, I, F> TakeWhileInclusive<'a, I, F> 18 where 19 I: Iterator, 20 F: FnMut(&I::Item) -> bool, 21 { 22 /// Create a new [`TakeWhileInclusive`] from an iterator and a predicate. new(iter: &'a mut I, predicate: F) -> Self23 pub fn new(iter: &'a mut I, predicate: F) -> Self { 24 Self { iter, predicate, done: false} 25 } 26 } 27 28 impl<'a, I, F> fmt::Debug for TakeWhileInclusive<'a, I, F> 29 where I: Iterator + fmt::Debug, 30 { 31 debug_fmt_fields!(TakeWhileInclusive, iter); 32 } 33 34 impl<'a, I, F> Iterator for TakeWhileInclusive<'a, I, F> 35 where 36 I: Iterator, 37 F: FnMut(&I::Item) -> bool 38 { 39 type Item = I::Item; 40 next(&mut self) -> Option<Self::Item>41 fn next(&mut self) -> Option<Self::Item> { 42 if self.done { 43 None 44 } else { 45 self.iter.next().map(|item| { 46 if !(self.predicate)(&item) { 47 self.done = true; 48 } 49 item 50 }) 51 } 52 } 53 size_hint(&self) -> (usize, Option<usize>)54 fn size_hint(&self) -> (usize, Option<usize>) { 55 if self.done { 56 (0, Some(0)) 57 } else { 58 (0, self.iter.size_hint().1) 59 } 60 } 61 } 62 63 impl<I, F> FusedIterator for TakeWhileInclusive<'_, I, F> 64 where 65 I: Iterator, 66 F: FnMut(&I::Item) -> bool 67 { 68 }