diff --git a/zebra-chain/src/fmt.rs b/zebra-chain/src/fmt.rs index e0635eedd43..ff3bbd09d22 100644 --- a/zebra-chain/src/fmt.rs +++ b/zebra-chain/src/fmt.rs @@ -2,20 +2,54 @@ use std::{fmt, ops}; +#[cfg(any(test, feature = "proptest-impl"))] +use proptest::prelude::*; +#[cfg(any(test, feature = "proptest-impl"))] +use proptest_derive::Arbitrary; + +/// Wrapper to override `Debug`, redirecting it to only output the type's name. +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[cfg_attr(any(test, feature = "proptest-impl"), derive(Arbitrary))] +pub struct TypeNameToDebug(pub T); + +impl fmt::Debug for TypeNameToDebug { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(std::any::type_name::()) + } +} + +impl ops::Deref for TypeNameToDebug { + type Target = T; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl ops::DerefMut for TypeNameToDebug { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +impl From for TypeNameToDebug { + fn from(t: T) -> Self { + Self(t) + } +} + /// Wrapper to override `Debug`, redirecting it to the `Display` impl. #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct DisplayToDebug(pub T); +#[cfg_attr(any(test, feature = "proptest-impl"), derive(Arbitrary))] +pub struct DisplayToDebug(pub T); -impl fmt::Debug for DisplayToDebug -where - T: fmt::Display, -{ +impl fmt::Debug for DisplayToDebug { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { self.0.fmt(f) } } -impl ops::Deref for DisplayToDebug { +impl ops::Deref for DisplayToDebug { type Target = T; fn deref(&self) -> &Self::Target { @@ -23,7 +57,13 @@ impl ops::Deref for DisplayToDebug { } } -impl From for DisplayToDebug { +impl ops::DerefMut for DisplayToDebug { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +impl From for DisplayToDebug { fn from(t: T) -> Self { Self(t) } @@ -34,7 +74,10 @@ impl From for DisplayToDebug { /// For collections and exact size iterators, it only displays the /// collection/iterator type, the item type, and the length. #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct SummaryDebug(pub CollectionOrIter); +pub struct SummaryDebug(pub CollectionOrIter) +where + CollectionOrIter: IntoIterator + Clone, + ::IntoIter: ExactSizeIterator; impl fmt::Debug for SummaryDebug where @@ -52,7 +95,11 @@ where } } -impl ops::Deref for SummaryDebug { +impl ops::Deref for SummaryDebug +where + CollectionOrIter: IntoIterator + Clone, + ::IntoIter: ExactSizeIterator, +{ type Target = CollectionOrIter; fn deref(&self) -> &Self::Target { @@ -60,7 +107,21 @@ impl ops::Deref for SummaryDebug { } } -impl From for SummaryDebug { +impl ops::DerefMut for SummaryDebug +where + CollectionOrIter: IntoIterator + Clone, + ::IntoIter: ExactSizeIterator, +{ + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +impl From for SummaryDebug +where + CollectionOrIter: IntoIterator + Clone, + ::IntoIter: ExactSizeIterator, +{ fn from(collection: CollectionOrIter) -> Self { Self(collection) } @@ -68,7 +129,8 @@ impl From for SummaryDebug impl IntoIterator for SummaryDebug where - CollectionOrIter: IntoIterator, + CollectionOrIter: IntoIterator + Clone, + ::IntoIter: ExactSizeIterator, { type Item = ::Item; type IntoIter = ::IntoIter; @@ -77,3 +139,20 @@ where self.0.into_iter() } } + +#[cfg(any(test, feature = "proptest-impl"))] +impl Arbitrary for SummaryDebug +where + CollectionOrIter: Arbitrary + IntoIterator + Clone + 'static, + ::IntoIter: ExactSizeIterator, +{ + type Parameters = ::Parameters; + + fn arbitrary_with(args: Self::Parameters) -> Self::Strategy { + CollectionOrIter::arbitrary_with(args) + .prop_map_into() + .boxed() + } + + type Strategy = BoxedStrategy; +}