use std::{
fmt::{
self,
Debug,
Display,
Formatter,
Write as _,
},
marker::PhantomData,
};
use crate::{
BoundedRedactedDisplay,
LogOutputLimit,
RedactMapValue,
RedactionPolicy,
text::internal::LogEscapeWriter,
};
#[must_use = "format or serialize the redacted map view"]
pub struct RedactedMap<'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> RedactedMap<'a, M, K, V> {
#[inline(always)]
pub const fn new(map: &'a M, policy: RedactionPolicy) -> Self {
Self {
map,
policy,
marker: PhantomData,
}
}
#[inline(always)]
pub const fn with_output_limit(
self,
limit: LogOutputLimit,
) -> BoundedRedactedDisplay<Self> {
BoundedRedactedDisplay::new(self, limit)
}
#[must_use = "format the bounded redacted 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: RedactMapValue<K, V> + ?Sized, K: ?Sized, V: ?Sized> Debug
for RedactedMap<'_, M, K, V>
{
#[inline(always)]
fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
self.map.fmt_redacted_map(&self.policy, formatter)
}
}
impl<M: RedactMapValue<K, V> + ?Sized, K: ?Sized, V: ?Sized> Display
for RedactedMap<'_, M, K, V>
{
#[inline]
fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
let mut writer = LogEscapeWriter::new(formatter);
write!(&mut writer, "{self:?}")
}
}
#[cfg(feature = "serde")]
impl<M: crate::domain::RedactMapSerialize<K, V> + ?Sized, K: ?Sized, V: ?Sized>
serde::Serialize for RedactedMap<'_, M, K, V>
{
#[inline(always)]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
self.map.serialize_redacted_map(&self.policy, serializer)
}
}