aoc/util/
iter.rs

1//! Add a `chunk` method to [`Iterator`] that duplicates the functionality of the unstable
2//! [`array_chunks`] method.
3//!
4//! Using Rust's const generics, concrete implementations are provided for sizes 2 to 8 to handle
5//! the most common situations. Once [`array_chunks`] is stablized then this module can be removed.
6//!
7//! [`array_chunks`]: std::iter::Iterator::array_chunks
8pub struct Chunk<I: Iterator, const N: usize> {
9    iter: I,
10}
11
12pub trait ChunkOps: Iterator + Sized {
13    fn chunk<const N: usize>(self) -> Chunk<Self, N>;
14}
15
16impl<I: Iterator> ChunkOps for I {
17    fn chunk<const N: usize>(self) -> Chunk<Self, N> {
18        Chunk::<Self, N> { iter: self }
19    }
20}
21
22impl<I: Iterator> Iterator for Chunk<I, 2> {
23    type Item = [I::Item; 2];
24
25    #[inline]
26    fn next(&mut self) -> Option<Self::Item> {
27        let a = self.iter.next()?;
28        let b = self.iter.next()?;
29        Some([a, b])
30    }
31}
32
33impl<I: Iterator> Iterator for Chunk<I, 3> {
34    type Item = [I::Item; 3];
35
36    #[inline]
37    fn next(&mut self) -> Option<Self::Item> {
38        let a = self.iter.next()?;
39        let b = self.iter.next()?;
40        let c = self.iter.next()?;
41        Some([a, b, c])
42    }
43}
44
45impl<I: Iterator> Iterator for Chunk<I, 4> {
46    type Item = [I::Item; 4];
47
48    #[inline]
49    fn next(&mut self) -> Option<Self::Item> {
50        let a = self.iter.next()?;
51        let b = self.iter.next()?;
52        let c = self.iter.next()?;
53        let d = self.iter.next()?;
54        Some([a, b, c, d])
55    }
56}
57
58impl<I: Iterator> Iterator for Chunk<I, 5> {
59    type Item = [I::Item; 5];
60
61    #[inline]
62    fn next(&mut self) -> Option<Self::Item> {
63        let a = self.iter.next()?;
64        let b = self.iter.next()?;
65        let c = self.iter.next()?;
66        let d = self.iter.next()?;
67        let e = self.iter.next()?;
68        Some([a, b, c, d, e])
69    }
70}
71
72impl<I: Iterator> Iterator for Chunk<I, 6> {
73    type Item = [I::Item; 6];
74
75    #[inline]
76    fn next(&mut self) -> Option<Self::Item> {
77        let a = self.iter.next()?;
78        let b = self.iter.next()?;
79        let c = self.iter.next()?;
80        let d = self.iter.next()?;
81        let e = self.iter.next()?;
82        let f = self.iter.next()?;
83        Some([a, b, c, d, e, f])
84    }
85}
86
87impl<I: Iterator> Iterator for Chunk<I, 7> {
88    type Item = [I::Item; 7];
89
90    #[inline]
91    fn next(&mut self) -> Option<Self::Item> {
92        let a = self.iter.next()?;
93        let b = self.iter.next()?;
94        let c = self.iter.next()?;
95        let d = self.iter.next()?;
96        let e = self.iter.next()?;
97        let f = self.iter.next()?;
98        let g = self.iter.next()?;
99        Some([a, b, c, d, e, f, g])
100    }
101}
102
103impl<I: Iterator> Iterator for Chunk<I, 8> {
104    type Item = [I::Item; 8];
105
106    #[inline]
107    fn next(&mut self) -> Option<Self::Item> {
108        let a = self.iter.next()?;
109        let b = self.iter.next()?;
110        let c = self.iter.next()?;
111        let d = self.iter.next()?;
112        let e = self.iter.next()?;
113        let f = self.iter.next()?;
114        let g = self.iter.next()?;
115        let h = self.iter.next()?;
116        Some([a, b, c, d, e, f, g, h])
117    }
118}