diff --git a/hashes/src/internal_macros.rs b/hashes/src/internal_macros.rs index d8a73ad18..aea52dfd0 100644 --- a/hashes/src/internal_macros.rs +++ b/hashes/src/internal_macros.rs @@ -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] { diff --git a/hashes/src/lib.rs b/hashes/src/lib.rs index 58d643b42..54302534b 100644 --- a/hashes/src/lib.rs +++ b/hashes/src/lib.rs @@ -95,15 +95,13 @@ pub mod _export { } mod internal_macros; -#[macro_use] -mod macros; -#[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; @@ -114,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. diff --git a/hashes/src/macros.rs b/hashes/src/macros.rs index d0da798f3..942b8a788 100644 --- a/hashes/src/macros.rs +++ b/hashes/src/macros.rs @@ -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(PhantomData); + + impl Default for HexVisitor { + fn default() -> Self { Self(PhantomData) } + } + + impl de::Visitor<'_> for HexVisitor + where + ValueT: 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(self, v: &[u8]) -> core::result::Result + where + E: de::Error, + { + if let Ok(hex) = str::from_utf8(v) { + hex.parse::().map_err(E::custom) + } else { + Err(E::invalid_value(de::Unexpected::Bytes(v), &self)) + } + } + + fn visit_str(self, v: &str) -> core::result::Result + where + E: de::Error, + { + v.parse::().map_err(E::custom) + } + } + + /// Type used to implement serde traits for hashes as bytes. + pub struct BytesVisitor(PhantomData); + + impl Default for BytesVisitor { + fn default() -> Self { Self(PhantomData) } + } + + impl de::Visitor<'_> for BytesVisitor + where + ValueT: crate::Hash, + ValueT: crate::Hash, + { + type Value = ValueT; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a bytestring") + } + + fn visit_bytes(self, v: &[u8]) -> core::result::Result + 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(::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(&self, s: S) -> core::result::Result { + if s.is_human_readable() { + s.collect_str(self) + } else { + s.serialize_bytes(::as_byte_array(self)) + } + } + } + + impl<'de $(, $gen: $gent)*> $crate::serde::Deserialize<'de> for $t<$($gen),*> { + fn deserialize>(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::::default()) + } else { + d.deserialize_bytes(BytesVisitor::::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; diff --git a/hashes/src/serde_macros.rs b/hashes/src/serde_macros.rs deleted file mode 100644 index dce900e7a..000000000 --- a/hashes/src/serde_macros.rs +++ /dev/null @@ -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(PhantomData); - - impl Default for HexVisitor { - fn default() -> Self { Self(PhantomData) } - } - - impl de::Visitor<'_> for HexVisitor - where - ValueT: 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(self, v: &[u8]) -> core::result::Result - where - E: de::Error, - { - if let Ok(hex) = str::from_utf8(v) { - hex.parse::().map_err(E::custom) - } else { - Err(E::invalid_value(de::Unexpected::Bytes(v), &self)) - } - } - - fn visit_str(self, v: &str) -> core::result::Result - where - E: de::Error, - { - v.parse::().map_err(E::custom) - } - } - - /// Type used to implement serde traits for hashes as bytes. - pub struct BytesVisitor(PhantomData); - - impl Default for BytesVisitor { - fn default() -> Self { Self(PhantomData) } - } - - impl de::Visitor<'_> for BytesVisitor - where - ValueT: crate::Hash, - ValueT: crate::Hash, - { - type Value = ValueT; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("a bytestring") - } - - fn visit_bytes(self, v: &[u8]) -> core::result::Result - 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(::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(&self, s: S) -> core::result::Result { - if s.is_human_readable() { - s.collect_str(self) - } else { - s.serialize_bytes(::as_byte_array(self)) - } - } - } - - impl<'de $(, $gen: $gent)*> $crate::serde::Deserialize<'de> for $t<$($gen),*> { - fn deserialize>(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::::default()) - } else { - d.deserialize_bytes(BytesVisitor::::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)*) => () -);