diff --git a/crates/safelog/src/lib.rs b/crates/safelog/src/lib.rs index 05492b76d..60ad14d5b 100644 --- a/crates/safelog/src/lib.rs +++ b/crates/safelog/src/lib.rs @@ -217,6 +217,14 @@ pub trait Redactable: std::fmt::Display + std::fmt::Debug { fn redacted(&self) -> Redacted<&Self> { Redacted(self) } + /// Return a smart pointer that redacts this object if `redact` is true. + fn maybe_redacted(&self, redact: bool) -> MaybeRedacted<&Self> { + if redact { + MaybeRedacted::Redacted(Redacted(self)) + } else { + MaybeRedacted::NotRedacted(self) + } + } } impl<'a, T: Redactable + ?Sized> Redactable for &'a T { @@ -278,6 +286,36 @@ impl std::fmt::Debug for Redacted { } } +/// An object that may or may not be redacted. +/// +/// Used to implement conditional redaction +#[derive(Clone)] +#[allow(clippy::exhaustive_enums)] +pub enum MaybeRedacted { + /// A variant where we are redacting the object. + Redacted(Redacted), + /// A variant where we are not redacting the object. + NotRedacted(T), +} + +impl std::fmt::Display for MaybeRedacted { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + MaybeRedacted::Redacted(v) => std::fmt::Display::fmt(v, f), + MaybeRedacted::NotRedacted(v) => std::fmt::Display::fmt(v, f), + } + } +} + +impl std::fmt::Debug for MaybeRedacted { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + MaybeRedacted::Redacted(v) => std::fmt::Debug::fmt(v, f), + MaybeRedacted::NotRedacted(v) => std::fmt::Debug::fmt(v, f), + } + } +} + #[cfg(test)] mod test { #![allow(clippy::unwrap_used)]