radix_rust/iterators/
overlaying_result_iterator.rs

1use crate::prelude::*;
2use core::cmp::*;
3use core::iter::*;
4
5/// An iterator overlaying a "change on a value" (coming from the [`overlaying`] iterator) over a
6/// "base value" (coming from the [`underlying`] iterator) which may error.
7/// The one is matched to another by a `K` part (of the iterated tuple `(K, V)`), which both
8/// iterators are assumed to be ordered by.
9pub struct OverlayingResultIterator<U, O>
10where
11    U: Iterator,
12    O: Iterator,
13{
14    underlying: Peekable<U>,
15    overlaying: Peekable<O>,
16    errored_out: bool,
17}
18
19impl<K, V, U, O, E> OverlayingResultIterator<U, O>
20where
21    K: Ord,
22    U: Iterator<Item = Result<(K, V), E>>,
23    O: Iterator<Item = (K, Option<V>)>,
24{
25    /// Creates an overlaying iterator.
26    /// The [`underlying`] iterator provides the "base values" from some I/O.
27    /// The [`overlaying`] one provides the "changes" to those values, represented as `Option<V>`:
28    /// - A [`Some`] is an upsert, i.e. it may override an existing base value, or "insert" a
29    ///   completely new one to the iterated results.
30    /// - A [`None`] is a delete, which causes the base value to be omitted in the iterated results.
31    #[allow(clippy::new_ret_no_self)]
32    pub fn new(underlying: U, overlaying: O) -> impl Iterator<Item = Result<(K, V), E>> {
33        Self {
34            underlying: underlying.peekable(),
35            overlaying: overlaying.peekable(),
36            errored_out: false,
37        }
38    }
39}
40
41impl<K, V, U, O, E> Iterator for OverlayingResultIterator<U, O>
42where
43    K: Ord,
44    U: Iterator<Item = Result<(K, V), E>>,
45    O: Iterator<Item = (K, Option<V>)>,
46{
47    type Item = Result<(K, V), E>;
48
49    fn next(&mut self) -> Option<Self::Item> {
50        if self.errored_out {
51            return None;
52        }
53
54        loop {
55            if let Some(overlaying_key) = self.overlaying.peek_key() {
56                if let Some(underlying) = self.underlying.peek() {
57                    match underlying {
58                        Ok((underlying_key, _)) => {
59                            match underlying_key.cmp(overlaying_key) {
60                                Ordering::Less => {
61                                    return self.underlying.next(); // return and move it forward
62                                }
63                                Ordering::Equal => {
64                                    self.underlying.next(); // only move it forward
65                                }
66                                Ordering::Greater => {
67                                    // leave it as-is
68                                }
69                            };
70                        }
71                        Err(..) => {
72                            self.errored_out = true;
73                            return self.underlying.next();
74                        }
75                    }
76                }
77
78                let (overlaying_key, overlaying_change) = self.overlaying.next().unwrap();
79                match overlaying_change {
80                    Some(value) => return Some(Ok((overlaying_key, value))),
81                    None => continue, // we may need to skip over an unbounded number of deletes
82                }
83            } else {
84                let rtn = self.underlying.next();
85                if let Some(Err(..)) = rtn {
86                    self.errored_out = true;
87                }
88                return rtn;
89            }
90        }
91    }
92}