zebra_chain/
fmt.rs

1//! Format wrappers for Zebra
2
3use std::{fmt, ops};
4
5#[cfg(any(test, feature = "proptest-impl"))]
6use proptest::prelude::*;
7#[cfg(any(test, feature = "proptest-impl"))]
8use proptest_derive::Arbitrary;
9
10pub mod time;
11
12pub use time::{duration_short, humantime_milliseconds, humantime_seconds};
13
14/// Wrapper to override `Debug`, redirecting it to only output the type's name.
15#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
16#[cfg_attr(any(test, feature = "proptest-impl"), derive(Arbitrary))]
17pub struct TypeNameToDebug<T>(pub T);
18
19impl<T> fmt::Debug for TypeNameToDebug<T> {
20    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
21        f.write_str(std::any::type_name::<T>())
22    }
23}
24
25impl<T> ops::Deref for TypeNameToDebug<T> {
26    type Target = T;
27
28    fn deref(&self) -> &Self::Target {
29        &self.0
30    }
31}
32
33impl<T> ops::DerefMut for TypeNameToDebug<T> {
34    fn deref_mut(&mut self) -> &mut Self::Target {
35        &mut self.0
36    }
37}
38
39impl<T> From<T> for TypeNameToDebug<T> {
40    fn from(t: T) -> Self {
41        Self(t)
42    }
43}
44
45/// Wrapper to override `Debug`, redirecting it to the `Display` impl.
46#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
47#[cfg_attr(any(test, feature = "proptest-impl"), derive(Arbitrary))]
48pub struct DisplayToDebug<T: fmt::Display>(pub T);
49
50impl<T: fmt::Display> fmt::Debug for DisplayToDebug<T> {
51    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
52        self.0.fmt(f)
53    }
54}
55
56impl<T: fmt::Display> ops::Deref for DisplayToDebug<T> {
57    type Target = T;
58
59    fn deref(&self) -> &Self::Target {
60        &self.0
61    }
62}
63
64impl<T: fmt::Display> ops::DerefMut for DisplayToDebug<T> {
65    fn deref_mut(&mut self) -> &mut Self::Target {
66        &mut self.0
67    }
68}
69
70impl<T: fmt::Display> From<T> for DisplayToDebug<T> {
71    fn from(t: T) -> Self {
72        Self(t)
73    }
74}
75
76/// Wrapper to override `Debug` to display a shorter summary of the type.
77///
78/// For collections and exact size iterators, it only displays the
79/// collection/iterator type, the item type, and the length.
80#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
81pub struct SummaryDebug<CollectionOrIter>(pub CollectionOrIter)
82where
83    CollectionOrIter: IntoIterator + Clone,
84    <CollectionOrIter as IntoIterator>::IntoIter: ExactSizeIterator;
85
86impl<CollectionOrIter> fmt::Debug for SummaryDebug<CollectionOrIter>
87where
88    CollectionOrIter: IntoIterator + Clone,
89    <CollectionOrIter as IntoIterator>::IntoIter: ExactSizeIterator,
90{
91    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
92        write!(
93            f,
94            "{}<{}>, len={}",
95            std::any::type_name::<CollectionOrIter>(),
96            std::any::type_name::<<CollectionOrIter as IntoIterator>::Item>(),
97            self.0.clone().into_iter().len()
98        )
99    }
100}
101
102impl<CollectionOrIter> ops::Deref for SummaryDebug<CollectionOrIter>
103where
104    CollectionOrIter: IntoIterator + Clone,
105    <CollectionOrIter as IntoIterator>::IntoIter: ExactSizeIterator,
106{
107    type Target = CollectionOrIter;
108
109    fn deref(&self) -> &Self::Target {
110        &self.0
111    }
112}
113
114impl<CollectionOrIter> ops::DerefMut for SummaryDebug<CollectionOrIter>
115where
116    CollectionOrIter: IntoIterator + Clone,
117    <CollectionOrIter as IntoIterator>::IntoIter: ExactSizeIterator,
118{
119    fn deref_mut(&mut self) -> &mut Self::Target {
120        &mut self.0
121    }
122}
123
124impl<CollectionOrIter> From<CollectionOrIter> for SummaryDebug<CollectionOrIter>
125where
126    CollectionOrIter: IntoIterator + Clone,
127    <CollectionOrIter as IntoIterator>::IntoIter: ExactSizeIterator,
128{
129    fn from(collection: CollectionOrIter) -> Self {
130        Self(collection)
131    }
132}
133
134impl<CollectionOrIter> IntoIterator for SummaryDebug<CollectionOrIter>
135where
136    CollectionOrIter: IntoIterator + Clone,
137    <CollectionOrIter as IntoIterator>::IntoIter: ExactSizeIterator,
138{
139    type Item = <CollectionOrIter as IntoIterator>::Item;
140    type IntoIter = <CollectionOrIter as IntoIterator>::IntoIter;
141
142    fn into_iter(self) -> Self::IntoIter {
143        self.0.into_iter()
144    }
145}
146
147#[cfg(any(test, feature = "proptest-impl"))]
148impl<CollectionOrIter> Arbitrary for SummaryDebug<CollectionOrIter>
149where
150    CollectionOrIter: Arbitrary + IntoIterator + Clone + 'static,
151    <CollectionOrIter as IntoIterator>::IntoIter: ExactSizeIterator,
152{
153    type Parameters = <CollectionOrIter as Arbitrary>::Parameters;
154
155    fn arbitrary_with(args: Self::Parameters) -> Self::Strategy {
156        CollectionOrIter::arbitrary_with(args)
157            .prop_map_into()
158            .boxed()
159    }
160
161    type Strategy = BoxedStrategy<Self>;
162}
163
164/// Wrapper to override `Debug`, redirecting it to hex-encode the type.
165/// The type must implement `AsRef<[u8]>`.
166#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize, Default)]
167#[cfg_attr(any(test, feature = "proptest-impl"), derive(Arbitrary))]
168#[serde(transparent)]
169pub struct HexDebug<T: AsRef<[u8]>>(pub T);
170
171impl<T: AsRef<[u8]>> fmt::Debug for HexDebug<T> {
172    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
173        f.debug_tuple(std::any::type_name::<T>())
174            .field(&hex::encode(self.as_ref()))
175            .finish()
176    }
177}
178
179impl<T: AsRef<[u8]>> ops::Deref for HexDebug<T> {
180    type Target = T;
181
182    fn deref(&self) -> &Self::Target {
183        &self.0
184    }
185}
186
187impl<T: AsRef<[u8]>> ops::DerefMut for HexDebug<T> {
188    fn deref_mut(&mut self) -> &mut Self::Target {
189        &mut self.0
190    }
191}
192
193impl<T: AsRef<[u8]>> From<T> for HexDebug<T> {
194    fn from(t: T) -> Self {
195        Self(t)
196    }
197}