Merge branch 'redactable_relayids' into 'main'

Implement Redactable for RelayIds, and other improvements

Closes #882

See merge request tpo/core/arti!1233
This commit is contained in:
Nick Mathewson 2023-06-12 16:06:11 +00:00
commit 3b93cdb2dd
4 changed files with 77 additions and 12 deletions

View File

@ -0,0 +1 @@
ADDED: display_relay_ids() on HasRelayIds.

View File

@ -208,10 +208,9 @@ impl Redactable for RelayId {
impl<'a> Redactable for RelayIdRef<'a> {
fn display_redacted(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
use std::fmt::Display as _;
match self {
RelayIdRef::Ed25519(k) => k.redacted().fmt(f),
RelayIdRef::Rsa(k) => k.redacted().fmt(f),
RelayIdRef::Ed25519(k) => write!(f, "ed25519:{}", k.redacted()),
RelayIdRef::Rsa(k) => write!(f, "${}", k.redacted()),
}
}

View File

@ -78,6 +78,17 @@ impl RelayIds {
}
}
impl std::fmt::Display for RelayIds {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.display_relay_ids())
}
}
impl Redactable for RelayIds {
fn display_redacted(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.display_relay_ids().redacted())
}
}
/// OwnedChanTarget is a summary of a [`ChanTarget`] that owns all of its
/// members.
#[derive(Debug, Clone, derive_builder::Builder)]
@ -323,4 +334,15 @@ mod test {
assert_eq!(format!("{:?}", ct), format!("{:?}", ct2));
assert_eq!(format!("{:?}", ct), format!("{:?}", ct.clone()));
}
#[test]
fn format_relay_ids() {
let mut builder = RelayIds::builder();
builder
.ed_identity([42; 32].into())
.rsa_identity([45; 20].into());
let ids = builder.build().unwrap();
assert_eq!(format!("{}", ids), "ed25519:KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKio $2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d");
assert_eq!(format!("{}", ids.redacted()), "ed25519:Ki…");
}
}

View File

@ -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<T: HasRelayIdsLegacy> HasRelayIds for T {
@ -130,6 +136,47 @@ impl<T: HasRelayIdsLegacy> 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> 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> 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 fmt::Formatter<'_>) -> 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, "]")
}
@ -297,11 +340,11 @@ impl<'a, T: ChanTarget> fmt::Display for DisplayChanTarget<'a, T> {
}
}
impl<'a, T: ChanTarget + std::fmt::Debug> safelog::Redactable for DisplayChanTarget<'a, T> {
fn display_redacted(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
impl<'a, T: ChanTarget + fmt::Debug> safelog::Redactable for DisplayChanTarget<'a, T> {
fn display_redacted(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.fmt_impl(f, true)
}
fn debug_redacted(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
fn debug_redacted(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "ChanTarget({:?})", self.redacted().to_string())
}
}