From 979a2bd6a0d5659c6784a74906e7fc00936f53af Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Fri, 9 Jun 2023 15:50:25 -0400 Subject: [PATCH] linkspec: Implement HasRelayIds::display_relay_ids(). --- crates/tor-linkspec/semver.md | 1 + crates/tor-linkspec/src/traits.rs | 55 +++++++++++++++++++++++++++---- 2 files changed, 50 insertions(+), 6 deletions(-) create mode 100644 crates/tor-linkspec/semver.md diff --git a/crates/tor-linkspec/semver.md b/crates/tor-linkspec/semver.md new file mode 100644 index 000000000..a5f4d7102 --- /dev/null +++ b/crates/tor-linkspec/semver.md @@ -0,0 +1 @@ +ADDED: display_relay_ids() on HasRelayIds. diff --git a/crates/tor-linkspec/src/traits.rs b/crates/tor-linkspec/src/traits.rs index 953ce8f45..fcdf310b9 100644 --- a/crates/tor-linkspec/src/traits.rs +++ b/crates/tor-linkspec/src/traits.rs @@ -119,6 +119,12 @@ pub trait HasRelayIds { } std::cmp::Ordering::Equal } + + /// Return a reference to this object suitable for formatting its + /// [`HasRelayIds`] members. + fn display_relay_ids(&self) -> DisplayRelayIds<'_, Self> { + DisplayRelayIds { inner: self } + } } impl HasRelayIds for T { @@ -130,6 +136,47 @@ impl HasRelayIds for T { } } +/// A helper type used to format the [`RelayId`](crate::RelayId)s in a +/// [`HasRelayIds`]. +#[derive(Clone)] +pub struct DisplayRelayIds<'a, T: HasRelayIds + ?Sized> { + /// The HasRelayIds that we're displaying. + inner: &'a T, +} +// Redactable must implement Debug. +impl<'a, T: HasRelayIds + ?Sized> std::fmt::Debug for DisplayRelayIds<'a, T> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("DisplayRelayIds").finish_non_exhaustive() + } +} + +impl<'a, T: HasRelayIds + ?Sized> DisplayRelayIds<'a, T> { + /// Helper: output `self` in a possibly redacted way. + fn fmt_impl(&self, f: &mut fmt::Formatter<'_>, redact: bool) -> fmt::Result { + let mut iter = self.inner.identities(); + if let Some(ident) = iter.next() { + write!(f, "{}", ident.maybe_redacted(redact))?; + } + if redact { + return Ok(()); + } + for ident in iter { + write!(f, " {}", ident.maybe_redacted(redact))?; + } + Ok(()) + } +} +impl<'a, T: HasRelayIds + ?Sized> std::fmt::Display for DisplayRelayIds<'a, T> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.fmt_impl(f, false) + } +} +impl<'a, T: HasRelayIds + ?Sized> Redactable for DisplayRelayIds<'a, T> { + fn display_redacted(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.fmt_impl(f, true) + } +} + /// An iterator over all of the relay identities held by a [`HasRelayIds`] #[derive(Clone)] pub struct RelayIdIter<'a, T: HasRelayIds + ?Sized> { @@ -280,12 +327,8 @@ impl<'a, T: ChanTarget> DisplayChanTarget<'a, T> { } } - for ident in self.inner.identities() { - write!(f, " {}", ident.maybe_redacted(redact))?; - if redact { - break; - } - } + write!(f, " ")?; + self.inner.display_relay_ids().fmt_impl(f, redact)?; write!(f, "]") }