// 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, ValueT> de::Visitor<'de> 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, ValueT, const N: usize> de::Visitor<'de> 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)*) => () );