gat_lending_iterator/adapters/
map_while.rs1use crate::{LendingIterator, OptionTrait, SingleArgFnMut, SingleArgFnOnce};
2use core::fmt;
3
4#[derive(Clone)]
12#[must_use = "iterators are lazy and do nothing unless consumed"]
13pub struct MapWhile<I, P> {
14 iter: I,
15 predicate: P,
16}
17
18impl<I, P> MapWhile<I, P> {
19 pub(crate) fn new(iter: I, predicate: P) -> Self {
20 Self { iter, predicate }
21 }
22}
23
24impl<I: fmt::Debug, P> fmt::Debug for MapWhile<I, P> {
25 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
26 f.debug_struct("MapWhile")
27 .field("iter", &self.iter)
28 .finish_non_exhaustive()
29 }
30}
31
32impl<I, P> LendingIterator for MapWhile<I, P>
33where
34 I: LendingIterator,
35 P: for<'a> SingleArgFnMut<I::Item<'a>>,
36 for<'a> <P as SingleArgFnOnce<I::Item<'a>>>::Output: OptionTrait,
37{
38 type Item<'a>
39 = <<P as SingleArgFnOnce<I::Item<'a>>>::Output as OptionTrait>::Item
40 where
41 Self: 'a;
42
43 #[inline]
44 fn next(&mut self) -> Option<Self::Item<'_>> {
45 let item = self.iter.next()?;
46 (self.predicate)(item).into_option()
47 }
48
49 #[inline]
50 fn size_hint(&self) -> (usize, Option<usize>) {
51 let (_, upper) = self.iter.size_hint();
52 (0, upper)
53 }
54}
55
56#[cfg(test)]
57mod tests {
58 use crate::{LendingIterator, ToLendingIterator};
59
60 fn identity(x: i32) -> i32 {
61 x
62 }
63
64 #[test]
65 fn map_while_basic() {
66 let result: Vec<_> = (0..10)
67 .into_lending()
68 .map_while(|x| if x < 5 { Some(x * 2) } else { None })
69 .map(identity)
70 .into_iter()
71 .collect();
72 assert_eq!(result, vec![0, 2, 4, 6, 8]);
73 }
74
75 #[test]
76 fn map_while_early_termination() {
77 let result: Vec<_> = (1..=10)
78 .into_lending()
79 .map_while(|x| if x <= 5 { Some(x * x) } else { None })
80 .map(identity)
81 .into_iter()
82 .collect();
83 assert_eq!(result, vec![1, 4, 9, 16, 25]);
84 }
85}