use std::borrow::Cow;
use crate::MaskingPolicy;
use crate::RedactionRules;
use crate::Sensitivity;
use crate::output::MaskedValue;
use crate::policy::ResolvedField;
pub(in crate::formats::http) struct FieldRedactor<'a> {
base_rules: &'a RedactionRules,
context_rules: &'a RedactionRules,
masking: &'a MaskingPolicy,
}
impl<'a> FieldRedactor<'a> {
#[must_use]
#[inline(always)]
pub(in crate::formats::http) const fn new(
base_rules: &'a RedactionRules,
context_rules: &'a RedactionRules,
masking: &'a MaskingPolicy,
) -> Self {
Self {
base_rules,
context_rules,
masking,
}
}
#[must_use]
#[inline(always)]
pub(in crate::formats::http) const fn base_rules(&self) -> &'a RedactionRules {
self.base_rules
}
#[must_use]
#[inline(always)]
pub(in crate::formats::http) const fn context_rules(&self) -> &'a RedactionRules {
self.context_rules
}
#[must_use]
#[inline(always)]
pub(in crate::formats::http) const fn masking(&self) -> &'a MaskingPolicy {
self.masking
}
#[must_use]
#[inline]
pub(in crate::formats::http) fn is_sensitive(&self, field: &str) -> bool {
matches!(
self.base_rules
.resolve_field(field)
.stronger(self.context_rules.resolve_field(field)),
ResolvedField::Sensitive { .. }
)
}
#[must_use]
#[inline]
pub(in crate::formats::http) fn sensitivity(&self, field: &str) -> Option<Sensitivity> {
match self
.base_rules
.resolve_field(field)
.stronger(self.context_rules.resolve_field(field))
{
ResolvedField::Sensitive { sensitivity } => Some(sensitivity),
ResolvedField::PassThrough => None,
}
}
#[must_use]
#[inline]
pub(in crate::formats::http) fn redact_bounded<'value>(
&self,
field: &str,
value: &'value str,
max_bytes: usize,
) -> MaskedValue<'value> {
self.redact_bounded_if_sensitive(field, value, max_bytes)
.unwrap_or_else(|| MaskedValue::new(Cow::Borrowed(value)))
}
#[must_use]
#[inline]
pub(in crate::formats::http) fn redact_bounded_if_sensitive<'value>(
&self,
field: &str,
value: &'value str,
max_bytes: usize,
) -> Option<MaskedValue<'value>> {
let resolved = self
.base_rules
.resolve_field(field)
.stronger(self.context_rules.resolve_field(field));
match resolved {
ResolvedField::Sensitive { sensitivity } => Some(MaskedValue::new(self.masking.mask_bounded(
sensitivity,
value,
max_bytes,
))),
ResolvedField::PassThrough => None,
}
}
#[must_use]
#[inline(always)]
pub(in crate::formats::http) fn mask_bounded<'value>(
&self,
level: Sensitivity,
value: &'value str,
max_bytes: usize,
) -> Cow<'value, str> {
self.masking.mask_bounded(level, value, max_bytes)
}
}