elements_miniscript/pub_macros.rs
1// SPDX-License-Identifier: CC0-1.0
2
3//! Macros exported by the miniscript crate
4//!
5
6/// Macro for failing translation for other associated types.
7/// Handy for testing String -> concrete keys as we don't want to specify these
8/// functions repeatedly.
9///
10/// This macro is handy when dealing with scripts that are only contain keys.
11/// See also [`crate::translate_hash_clone`]
12/// ```rust
13/// use elements_miniscript as miniscript;
14/// use miniscript::{bitcoin::PublicKey, policy::concrete::Policy, Translator, hash256};
15/// use std::str::FromStr;
16/// use miniscript::translate_hash_fail;
17/// use std::collections::HashMap;
18/// use miniscript::bitcoin::hashes::{sha256, hash160, ripemd160};
19/// let alice_key = "0270cf3c71f65a3d93d285d9149fddeeb638f87a2d4d8cf16c525f71c417439777";
20/// let bob_key = "02f43b15c50a436f5335dbea8a64dd3b4e63e34c3b50c42598acb5f4f336b5d2fb";
21/// let placeholder_policy = Policy::<String>::from_str("and(pk(alice_key),pk(bob_key))").unwrap();
22///
23/// // Information to translator abstract String type keys to concrete bitcoin::PublicKey.
24/// // In practice, wallets would map from String key names to BIP32 keys
25/// struct StrPkTranslator {
26/// pk_map: HashMap<String, bitcoin::PublicKey>
27/// }
28///
29/// // If we also wanted to provide mapping of other associated types(sha256, older etc),
30/// // we would use the general Translator Trait.
31/// impl Translator<String, bitcoin::PublicKey, ()> for StrPkTranslator {
32/// // Provides the translation public keys P -> Q
33/// fn pk(&mut self, pk: &String) -> Result<bitcoin::PublicKey, ()> {
34/// self.pk_map.get(pk).copied().ok_or(()) // Dummy Err
35/// }
36///
37/// // Fail for hash types
38/// translate_hash_fail!(String, bitcoin::PublicKey, ());
39/// }
40///
41/// let mut pk_map = HashMap::new();
42/// pk_map.insert(String::from("alice_key"), bitcoin::PublicKey::from_str(alice_key).unwrap());
43/// pk_map.insert(String::from("bob_key"), bitcoin::PublicKey::from_str(bob_key).unwrap());
44/// let mut t = StrPkTranslator { pk_map: pk_map };
45/// ```
46#[macro_export]
47macro_rules! translate_hash_fail {
48 ($source: ty, $target:ty, $error_ty: ty) => {
49 fn sha256(
50 &mut self,
51 _sha256: &<$source as $crate::MiniscriptKey>::Sha256,
52 ) -> Result<<$target as $crate::MiniscriptKey>::Sha256, $error_ty> {
53 panic!("Called sha256 on translate_only_pk")
54 }
55
56 fn hash256(
57 &mut self,
58 _hash256: &<$source as $crate::MiniscriptKey>::Hash256,
59 ) -> Result<<$target as $crate::MiniscriptKey>::Hash256, $error_ty> {
60 panic!("Called hash256 on translate_only_pk")
61 }
62
63 fn hash160(
64 &mut self,
65 _hash160: &<$source as $crate::MiniscriptKey>::Hash160,
66 ) -> Result<<$target as $crate::MiniscriptKey>::Hash160, $error_ty> {
67 panic!("Called hash160 on translate_only_pk")
68 }
69
70 fn ripemd160(
71 &mut self,
72 _ripemd160: &<$source as $crate::MiniscriptKey>::Ripemd160,
73 ) -> Result<<$target as $crate::MiniscriptKey>::Ripemd160, $error_ty> {
74 panic!("Called ripemd160 on translate_only_pk")
75 }
76 };
77}
78
79/// Macro for translation of associated types where the associated type is the same
80/// Handy for Derived -> concrete keys where the associated types are the same.
81///
82/// Writing the complete translator trait is tedious. This macro is handy when
83/// we are not trying the associated types for hash160, ripemd160, hash256 and
84/// sha256.
85///
86/// See also [`crate::translate_hash_fail`]
87#[macro_export]
88macro_rules! translate_hash_clone {
89 ($source: ty, $target:ty, $error_ty: ty) => {
90 fn sha256(
91 &mut self,
92 sha256: &<$source as $crate::MiniscriptKey>::Sha256,
93 ) -> Result<<$target as $crate::MiniscriptKey>::Sha256, $error_ty> {
94 Ok((*sha256).into())
95 }
96
97 fn hash256(
98 &mut self,
99 hash256: &<$source as $crate::MiniscriptKey>::Hash256,
100 ) -> Result<<$target as $crate::MiniscriptKey>::Hash256, $error_ty> {
101 Ok((*hash256).into())
102 }
103
104 fn hash160(
105 &mut self,
106 hash160: &<$source as $crate::MiniscriptKey>::Hash160,
107 ) -> Result<<$target as $crate::MiniscriptKey>::Hash160, $error_ty> {
108 Ok((*hash160).into())
109 }
110
111 fn ripemd160(
112 &mut self,
113 ripemd160: &<$source as $crate::MiniscriptKey>::Ripemd160,
114 ) -> Result<<$target as $crate::MiniscriptKey>::Ripemd160, $error_ty> {
115 Ok((*ripemd160).into())
116 }
117 };
118}