1use core::iter::FusedIterator;
2use 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"]
11pub struct TakeWhileInclusive<'a, I: 'a, F> {
12 iter: &'a mut I,
13 predicate: F,
14 done: bool,
15}
16
17impl<'a, I, F> TakeWhileInclusive<'a, I, F>
18where
19 I: Iterator,
20 F: FnMut(&I::Item) -> bool,
21{
22 /// Create a new [`TakeWhileInclusive`] from an iterator and a predicate.
23 pub fn new(iter: &'a mut I, predicate: F) -> Self {
24 Self { iter, predicate, done: false}
25 }
26}
27
28impl<'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
34impl<'a, I, F> Iterator for TakeWhileInclusive<'a, I, F>
35where
36 I: Iterator,
37 F: FnMut(&I::Item) -> bool
38{
39 type Item = I::Item;
40
41 fn next(&mut self) -> Option<Self::Item> {
42 if self.done {
43 None
44 } else {
45 self.iter.next().map(|item: ::Item| {
46 if !(self.predicate)(&item) {
47 self.done = true;
48 }
49 item
50 })
51 }
52 }
53
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
63impl<I, F> FusedIterator for TakeWhileInclusive<'_, I, F>
64where
65 I: Iterator,
66 F: FnMut(&I::Item) -> bool
67{
68}