use std::{
fmt::Write as _,
fmt::{
self,
Debug,
Display,
Formatter,
},
};
use crate::{
Redact,
RedactValue,
RedactionPolicy,
text::internal::LogEscapeWriter,
};
#[must_use = "format or serialize the keyed redaction view"]
pub struct RedactedKeyedValue<'value, 'policy, T: ?Sized> {
key: &'value str,
value: &'value T,
policy: &'policy RedactionPolicy,
}
impl<'value, 'policy, T: ?Sized> RedactedKeyedValue<'value, 'policy, T> {
#[must_use = "format or serialize the keyed redaction view"]
#[inline(always)]
pub const fn new(
key: &'value str,
value: &'value T,
policy: &'policy RedactionPolicy,
) -> Self {
Self { key, value, policy }
}
#[must_use]
#[inline(always)]
pub const fn key(&self) -> &'value str {
self.key
}
}
impl<T: Redact + RedactValue + ?Sized> Debug for RedactedKeyedValue<'_, '_, T> {
#[inline]
fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
match self.policy.sensitivity_for(self.key) {
Some(level) => Debug::fmt(
&self.value.redact_value(level, self.policy.masking()),
formatter,
),
None => self.value.fmt_redacted(self.policy, formatter),
}
}
}
impl<T: Redact + RedactValue + ?Sized> Display
for RedactedKeyedValue<'_, '_, T>
{
#[inline]
fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
let mut writer = LogEscapeWriter::new(formatter);
write!(&mut writer, "{self:?}")
}
}
#[cfg(feature = "serde")]
impl<T: RedactValue + crate::domain::RedactSerialize + ?Sized> serde::Serialize
for RedactedKeyedValue<'_, '_, T>
{
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
match self.policy.sensitivity_for(self.key) {
Some(level) => serde::Serialize::serialize(
&self.value.redact_value(level, self.policy.masking()),
serializer,
),
None => crate::domain::RedactSerialize::serialize_redacted(
self.value,
self.policy,
serializer,
),
}
}
}