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