Merge rust-bitcoin/rust-bitcoin#2585: Improve array macros
6ba7758b30
Improve array macros (Tobin C. Harding) Pull request description: Currently we have two macros used when creating array wrapper types, one is in `internals` and the other in `bitcoin::internal_macros`. It is not immediately obvious what is what and why there are two. Improve the macros by: - Move the inherent functions to `impl_array_newtype` - Use `*_byte_array` for the names instead of `*_bytes` - Re-name the other macro to match what it now does ACKs for top commit: apoelstra: ACK6ba7758b30
Tree-SHA512: 36ed0fae0d28f24d29287062eb05bbc1e9e8b565f4ff41fd893503a25404ed8e185a34d75e398a8a660923ffda3b832b6157011598d5a75a5c4aafdffc74af2a
This commit is contained in:
commit
65a5dfcd6b
|
@ -13,7 +13,7 @@ use internals::impl_array_newtype;
|
||||||
use io::{BufRead, Write};
|
use io::{BufRead, Write};
|
||||||
|
|
||||||
use crate::consensus::encode::{self, Decodable, Encodable, VarInt};
|
use crate::consensus::encode::{self, Decodable, Encodable, VarInt};
|
||||||
use crate::internal_macros::{impl_bytes_newtype, impl_consensus_encoding};
|
use crate::internal_macros::{impl_array_newtype_stringify, impl_consensus_encoding};
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use crate::{block, Block, BlockHash, Transaction};
|
use crate::{block, Block, BlockHash, Transaction};
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ impl Decodable for PrefilledTransaction {
|
||||||
#[derive(PartialEq, Eq, Clone, Copy, Hash, Default, PartialOrd, Ord)]
|
#[derive(PartialEq, Eq, Clone, Copy, Hash, Default, PartialOrd, Ord)]
|
||||||
pub struct ShortId([u8; 6]);
|
pub struct ShortId([u8; 6]);
|
||||||
impl_array_newtype!(ShortId, u8, 6);
|
impl_array_newtype!(ShortId, u8, 6);
|
||||||
impl_bytes_newtype!(ShortId, 6);
|
impl_array_newtype_stringify!(ShortId, 6);
|
||||||
|
|
||||||
impl ShortId {
|
impl ShortId {
|
||||||
/// Calculate the SipHash24 keys used to calculate short IDs.
|
/// Calculate the SipHash24 keys used to calculate short IDs.
|
||||||
|
|
|
@ -15,7 +15,7 @@ use io::Write;
|
||||||
use secp256k1::{Secp256k1, XOnlyPublicKey};
|
use secp256k1::{Secp256k1, XOnlyPublicKey};
|
||||||
|
|
||||||
use crate::crypto::key::{CompressedPublicKey, Keypair, PrivateKey};
|
use crate::crypto::key::{CompressedPublicKey, Keypair, PrivateKey};
|
||||||
use crate::internal_macros::impl_bytes_newtype;
|
use crate::internal_macros::impl_array_newtype_stringify;
|
||||||
use crate::network::NetworkKind;
|
use crate::network::NetworkKind;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ pub type ExtendedPrivKey = Xpriv;
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
pub struct ChainCode([u8; 32]);
|
pub struct ChainCode([u8; 32]);
|
||||||
impl_array_newtype!(ChainCode, u8, 32);
|
impl_array_newtype!(ChainCode, u8, 32);
|
||||||
impl_bytes_newtype!(ChainCode, 32);
|
impl_array_newtype_stringify!(ChainCode, 32);
|
||||||
|
|
||||||
impl ChainCode {
|
impl ChainCode {
|
||||||
fn from_hmac(hmac: Hmac<sha512::Hash>) -> Self {
|
fn from_hmac(hmac: Hmac<sha512::Hash>) -> Self {
|
||||||
|
@ -52,7 +52,7 @@ impl ChainCode {
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
|
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
|
||||||
pub struct Fingerprint([u8; 4]);
|
pub struct Fingerprint([u8; 4]);
|
||||||
impl_array_newtype!(Fingerprint, u8, 4);
|
impl_array_newtype!(Fingerprint, u8, 4);
|
||||||
impl_bytes_newtype!(Fingerprint, 4);
|
impl_array_newtype_stringify!(Fingerprint, 4);
|
||||||
|
|
||||||
hash_newtype! {
|
hash_newtype! {
|
||||||
/// Extended key identifier as defined in BIP-32.
|
/// Extended key identifier as defined in BIP-32.
|
||||||
|
|
|
@ -16,7 +16,7 @@ use crate::blockdata::script;
|
||||||
use crate::blockdata::transaction::{self, OutPoint, Sequence, Transaction, TxIn, TxOut};
|
use crate::blockdata::transaction::{self, OutPoint, Sequence, Transaction, TxIn, TxOut};
|
||||||
use crate::blockdata::witness::Witness;
|
use crate::blockdata::witness::Witness;
|
||||||
use crate::consensus::Params;
|
use crate::consensus::Params;
|
||||||
use crate::internal_macros::impl_bytes_newtype;
|
use crate::internal_macros::impl_array_newtype_stringify;
|
||||||
use crate::network::Network;
|
use crate::network::Network;
|
||||||
use crate::pow::CompactTarget;
|
use crate::pow::CompactTarget;
|
||||||
use crate::{Amount, BlockHash};
|
use crate::{Amount, BlockHash};
|
||||||
|
@ -155,7 +155,7 @@ pub fn genesis_block(params: impl AsRef<Params>) -> Block {
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
pub struct ChainHash([u8; 32]);
|
pub struct ChainHash([u8; 32]);
|
||||||
impl_array_newtype!(ChainHash, u8, 32);
|
impl_array_newtype!(ChainHash, u8, 32);
|
||||||
impl_bytes_newtype!(ChainHash, 32);
|
impl_array_newtype_stringify!(ChainHash, 32);
|
||||||
|
|
||||||
impl ChainHash {
|
impl ChainHash {
|
||||||
// Mainnet value can be verified at https://github.com/lightning/bolts/blob/master/00-introduction.md
|
// Mainnet value can be verified at https://github.com/lightning/bolts/blob/master/00-introduction.md
|
||||||
|
|
|
@ -43,30 +43,17 @@ macro_rules! impl_consensus_encoding {
|
||||||
}
|
}
|
||||||
pub(crate) use impl_consensus_encoding;
|
pub(crate) use impl_consensus_encoding;
|
||||||
|
|
||||||
/// Implements several traits for byte-based newtypes.
|
/// Implements several string-ish traits for byte-based newtypes.
|
||||||
/// Implements:
|
///
|
||||||
/// - core::fmt::LowerHex
|
/// - `fmt::Display` and `str::FromStr` (using lowercase hex)
|
||||||
/// - core::fmt::UpperHex
|
/// - `fmt::LowerHex` and `UpperHex`
|
||||||
/// - core::fmt::Display
|
/// - `fmt::Debug` (using `LowerHex`)
|
||||||
/// - core::str::FromStr
|
/// - `serde::Serialize` and `Deserialize` (using lowercase hex)
|
||||||
macro_rules! impl_bytes_newtype {
|
///
|
||||||
|
/// As well as an inherent `from_hex` method.
|
||||||
|
macro_rules! impl_array_newtype_stringify {
|
||||||
($t:ident, $len:literal) => {
|
($t:ident, $len:literal) => {
|
||||||
impl $t {
|
impl $t {
|
||||||
/// Returns a reference the underlying bytes.
|
|
||||||
#[inline]
|
|
||||||
pub fn as_bytes(&self) -> &[u8; $len] { &self.0 }
|
|
||||||
|
|
||||||
/// Returns the underlying bytes.
|
|
||||||
#[inline]
|
|
||||||
pub fn to_bytes(self) -> [u8; $len] {
|
|
||||||
// We rely on `Copy` being implemented for $t so conversion
|
|
||||||
// methods use the correct Rust naming conventions.
|
|
||||||
fn check_copy<T: Copy>() {}
|
|
||||||
check_copy::<$t>();
|
|
||||||
|
|
||||||
self.0
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates `Self` from a hex string.
|
/// Creates `Self` from a hex string.
|
||||||
pub fn from_hex(s: &str) -> Result<Self, hex::HexToArrayError> {
|
pub fn from_hex(s: &str) -> Result<Self, hex::HexToArrayError> {
|
||||||
Ok($t($crate::hex::FromHex::from_hex(s)?))
|
Ok($t($crate::hex::FromHex::from_hex(s)?))
|
||||||
|
@ -185,7 +172,7 @@ macro_rules! impl_bytes_newtype {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
pub(crate) use impl_bytes_newtype;
|
pub(crate) use impl_array_newtype_stringify;
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
macro_rules! impl_hashencode {
|
macro_rules! impl_hashencode {
|
||||||
|
|
|
@ -184,7 +184,7 @@ impl Serialize for KeySource {
|
||||||
fn serialize(&self) -> Vec<u8> {
|
fn serialize(&self) -> Vec<u8> {
|
||||||
let mut rv: Vec<u8> = Vec::with_capacity(key_source_len(self));
|
let mut rv: Vec<u8> = Vec::with_capacity(key_source_len(self));
|
||||||
|
|
||||||
rv.append(&mut self.0.to_bytes().to_vec());
|
rv.append(&mut self.0.to_byte_array().to_vec());
|
||||||
|
|
||||||
for cnum in self.1.into_iter() {
|
for cnum in self.1.into_iter() {
|
||||||
rv.append(&mut serialize(&u32::from(*cnum)))
|
rv.append(&mut serialize(&u32::from(*cnum)))
|
||||||
|
|
|
@ -7,6 +7,34 @@
|
||||||
macro_rules! impl_array_newtype {
|
macro_rules! impl_array_newtype {
|
||||||
($thing:ident, $ty:ty, $len:literal) => {
|
($thing:ident, $ty:ty, $len:literal) => {
|
||||||
impl $thing {
|
impl $thing {
|
||||||
|
/// Creates `Self` by wrapping `bytes`.
|
||||||
|
#[inline]
|
||||||
|
pub fn from_byte_array(bytes: [u8; $len]) -> Self { Self(bytes) }
|
||||||
|
|
||||||
|
/// Returns a reference the underlying byte array.
|
||||||
|
#[inline]
|
||||||
|
pub fn as_byte_array(&self) -> &[u8; $len] { &self.0 }
|
||||||
|
|
||||||
|
/// Returns the underlying byte array.
|
||||||
|
#[inline]
|
||||||
|
pub fn to_byte_array(self) -> [u8; $len] {
|
||||||
|
// We rely on `Copy` being implemented for $thing so conversion
|
||||||
|
// methods use the correct Rust naming conventions.
|
||||||
|
fn check_copy<T: Copy>() {}
|
||||||
|
check_copy::<$thing>();
|
||||||
|
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a slice of the underlying bytes.
|
||||||
|
#[inline]
|
||||||
|
pub fn as_bytes(&self) -> &[u8] { &self.0 }
|
||||||
|
|
||||||
|
/// Copies the underlying bytes into a new `Vec`.
|
||||||
|
#[cfg(feature = "alloc")]
|
||||||
|
#[inline]
|
||||||
|
pub fn to_bytes(&self) -> alloc::vec::Vec<u8> { self.0.to_vec() }
|
||||||
|
|
||||||
/// Converts the object to a raw pointer.
|
/// Converts the object to a raw pointer.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn as_ptr(&self) -> *const $ty {
|
pub fn as_ptr(&self) -> *const $ty {
|
||||||
|
|
Loading…
Reference in New Issue