use std::borrow::Cow;
use crate::{
RedactMapValueMut,
RedactedKeyedValue,
RedactedText,
RedactionPolicy,
Sensitivity,
};
#[must_use]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Redactor {
policy: RedactionPolicy,
}
impl Redactor {
#[inline(always)]
pub const fn new(policy: RedactionPolicy) -> Self {
Self { policy }
}
#[must_use = "use the policy snapshot backing this redactor"]
#[inline(always)]
pub const fn policy(&self) -> &RedactionPolicy {
&self.policy
}
#[must_use = "use the returned redacted value"]
#[inline]
pub fn redact<'a>(&self, field: &str, value: &'a str) -> RedactedText<'a> {
let value = match self.policy.sensitivity_for(field) {
Some(level) => self.policy.masking().mask(level, value),
None => Cow::Borrowed(value),
};
RedactedText::new(value)
}
#[must_use = "use the returned redacted value"]
#[inline]
pub fn redact_at<'a>(
&self,
level: Sensitivity,
value: &'a str,
) -> RedactedText<'a> {
RedactedText::new(self.policy.masking().mask(level, value))
}
#[must_use = "format or serialize the returned keyed redaction view"]
#[inline(always)]
pub fn redact_keyed<'value, T: ?Sized>(
&self,
key: &'value str,
value: &'value T,
) -> RedactedKeyedValue<'value, '_, T> {
RedactedKeyedValue::new(key, value, &self.policy)
}
#[cfg(feature = "http")]
pub(crate) fn redact_bounded<'a>(
&self,
field: &str,
value: &'a str,
max_bytes: usize,
) -> RedactedText<'a> {
let value = match self.policy.sensitivity_for(field) {
Some(level) => {
self.policy.masking().mask_bounded(level, value, max_bytes)
}
None => Cow::Borrowed(value),
};
RedactedText::new(value)
}
#[must_use = "use the returned redacted map"]
pub fn redact_map<M, K: ?Sized, V: ?Sized>(&self, map: &M) -> M
where
M: Clone + RedactMapValueMut<K, V>,
{
let mut redacted = map.clone();
RedactMapValueMut::redact_map_in_place(&mut redacted, &self.policy);
redacted
}
#[inline(always)]
pub fn redact_map_in_place<M, K: ?Sized, V: ?Sized>(&self, map: &mut M)
where
M: RedactMapValueMut<K, V> + ?Sized,
{
RedactMapValueMut::redact_map_in_place(map, &self.policy);
}
}
impl Default for Redactor {
#[inline(always)]
fn default() -> Self {
Self::new(RedactionPolicy::default())
}
}