bitcoin/
internal_macros.rs

1// Rust Bitcoin Library
2// Written in 2014 by
3//     Andrew Poelstra <apoelstra@wpsoftware.net>
4//
5// To the extent possible under law, the author(s) have dedicated all
6// copyright and related and neighboring rights to this software to
7// the public domain worldwide. This software is distributed without
8// any warranty.
9//
10// You should have received a copy of the CC0 Public Domain Dedication
11// along with this software.
12// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
13//
14
15//! Internal Macros
16//!
17//! Macros meant to be used inside the Rust Bitcoin library
18
19macro_rules! impl_consensus_encoding {
20    ($thing:ident, $($field:ident),+) => (
21        impl<S: ::consensus::encode::Encoder> ::consensus::encode::Encodable<S> for $thing {
22            #[inline]
23            fn consensus_encode(&self, s: &mut S) -> Result<(), ::consensus::encode::Error> {
24                $( self.$field.consensus_encode(s)?; )+
25                Ok(())
26            }
27        }
28
29        impl<D: ::consensus::encode::Decoder> ::consensus::encode::Decodable<D> for $thing {
30            #[inline]
31            fn consensus_decode(d: &mut D) -> Result<$thing, ::consensus::encode::Error> {
32                use consensus::encode::Decodable;
33                Ok($thing {
34                    $( $field: Decodable::consensus_decode(d)?, )+
35                })
36            }
37        }
38    );
39}
40
41macro_rules! impl_array_newtype {
42    ($thing:ident, $ty:ty, $len:expr) => {
43        impl $thing {
44            #[inline]
45            /// Converts the object to a raw pointer
46            pub fn as_ptr(&self) -> *const $ty {
47                let &$thing(ref dat) = self;
48                dat.as_ptr()
49            }
50
51            #[inline]
52            /// Converts the object to a mutable raw pointer
53            pub fn as_mut_ptr(&mut self) -> *mut $ty {
54                let &mut $thing(ref mut dat) = self;
55                dat.as_mut_ptr()
56            }
57
58            #[inline]
59            /// Returns the length of the object as an array
60            pub fn len(&self) -> usize { $len }
61
62            #[inline]
63            /// Returns whether the object, as an array, is empty. Always false.
64            pub fn is_empty(&self) -> bool { false }
65
66            #[inline]
67            /// Returns the underlying bytes.
68            pub fn as_bytes(&self) -> &[$ty; $len] { &self.0 }
69
70            #[inline]
71            /// Returns the underlying bytes.
72            pub fn to_bytes(&self) -> [$ty; $len] { self.0.clone() }
73
74            #[inline]
75            /// Returns the underlying bytes.
76            pub fn into_bytes(self) -> [$ty; $len] { self.0 }
77        }
78
79        impl<'a> From<&'a [$ty]> for $thing {
80            fn from(data: &'a [$ty]) -> $thing {
81                assert_eq!(data.len(), $len);
82                let mut ret = [0; $len];
83                ret.copy_from_slice(&data[..]);
84                $thing(ret)
85            }
86        }
87
88        impl ::std::ops::Index<usize> for $thing {
89            type Output = $ty;
90
91            #[inline]
92            fn index(&self, index: usize) -> &$ty {
93                let &$thing(ref dat) = self;
94                &dat[index]
95            }
96        }
97
98        impl_index_newtype!($thing, $ty);
99
100        impl PartialEq for $thing {
101            #[inline]
102            fn eq(&self, other: &$thing) -> bool {
103                &self[..] == &other[..]
104            }
105        }
106
107        impl Eq for $thing {}
108
109        impl PartialOrd for $thing {
110            #[inline]
111            fn partial_cmp(&self, other: &$thing) -> Option<::std::cmp::Ordering> {
112                Some(self.cmp(&other))
113            }
114        }
115
116        impl Ord for $thing {
117            #[inline]
118            fn cmp(&self, other: &$thing) -> ::std::cmp::Ordering {
119                // manually implement comparison to get little-endian ordering
120                // (we need this for our numeric types; non-numeric ones shouldn't
121                // be ordered anyway except to put them in BTrees or whatever, and
122                // they don't care how we order as long as we're consistent).
123                for i in 0..$len {
124                    if self[$len - 1 - i] < other[$len - 1 - i] { return ::std::cmp::Ordering::Less; }
125                    if self[$len - 1 - i] > other[$len - 1 - i] { return ::std::cmp::Ordering::Greater; }
126                }
127                ::std::cmp::Ordering::Equal
128            }
129        }
130
131        #[cfg_attr(feature = "clippy", allow(expl_impl_clone_on_copy))] // we don't define the `struct`, we have to explicitly impl
132        impl Clone for $thing {
133            #[inline]
134            fn clone(&self) -> $thing {
135                $thing::from(&self[..])
136            }
137        }
138
139        impl Copy for $thing {}
140
141        impl ::std::hash::Hash for $thing {
142            #[inline]
143            fn hash<H>(&self, state: &mut H)
144                where H: ::std::hash::Hasher
145            {
146                (&self[..]).hash(state);
147            }
148
149            fn hash_slice<H>(data: &[$thing], state: &mut H)
150                where H: ::std::hash::Hasher
151            {
152                for d in data.iter() {
153                    (&d[..]).hash(state);
154                }
155            }
156        }
157
158        impl ::rand::Rand for $thing {
159            #[inline]
160            fn rand<R: ::rand::Rng>(r: &mut R) -> $thing {
161                $thing(::rand::Rand::rand(r))
162            }
163        }
164    }
165}
166
167macro_rules! impl_array_newtype_encodable {
168    ($thing:ident, $ty:ty, $len:expr) => {
169        #[cfg(feature = "serde")]
170        impl<'de> $crate::serde::Deserialize<'de> for $thing {
171            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
172            where
173                D: $crate::serde::Deserializer<'de>,
174            {
175                use $crate::std::fmt::{self, Formatter};
176
177                struct Visitor;
178                impl<'de> $crate::serde::de::Visitor<'de> for Visitor {
179                    type Value = $thing;
180
181                    fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
182                        formatter.write_str("a fixed size array")
183                    }
184
185                    #[inline]
186                    fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
187                    where
188                        A: $crate::serde::de::SeqAccess<'de>,
189                    {
190                        let mut ret: [$ty; $len] = [0; $len];
191                        for item in ret.iter_mut() {
192                            *item = match seq.next_element()? {
193                                Some(c) => c,
194                                None => return Err($crate::serde::de::Error::custom("end of stream"))
195                            };
196                        }
197                        Ok($thing(ret))
198                    }
199                }
200
201                deserializer.deserialize_seq(Visitor)
202            }
203        }
204
205        #[cfg(feature = "serde")]
206        impl $crate::serde::Serialize for $thing {
207            fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
208            where
209                S: $crate::serde::Serializer,
210            {
211                let &$thing(ref dat) = self;
212                (&dat[..]).serialize(serializer)
213            }
214        }
215    }
216}
217
218macro_rules! impl_array_newtype_show {
219    ($thing:ident) => {
220        impl ::std::fmt::Debug for $thing {
221            fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
222                write!(f, concat!(stringify!($thing), "({:?})"), &self[..])
223            }
224        }
225    }
226}
227
228macro_rules! impl_index_newtype {
229    ($thing:ident, $ty:ty) => {
230        impl ::std::ops::Index<::std::ops::Range<usize>> for $thing {
231            type Output = [$ty];
232
233            #[inline]
234            fn index(&self, index: ::std::ops::Range<usize>) -> &[$ty] {
235                &self.0[index]
236            }
237        }
238
239        impl ::std::ops::Index<::std::ops::RangeTo<usize>> for $thing {
240            type Output = [$ty];
241
242            #[inline]
243            fn index(&self, index: ::std::ops::RangeTo<usize>) -> &[$ty] {
244                &self.0[index]
245            }
246        }
247
248        impl ::std::ops::Index<::std::ops::RangeFrom<usize>> for $thing {
249            type Output = [$ty];
250
251            #[inline]
252            fn index(&self, index: ::std::ops::RangeFrom<usize>) -> &[$ty] {
253                &self.0[index]
254            }
255        }
256
257        impl ::std::ops::Index<::std::ops::RangeFull> for $thing {
258            type Output = [$ty];
259
260            #[inline]
261            fn index(&self, _: ::std::ops::RangeFull) -> &[$ty] {
262                &self.0[..]
263            }
264        }
265
266    }
267}
268
269macro_rules! display_from_debug {
270    ($thing:ident) => {
271        impl ::std::fmt::Display for $thing {
272            fn fmt(&self, f: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> {
273                ::std::fmt::Debug::fmt(self, f)
274            }
275        }
276    }
277}
278
279#[cfg(test)]
280macro_rules! hex_script (($s:expr) => (::blockdata::script::Script::from(::hex::decode($s).unwrap())));
281
282#[cfg(test)]
283macro_rules! hex_hash (($s:expr) => (::bitcoin_hashes::sha256d::Hash::from_slice(&::hex::decode($s).unwrap()).unwrap()));
284
285macro_rules! serde_struct_impl {
286    ($name:ident, $($fe:ident),*) => (
287        #[cfg(feature = "serde")]
288        impl<'de> $crate::serde::Deserialize<'de> for $name {
289            fn deserialize<D>(deserializer: D) -> Result<$name, D::Error>
290            where
291                D: $crate::serde::de::Deserializer<'de>,
292            {
293                use $crate::std::fmt::{self, Formatter};
294                use $crate::serde::de::IgnoredAny;
295
296                #[allow(non_camel_case_types)]
297                enum Enum { Unknown__Field, $($fe),* }
298
299                struct EnumVisitor;
300                impl<'de> $crate::serde::de::Visitor<'de> for EnumVisitor {
301                    type Value = Enum;
302
303                    fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
304                        formatter.write_str("a field name")
305                    }
306
307                    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
308                    where
309                        E: $crate::serde::de::Error,
310                    {
311                        match v {
312                            $(
313                            stringify!($fe) => Ok(Enum::$fe)
314                            ),*,
315                            _ => Ok(Enum::Unknown__Field)
316                        }
317                    }
318                }
319
320                impl<'de> $crate::serde::Deserialize<'de> for Enum {
321                    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
322                    where
323                        D: ::serde::de::Deserializer<'de>,
324                    {
325                        deserializer.deserialize_str(EnumVisitor)
326                    }
327                }
328
329                struct Visitor;
330
331                impl<'de> $crate::serde::de::Visitor<'de> for Visitor {
332                    type Value = $name;
333
334                    fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
335                        formatter.write_str("a struct")
336                    }
337
338                    fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
339                    where
340                        A: $crate::serde::de::MapAccess<'de>,
341                    {
342                        use $crate::serde::de::Error;
343
344                        $(let mut $fe = None;)*
345
346                        loop {
347                            match map.next_key::<Enum>()? {
348                                Some(Enum::Unknown__Field) => {
349                                    map.next_value::<IgnoredAny>()?;
350                                }
351                                $(
352                                    Some(Enum::$fe) => {
353                                        $fe = Some(map.next_value()?);
354                                    }
355                                )*
356                                None => { break; }
357                            }
358                        }
359
360                        $(
361                            let $fe = match $fe {
362                                Some(x) => x,
363                                None => return Err(A::Error::missing_field(stringify!($fe))),
364                            };
365                        )*
366
367                        let ret = $name {
368                            $($fe: $fe),*
369                        };
370
371                        Ok(ret)
372                    }
373                }
374                // end type defs
375
376                static FIELDS: &'static [&'static str] = &[$(stringify!($fe)),*];
377
378                deserializer.deserialize_struct(stringify!($name), FIELDS, Visitor)
379            }
380        }
381
382        #[cfg(feature = "serde")]
383        impl<'de> $crate::serde::Serialize for $name {
384            fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
385            where
386                S: $crate::serde::Serializer,
387            {
388                use $crate::serde::ser::SerializeStruct;
389
390                // Only used to get the struct length.
391                static FIELDS: &'static [&'static str] = &[$(stringify!($fe)),*];
392
393                let mut st = serializer.serialize_struct(stringify!($name), FIELDS.len())?;
394
395                $(
396                    st.serialize_field(stringify!($fe), &self.$fe)?;
397                )*
398
399                st.end()
400            }
401        }
402    )
403}
404
405macro_rules! user_enum {
406    (
407        $(#[$attr:meta])*
408        pub enum $name:ident {
409            $(#[$doc:meta]
410              $elem:ident <-> $txt:expr),*
411        }
412    ) => (
413        $(#[$attr])*
414        pub enum $name {
415            $(#[$doc] $elem),*
416        }
417
418        impl ::std::fmt::Debug for $name {
419            fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
420                f.pad(match *self {
421                    $($name::$elem => $txt),*
422                })
423            }
424        }
425
426        impl ::std::fmt::Display for $name {
427            fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
428                f.pad(match *self {
429                    $($name::$elem => $txt),*
430                })
431            }
432        }
433
434        impl ::std::str::FromStr for $name {
435            type Err = ::std::io::Error;
436            #[inline]
437            fn from_str(s: &str) -> Result<Self, Self::Err> {
438                match s {
439                    $($txt => Ok($name::$elem)),*,
440                    _ => Err(::std::io::Error::new(
441                        ::std::io::ErrorKind::InvalidInput,
442                        format!("Unknown network (type {})", s),
443                    )),
444                }
445            }
446        }
447
448        #[cfg(feature = "serde")]
449        impl<'de> $crate::serde::Deserialize<'de> for $name {
450            #[inline]
451            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
452            where
453                D: $crate::serde::Deserializer<'de>,
454            {
455                use $crate::std::fmt::{self, Formatter};
456
457                struct Visitor;
458                impl<'de> $crate::serde::de::Visitor<'de> for Visitor {
459                    type Value = $name;
460
461                    fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
462                        formatter.write_str("an enum value")
463                    }
464
465                    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
466                    where
467                        E: $crate::serde::de::Error,
468                    {
469                        static FIELDS: &'static [&'static str] = &[$(stringify!($txt)),*];
470
471                        $( if v == $txt { Ok($name::$elem) } )else*
472                        else {
473                            Err(E::unknown_variant(v, FIELDS))
474                        }
475                    }
476
477                    fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
478                    where
479                        E: $crate::serde::de::Error,
480                    {
481                        self.visit_str(v)
482                    }
483
484                    fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
485                    where
486                        E: $crate::serde::de::Error,
487                    {
488                        self.visit_str(&v)
489                    }
490
491                }
492
493                deserializer.deserialize_str(Visitor)
494            }
495        }
496
497        #[cfg(feature = "serde")]
498        impl ::serde::Serialize for $name {
499            fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
500            where
501                S: ::serde::Serializer,
502            {
503                serializer.serialize_str(&self.to_string())
504            }
505        }
506    );
507}