Skip to content

Commit b836032

Browse files
committed
Iterator improvements according to review
1 parent b9d7d6a commit b836032

File tree

1 file changed

+40
-11
lines changed

1 file changed

+40
-11
lines changed

src/miniscript/iter.rs

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,38 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> Miniscript<Pk, Ctx> {
7676
}
7777
}
7878

79+
/// Returns child node with given index, if any
80+
pub fn get_nth_child(&self, n: usize) -> Option<&Miniscript<Pk, Ctx>> {
81+
match (n, &self.node) {
82+
(0, &Terminal::Alt(ref node))
83+
| (0, &Terminal::Swap(ref node))
84+
| (0, &Terminal::Check(ref node))
85+
| (0, &Terminal::DupIf(ref node))
86+
| (0, &Terminal::Verify(ref node))
87+
| (0, &Terminal::NonZero(ref node))
88+
| (0, &Terminal::ZeroNotEqual(ref node))
89+
| (0, &Terminal::AndV(ref node, _))
90+
| (0, &Terminal::AndB(ref node, _))
91+
| (0, &Terminal::OrB(ref node, _))
92+
| (0, &Terminal::OrD(ref node, _))
93+
| (0, &Terminal::OrC(ref node, _))
94+
| (0, &Terminal::OrI(ref node, _))
95+
| (1, &Terminal::AndV(_, ref node))
96+
| (1, &Terminal::AndB(_, ref node))
97+
| (1, &Terminal::OrB(_, ref node))
98+
| (1, &Terminal::OrD(_, ref node))
99+
| (1, &Terminal::OrC(_, ref node))
100+
| (1, &Terminal::OrI(_, ref node))
101+
| (0, &Terminal::AndOr(ref node, _, _))
102+
| (1, &Terminal::AndOr(_, ref node, _))
103+
| (2, &Terminal::AndOr(_, _, ref node)) => Some(node),
104+
105+
(n, &Terminal::Thresh(_, ref node_vec)) => node_vec.get(n).map(|x| &**x),
106+
107+
_ => None,
108+
}
109+
}
110+
79111
/// Returns `Vec` with cloned version of all public keys from the current miniscript item,
80112
/// if any. Otherwise returns an empty `Vec`.
81113
///
@@ -94,7 +126,7 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> Miniscript<Pk, Ctx> {
94126
/// Otherwise returns an empty `Vec`.
95127
///
96128
/// For each public key the function computes hash; for each hash of the public key the function
97-
/// returns it cloned copy.
129+
/// returns its cloned copy.
98130
///
99131
/// NB: The function analyzes only single miniscript item and not any of its descendants in AST.
100132
/// To obtain a list of all public key hashes within AST use [`iter_pkh()`] function,
@@ -177,10 +209,8 @@ pub struct Iter<'a, Pk: 'a + MiniscriptKey, Ctx: 'a + ScriptContext> {
177209
next: Option<&'a Miniscript<Pk, Ctx>>,
178210
// Here we store vec of path elements, where each element is a tuple, consisting of:
179211
// 1. Miniscript node on the path
180-
// 2. It's branches stored as a vec (used for avoiding multiple vec allocations
181-
// during path traversal)
182-
// 3. Index of the current branch
183-
path: Vec<(&'a Miniscript<Pk, Ctx>, Vec<&'a Miniscript<Pk, Ctx>>, usize)>,
212+
// 2. Index of the current branch
213+
path: Vec<(&'a Miniscript<Pk, Ctx>, usize)>,
184214
}
185215

186216
impl<'a, Pk: MiniscriptKey, Ctx: ScriptContext> Iter<'a, Pk, Ctx> {
@@ -219,18 +249,17 @@ impl<'a, Pk: MiniscriptKey, Ctx: ScriptContext> Iterator for Iter<'a, Pk, Ctx> {
219249
fn next(&mut self) -> Option<Self::Item> {
220250
let mut curr = self.next;
221251
if let None = curr {
222-
while let Some((node, branches, child)) = self.path.pop() {
223-
curr = branches.get(child).map(|x| *x);
252+
while let Some((node, child)) = self.path.pop() {
253+
curr = node.get_nth_child(child);
224254
if curr.is_some() {
225-
self.path.push((node, branches, child + 1));
255+
self.path.push((node, child + 1));
226256
break;
227257
}
228258
}
229259
}
230260
if let Some(node) = curr {
231-
let branches = node.branches();
232-
self.next = branches.first().map(|x| *x);
233-
self.path.push((node, branches, 1));
261+
self.next = node.get_nth_child(0);
262+
self.path.push((node, 1));
234263
}
235264
curr
236265
}

0 commit comments

Comments
 (0)