@@ -76,6 +76,38 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> Miniscript<Pk, Ctx> {
76
76
}
77
77
}
78
78
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
+
79
111
/// Returns `Vec` with cloned version of all public keys from the current miniscript item,
80
112
/// if any. Otherwise returns an empty `Vec`.
81
113
///
@@ -94,7 +126,7 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> Miniscript<Pk, Ctx> {
94
126
/// Otherwise returns an empty `Vec`.
95
127
///
96
128
/// 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.
98
130
///
99
131
/// NB: The function analyzes only single miniscript item and not any of its descendants in AST.
100
132
/// 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> {
177
209
next : Option < & ' a Miniscript < Pk , Ctx > > ,
178
210
// Here we store vec of path elements, where each element is a tuple, consisting of:
179
211
// 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 ) > ,
184
214
}
185
215
186
216
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> {
219
249
fn next ( & mut self ) -> Option < Self :: Item > {
220
250
let mut curr = self . next ;
221
251
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) ;
224
254
if curr. is_some ( ) {
225
- self . path . push ( ( node, branches , child + 1 ) ) ;
255
+ self . path . push ( ( node, child + 1 ) ) ;
226
256
break ;
227
257
}
228
258
}
229
259
}
230
260
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 ) ) ;
234
263
}
235
264
curr
236
265
}
0 commit comments