tea_core/vec_core/
iter_traits.rs

1use std::iter::IntoIterator;
2
3use tea_dtype::IsNone;
4
5use super::trusted::TrustedLen;
6
7/// A trait combining `Iterator`, `DoubleEndedIterator`, and `TrustedLen` capabilities.
8pub trait TIterator: Iterator + DoubleEndedIterator + TrustedLen {}
9impl<I: Iterator + DoubleEndedIterator + TrustedLen> TIterator for I {}
10
11/// A trait providing additional iterator methods for types that can be converted into an iterator.
12pub trait IterBasic: IntoIterator + Sized {
13    /// Folds the elements of the iterator, skipping `None` values.
14    ///
15    /// # Arguments
16    /// * `init` - The initial value for the fold operation.
17    /// * `f` - A closure that takes the accumulator and a non-None item, returning a new accumulator.
18    ///
19    /// # Returns
20    /// The final accumulated value.
21    #[inline]
22    fn vfold<U, F>(self, init: U, mut f: F) -> U
23    where
24        F: FnMut(U, Self::Item) -> U,
25        Self::Item: IsNone,
26    {
27        self.into_iter()
28            .fold(init, |acc, v| if v.not_none() { f(acc, v) } else { acc })
29    }
30
31    /// Folds two iterators together, skipping `None` values from either iterator.
32    ///
33    /// # Arguments
34    /// * `other` - The second iterator to fold with.
35    /// * `init` - The initial value for the fold operation.
36    /// * `f` - A closure that takes the accumulator and non-None items from both iterators, returning a new accumulator.
37    ///
38    /// # Returns
39    /// The final accumulated value.
40    #[inline]
41    fn vfold2<U, I2, F>(self, other: I2, init: U, mut f: F) -> U
42    where
43        I2: IntoIterator,
44        I2::Item: IsNone,
45        F: FnMut(U, Self::Item, I2::Item) -> U,
46        Self::Item: IsNone,
47    {
48        self.into_iter().zip(other).fold(init, |acc, (va, vb)| {
49            if va.not_none() && vb.not_none() {
50                f(acc, va, vb)
51            } else {
52                acc
53            }
54        })
55    }
56
57    /// Folds the elements of the iterator, skipping `None` values and counting non-None elements.
58    ///
59    /// # Arguments
60    /// * `init` - The initial value for the fold operation.
61    /// * `f` - A closure that takes the accumulator and the inner value of a non-None item, returning a new accumulator.
62    ///
63    /// # Returns
64    /// A tuple containing the count of non-None elements and the final accumulated value.
65    #[inline]
66    fn vfold_n<U, F>(self, init: U, mut f: F) -> (usize, U)
67    where
68        F: FnMut(U, <Self::Item as IsNone>::Inner) -> U,
69        Self::Item: IsNone,
70    {
71        let mut n = 0;
72        let acc = self.into_iter().fold(init, |acc, v| {
73            if v.not_none() {
74                n += 1;
75                f(acc, v.unwrap())
76            } else {
77                acc
78            }
79        });
80        (n, acc)
81    }
82
83    /// Applies a function to each non-None element of the iterator.
84    ///
85    /// # Arguments
86    /// * `f` - A closure that takes the inner value of a non-None item and performs some operation.
87    #[inline]
88    fn vapply<F>(self, mut f: F)
89    where
90        F: FnMut(<Self::Item as IsNone>::Inner),
91        Self::Item: IsNone,
92    {
93        self.into_iter().fold((), |(), v| {
94            if v.not_none() {
95                f(v.unwrap())
96            }
97        })
98    }
99
100    /// Applies a function to each non-None element of the iterator and counts the number of applications.
101    ///
102    /// # Arguments
103    /// * `f` - A closure that takes the inner value of a non-None item and performs some operation.
104    ///
105    /// # Returns
106    /// The number of non-None elements processed.
107    #[inline]
108    fn vapply_n<F>(self, mut f: F) -> usize
109    where
110        F: FnMut(<Self::Item as IsNone>::Inner),
111        Self::Item: IsNone,
112    {
113        let mut n = 0;
114        self.into_iter().fold((), |(), v| {
115            if v.not_none() {
116                n += 1;
117                f(v.unwrap())
118            }
119        });
120        n
121    }
122}
123
124impl<I: IntoIterator + Sized> IterBasic for I {}