From a6b7ab32a8567e39d31e4276a394af1c32c1c2ee Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Thu, 31 Oct 2024 14:15:41 +1100 Subject: [PATCH] Move impl_array_newtype to internal_macros The current feature gating is wrong, this bug is unreleased because it was introduced #2585. The `impl_array_newtype` macro is only used in the `bitcoin` crate, it does not need to be in `internals`. Also, other crates have an `alloc` feature which `bitcoin` does not have so if we ever need it in other places we'll need a duplicate with the correct feature gating anyways. Move the macro to `bitcoin::internal_macros` and remove the incorrect `alloc` feature gating. --- bitcoin/src/bip152.rs | 6 +- bitcoin/src/bip32.rs | 4 +- bitcoin/src/blockdata/constants.rs | 3 +- bitcoin/src/internal_macros.rs | 118 ++++++++++++++++++++++++++++ internals/src/macros.rs | 119 ----------------------------- 5 files changed, 125 insertions(+), 125 deletions(-) diff --git a/bitcoin/src/bip152.rs b/bitcoin/src/bip152.rs index f7f79cf43..3cad34e46 100644 --- a/bitcoin/src/bip152.rs +++ b/bitcoin/src/bip152.rs @@ -9,11 +9,13 @@ use core::{convert, fmt, mem}; use std::error; use hashes::{sha256, siphash24}; -use internals::{impl_array_newtype, ToU64 as _}; +use internals::ToU64 as _; use io::{BufRead, Write}; use crate::consensus::encode::{self, Decodable, Encodable, ReadExt, WriteExt}; -use crate::internal_macros::{impl_array_newtype_stringify, impl_consensus_encoding}; +use crate::internal_macros::{ + impl_array_newtype, impl_array_newtype_stringify, impl_consensus_encoding, +}; use crate::prelude::Vec; use crate::transaction::TxIdentifier; use crate::{block, consensus, Block, BlockHash, Transaction}; diff --git a/bitcoin/src/bip32.rs b/bitcoin/src/bip32.rs index 8f03e2ab6..ca6f957fc 100644 --- a/bitcoin/src/bip32.rs +++ b/bitcoin/src/bip32.rs @@ -10,11 +10,11 @@ use core::str::FromStr; use core::{fmt, slice}; use hashes::{hash160, hash_newtype, sha512, GeneralHash, HashEngine, Hmac, HmacEngine}; -use internals::{impl_array_newtype, write_err}; +use internals::write_err; use secp256k1::{Secp256k1, XOnlyPublicKey}; use crate::crypto::key::{CompressedPublicKey, Keypair, PrivateKey}; -use crate::internal_macros::impl_array_newtype_stringify; +use crate::internal_macros::{impl_array_newtype, impl_array_newtype_stringify}; use crate::network::NetworkKind; use crate::prelude::{String, Vec}; diff --git a/bitcoin/src/blockdata/constants.rs b/bitcoin/src/blockdata/constants.rs index 47c5b84c2..684ca50b8 100644 --- a/bitcoin/src/blockdata/constants.rs +++ b/bitcoin/src/blockdata/constants.rs @@ -7,10 +7,9 @@ //! single transaction. use hashes::sha256d; -use internals::impl_array_newtype; use crate::block::{self, Block}; -use crate::internal_macros::impl_array_newtype_stringify; +use crate::internal_macros::{impl_array_newtype, impl_array_newtype_stringify}; use crate::locktime::absolute; use crate::network::{Network, Params}; use crate::opcodes::all::*; diff --git a/bitcoin/src/internal_macros.rs b/bitcoin/src/internal_macros.rs index c45f47091..8cb9c3d4e 100644 --- a/bitcoin/src/internal_macros.rs +++ b/bitcoin/src/internal_macros.rs @@ -276,3 +276,121 @@ macro_rules! define_extension_trait { }; } pub(crate) use define_extension_trait; + +/// Implements standard array methods for a given wrapper type. +macro_rules! impl_array_newtype { + ($thing:ident, $ty:ty, $len:literal) => { + 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() {} + 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`. + #[inline] + pub fn to_bytes(&self) -> alloc::vec::Vec { self.0.to_vec() } + + /// Converts the object to a raw pointer. + #[inline] + pub fn as_ptr(&self) -> *const $ty { + let &$thing(ref dat) = self; + dat.as_ptr() + } + + /// Converts the object to a mutable raw pointer. + #[inline] + pub fn as_mut_ptr(&mut self) -> *mut $ty { + let &mut $thing(ref mut dat) = self; + dat.as_mut_ptr() + } + + /// Returns the length of the object as an array. + #[inline] + pub fn len(&self) -> usize { $len } + + /// Returns whether the object, as an array, is empty. Always false. + #[inline] + pub fn is_empty(&self) -> bool { false } + } + + impl<'a> core::convert::From<[$ty; $len]> for $thing { + fn from(data: [$ty; $len]) -> Self { $thing(data) } + } + + impl<'a> core::convert::From<&'a [$ty; $len]> for $thing { + fn from(data: &'a [$ty; $len]) -> Self { $thing(*data) } + } + + impl<'a> core::convert::TryFrom<&'a [$ty]> for $thing { + type Error = core::array::TryFromSliceError; + + fn try_from(data: &'a [$ty]) -> core::result::Result { + use core::convert::TryInto; + + Ok($thing(data.try_into()?)) + } + } + + impl AsRef<[$ty; $len]> for $thing { + fn as_ref(&self) -> &[$ty; $len] { &self.0 } + } + + impl AsMut<[$ty; $len]> for $thing { + fn as_mut(&mut self) -> &mut [$ty; $len] { &mut self.0 } + } + + impl AsRef<[$ty]> for $thing { + fn as_ref(&self) -> &[$ty] { &self.0 } + } + + impl AsMut<[$ty]> for $thing { + fn as_mut(&mut self) -> &mut [$ty] { &mut self.0 } + } + + impl core::borrow::Borrow<[$ty; $len]> for $thing { + fn borrow(&self) -> &[$ty; $len] { &self.0 } + } + + impl core::borrow::BorrowMut<[$ty; $len]> for $thing { + fn borrow_mut(&mut self) -> &mut [$ty; $len] { &mut self.0 } + } + + // The following two are valid because `[T; N]: Borrow<[T]>` + impl core::borrow::Borrow<[$ty]> for $thing { + fn borrow(&self) -> &[$ty] { &self.0 } + } + + impl core::borrow::BorrowMut<[$ty]> for $thing { + fn borrow_mut(&mut self) -> &mut [$ty] { &mut self.0 } + } + + impl core::ops::Index for $thing + where + [$ty]: core::ops::Index, + { + type Output = <[$ty] as core::ops::Index>::Output; + + #[inline] + fn index(&self, index: I) -> &Self::Output { &self.0[index] } + } + }; +} +pub(crate) use impl_array_newtype; diff --git a/internals/src/macros.rs b/internals/src/macros.rs index d0ae5bbb1..a62c884a3 100644 --- a/internals/src/macros.rs +++ b/internals/src/macros.rs @@ -2,125 +2,6 @@ //! Various macros used by the Rust Bitcoin ecosystem. -/// Implements standard array methods for a given wrapper type. -#[macro_export] -macro_rules! impl_array_newtype { - ($thing:ident, $ty:ty, $len:literal) => { - 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() {} - 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 { self.0.to_vec() } - - /// Converts the object to a raw pointer. - #[inline] - pub fn as_ptr(&self) -> *const $ty { - let &$thing(ref dat) = self; - dat.as_ptr() - } - - /// Converts the object to a mutable raw pointer. - #[inline] - pub fn as_mut_ptr(&mut self) -> *mut $ty { - let &mut $thing(ref mut dat) = self; - dat.as_mut_ptr() - } - - /// Returns the length of the object as an array. - #[inline] - pub fn len(&self) -> usize { $len } - - /// Returns whether the object, as an array, is empty. Always false. - #[inline] - pub fn is_empty(&self) -> bool { false } - } - - impl<'a> core::convert::From<[$ty; $len]> for $thing { - fn from(data: [$ty; $len]) -> Self { $thing(data) } - } - - impl<'a> core::convert::From<&'a [$ty; $len]> for $thing { - fn from(data: &'a [$ty; $len]) -> Self { $thing(*data) } - } - - impl<'a> core::convert::TryFrom<&'a [$ty]> for $thing { - type Error = core::array::TryFromSliceError; - - fn try_from(data: &'a [$ty]) -> core::result::Result { - use core::convert::TryInto; - - Ok($thing(data.try_into()?)) - } - } - - impl AsRef<[$ty; $len]> for $thing { - fn as_ref(&self) -> &[$ty; $len] { &self.0 } - } - - impl AsMut<[$ty; $len]> for $thing { - fn as_mut(&mut self) -> &mut [$ty; $len] { &mut self.0 } - } - - impl AsRef<[$ty]> for $thing { - fn as_ref(&self) -> &[$ty] { &self.0 } - } - - impl AsMut<[$ty]> for $thing { - fn as_mut(&mut self) -> &mut [$ty] { &mut self.0 } - } - - impl core::borrow::Borrow<[$ty; $len]> for $thing { - fn borrow(&self) -> &[$ty; $len] { &self.0 } - } - - impl core::borrow::BorrowMut<[$ty; $len]> for $thing { - fn borrow_mut(&mut self) -> &mut [$ty; $len] { &mut self.0 } - } - - // The following two are valid because `[T; N]: Borrow<[T]>` - impl core::borrow::Borrow<[$ty]> for $thing { - fn borrow(&self) -> &[$ty] { &self.0 } - } - - impl core::borrow::BorrowMut<[$ty]> for $thing { - fn borrow_mut(&mut self) -> &mut [$ty] { &mut self.0 } - } - - impl core::ops::Index for $thing - where - [$ty]: core::ops::Index, - { - type Output = <[$ty] as core::ops::Index>::Output; - - #[inline] - fn index(&self, index: I) -> &Self::Output { &self.0[index] } - } - }; -} - /// Implements `Debug` by calling through to `Display`. #[macro_export] macro_rules! debug_from_display {