miniscript/iter/
mod.rs

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