Skip to content

Commit 5ec0f44

Browse files
committed
add blanket_traits module to replace very noisy trait definitions
1 parent 4c4597e commit 5ec0f44

File tree

5 files changed

+83
-61
lines changed

5 files changed

+83
-61
lines changed

src/blanket_traits.rs

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
// SPDX-License-Identifier: CC0-1.0
2+
3+
//! Blanket Traits
4+
//!
5+
//! Because of this library's heavy use of generics, we often require complicated
6+
//! trait bounds (especially when it comes to [`FromStr`] and its
7+
//! associated error types). These blanket traits act as aliases, allowing easier
8+
//! descriptions of them.
9+
//!
10+
//! While these traits are not sealed, they have blanket-impls which prevent you
11+
//! from directly implementing them on your own types. The traits will be
12+
//! automatically implemented if you satisfy all the bounds.
13+
//!
14+
15+
use core::fmt;
16+
use core::str::FromStr;
17+
18+
use crate::MiniscriptKey;
19+
20+
/// Blanket trait describing a key where all associated types implement `FromStr`,
21+
/// and all `FromStr` errors can be displayed.
22+
pub trait FromStrKey:
23+
MiniscriptKey<
24+
Sha256 = Self::_Sha256,
25+
Hash256 = Self::_Hash256,
26+
Ripemd160 = Self::_Ripemd160,
27+
Hash160 = Self::_Hash160,
28+
> + FromStr<Err = Self::_FromStrErr>
29+
{
30+
/// Dummy type. Do not use.
31+
type _Sha256: FromStr<Err = Self::_Sha256FromStrErr>;
32+
/// Dummy type. Do not use.
33+
type _Sha256FromStrErr: fmt::Debug + fmt::Display;
34+
/// Dummy type. Do not use.
35+
type _Hash256: FromStr<Err = Self::_Hash256FromStrErr>;
36+
/// Dummy type. Do not use.
37+
type _Hash256FromStrErr: fmt::Debug + fmt::Display;
38+
/// Dummy type. Do not use.
39+
type _Ripemd160: FromStr<Err = Self::_Ripemd160FromStrErr>;
40+
/// Dummy type. Do not use.
41+
type _Ripemd160FromStrErr: fmt::Debug + fmt::Display;
42+
/// Dummy type. Do not use.
43+
type _Hash160: FromStr<Err = Self::_Hash160FromStrErr>;
44+
/// Dummy type. Do not use.
45+
type _Hash160FromStrErr: fmt::Debug + fmt::Display;
46+
/// Dummy type. Do not use.
47+
type _FromStrErr: fmt::Debug + fmt::Display;
48+
}
49+
50+
impl<T> FromStrKey for T
51+
where
52+
Self: MiniscriptKey + FromStr,
53+
<Self as MiniscriptKey>::Sha256: FromStr,
54+
Self::Hash256: FromStr,
55+
Self::Ripemd160: FromStr,
56+
Self::Hash160: FromStr,
57+
<Self as FromStr>::Err: fmt::Debug + fmt::Display,
58+
<<Self as MiniscriptKey>::Sha256 as FromStr>::Err: fmt::Debug + fmt::Display,
59+
<Self::Hash256 as FromStr>::Err: fmt::Debug + fmt::Display,
60+
<Self::Ripemd160 as FromStr>::Err: fmt::Debug + fmt::Display,
61+
<Self::Hash160 as FromStr>::Err: fmt::Debug + fmt::Display,
62+
{
63+
type _Sha256 = <T as MiniscriptKey>::Sha256;
64+
type _Sha256FromStrErr = <<T as MiniscriptKey>::Sha256 as FromStr>::Err;
65+
type _Hash256 = <T as MiniscriptKey>::Hash256;
66+
type _Hash256FromStrErr = <<T as MiniscriptKey>::Hash256 as FromStr>::Err;
67+
type _Ripemd160 = <T as MiniscriptKey>::Ripemd160;
68+
type _Ripemd160FromStrErr = <<T as MiniscriptKey>::Ripemd160 as FromStr>::Err;
69+
type _Hash160 = <T as MiniscriptKey>::Hash160;
70+
type _Hash160FromStrErr = <<T as MiniscriptKey>::Hash160 as FromStr>::Err;
71+
type _FromStrErr = <T as FromStr>::Err;
72+
}

src/descriptor/sortedmulti.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> SortedMultiVec<Pk, Ctx> {
6060
pub fn from_tree(tree: &expression::Tree) -> Result<Self, Error>
6161
where
6262
Pk: FromStr,
63-
<Pk as FromStr>::Err: ToString,
63+
<Pk as FromStr>::Err: fmt::Display,
6464
{
6565
if tree.args.is_empty() {
6666
return Err(errstr("no arguments given for sortedmulti"));

src/expression.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
//! # Function-like Expression Language
44
//!
5+
use core::fmt;
56
use core::str::FromStr;
67

78
use crate::prelude::*;
@@ -218,7 +219,7 @@ pub fn parse_num(s: &str) -> Result<u32, Error> {
218219
pub fn terminal<T, F, Err>(term: &Tree, convert: F) -> Result<T, Error>
219220
where
220221
F: FnOnce(&str) -> Result<T, Err>,
221-
Err: ToString,
222+
Err: fmt::Display,
222223
{
223224
if term.args.is_empty() {
224225
convert(term.name).map_err(|e| Error::Unexpected(e.to_string()))

src/lib.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ mod macros;
117117
#[macro_use]
118118
mod pub_macros;
119119

120+
mod blanket_traits;
120121
pub mod descriptor;
121122
pub mod expression;
122123
pub mod interpreter;
@@ -139,6 +140,7 @@ use bitcoin::hex::DisplayHex;
139140
use bitcoin::locktime::absolute;
140141
use bitcoin::{script, Opcode};
141142

143+
pub use crate::blanket_traits::FromStrKey;
142144
pub use crate::descriptor::{DefiniteDescriptorKey, Descriptor, DescriptorPublicKey};
143145
pub use crate::interpreter::Interpreter;
144146
pub use crate::miniscript::analyzable::{AnalysisError, ExtParams};
@@ -148,7 +150,7 @@ pub use crate::miniscript::satisfy::{Preimage32, Satisfier};
148150
pub use crate::miniscript::{hash256, Miniscript};
149151
use crate::prelude::*;
150152

151-
///Public key trait which can be converted to Hash type
153+
/// Public key trait which can be converted to Hash type
152154
pub trait MiniscriptKey: Clone + Eq + Ord + fmt::Debug + fmt::Display + hash::Hash {
153155
/// Returns true if the pubkey is uncompressed. Defaults to `false`.
154156
fn is_uncompressed(&self) -> bool { false }

src/macros.rs

+5-58
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,7 @@ macro_rules! impl_from_tree {
2828
) => {
2929
impl<Pk $(, $gen)*> $crate::expression::FromTree for $name
3030
where
31-
Pk: MiniscriptKey + core::str::FromStr,
32-
Pk::Sha256: core::str::FromStr,
33-
Pk::Hash256: core::str::FromStr,
34-
Pk::Ripemd160: core::str::FromStr,
35-
Pk::Hash160: core::str::FromStr,
36-
<Pk as core::str::FromStr>::Err: $crate::prelude::ToString,
37-
<<Pk as MiniscriptKey>::Sha256 as core::str::FromStr>::Err: $crate::prelude::ToString,
38-
<<Pk as MiniscriptKey>::Hash256 as core::str::FromStr>::Err: $crate::prelude::ToString,
39-
<<Pk as MiniscriptKey>::Ripemd160 as core::str::FromStr>::Err: $crate::prelude::ToString,
40-
<<Pk as MiniscriptKey>::Hash160 as core::str::FromStr>::Err: $crate::prelude::ToString,
31+
Pk: $crate::FromStrKey,
4132
$($gen : $gen_con,)*
4233
{
4334

@@ -60,16 +51,7 @@ macro_rules! impl_from_str {
6051
) => {
6152
impl<Pk $(, $gen)*> core::str::FromStr for $name
6253
where
63-
Pk: MiniscriptKey + core::str::FromStr,
64-
Pk::Sha256: core::str::FromStr,
65-
Pk::Hash256: core::str::FromStr,
66-
Pk::Ripemd160: core::str::FromStr,
67-
Pk::Hash160: core::str::FromStr,
68-
<Pk as core::str::FromStr>::Err: $crate::prelude::ToString,
69-
<<Pk as MiniscriptKey>::Sha256 as core::str::FromStr>::Err: $crate::prelude::ToString,
70-
<<Pk as MiniscriptKey>::Hash256 as core::str::FromStr>::Err: $crate::prelude::ToString,
71-
<<Pk as MiniscriptKey>::Ripemd160 as core::str::FromStr>::Err: $crate::prelude::ToString,
72-
<<Pk as MiniscriptKey>::Hash160 as core::str::FromStr>::Err: $crate::prelude::ToString,
54+
Pk: $crate::FromStrKey,
7355
$($gen : $gen_con,)*
7456
{
7557
type Err = $err_ty;
@@ -92,16 +74,7 @@ macro_rules! impl_block_str {
9274
) => {
9375
impl<Pk $(, $gen)*> $name
9476
where
95-
Pk: MiniscriptKey + core::str::FromStr,
96-
Pk::Sha256: core::str::FromStr,
97-
Pk::Hash256: core::str::FromStr,
98-
Pk::Ripemd160: core::str::FromStr,
99-
Pk::Hash160: core::str::FromStr,
100-
<Pk as core::str::FromStr>::Err: $crate::prelude::ToString,
101-
<<Pk as MiniscriptKey>::Sha256 as core::str::FromStr>::Err: $crate::prelude::ToString,
102-
<<Pk as MiniscriptKey>::Hash256 as core::str::FromStr>::Err: $crate::prelude::ToString,
103-
<<Pk as MiniscriptKey>::Ripemd160 as core::str::FromStr>::Err: $crate::prelude::ToString,
104-
<<Pk as MiniscriptKey>::Hash160 as core::str::FromStr>::Err: $crate::prelude::ToString,
77+
Pk: $crate::FromStrKey,
10578
$($gen : $gen_con,)*
10679
{
10780
$(#[$meta])*
@@ -119,20 +92,7 @@ macro_rules! serde_string_impl_pk {
11992
#[cfg(feature = "serde")]
12093
impl<'de, Pk $(, $gen)*> $crate::serde::Deserialize<'de> for $name<Pk $(, $gen)*>
12194
where
122-
Pk: $crate::MiniscriptKey + core::str::FromStr,
123-
Pk::Sha256: core::str::FromStr,
124-
Pk::Hash256: core::str::FromStr,
125-
Pk::Ripemd160: core::str::FromStr,
126-
Pk::Hash160: core::str::FromStr,
127-
<Pk as core::str::FromStr>::Err: core::fmt::Display,
128-
<<Pk as $crate::MiniscriptKey>::Sha256 as core::str::FromStr>::Err:
129-
core::fmt::Display,
130-
<<Pk as $crate::MiniscriptKey>::Hash256 as core::str::FromStr>::Err:
131-
core::fmt::Display,
132-
<<Pk as $crate::MiniscriptKey>::Ripemd160 as core::str::FromStr>::Err:
133-
core::fmt::Display,
134-
<<Pk as $crate::MiniscriptKey>::Hash160 as core::str::FromStr>::Err:
135-
core::fmt::Display,
95+
Pk: $crate::FromStrKey,
13696
$($gen : $gen_con,)*
13797
{
13898
fn deserialize<D>(deserializer: D) -> Result<$name<Pk $(, $gen)*>, D::Error>
@@ -147,20 +107,7 @@ macro_rules! serde_string_impl_pk {
147107
struct Visitor<Pk $(, $gen)*>(PhantomData<(Pk $(, $gen)*)>);
148108
impl<'de, Pk $(, $gen)*> $crate::serde::de::Visitor<'de> for Visitor<Pk $(, $gen)*>
149109
where
150-
Pk: $crate::MiniscriptKey + core::str::FromStr,
151-
Pk::Sha256: core::str::FromStr,
152-
Pk::Hash256: core::str::FromStr,
153-
Pk::Ripemd160: core::str::FromStr,
154-
Pk::Hash160: core::str::FromStr,
155-
<Pk as core::str::FromStr>::Err: core::fmt::Display,
156-
<<Pk as $crate::MiniscriptKey>::Sha256 as core::str::FromStr>::Err:
157-
core::fmt::Display,
158-
<<Pk as $crate::MiniscriptKey>::Hash256 as core::str::FromStr>::Err:
159-
core::fmt::Display,
160-
<<Pk as $crate::MiniscriptKey>::Ripemd160 as core::str::FromStr>::Err:
161-
core::fmt::Display,
162-
<<Pk as $crate::MiniscriptKey>::Hash160 as core::str::FromStr>::Err:
163-
core::fmt::Display,
110+
Pk: $crate::FromStrKey,
164111
$($gen: $gen_con,)*
165112
{
166113
type Value = $name<Pk $(, $gen)*>;

0 commit comments

Comments
 (0)