Skip to content

Commit

Permalink
Add impl_from_tree!
Browse files Browse the repository at this point in the history
It is not possible to add a supertrait(and a blanket implemnetation)
that captures associated types currently. The where clauses must
be carried around everywhere. Use a macro instead
  • Loading branch information
sanket1729 committed Jun 8, 2022
1 parent c43129c commit 5d44dc0
Show file tree
Hide file tree
Showing 10 changed files with 227 additions and 283 deletions.
51 changes: 14 additions & 37 deletions src/descriptor/bare.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
//!
use core::fmt;
use core::str::FromStr;

use bitcoin::blockdata::script;
use bitcoin::{Address, Network, Script};
Expand Down Expand Up @@ -145,35 +144,24 @@ impl<Pk: MiniscriptKey> Liftable<Pk> for Bare<Pk> {
}
}

impl<Pk> FromTree for Bare<Pk>
where
Pk: MiniscriptKey + FromStr,
Pk::Hash: FromStr,
<Pk as FromStr>::Err: ToString,
<<Pk as MiniscriptKey>::Hash as FromStr>::Err: ToString,
{
impl_from_tree!(
Bare<Pk>,
fn from_tree(top: &expression::Tree) -> Result<Self, Error> {
let sub = Miniscript::<Pk, BareCtx>::from_tree(top)?;
BareCtx::top_level_checks(&sub)?;
Bare::new(sub)
}
}

impl<Pk> FromStr for Bare<Pk>
where
Pk: MiniscriptKey + FromStr,
Pk::Hash: FromStr,
<Pk as FromStr>::Err: ToString,
<<Pk as MiniscriptKey>::Hash as FromStr>::Err: ToString,
{
type Err = Error;
);

impl_from_str!(
Bare<Pk>,
type Err = Error;,
fn from_str(s: &str) -> Result<Self, Self::Err> {
let desc_str = verify_checksum(s)?;
let top = expression::Tree::from_str(desc_str)?;
Self::from_tree(&top)
}
}
);

impl<Pk: MiniscriptKey> ForEachKey<Pk> for Bare<Pk> {
fn for_each_key<'a, F: FnMut(ForEach<'a, Pk>) -> bool>(&'a self, pred: F) -> bool
Expand Down Expand Up @@ -313,13 +301,8 @@ impl<Pk: MiniscriptKey> Liftable<Pk> for Pkh<Pk> {
}
}

impl<Pk> FromTree for Pkh<Pk>
where
Pk: MiniscriptKey + FromStr,
Pk::Hash: FromStr,
<Pk as FromStr>::Err: ToString,
<<Pk as MiniscriptKey>::Hash as FromStr>::Err: ToString,
{
impl_from_tree!(
Pkh<Pk>,
fn from_tree(top: &expression::Tree) -> Result<Self, Error> {
if top.name == "pkh" && top.args.len() == 1 {
Ok(Pkh::new(expression::terminal(&top.args[0], |pk| {
Expand All @@ -333,23 +316,17 @@ where
)))
}
}
}

impl<Pk> FromStr for Pkh<Pk>
where
Pk: MiniscriptKey + FromStr,
Pk::Hash: FromStr,
<Pk as FromStr>::Err: ToString,
<<Pk as MiniscriptKey>::Hash as FromStr>::Err: ToString,
{
type Err = Error;
);

impl_from_str!(
Pkh<Pk>,
type Err = Error;,
fn from_str(s: &str) -> Result<Self, Self::Err> {
let desc_str = verify_checksum(s)?;
let top = expression::Tree::from_str(desc_str)?;
Self::from_tree(&top)
}
}
);

impl<Pk: MiniscriptKey> ForEachKey<Pk> for Pkh<Pk> {
fn for_each_key<'a, F: FnMut(ForEach<'a, Pk>) -> bool>(&'a self, mut pred: F) -> bool
Expand Down
27 changes: 8 additions & 19 deletions src/descriptor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -651,14 +651,9 @@ impl Descriptor<DescriptorPublicKey> {
}
}

impl<Pk> expression::FromTree for Descriptor<Pk>
where
Pk: MiniscriptKey + str::FromStr,
Pk::Hash: str::FromStr,
<Pk as FromStr>::Err: ToString,
<<Pk as MiniscriptKey>::Hash as FromStr>::Err: ToString,
{
/// Parse an expression tree into a descriptor
impl_from_tree!(
Descriptor<Pk>,
/// Parse an expression tree into a descriptor.
fn from_tree(top: &expression::Tree) -> Result<Descriptor<Pk>, Error> {
Ok(match (top.name, top.args.len() as u32) {
("pkh", 1) => Descriptor::Pkh(Pkh::from_tree(top)?),
Expand All @@ -669,17 +664,11 @@ where
_ => Descriptor::Bare(Bare::from_tree(top)?),
})
}
}

impl<Pk> FromStr for Descriptor<Pk>
where
Pk: MiniscriptKey + str::FromStr,
Pk::Hash: str::FromStr,
<Pk as FromStr>::Err: ToString,
<<Pk as MiniscriptKey>::Hash as FromStr>::Err: ToString,
{
type Err = Error;
);

impl_from_str!(
Descriptor<Pk>,
type Err = Error;,
fn from_str(s: &str) -> Result<Descriptor<Pk>, Error> {
// tr tree parsing has special code
// Tr::from_str will check the checksum
Expand All @@ -692,7 +681,7 @@ where
expression::FromTree::from_tree(&top)
}
}
}
);

impl<Pk: MiniscriptKey> fmt::Debug for Descriptor<Pk> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Expand Down
52 changes: 15 additions & 37 deletions src/descriptor/segwitv0.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
//! of wsh, wpkh and sortedmulti inside wsh.
use core::fmt;
use core::str::FromStr;

use bitcoin::{self, Address, Network, Script};

Expand Down Expand Up @@ -194,13 +193,8 @@ impl<Pk: MiniscriptKey> Liftable<Pk> for Wsh<Pk> {
}
}

impl<Pk> FromTree for Wsh<Pk>
where
Pk: MiniscriptKey + FromStr,
Pk::Hash: FromStr,
<Pk as FromStr>::Err: ToString,
<<Pk as MiniscriptKey>::Hash as FromStr>::Err: ToString,
{
impl_from_tree!(
Wsh<Pk>,
fn from_tree(top: &expression::Tree) -> Result<Self, Error> {
if top.name == "wsh" && top.args.len() == 1 {
let top = &top.args[0];
Expand All @@ -222,7 +216,8 @@ where
)))
}
}
}
);

impl<Pk: MiniscriptKey> fmt::Debug for Wsh<Pk> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self.inner {
Expand All @@ -240,21 +235,15 @@ impl<Pk: MiniscriptKey> fmt::Display for Wsh<Pk> {
}
}

impl<Pk> FromStr for Wsh<Pk>
where
Pk: MiniscriptKey + FromStr,
Pk::Hash: FromStr,
<Pk as FromStr>::Err: ToString,
<<Pk as MiniscriptKey>::Hash as FromStr>::Err: ToString,
{
type Err = Error;

impl_from_str!(
Wsh<Pk>,
type Err = Error;,
fn from_str(s: &str) -> Result<Self, Self::Err> {
let desc_str = verify_checksum(s)?;
let top = expression::Tree::from_str(desc_str)?;
Wsh::<Pk>::from_tree(&top)
}
}
);

impl<Pk: MiniscriptKey> ForEachKey<Pk> for Wsh<Pk> {
fn for_each_key<'a, F: FnMut(ForEach<'a, Pk>) -> bool>(&'a self, pred: F) -> bool
Expand Down Expand Up @@ -423,13 +412,8 @@ impl<Pk: MiniscriptKey> Liftable<Pk> for Wpkh<Pk> {
}
}

impl<Pk> FromTree for Wpkh<Pk>
where
Pk: MiniscriptKey + FromStr,
Pk::Hash: FromStr,
<Pk as FromStr>::Err: ToString,
<<Pk as MiniscriptKey>::Hash as FromStr>::Err: ToString,
{
impl_from_tree!(
Wpkh<Pk>,
fn from_tree(top: &expression::Tree) -> Result<Self, Error> {
if top.name == "wpkh" && top.args.len() == 1 {
Ok(Wpkh::new(expression::terminal(&top.args[0], |pk| {
Expand All @@ -443,23 +427,17 @@ where
)))
}
}
}

impl<Pk> FromStr for Wpkh<Pk>
where
Pk: MiniscriptKey + FromStr,
Pk::Hash: FromStr,
<Pk as FromStr>::Err: ToString,
<<Pk as MiniscriptKey>::Hash as FromStr>::Err: ToString,
{
type Err = Error;
);

impl_from_str!(
Wpkh<Pk>,
type Err = Error;,
fn from_str(s: &str) -> Result<Self, Self::Err> {
let desc_str = verify_checksum(s)?;
let top = expression::Tree::from_str(desc_str)?;
Self::from_tree(&top)
}
}
);

impl<Pk: MiniscriptKey> ForEachKey<Pk> for Wpkh<Pk> {
fn for_each_key<'a, F: FnMut(ForEach<'a, Pk>) -> bool>(&'a self, mut pred: F) -> bool
Expand Down
25 changes: 7 additions & 18 deletions src/descriptor/sh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
//!
use core::fmt;
use core::str::FromStr;

use bitcoin::blockdata::script;
use bitcoin::{Address, Network, Script};
Expand Down Expand Up @@ -91,13 +90,8 @@ impl<Pk: MiniscriptKey> fmt::Display for Sh<Pk> {
}
}

impl<Pk> FromTree for Sh<Pk>
where
Pk: MiniscriptKey + FromStr,
Pk::Hash: FromStr,
<Pk as FromStr>::Err: ToString,
<<Pk as MiniscriptKey>::Hash as FromStr>::Err: ToString,
{
impl_from_tree!(
Sh<Pk>,
fn from_tree(top: &expression::Tree) -> Result<Self, Error> {
if top.name == "sh" && top.args.len() == 1 {
let top = &top.args[0];
Expand All @@ -120,22 +114,17 @@ where
)))
}
}
}
);

impl<Pk> FromStr for Sh<Pk>
where
Pk: MiniscriptKey + FromStr,
Pk::Hash: FromStr,
<Pk as FromStr>::Err: ToString,
<<Pk as MiniscriptKey>::Hash as FromStr>::Err: ToString,
{
type Err = Error;
impl_from_str!(
Sh<Pk>,
type Err = Error;,
fn from_str(s: &str) -> Result<Self, Self::Err> {
let desc_str = verify_checksum(s)?;
let top = expression::Tree::from_str(desc_str)?;
Self::from_tree(&top)
}
}
);

impl<Pk: MiniscriptKey> Sh<Pk> {
/// Get the Inner
Expand Down
Loading

0 comments on commit 5d44dc0

Please sign in to comment.