miniscript_debug/
pub_macros.rs

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