Skip to main content

alux_sdk/
iterator.rs

1use alux_ext::ext;
2
3/// Iterator utility functions.
4#[ext(name = IteratorExt)]
5pub impl<This> This
6where
7    This: Iterator,
8{
9    /// Omits the item at one zero-based position.
10    fn skip_nth(self, position: usize) -> impl Iterator<Item = This::Item> {
11        self.enumerate().filter_map(move |(index, item)| (index != position).then_some(item))
12    }
13
14    /// Includes items through the first item satisfying `predicate`, then stops.
15    fn stop_if<Predicate>(self, mut predicate: Predicate) -> impl Iterator<Item = This::Item>
16    where
17        Predicate: FnMut(&This::Item) -> bool,
18    {
19        self.scan(false, move |stopped, item| {
20            if *stopped {
21                None
22            } else {
23                *stopped = predicate(&item);
24                Some(item)
25            }
26        })
27    }
28}
29
30#[cfg(test)]
31mod tests {
32    use super::IteratorExt;
33
34    #[test]
35    fn test_skip_nth() {
36        assert_eq!((0..4).skip_nth(0).collect::<Vec<_>>(), vec![1, 2, 3]);
37        assert_eq!((0..4).skip_nth(2).collect::<Vec<_>>(), vec![0, 1, 3]);
38        assert_eq!((0..4).skip_nth(3).collect::<Vec<_>>(), vec![0, 1, 2]);
39    }
40
41    #[test]
42    fn test_stop_if() {
43        assert_eq!((0..10).stop_if(|value| *value > 2).collect::<Vec<_>>(), vec![0, 1, 2, 3]);
44    }
45}