Skip to content

Commit 3c0ff73

Browse files
committed
iter: add module, copied in large from rust-simplicity
Introduces the new `iter` module which provides iteration abilities over various tree-like structures. This is largely copied from rust-simplicity, but is both simpler (because there is no sharing) and more complicated (because we need to handle n-ary nodes, not just binary ones). This currently uses Arc<[T]> in a number of places; we should eventually replace these with some sort of ArrayVec-type structure.
1 parent a807ea4 commit 3c0ff73

File tree

3 files changed

+418
-0
lines changed

3 files changed

+418
-0
lines changed

src/iter/mod.rs

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
// Written in 2023 by Andrew Poelstra <[email protected]>
2+
// SPDX-License-Identifier: CC0-1.0
3+
4+
//! Abstract Tree Iteration
5+
//!
6+
//! This module provides functionality to treat Miniscript objects abstractly
7+
//! as trees, iterating over them in various orders. The iterators in this
8+
//! module can be used to avoid explicitly recursive algorithms.
9+
//!
10+
11+
mod tree;
12+
13+
pub use tree::{
14+
PostOrderIter, PostOrderIterItem, PreOrderIter, PreOrderIterItem, Tree, TreeLike,
15+
VerbosePreOrderIter,
16+
};
17+
18+
use crate::sync::Arc;
19+
use crate::{Miniscript, MiniscriptKey, ScriptContext, Terminal};
20+
21+
impl<'a, Pk: MiniscriptKey, Ctx: ScriptContext> TreeLike for &'a Miniscript<Pk, Ctx> {
22+
fn as_node(&self) -> Tree<Self> {
23+
match self.node {
24+
Terminal::PkK(..)
25+
| Terminal::PkH(..)
26+
| Terminal::RawPkH(..)
27+
| Terminal::After(..)
28+
| Terminal::Older(..)
29+
| Terminal::Sha256(..)
30+
| Terminal::Hash256(..)
31+
| Terminal::Ripemd160(..)
32+
| Terminal::Hash160(..)
33+
| Terminal::True
34+
| Terminal::False
35+
| Terminal::Multi(..)
36+
| Terminal::MultiA(..) => Tree::Nullary,
37+
Terminal::Alt(ref sub)
38+
| Terminal::Swap(ref sub)
39+
| Terminal::Check(ref sub)
40+
| Terminal::DupIf(ref sub)
41+
| Terminal::Verify(ref sub)
42+
| Terminal::NonZero(ref sub)
43+
| Terminal::ZeroNotEqual(ref sub) => Tree::Unary(sub),
44+
Terminal::AndV(ref left, ref right)
45+
| Terminal::AndB(ref left, ref right)
46+
| Terminal::OrB(ref left, ref right)
47+
| Terminal::OrD(ref left, ref right)
48+
| Terminal::OrC(ref left, ref right)
49+
| Terminal::OrI(ref left, ref right) => Tree::Binary(left, right),
50+
Terminal::AndOr(ref a, ref b, ref c) => Tree::Nary(Arc::from([a.as_ref(), b, c])),
51+
Terminal::Thresh(_, ref subs) => Tree::Nary(subs.iter().map(Arc::as_ref).collect()),
52+
}
53+
}
54+
}
55+
56+
impl<Pk: MiniscriptKey, Ctx: ScriptContext> TreeLike for Arc<Miniscript<Pk, Ctx>> {
57+
fn as_node(&self) -> Tree<Self> {
58+
match self.node {
59+
Terminal::PkK(..)
60+
| Terminal::PkH(..)
61+
| Terminal::RawPkH(..)
62+
| Terminal::After(..)
63+
| Terminal::Older(..)
64+
| Terminal::Sha256(..)
65+
| Terminal::Hash256(..)
66+
| Terminal::Ripemd160(..)
67+
| Terminal::Hash160(..)
68+
| Terminal::True
69+
| Terminal::False
70+
| Terminal::Multi(..)
71+
| Terminal::MultiA(..) => Tree::Nullary,
72+
Terminal::Alt(ref sub)
73+
| Terminal::Swap(ref sub)
74+
| Terminal::Check(ref sub)
75+
| Terminal::DupIf(ref sub)
76+
| Terminal::Verify(ref sub)
77+
| Terminal::NonZero(ref sub)
78+
| Terminal::ZeroNotEqual(ref sub) => Tree::Unary(Arc::clone(sub)),
79+
Terminal::AndV(ref left, ref right)
80+
| Terminal::AndB(ref left, ref right)
81+
| Terminal::OrB(ref left, ref right)
82+
| Terminal::OrD(ref left, ref right)
83+
| Terminal::OrC(ref left, ref right)
84+
| Terminal::OrI(ref left, ref right) => {
85+
Tree::Binary(Arc::clone(left), Arc::clone(right))
86+
}
87+
Terminal::AndOr(ref a, ref b, ref c) => {
88+
Tree::Nary(Arc::from([Arc::clone(a), Arc::clone(b), Arc::clone(c)]))
89+
}
90+
Terminal::Thresh(_, ref subs) => Tree::Nary(subs.iter().map(Arc::clone).collect()),
91+
}
92+
}
93+
}

0 commit comments

Comments
 (0)