gat_lending_iterator/adapters/
chain.rs

1use crate::LendingIterator;
2
3/// A lending iterator that iterates over the elements of two iterators
4/// in sequence.
5///
6/// This `struct` is created by the [`chain`] method on [`LendingIterator`]. See
7/// its documentation for more.
8///
9/// [`LendingIterator`]: crate::LendingIterator
10/// [`chain`]: crate::LendingIterator::chain
11#[derive(Clone, Debug)]
12#[must_use = "iterators are lazy and do nothing unless consumed"]
13pub struct Chain<A, B> {
14    a: A,
15    b: B,
16    a_done: bool,
17}
18impl<A, B> Chain<A, B> {
19    pub(crate) fn new(a: A, b: B) -> Chain<A, B> {
20        Chain {
21            a,
22            b,
23            a_done: false,
24        }
25    }
26}
27
28impl<A, B> LendingIterator for Chain<A, B>
29where
30    A: LendingIterator,
31    for<'a> B: LendingIterator<Item<'a> = A::Item<'a>> + 'a,
32{
33    type Item<'a>
34        = A::Item<'a>
35    where
36        Self: 'a;
37
38    #[inline]
39    fn next(&mut self) -> Option<A::Item<'_>> {
40        if self.a_done {
41            self.b.next()
42        } else {
43            self.a.next().or_else(|| {
44                self.a_done = true;
45                self.b.next()
46            })
47        }
48    }
49}
50
51#[cfg(test)]
52mod tests {
53    use crate::{LendingIterator, ToLendingIterator};
54
55    fn to_vec_i32(w: &[i32]) -> Vec<i32> {
56        w.to_vec()
57    }
58
59    #[test]
60    fn chain_basic() {
61        let result: Vec<_> = (0..3)
62            .windows(2)
63            .chain((5..8).windows(2))
64            .map(to_vec_i32)
65            .into_iter()
66            .collect();
67        assert_eq!(result, vec![vec![0, 1], vec![1, 2], vec![5, 6], vec![6, 7]]);
68    }
69}