Skip to content

Commit

Permalink
add blanket_traits module to replace very noisy trait definitions
Browse files Browse the repository at this point in the history
  • Loading branch information
apoelstra committed Mar 4, 2024
1 parent 4c4597e commit 5ec0f44
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 61 deletions.
72 changes: 72 additions & 0 deletions src/blanket_traits.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// SPDX-License-Identifier: CC0-1.0

//! Blanket Traits
//!
//! Because of this library's heavy use of generics, we often require complicated
//! trait bounds (especially when it comes to [`FromStr`] and its
//! associated error types). These blanket traits act as aliases, allowing easier
//! descriptions of them.
//!
//! While these traits are not sealed, they have blanket-impls which prevent you
//! from directly implementing them on your own types. The traits will be
//! automatically implemented if you satisfy all the bounds.
//!
use core::fmt;
use core::str::FromStr;

use crate::MiniscriptKey;

/// Blanket trait describing a key where all associated types implement `FromStr`,
/// and all `FromStr` errors can be displayed.
pub trait FromStrKey:
MiniscriptKey<
Sha256 = Self::_Sha256,
Hash256 = Self::_Hash256,
Ripemd160 = Self::_Ripemd160,
Hash160 = Self::_Hash160,
> + FromStr<Err = Self::_FromStrErr>
{
/// Dummy type. Do not use.
type _Sha256: FromStr<Err = Self::_Sha256FromStrErr>;
/// Dummy type. Do not use.
type _Sha256FromStrErr: fmt::Debug + fmt::Display;
/// Dummy type. Do not use.
type _Hash256: FromStr<Err = Self::_Hash256FromStrErr>;
/// Dummy type. Do not use.
type _Hash256FromStrErr: fmt::Debug + fmt::Display;
/// Dummy type. Do not use.
type _Ripemd160: FromStr<Err = Self::_Ripemd160FromStrErr>;
/// Dummy type. Do not use.
type _Ripemd160FromStrErr: fmt::Debug + fmt::Display;
/// Dummy type. Do not use.
type _Hash160: FromStr<Err = Self::_Hash160FromStrErr>;
/// Dummy type. Do not use.
type _Hash160FromStrErr: fmt::Debug + fmt::Display;
/// Dummy type. Do not use.
type _FromStrErr: fmt::Debug + fmt::Display;
}

impl<T> FromStrKey for T
where
Self: MiniscriptKey + FromStr,
<Self as MiniscriptKey>::Sha256: FromStr,
Self::Hash256: FromStr,
Self::Ripemd160: FromStr,
Self::Hash160: FromStr,
<Self as FromStr>::Err: fmt::Debug + fmt::Display,
<<Self as MiniscriptKey>::Sha256 as FromStr>::Err: fmt::Debug + fmt::Display,
<Self::Hash256 as FromStr>::Err: fmt::Debug + fmt::Display,
<Self::Ripemd160 as FromStr>::Err: fmt::Debug + fmt::Display,
<Self::Hash160 as FromStr>::Err: fmt::Debug + fmt::Display,
{
type _Sha256 = <T as MiniscriptKey>::Sha256;
type _Sha256FromStrErr = <<T as MiniscriptKey>::Sha256 as FromStr>::Err;
type _Hash256 = <T as MiniscriptKey>::Hash256;
type _Hash256FromStrErr = <<T as MiniscriptKey>::Hash256 as FromStr>::Err;
type _Ripemd160 = <T as MiniscriptKey>::Ripemd160;
type _Ripemd160FromStrErr = <<T as MiniscriptKey>::Ripemd160 as FromStr>::Err;
type _Hash160 = <T as MiniscriptKey>::Hash160;
type _Hash160FromStrErr = <<T as MiniscriptKey>::Hash160 as FromStr>::Err;
type _FromStrErr = <T as FromStr>::Err;
}
2 changes: 1 addition & 1 deletion src/descriptor/sortedmulti.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> SortedMultiVec<Pk, Ctx> {
pub fn from_tree(tree: &expression::Tree) -> Result<Self, Error>
where
Pk: FromStr,
<Pk as FromStr>::Err: ToString,
<Pk as FromStr>::Err: fmt::Display,
{
if tree.args.is_empty() {
return Err(errstr("no arguments given for sortedmulti"));
Expand Down
3 changes: 2 additions & 1 deletion src/expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

//! # Function-like Expression Language
//!
use core::fmt;
use core::str::FromStr;

use crate::prelude::*;
Expand Down Expand Up @@ -218,7 +219,7 @@ pub fn parse_num(s: &str) -> Result<u32, Error> {
pub fn terminal<T, F, Err>(term: &Tree, convert: F) -> Result<T, Error>
where
F: FnOnce(&str) -> Result<T, Err>,
Err: ToString,
Err: fmt::Display,
{
if term.args.is_empty() {
convert(term.name).map_err(|e| Error::Unexpected(e.to_string()))
Expand Down
4 changes: 3 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ mod macros;
#[macro_use]
mod pub_macros;

mod blanket_traits;
pub mod descriptor;
pub mod expression;
pub mod interpreter;
Expand All @@ -139,6 +140,7 @@ use bitcoin::hex::DisplayHex;
use bitcoin::locktime::absolute;
use bitcoin::{script, Opcode};

pub use crate::blanket_traits::FromStrKey;
pub use crate::descriptor::{DefiniteDescriptorKey, Descriptor, DescriptorPublicKey};
pub use crate::interpreter::Interpreter;
pub use crate::miniscript::analyzable::{AnalysisError, ExtParams};
Expand All @@ -148,7 +150,7 @@ pub use crate::miniscript::satisfy::{Preimage32, Satisfier};
pub use crate::miniscript::{hash256, Miniscript};
use crate::prelude::*;

///Public key trait which can be converted to Hash type
/// Public key trait which can be converted to Hash type
pub trait MiniscriptKey: Clone + Eq + Ord + fmt::Debug + fmt::Display + hash::Hash {
/// Returns true if the pubkey is uncompressed. Defaults to `false`.
fn is_uncompressed(&self) -> bool { false }
Expand Down
63 changes: 5 additions & 58 deletions src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,7 @@ macro_rules! impl_from_tree {
) => {
impl<Pk $(, $gen)*> $crate::expression::FromTree for $name
where
Pk: MiniscriptKey + core::str::FromStr,
Pk::Sha256: core::str::FromStr,
Pk::Hash256: core::str::FromStr,
Pk::Ripemd160: core::str::FromStr,
Pk::Hash160: core::str::FromStr,
<Pk as core::str::FromStr>::Err: $crate::prelude::ToString,
<<Pk as MiniscriptKey>::Sha256 as core::str::FromStr>::Err: $crate::prelude::ToString,
<<Pk as MiniscriptKey>::Hash256 as core::str::FromStr>::Err: $crate::prelude::ToString,
<<Pk as MiniscriptKey>::Ripemd160 as core::str::FromStr>::Err: $crate::prelude::ToString,
<<Pk as MiniscriptKey>::Hash160 as core::str::FromStr>::Err: $crate::prelude::ToString,
Pk: $crate::FromStrKey,
$($gen : $gen_con,)*
{

Expand All @@ -60,16 +51,7 @@ macro_rules! impl_from_str {
) => {
impl<Pk $(, $gen)*> core::str::FromStr for $name
where
Pk: MiniscriptKey + core::str::FromStr,
Pk::Sha256: core::str::FromStr,
Pk::Hash256: core::str::FromStr,
Pk::Ripemd160: core::str::FromStr,
Pk::Hash160: core::str::FromStr,
<Pk as core::str::FromStr>::Err: $crate::prelude::ToString,
<<Pk as MiniscriptKey>::Sha256 as core::str::FromStr>::Err: $crate::prelude::ToString,
<<Pk as MiniscriptKey>::Hash256 as core::str::FromStr>::Err: $crate::prelude::ToString,
<<Pk as MiniscriptKey>::Ripemd160 as core::str::FromStr>::Err: $crate::prelude::ToString,
<<Pk as MiniscriptKey>::Hash160 as core::str::FromStr>::Err: $crate::prelude::ToString,
Pk: $crate::FromStrKey,
$($gen : $gen_con,)*
{
type Err = $err_ty;
Expand All @@ -92,16 +74,7 @@ macro_rules! impl_block_str {
) => {
impl<Pk $(, $gen)*> $name
where
Pk: MiniscriptKey + core::str::FromStr,
Pk::Sha256: core::str::FromStr,
Pk::Hash256: core::str::FromStr,
Pk::Ripemd160: core::str::FromStr,
Pk::Hash160: core::str::FromStr,
<Pk as core::str::FromStr>::Err: $crate::prelude::ToString,
<<Pk as MiniscriptKey>::Sha256 as core::str::FromStr>::Err: $crate::prelude::ToString,
<<Pk as MiniscriptKey>::Hash256 as core::str::FromStr>::Err: $crate::prelude::ToString,
<<Pk as MiniscriptKey>::Ripemd160 as core::str::FromStr>::Err: $crate::prelude::ToString,
<<Pk as MiniscriptKey>::Hash160 as core::str::FromStr>::Err: $crate::prelude::ToString,
Pk: $crate::FromStrKey,
$($gen : $gen_con,)*
{
$(#[$meta])*
Expand All @@ -119,20 +92,7 @@ macro_rules! serde_string_impl_pk {
#[cfg(feature = "serde")]
impl<'de, Pk $(, $gen)*> $crate::serde::Deserialize<'de> for $name<Pk $(, $gen)*>
where
Pk: $crate::MiniscriptKey + core::str::FromStr,
Pk::Sha256: core::str::FromStr,
Pk::Hash256: core::str::FromStr,
Pk::Ripemd160: core::str::FromStr,
Pk::Hash160: core::str::FromStr,
<Pk as core::str::FromStr>::Err: core::fmt::Display,
<<Pk as $crate::MiniscriptKey>::Sha256 as core::str::FromStr>::Err:
core::fmt::Display,
<<Pk as $crate::MiniscriptKey>::Hash256 as core::str::FromStr>::Err:
core::fmt::Display,
<<Pk as $crate::MiniscriptKey>::Ripemd160 as core::str::FromStr>::Err:
core::fmt::Display,
<<Pk as $crate::MiniscriptKey>::Hash160 as core::str::FromStr>::Err:
core::fmt::Display,
Pk: $crate::FromStrKey,
$($gen : $gen_con,)*
{
fn deserialize<D>(deserializer: D) -> Result<$name<Pk $(, $gen)*>, D::Error>
Expand All @@ -147,20 +107,7 @@ macro_rules! serde_string_impl_pk {
struct Visitor<Pk $(, $gen)*>(PhantomData<(Pk $(, $gen)*)>);
impl<'de, Pk $(, $gen)*> $crate::serde::de::Visitor<'de> for Visitor<Pk $(, $gen)*>
where
Pk: $crate::MiniscriptKey + core::str::FromStr,
Pk::Sha256: core::str::FromStr,
Pk::Hash256: core::str::FromStr,
Pk::Ripemd160: core::str::FromStr,
Pk::Hash160: core::str::FromStr,
<Pk as core::str::FromStr>::Err: core::fmt::Display,
<<Pk as $crate::MiniscriptKey>::Sha256 as core::str::FromStr>::Err:
core::fmt::Display,
<<Pk as $crate::MiniscriptKey>::Hash256 as core::str::FromStr>::Err:
core::fmt::Display,
<<Pk as $crate::MiniscriptKey>::Ripemd160 as core::str::FromStr>::Err:
core::fmt::Display,
<<Pk as $crate::MiniscriptKey>::Hash160 as core::str::FromStr>::Err:
core::fmt::Display,
Pk: $crate::FromStrKey,
$($gen: $gen_con,)*
{
type Value = $name<Pk $(, $gen)*>;
Expand Down

0 comments on commit 5ec0f44

Please sign in to comment.