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}