rust-bitcoin-unsafe-fast/src/util/psbt/macros.rs

158 lines
5.7 KiB
Rust
Raw Normal View History

// Rust Bitcoin Library
// Written by
// The Rust Bitcoin developers
//
// To the extent possible under law, the author(s) have dedicated all
// copyright and related and neighboring rights to this software to
// the public domain worldwide. This software is distributed without
// any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication
// along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
//
#[allow(unused_macros)]
macro_rules! hex_psbt {
2020-01-25 04:21:57 +00:00
($s:expr) => { $crate::consensus::deserialize(&<Vec<u8> as $crate::hashes::hex::FromHex>::from_hex($s).unwrap()) };
}
macro_rules! merge {
($thing:ident, $slf:ident, $other:ident) => {
if let (&None, Some($thing)) = (&$slf.$thing, $other.$thing) {
$slf.$thing = Some($thing);
}
};
}
macro_rules! impl_psbt_de_serialize {
($thing:ty) => {
impl_psbt_serialize!($thing);
impl_psbt_deserialize!($thing);
};
}
macro_rules! impl_psbt_deserialize {
($thing:ty) => {
2020-01-25 04:21:57 +00:00
impl $crate::util::psbt::serialize::Deserialize for $thing {
fn deserialize(bytes: &[u8]) -> Result<Self, $crate::consensus::encode::Error> {
$crate::consensus::deserialize(&bytes[..])
}
}
};
}
macro_rules! impl_psbt_serialize {
($thing:ty) => {
2020-01-25 04:21:57 +00:00
impl $crate::util::psbt::serialize::Serialize for $thing {
fn serialize(&self) -> Vec<u8> {
2020-01-25 04:21:57 +00:00
$crate::consensus::serialize(self)
}
}
};
}
macro_rules! impl_psbtmap_consensus_encoding {
($thing:ty) => {
2020-01-25 04:21:57 +00:00
impl $crate::consensus::Encodable for $thing {
2020-01-25 04:43:39 +00:00
fn consensus_encode<S: ::std::io::Write>(
&self,
mut s: S,
2020-01-25 04:21:57 +00:00
) -> Result<usize, $crate::consensus::encode::Error> {
let mut len = 0;
2020-01-25 04:21:57 +00:00
for pair in $crate::util::psbt::Map::get_pairs(self)? {
len += $crate::consensus::Encodable::consensus_encode(
&pair,
&mut s,
)?;
}
2020-01-25 04:21:57 +00:00
Ok(len + $crate::consensus::Encodable::consensus_encode(&0x00_u8, s)?)
}
}
};
}
macro_rules! impl_psbtmap_consensus_decoding {
($thing:ty) => {
2020-01-25 04:21:57 +00:00
impl $crate::consensus::Decodable for $thing {
2020-01-25 04:43:39 +00:00
fn consensus_decode<D: ::std::io::Read>(
mut d: D,
2020-01-25 04:21:57 +00:00
) -> Result<Self, $crate::consensus::encode::Error> {
2020-01-25 04:43:39 +00:00
let mut rv: Self = ::std::default::Default::default();
loop {
2020-01-25 04:21:57 +00:00
match $crate::consensus::Decodable::consensus_decode(&mut d) {
Ok(pair) => $crate::util::psbt::Map::insert_pair(&mut rv, pair)?,
Err($crate::consensus::encode::Error::Psbt($crate::util::psbt::Error::NoMorePairs)) => return Ok(rv),
Err(e) => return Err(e),
}
}
}
}
};
}
macro_rules! impl_psbtmap_consensus_enc_dec_oding {
($thing:ty) => {
impl_psbtmap_consensus_decoding!($thing);
impl_psbtmap_consensus_encoding!($thing);
};
}
#[cfg_attr(rustfmt, rustfmt_skip)]
macro_rules! impl_psbt_insert_pair {
($slf:ident.$unkeyed_name:ident <= <$raw_key:ident: _>|<$raw_value:ident: $unkeyed_value_type:ty>) => {
if $raw_key.key.is_empty() {
2019-08-05 19:41:07 +00:00
if $slf.$unkeyed_name.is_none() {
2020-01-25 04:21:57 +00:00
let val: $unkeyed_value_type = $crate::util::psbt::serialize::Deserialize::deserialize(&$raw_value)?;
$slf.$unkeyed_name = Some(val)
} else {
2020-01-25 04:21:57 +00:00
return Err($crate::util::psbt::Error::DuplicateKey($raw_key).into());
}
} else {
2020-01-25 04:21:57 +00:00
return Err($crate::util::psbt::Error::InvalidKey($raw_key).into());
}
};
($slf:ident.$keyed_name:ident <= <$raw_key:ident: $keyed_key_type:ty>|<$raw_value:ident: $keyed_value_type:ty>) => {
if !$raw_key.key.is_empty() {
2020-01-25 04:21:57 +00:00
let key_val: $keyed_key_type = $crate::util::psbt::serialize::Deserialize::deserialize(&$raw_key.key)?;
match $slf.$keyed_name.entry(key_val) {
::std::collections::btree_map::Entry::Vacant(empty_key) => {
2020-01-25 04:21:57 +00:00
let val: $keyed_value_type = $crate::util::psbt::serialize::Deserialize::deserialize(&$raw_value)?;
empty_key.insert(val);
}
2020-01-25 04:21:57 +00:00
::std::collections::btree_map::Entry::Occupied(_) => return Err($crate::util::psbt::Error::DuplicateKey($raw_key).into()),
}
} else {
2020-01-25 04:21:57 +00:00
return Err($crate::util::psbt::Error::InvalidKey($raw_key).into());
}
};
}
#[cfg_attr(rustfmt, rustfmt_skip)]
macro_rules! impl_psbt_get_pair {
($rv:ident.push($slf:ident.$unkeyed_name:ident as <$unkeyed_typeval:expr, _>|<$unkeyed_value_type:ty>)) => {
if let Some(ref $unkeyed_name) = $slf.$unkeyed_name {
2020-01-25 04:21:57 +00:00
$rv.push($crate::util::psbt::raw::Pair {
key: $crate::util::psbt::raw::Key {
type_value: $unkeyed_typeval,
key: vec![],
},
2020-01-25 04:21:57 +00:00
value: $crate::util::psbt::serialize::Serialize::serialize($unkeyed_name),
});
}
};
($rv:ident.push($slf:ident.$keyed_name:ident as <$keyed_typeval:expr, $keyed_key_type:ty>|<$keyed_value_type:ty>)) => {
for (key, val) in &$slf.$keyed_name {
2020-01-25 04:21:57 +00:00
$rv.push($crate::util::psbt::raw::Pair {
key: $crate::util::psbt::raw::Key {
type_value: $keyed_typeval,
2020-01-25 04:21:57 +00:00
key: $crate::util::psbt::serialize::Serialize::serialize(key),
},
2020-01-25 04:21:57 +00:00
value: $crate::util::psbt::serialize::Serialize::serialize(val),
});
}
};
}