Merge rust-bitcoin/rust-bitcoin#3299: hashes: Remove `utils` module

5a736edaaa hashes: Move serde_macros code into macros (Tobin C. Harding)
aaa78a3a09 hashes: Rename util to macros (Tobin C. Harding)
34e638d40c hashes: Separate private and public modules (Tobin C. Harding)

Pull request description:

  We don't want dump-all module names. Remove `utils` in favour of `macros`, while we are at it roll the `serde_maros` code into it as well and remove that module.

  Fix: #2665

ACKs for top commit:
  apoelstra:
    ACK 5a736edaaac5e13166dc907c8608b84132c65096; successfully ran local tests

Tree-SHA512: 95de1ecb0ec3884824df10a4a2e48b20786fbe819adc26e2260981d53810ff6d3f2c9ce7916e7184e54d0f8bf724217b1a10497c63020f972c6f81cc9ccd590d
This commit is contained in:
merge-script 2024-10-29 01:05:03 +00:00
commit 0bef101262
No known key found for this signature in database
GPG Key ID: C588D63CE41B97C1
4 changed files with 132 additions and 123 deletions

View File

@ -77,8 +77,8 @@ macro_rules! hash_trait_impls {
}
$crate::internal_macros::arr_newtype_fmt_impl!(Hash, $bits / 8 $(, $gen: $gent)*);
serde_impl!(Hash, { $bits / 8 } $(, $gen: $gent)*);
borrow_slice_impl!(Hash $(, $gen: $gent)*);
$crate::serde_impl!(Hash, { $bits / 8 } $(, $gen: $gent)*);
$crate::borrow_slice_impl!(Hash $(, $gen: $gent)*);
impl<$($gen: $gent),*> $crate::_export::_core::convert::AsRef<[u8; $bits / 8]> for Hash<$($gen),*> {
fn as_ref(&self) -> &[u8; $bits / 8] {

View File

@ -95,14 +95,13 @@ pub mod _export {
}
mod internal_macros;
#[macro_use]
mod util;
#[macro_use]
pub mod serde_macros;
pub mod cmp;
pub mod hash160;
pub mod hkdf;
pub mod hmac;
#[macro_use]
pub mod macros;
pub mod ripemd160;
pub mod sha1;
pub mod sha256;
@ -113,6 +112,17 @@ pub mod sha512;
pub mod sha512_256;
pub mod siphash24;
#[deprecated(since = "TBD", note = "use crate::macros instead")]
pub mod serde_macros {
//! Macros for serde trait implementations, and supporting code.
#[cfg(feature = "serde")]
pub mod serde_details {
//! Functions used by serde impls of all hashes.
pub use crate::macros::serde_details::*;
}
}
use core::{convert, fmt, hash};
#[rustfmt::skip] // Keep public re-exports separate.

View File

@ -1,5 +1,7 @@
// SPDX-License-Identifier: CC0-1.0
//! Public macros.
#[macro_export]
/// Adds hexadecimal formatting implementation of a trait `$imp` to a given type `$ty`.
macro_rules! hex_fmt_impl(
@ -357,6 +359,120 @@ macro_rules! hash_newtype_known_attrs {
($($ignore:tt)*) => {};
}
/// Functions used by serde impls of all hashes.
#[cfg(feature = "serde")]
pub mod serde_details {
use core::marker::PhantomData;
use core::str::FromStr;
use core::{fmt, str};
use serde::de;
/// Type used to implement serde traits for hashes as hex strings.
pub struct HexVisitor<ValueT>(PhantomData<ValueT>);
impl<ValueT> Default for HexVisitor<ValueT> {
fn default() -> Self { Self(PhantomData) }
}
impl<ValueT> de::Visitor<'_> for HexVisitor<ValueT>
where
ValueT: FromStr,
<ValueT as FromStr>::Err: fmt::Display,
{
type Value = ValueT;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("an ASCII hex string")
}
fn visit_bytes<E>(self, v: &[u8]) -> core::result::Result<Self::Value, E>
where
E: de::Error,
{
if let Ok(hex) = str::from_utf8(v) {
hex.parse::<Self::Value>().map_err(E::custom)
} else {
Err(E::invalid_value(de::Unexpected::Bytes(v), &self))
}
}
fn visit_str<E>(self, v: &str) -> core::result::Result<Self::Value, E>
where
E: de::Error,
{
v.parse::<Self::Value>().map_err(E::custom)
}
}
/// Type used to implement serde traits for hashes as bytes.
pub struct BytesVisitor<ValueT, const N: usize>(PhantomData<ValueT>);
impl<ValueT, const N: usize> Default for BytesVisitor<ValueT, N> {
fn default() -> Self { Self(PhantomData) }
}
impl<ValueT, const N: usize> de::Visitor<'_> for BytesVisitor<ValueT, N>
where
ValueT: crate::Hash,
ValueT: crate::Hash<Bytes = [u8; N]>,
{
type Value = ValueT;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a bytestring")
}
fn visit_bytes<E>(self, v: &[u8]) -> core::result::Result<Self::Value, E>
where
E: de::Error,
{
let bytes = <[u8; N]>::try_from(v).map_err(|_| {
// from_slice only errors on incorrect length
E::invalid_length(v.len(), &stringify!(N))
})?;
Ok(<Self::Value as crate::Hash>::from_byte_array(bytes))
}
}
}
/// Implements `Serialize` and `Deserialize` for a type `$t` which
/// represents a newtype over a byte-slice over length `$len`.
#[macro_export]
#[cfg(feature = "serde")]
macro_rules! serde_impl(
($t:ident, $len:expr $(, $gen:ident: $gent:ident)*) => (
impl<$($gen: $gent),*> $crate::serde::Serialize for $t<$($gen),*> {
fn serialize<S: $crate::serde::Serializer>(&self, s: S) -> core::result::Result<S::Ok, S::Error> {
if s.is_human_readable() {
s.collect_str(self)
} else {
s.serialize_bytes(<Self as $crate::Hash>::as_byte_array(self))
}
}
}
impl<'de $(, $gen: $gent)*> $crate::serde::Deserialize<'de> for $t<$($gen),*> {
fn deserialize<D: $crate::serde::Deserializer<'de>>(d: D) -> core::result::Result<$t<$($gen),*>, D::Error> {
use $crate::serde_macros::serde_details::{BytesVisitor, HexVisitor};
if d.is_human_readable() {
d.deserialize_str(HexVisitor::<Self>::default())
} else {
d.deserialize_bytes(BytesVisitor::<Self, $len>::default())
}
}
}
));
/// Does an "empty" serde implementation for the configuration without serde feature.
#[macro_export]
#[cfg(not(feature = "serde"))]
macro_rules! serde_impl(
($t:ident, $len:expr $(, $gen:ident: $gent:ident)*) => ()
);
#[cfg(test)]
mod test {
use crate::sha256;

View File

@ -1,117 +0,0 @@
// SPDX-License-Identifier: CC0-1.0
//! Macros for serde trait implementations, and supporting code.
/// Functions used by serde impls of all hashes.
#[cfg(feature = "serde")]
pub mod serde_details {
use core::marker::PhantomData;
use core::str::FromStr;
use core::{fmt, str};
use serde::de;
/// Type used to implement serde traits for hashes as hex strings.
pub struct HexVisitor<ValueT>(PhantomData<ValueT>);
impl<ValueT> Default for HexVisitor<ValueT> {
fn default() -> Self { Self(PhantomData) }
}
impl<ValueT> de::Visitor<'_> for HexVisitor<ValueT>
where
ValueT: FromStr,
<ValueT as FromStr>::Err: fmt::Display,
{
type Value = ValueT;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("an ASCII hex string")
}
fn visit_bytes<E>(self, v: &[u8]) -> core::result::Result<Self::Value, E>
where
E: de::Error,
{
if let Ok(hex) = str::from_utf8(v) {
hex.parse::<Self::Value>().map_err(E::custom)
} else {
Err(E::invalid_value(de::Unexpected::Bytes(v), &self))
}
}
fn visit_str<E>(self, v: &str) -> core::result::Result<Self::Value, E>
where
E: de::Error,
{
v.parse::<Self::Value>().map_err(E::custom)
}
}
/// Type used to implement serde traits for hashes as bytes.
pub struct BytesVisitor<ValueT, const N: usize>(PhantomData<ValueT>);
impl<ValueT, const N: usize> Default for BytesVisitor<ValueT, N> {
fn default() -> Self { Self(PhantomData) }
}
impl<ValueT, const N: usize> de::Visitor<'_> for BytesVisitor<ValueT, N>
where
ValueT: crate::Hash,
ValueT: crate::Hash<Bytes = [u8; N]>,
{
type Value = ValueT;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a bytestring")
}
fn visit_bytes<E>(self, v: &[u8]) -> core::result::Result<Self::Value, E>
where
E: de::Error,
{
let bytes = <[u8; N]>::try_from(v).map_err(|_| {
// from_slice only errors on incorrect length
E::invalid_length(v.len(), &stringify!(N))
})?;
Ok(<Self::Value as crate::Hash>::from_byte_array(bytes))
}
}
}
/// Implements `Serialize` and `Deserialize` for a type `$t` which
/// represents a newtype over a byte-slice over length `$len`.
#[macro_export]
#[cfg(feature = "serde")]
macro_rules! serde_impl(
($t:ident, $len:expr $(, $gen:ident: $gent:ident)*) => (
impl<$($gen: $gent),*> $crate::serde::Serialize for $t<$($gen),*> {
fn serialize<S: $crate::serde::Serializer>(&self, s: S) -> core::result::Result<S::Ok, S::Error> {
if s.is_human_readable() {
s.collect_str(self)
} else {
s.serialize_bytes(<Self as $crate::Hash>::as_byte_array(self))
}
}
}
impl<'de $(, $gen: $gent)*> $crate::serde::Deserialize<'de> for $t<$($gen),*> {
fn deserialize<D: $crate::serde::Deserializer<'de>>(d: D) -> core::result::Result<$t<$($gen),*>, D::Error> {
use $crate::serde_macros::serde_details::{BytesVisitor, HexVisitor};
if d.is_human_readable() {
d.deserialize_str(HexVisitor::<Self>::default())
} else {
d.deserialize_bytes(BytesVisitor::<Self, $len>::default())
}
}
}
));
/// Does an "empty" serde implementation for the configuration without serde feature.
#[macro_export]
#[cfg(not(feature = "serde"))]
macro_rules! serde_impl(
($t:ident, $len:expr $(, $gen:ident: $gent:ident)*) => ()
);