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