Skip to content

Commit 88d79c1

Browse files
committed
Add iterator for taptree
1 parent df74a87 commit 88d79c1

File tree

1 file changed

+43
-1
lines changed

1 file changed

+43
-1
lines changed

src/descriptor/tr.rs

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

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

91133
impl<Pk> Tr<Pk>

0 commit comments

Comments
 (0)