nakamoto_common/block/
iter.rs

1//! Double-ended iterator over a `NonEmpty` blockchain.
2use nonempty::NonEmpty;
3
4use super::Height;
5
6/// An iterator over a chain.
7#[derive(Debug)]
8pub struct Iter<'a, T> {
9    chain: &'a NonEmpty<T>,
10    next: usize,
11    next_back: usize,
12}
13
14impl<'a, T> Iter<'a, T> {
15    /// Create a new iterator.
16    pub fn new(chain: &'a NonEmpty<T>) -> Self {
17        Self {
18            chain,
19            next: 0,
20            next_back: chain.len(),
21        }
22    }
23}
24
25impl<'a, T> Iterator for Iter<'a, T> {
26    type Item = (Height, &'a T);
27
28    fn next(&mut self) -> Option<Self::Item> {
29        if self.next == self.next_back {
30            return None;
31        }
32        let height = self.next;
33        self.next += 1;
34
35        self.chain.get(height).map(|item| (height as Height, item))
36    }
37}
38
39impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
40    ///```
41    /// use nonempty::NonEmpty;
42    /// use nakamoto_common::block::iter::Iter;
43    ///
44    /// let chain = NonEmpty::from_vec(vec![1, 2, 3, 4, 5]).unwrap();
45    /// let mut iter = Iter::new(&chain);
46    ///
47    /// assert_eq!(Some((4, &5)), iter.next_back());
48    /// assert_eq!(Some((3, &4)), iter.next_back());
49    /// assert_eq!(Some((2, &3)), iter.next_back());
50    /// assert_eq!(Some((1, &2)), iter.next_back());
51    /// assert_eq!(Some((0, &1)), iter.next_back());
52    ///
53    /// let mut iter = Iter::new(&chain);
54    ///
55    /// assert_eq!(Some((4, &5)), iter.next_back());
56    /// assert_eq!(Some((0, &1)), iter.next());
57    /// assert_eq!(Some((3, &4)), iter.next_back());
58    /// assert_eq!(Some((1, &2)), iter.next());
59    /// assert_eq!(Some((2, &3)), iter.next_back());
60    /// assert_eq!(None, iter.next());
61    /// assert_eq!(None, iter.next_back());
62    ///```
63    fn next_back(&mut self) -> Option<Self::Item> {
64        if self.next_back == self.next {
65            return None;
66        }
67
68        self.next_back -= 1;
69        let height = self.next_back;
70
71        self.chain.get(height).map(|item| (height as Height, item))
72    }
73}