From ebfbe74243bcf16fbf8279a1f841c343afc711cc Mon Sep 17 00:00:00 2001 From: Jiri Jakes Date: Sun, 22 Jan 2023 16:23:10 +0800 Subject: [PATCH] Implement `Debug` for generic `Address` Previously `Debug` was implemented for both `Address` and `Address`, but not for cases when the `NetworkValidation` parameter was generic. This change adds this ability. --- bitcoin/src/address.rs | 50 ++++++++++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 14 deletions(-) diff --git a/bitcoin/src/address.rs b/bitcoin/src/address.rs index de76ad79..7d51d526 100644 --- a/bitcoin/src/address.rs +++ b/bitcoin/src/address.rs @@ -571,20 +571,23 @@ mod sealed { /// Marker of status of address's network validation. See section [*Parsing addresses*](Address#parsing-addresses) /// on [`Address`] for details. -pub trait NetworkValidation: sealed::NetworkValidation {} +pub trait NetworkValidation: sealed::NetworkValidation { + /// Indicates whether this `NetworkValidation` is `NetworkChecked` or not. + const IS_CHECKED: bool; +} /// Marker that address's network has been successfully validated. See section [*Parsing addresses*](Address#parsing-addresses) /// on [`Address`] for details. -#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum NetworkChecked {} /// Marker that address's network has not yet been validated. See section [*Parsing addresses*](Address#parsing-addresses) /// on [`Address`] for details. -#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum NetworkUnchecked {} -impl NetworkValidation for NetworkChecked {} -impl NetworkValidation for NetworkUnchecked {} +impl NetworkValidation for NetworkChecked { const IS_CHECKED: bool = true; } +impl NetworkValidation for NetworkUnchecked { const IS_CHECKED: bool = false; } /// A Bitcoin address. /// @@ -970,15 +973,15 @@ impl fmt::Display for Address { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { self.fmt_internal(fmt) } } -impl fmt::Debug for Address { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.fmt_internal(f) } -} - -impl fmt::Debug for Address { +impl fmt::Debug for Address { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "Address(")?; - self.fmt_internal(f)?; - write!(f, ")") + if V::IS_CHECKED { + self.fmt_internal(f) + } else { + write!(f, "Address(")?; + self.fmt_internal(f)?; + write!(f, ")") + } } } @@ -1005,7 +1008,7 @@ fn find_bech32_prefix(bech32: &str) -> &str { } } -// Address can be parsed only with NetworkUnchecked. +/// Address can be parsed only with `NetworkUnchecked`. impl FromStr for Address { type Err = Error; @@ -1232,6 +1235,25 @@ mod tests { roundtrips(&addr); } + #[test] + fn test_address_debug() { + // This is not really testing output of Debug but the ability and proper functioning + // of Debug derivation on structs generic in NetworkValidation. + #[derive(Debug)] #[allow(unused)] + struct Test { address: Address } + + let addr_str = "33iFwdLuRpW1uK1RTRqsoi8rR4NpDzk66k"; + let unchecked = Address::from_str(addr_str).unwrap(); + + assert_eq!( + format!("{:?}", Test { address: unchecked.clone() }), + format!("Test {{ address: Address({}) }}", addr_str)); + + assert_eq!( + format!("{:?}", Test { address: unchecked.assume_checked() }), + format!("Test {{ address: {} }}", addr_str)); + } + #[test] fn test_address_type() { let addresses = [