gat_lending_iterator/adapters/
inspect.rs

1use crate::LendingIterator;
2use core::fmt;
3
4/// A lending iterator that calls a function with a reference to each element
5/// before yielding it.
6///
7/// This `struct` is created by the [`inspect`] method on [`LendingIterator`]. See
8/// its documentation for more.
9///
10/// [`LendingIterator`]: crate::LendingIterator
11/// [`inspect`]: crate::LendingIterator::inspect
12#[derive(Clone)]
13#[must_use = "iterators are lazy and do nothing unless consumed"]
14pub struct Inspect<I, F> {
15    iter: I,
16    f: F,
17}
18
19impl<I, F> Inspect<I, F> {
20    pub(crate) fn new(iter: I, f: F) -> Self {
21        Self { iter, f }
22    }
23}
24
25impl<I: fmt::Debug, F> fmt::Debug for Inspect<I, F> {
26    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
27        f.debug_struct("Inspect")
28            .field("iter", &self.iter)
29            .finish_non_exhaustive()
30    }
31}
32
33impl<I, F> LendingIterator for Inspect<I, F>
34where
35    I: LendingIterator,
36    F: for<'a> FnMut(&I::Item<'a>),
37{
38    type Item<'a>
39        = I::Item<'a>
40    where
41        Self: 'a;
42
43    #[inline]
44    fn next(&mut self) -> Option<Self::Item<'_>> {
45        let item = self.iter.next()?;
46        (self.f)(&item);
47        Some(item)
48    }
49
50    #[inline]
51    fn size_hint(&self) -> (usize, Option<usize>) {
52        self.iter.size_hint()
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 inspect_basic() {
66        let result: Vec<_> = (0..5)
67            .into_lending()
68            .inspect(|_| {})
69            .map(identity)
70            .into_iter()
71            .collect();
72        assert_eq!(result, vec![0, 1, 2, 3, 4]);
73    }
74
75    #[test]
76    fn inspect_with_filter() {
77        let result: Vec<_> = (0..10)
78            .into_lending()
79            .inspect(|_| {})
80            .filter(|&x| x % 2 == 0)
81            .map(identity)
82            .into_iter()
83            .collect();
84        assert_eq!(result, vec![0, 2, 4, 6, 8]);
85    }
86
87    #[test]
88    fn inspect_with_windows() {
89        let result: Vec<_> = (0..5)
90            .windows(2)
91            .inspect(|_| {})
92            .map(|w: &[i32]| w[0] + w[1])
93            .into_iter()
94            .collect();
95        assert_eq!(result, vec![1, 3, 5, 7]);
96    }
97}