use std::{
fmt::{
self,
Debug,
Display,
Formatter,
Write as _,
},
marker::PhantomData,
};
use crate::{
BoundedRedactedDisplay,
LogOutputLimit,
Redact,
RedactValue,
RedactedKeyedValue,
RedactionPolicy,
text::internal::LogEscapeWriter,
};
#[must_use = "format the recursive keyed redaction view"]
pub struct RedactedKeyedMap<
'a,
M: ?Sized,
K: ?Sized = String,
V: ?Sized = String,
> {
map: &'a M,
policy: RedactionPolicy,
marker: PhantomData<fn() -> (*const K, *const V)>,
}
impl<'a, M: ?Sized, K: ?Sized, V: ?Sized> RedactedKeyedMap<'a, M, K, V> {
#[must_use = "format the recursive keyed redaction view"]
#[inline(always)]
pub const fn new(map: &'a M, policy: RedactionPolicy) -> Self {
Self {
map,
policy,
marker: PhantomData,
}
}
#[must_use = "format the bounded recursive keyed map display adapter"]
#[inline(always)]
pub const fn with_output_limit(
self,
limit: LogOutputLimit,
) -> BoundedRedactedDisplay<Self> {
BoundedRedactedDisplay::new(self, limit)
}
#[must_use = "format the bounded recursive keyed map display adapter"]
#[inline]
pub fn with_policy_output_limit(self) -> BoundedRedactedDisplay<Self> {
let limit = LogOutputLimit::from(self.policy.diagnostic_budget());
BoundedRedactedDisplay::new(self, limit)
}
}
impl<
M: ?Sized,
K: AsRef<str> + Debug + ?Sized,
V: Redact + RedactValue + ?Sized,
> Debug for RedactedKeyedMap<'_, M, K, V>
where
for<'entry> &'entry M: IntoIterator<Item = (&'entry K, &'entry V)>,
{
#[inline]
fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
let mut output = formatter.debug_map();
for (key, value) in self.map {
output.entry(
&key,
&RedactedKeyedValue::new(key.as_ref(), value, &self.policy),
);
}
output.finish()
}
}
impl<
M: ?Sized,
K: AsRef<str> + Debug + ?Sized,
V: Redact + RedactValue + ?Sized,
> Display for RedactedKeyedMap<'_, M, K, V>
where
for<'entry> &'entry M: IntoIterator<Item = (&'entry K, &'entry V)>,
{
#[inline]
fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
let mut writer = LogEscapeWriter::new(formatter);
write!(&mut writer, "{self:?}")
}
}