Skip to content

Commit 8423557

Browse files
committed
expression: replace poorly-typed binary function with new one
Improves the typing of the errors (and the error messages themselves) by eliminating another instance of `errstr`. Saves another instance of `errstr` by removing the unused `unary` method. There are now 5 left in the entire library :). Strictly speaking, we ought to do a deprecation cycle on these. But because we are changing the `expression` module so thoroughly, and we don't expect any users are directly using it, it doesn't seem worth the difficult (impossible?) task of preserving the old API for the sake of deprecation messages.
1 parent fd28e86 commit 8423557

File tree

2 files changed

+32
-36
lines changed

2 files changed

+32
-36
lines changed

src/expression/mod.rs

Lines changed: 14 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,20 @@ impl<'a> Tree<'a> {
137137
}
138138
}
139139

140+
/// Check that a tree node has exactly two children.
141+
///
142+
/// If so, return them.
143+
///
144+
/// The `description` argument is only used to populate the error return,
145+
/// and is not validated in any way.
146+
pub fn verify_binary(
147+
&self,
148+
description: &'static str,
149+
) -> Result<(&Self, &Self), ParseTreeError> {
150+
self.verify_n_children(description, 2..=2)?;
151+
Ok((&self.args[0], &self.args[1]))
152+
}
153+
140154
/// Check that a tree has no curly-brace children in it.
141155
pub fn verify_no_curly_braces(&self) -> Result<(), ParseTreeError> {
142156
for tree in self.pre_order_iter() {
@@ -356,36 +370,6 @@ where
356370
}
357371
}
358372

359-
/// Attempts to parse an expression with exactly one child
360-
pub fn unary<L, T, F>(term: &Tree, convert: F) -> Result<T, Error>
361-
where
362-
L: FromTree,
363-
F: FnOnce(L) -> T,
364-
{
365-
if term.args.len() == 1 {
366-
let left = FromTree::from_tree(&term.args[0])?;
367-
Ok(convert(left))
368-
} else {
369-
Err(errstr(term.name))
370-
}
371-
}
372-
373-
/// Attempts to parse an expression with exactly two children
374-
pub fn binary<L, R, T, F>(term: &Tree, convert: F) -> Result<T, Error>
375-
where
376-
L: FromTree,
377-
R: FromTree,
378-
F: FnOnce(L, R) -> T,
379-
{
380-
if term.args.len() == 2 {
381-
let left = FromTree::from_tree(&term.args[0])?;
382-
let right = FromTree::from_tree(&term.args[1])?;
383-
Ok(convert(left, right))
384-
} else {
385-
Err(errstr(term.name))
386-
}
387-
}
388-
389373
#[cfg(test)]
390374
mod tests {
391375
use super::*;

src/miniscript/astelem.rs

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,18 @@ impl<Pk: FromStrKey, Ctx: ScriptContext> crate::expression::FromTree for Arc<Ter
3030

3131
impl<Pk: FromStrKey, Ctx: ScriptContext> crate::expression::FromTree for Terminal<Pk, Ctx> {
3232
fn from_tree(top: &expression::Tree) -> Result<Terminal<Pk, Ctx>, Error> {
33+
let binary =
34+
|node: &expression::Tree, name, termfn: fn(_, _) -> Self| -> Result<Self, Error> {
35+
node.verify_binary(name)
36+
.map_err(crate::ParseError::Tree)
37+
.map_err(Error::Parse)
38+
.and_then(|(x, y)| {
39+
let x = Arc::<Miniscript<Pk, Ctx>>::from_tree(x)?;
40+
let y = Arc::<Miniscript<Pk, Ctx>>::from_tree(y)?;
41+
Ok(termfn(x, y))
42+
})
43+
};
44+
3345
let (frag_name, frag_wrap) = super::split_expression_name(top.name)?;
3446
let unwrapped = match (frag_name, top.args.len()) {
3547
("expr_raw_pkh", 1) => expression::terminal(&top.args[0], |x| {
@@ -65,8 +77,8 @@ impl<Pk: FromStrKey, Ctx: ScriptContext> crate::expression::FromTree for Termina
6577
}),
6678
("1", 0) => Ok(Terminal::True),
6779
("0", 0) => Ok(Terminal::False),
68-
("and_v", 2) => expression::binary(top, Terminal::AndV),
69-
("and_b", 2) => expression::binary(top, Terminal::AndB),
80+
("and_v", _) => binary(top, "and_v", Terminal::AndV),
81+
("and_b", _) => binary(top, "and_b", Terminal::AndB),
7082
("and_n", 2) => Ok(Terminal::AndOr(
7183
expression::FromTree::from_tree(&top.args[0])?,
7284
expression::FromTree::from_tree(&top.args[1])?,
@@ -77,10 +89,10 @@ impl<Pk: FromStrKey, Ctx: ScriptContext> crate::expression::FromTree for Termina
7789
expression::FromTree::from_tree(&top.args[1])?,
7890
expression::FromTree::from_tree(&top.args[2])?,
7991
)),
80-
("or_b", 2) => expression::binary(top, Terminal::OrB),
81-
("or_d", 2) => expression::binary(top, Terminal::OrD),
82-
("or_c", 2) => expression::binary(top, Terminal::OrC),
83-
("or_i", 2) => expression::binary(top, Terminal::OrI),
92+
("or_b", _) => binary(top, "or_b", Terminal::OrB),
93+
("or_d", _) => binary(top, "or_d", Terminal::OrD),
94+
("or_c", _) => binary(top, "or_c", Terminal::OrC),
95+
("or_i", _) => binary(top, "or_i", Terminal::OrI),
8496
("thresh", _) => top
8597
.to_null_threshold()
8698
.map_err(Error::ParseThreshold)?

0 commit comments

Comments
 (0)