use core::fmt::Debug;
use std::fmt::Write;
use std::sync::Arc;
use crate::redaction_engine_builder::RedactionEngineBuilder;
use crate::redaction_engine_inner::RedactionEngineInner;
use crate::{DataClass, RedactedDebug, RedactedDisplay, RedactedToString, Redactor};
#[derive(Clone, Default)]
pub struct RedactionEngine {
inner: Arc<RedactionEngineInner>,
}
impl RedactionEngine {
#[must_use]
pub fn builder() -> RedactionEngineBuilder {
RedactionEngineBuilder::new()
}
#[must_use]
pub(crate) fn new(mut inner: RedactionEngineInner) -> Self {
inner.shrink();
Self { inner: Arc::new(inner) }
}
pub fn redacted_debug(&self, value: &impl RedactedDebug, output: &mut impl Write) -> core::fmt::Result {
let d = core::fmt::from_fn(|f| value.fmt(self, f));
write!(output, "{d:?}")
}
pub fn redacted_display(&self, value: &impl RedactedDisplay, output: &mut impl Write) -> core::fmt::Result {
let d = core::fmt::from_fn(|f| value.fmt(self, f));
write!(output, "{d}")
}
pub fn redacted_to_string(&self, value: &impl RedactedToString) -> String {
value.to_redacted_string(self)
}
}
impl Redactor for RedactionEngine {
fn redacts(&self, data_class: &DataClass) -> bool {
self.inner.redacts(data_class)
}
fn redact(&self, data_class: &DataClass, value: &str, output: &mut dyn Write) -> core::fmt::Result {
if let Some(strategy) = self.inner.resolve(data_class) {
strategy.redact(data_class, value, output)
} else {
output.write_str(value)
}
}
}
impl Debug for RedactionEngine {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
self.inner.fmt(f)
}
}