Skip to content

Commit a0ef37f

Browse files
committed
Add iterator for taptree
1 parent 81d1658 commit a0ef37f

File tree

1 file changed

+43
-1
lines changed

1 file changed

+43
-1
lines changed

src/descriptor/tr.rs

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use {Error, MiniscriptKey};
1313
/// A Taproot Tree representation.
1414
// Hidden leaves are not yet supported in descriptor spec. Conceptually, it should
1515
// be simple to integrate those here, but it is best to wait on core for the exact syntax.
16-
#[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
16+
#[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug)]
1717
pub enum TapTree<Pk: MiniscriptKey> {
1818
/// A taproot tree structure
1919
Tree(Arc<TapTree<Pk>>, Arc<TapTree<Pk>>),
@@ -42,6 +42,11 @@ impl<Pk: MiniscriptKey> TapTree<Pk> {
4242
TapTree::Leaf(_) => 1,
4343
}
4444
}
45+
46+
/// Iterate over all miniscripts
47+
pub fn iter(&self) -> TapTreeIter<Pk> {
48+
TapTreeIter { stack: vec![self] }
49+
}
4550
}
4651

4752
impl<Pk: MiniscriptKey> fmt::Display for TapTree<Pk> {
@@ -82,6 +87,43 @@ impl<Pk: MiniscriptKey> Tr<Pk> {
8287
pub fn taptree(&self) -> &Option<TapTree<Pk>> {
8388
&self.tree
8489
}
90+
91+
/// Iterate over all scripts in merkle tree. If there is no script path, the iterator
92+
/// yields [`None`]
93+
pub fn iter_scripts(&self) -> TapTreeIter<Pk> {
94+
match self.tree {
95+
Some(ref t) => t.iter(),
96+
None => TapTreeIter { stack: vec![] },
97+
}
98+
}
99+
}
100+
101+
/// Iterator for Taproot structures
102+
/// Yields the miniscript in a depth first walk
103+
#[derive(Debug, Clone)]
104+
pub struct TapTreeIter<'a, Pk: MiniscriptKey> where Pk: 'a {
105+
stack: Vec<&'a TapTree<Pk>>,
106+
}
107+
108+
impl<'a, Pk> Iterator for TapTreeIter<'a, Pk>
109+
where
110+
Pk: MiniscriptKey + 'a,
111+
{
112+
type Item = &'a Miniscript<Pk, Tap>;
113+
114+
fn next(&mut self) -> Option<Self::Item> {
115+
while !self.stack.is_empty() {
116+
let last = self.stack.pop().expect("Size checked above");
117+
match &*last {
118+
TapTree::Tree(l, r) => {
119+
self.stack.push(&r);
120+
self.stack.push(&l);
121+
}
122+
TapTree::Leaf(ref ms) => return Some(ms),
123+
}
124+
}
125+
None
126+
}
85127
}
86128

87129
impl<Pk: MiniscriptKey> FromTree for Tr<Pk>

0 commit comments

Comments
 (0)