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}