o1_utils/
adjacent_pairs.rs

1//! This module hosts the [AdjacentPairs] type,
2//! which can be used to list all the adjacent pairs of a list.
3//! For example, if you have a list of integers `[1, 2, 3]`,
4//! you can use it to obtain the list of tuples `[(1, 2), (2, 3)]`.
5
6/// You can create a new [AdjacentPairs] from an iterator using:
7///
8/// ```
9/// use o1_utils::adjacent_pairs::AdjacentPairs;
10///
11/// let a = vec![1, 2, 3];
12/// let mut pairs = AdjacentPairs::from(a);
13///
14/// assert_eq!(pairs.next(), Some((1, 2)));
15/// assert_eq!(pairs.next(), Some((2, 3)));
16/// assert_eq!(pairs.next(), None);
17/// ```
18pub struct AdjacentPairs<A, I>
19where
20    I: Iterator<Item = A>,
21{
22    prev_second_component: Option<A>,
23    i: I,
24}
25
26impl<A: Copy, I: Iterator<Item = A>> Iterator for AdjacentPairs<A, I> {
27    type Item = (A, A);
28
29    fn next(&mut self) -> Option<(A, A)> {
30        match self.prev_second_component {
31            Some(x) => match self.i.next() {
32                None => None,
33                Some(y) => {
34                    self.prev_second_component = Some(y);
35                    Some((x, y))
36                }
37            },
38            None => {
39                let x = self.i.next();
40                let y = self.i.next();
41                match (x, y) {
42                    (None, _) | (_, None) => None,
43                    (Some(x), Some(y)) => {
44                        self.prev_second_component = Some(y);
45                        Some((x, y))
46                    }
47                }
48            }
49        }
50    }
51}
52
53impl<A, I, T> From<T> for AdjacentPairs<A, I>
54where
55    T: IntoIterator<Item = A, IntoIter = I>,
56    I: Iterator<Item = A>,
57{
58    fn from(i: T) -> Self {
59        Self {
60            i: i.into_iter(),
61            prev_second_component: None,
62        }
63    }
64}