bitcoin/util/psbt/
macros.rs1#[allow(unused_macros)]
16macro_rules! hex_psbt {
17 ($s:expr) => { $crate::consensus::deserialize(&<Vec<u8> as $crate::hashes::hex::FromHex>::from_hex($s).unwrap()) };
18}
19
20macro_rules! merge {
21 ($thing:ident, $slf:ident, $other:ident) => {
22 if let (&None, Some($thing)) = (&$slf.$thing, $other.$thing) {
23 $slf.$thing = Some($thing);
24 }
25 };
26}
27
28macro_rules! impl_psbt_de_serialize {
29 ($thing:ty) => {
30 impl_psbt_serialize!($thing);
31 impl_psbt_deserialize!($thing);
32 };
33}
34
35macro_rules! impl_psbt_deserialize {
36 ($thing:ty) => {
37 impl $crate::util::psbt::serialize::Deserialize for $thing {
38 fn deserialize(bytes: &[u8]) -> Result<Self, $crate::consensus::encode::Error> {
39 $crate::consensus::deserialize(&bytes[..])
40 }
41 }
42 };
43}
44
45macro_rules! impl_psbt_serialize {
46 ($thing:ty) => {
47 impl $crate::util::psbt::serialize::Serialize for $thing {
48 fn serialize(&self) -> Vec<u8> {
49 $crate::consensus::serialize(self)
50 }
51 }
52 };
53}
54
55macro_rules! impl_psbtmap_consensus_encoding {
56 ($thing:ty) => {
57 impl $crate::consensus::Encodable for $thing {
58 fn consensus_encode<S: ::std::io::Write>(
59 &self,
60 mut s: S,
61 ) -> Result<usize, ::std::io::Error> {
62 let mut len = 0;
63 for pair in $crate::util::psbt::Map::get_pairs(self)? {
64 len += $crate::consensus::Encodable::consensus_encode(
65 &pair,
66 &mut s,
67 )?;
68 }
69
70 Ok(len + $crate::consensus::Encodable::consensus_encode(&0x00_u8, s)?)
71 }
72 }
73 };
74}
75
76macro_rules! impl_psbtmap_consensus_decoding {
77 ($thing:ty) => {
78 impl $crate::consensus::Decodable for $thing {
79 fn consensus_decode<D: ::std::io::Read>(
80 mut d: D,
81 ) -> Result<Self, $crate::consensus::encode::Error> {
82 let mut rv: Self = ::std::default::Default::default();
83
84 loop {
85 match $crate::consensus::Decodable::consensus_decode(&mut d) {
86 Ok(pair) => $crate::util::psbt::Map::insert_pair(&mut rv, pair)?,
87 Err($crate::consensus::encode::Error::Psbt($crate::util::psbt::Error::NoMorePairs)) => return Ok(rv),
88 Err(e) => return Err(e),
89 }
90 }
91 }
92 }
93 };
94}
95
96macro_rules! impl_psbtmap_consensus_enc_dec_oding {
97 ($thing:ty) => {
98 impl_psbtmap_consensus_decoding!($thing);
99 impl_psbtmap_consensus_encoding!($thing);
100 };
101}
102
103#[cfg_attr(rustfmt, rustfmt_skip)]
104macro_rules! impl_psbt_insert_pair {
105 ($slf:ident.$unkeyed_name:ident <= <$raw_key:ident: _>|<$raw_value:ident: $unkeyed_value_type:ty>) => {
106 if $raw_key.key.is_empty() {
107 if $slf.$unkeyed_name.is_none() {
108 let val: $unkeyed_value_type = $crate::util::psbt::serialize::Deserialize::deserialize(&$raw_value)?;
109 $slf.$unkeyed_name = Some(val)
110 } else {
111 return Err($crate::util::psbt::Error::DuplicateKey($raw_key).into());
112 }
113 } else {
114 return Err($crate::util::psbt::Error::InvalidKey($raw_key).into());
115 }
116 };
117 ($slf:ident.$keyed_name:ident <= <$raw_key:ident: $keyed_key_type:ty>|<$raw_value:ident: $keyed_value_type:ty>) => {
118 if !$raw_key.key.is_empty() {
119 let key_val: $keyed_key_type = $crate::util::psbt::serialize::Deserialize::deserialize(&$raw_key.key)?;
120 match $slf.$keyed_name.entry(key_val) {
121 ::std::collections::btree_map::Entry::Vacant(empty_key) => {
122 let val: $keyed_value_type = $crate::util::psbt::serialize::Deserialize::deserialize(&$raw_value)?;
123 empty_key.insert(val);
124 }
125 ::std::collections::btree_map::Entry::Occupied(_) => return Err($crate::util::psbt::Error::DuplicateKey($raw_key).into()),
126 }
127 } else {
128 return Err($crate::util::psbt::Error::InvalidKey($raw_key).into());
129 }
130 };
131}
132
133
134#[cfg_attr(rustfmt, rustfmt_skip)]
135macro_rules! impl_psbt_get_pair {
136 ($rv:ident.push($slf:ident.$unkeyed_name:ident as <$unkeyed_typeval:expr, _>|<$unkeyed_value_type:ty>)) => {
137 if let Some(ref $unkeyed_name) = $slf.$unkeyed_name {
138 $rv.push($crate::util::psbt::raw::Pair {
139 key: $crate::util::psbt::raw::Key {
140 type_value: $unkeyed_typeval,
141 key: vec![],
142 },
143 value: $crate::util::psbt::serialize::Serialize::serialize($unkeyed_name),
144 });
145 }
146 };
147 ($rv:ident.push($slf:ident.$keyed_name:ident as <$keyed_typeval:expr, $keyed_key_type:ty>|<$keyed_value_type:ty>)) => {
148 for (key, val) in &$slf.$keyed_name {
149 $rv.push($crate::util::psbt::raw::Pair {
150 key: $crate::util::psbt::raw::Key {
151 type_value: $keyed_typeval,
152 key: $crate::util::psbt::serialize::Serialize::serialize(key),
153 },
154 value: $crate::util::psbt::serialize::Serialize::serialize(val),
155 });
156 }
157 };
158}
159
160macro_rules! impl_psbt_hash_de_serialize {
162 ($hash_type:ty) => {
163 impl_psbt_hash_serialize!($hash_type);
164 impl_psbt_hash_deserialize!($hash_type);
165 };
166}
167
168macro_rules! impl_psbt_hash_deserialize {
169 ($hash_type:ty) => {
170 impl $crate::util::psbt::serialize::Deserialize for $hash_type {
171 fn deserialize(bytes: &[u8]) -> Result<Self, $crate::consensus::encode::Error> {
172 <$hash_type>::from_slice(&bytes[..]).map_err(|e| {
173 $crate::util::psbt::Error::from(e).into()
174 })
175 }
176 }
177 };
178}
179
180macro_rules! impl_psbt_hash_serialize {
181 ($hash_type:ty) => {
182 impl $crate::util::psbt::serialize::Serialize for $hash_type {
183 fn serialize(&self) -> Vec<u8> {
184 self.into_inner().to_vec()
185 }
186 }
187 };
188}