use std::fmt::Debug;
use crate::Sensitivity;
use crate::domain::Redact;
use crate::domain::RedactLevelValue;
use crate::domain::RedactionWriter;
pub struct RedactionItems<'writer, 'session> {
pub(super) writer: &'writer mut RedactionWriter<'session>,
}
impl<'writer, 'session> RedactionItems<'writer, 'session> {
pub fn unredacted_item<T, F>(&mut self, access: F) -> &mut Self
where
T: Debug,
F: FnOnce() -> T,
{
if !self.admit_item() {
self.write_truncated();
return self;
}
if self.writer.session.is_inspection() {
return self;
}
self.writer.write_debug(&access());
self.writer.write_fragment(", ");
self
}
pub fn sensitive_item<T, F>(&mut self, level: Sensitivity, access: F) -> &mut Self
where
T: Debug,
F: FnOnce() -> T,
{
if !self.admit_item() {
self.write_truncated();
return self;
}
if self.writer.session.is_inspection() {
self.writer.session.observe_sensitivity(level);
return self;
}
if matches!(level, Sensitivity::High | Sensitivity::Secret) {
let value = self
.writer
.session
.policy()
.masking()
.mask_opaque_bounded(level, self.writer.remaining_output_bytes());
self.writer.write_debug(&value);
} else {
self.writer.write_masked_debug(level, &access());
}
self.writer.write_fragment(", ");
self
}
#[cfg(feature = "json")]
pub fn json_value_item(&mut self, value: &serde_json::Value) -> &mut Self {
if !self.admit_item() {
self.write_truncated();
return self;
}
self.writer.write_json_value(value);
self.writer.write_fragment(", ");
self
}
pub(crate) fn level_value<T>(&mut self, value: &T, level: Sensitivity) -> &mut Self
where
T: RedactLevelValue + ?Sized,
{
if !self.admit_item() {
self.write_truncated();
return self;
}
value.write_redacted_level(self.writer, level);
self.writer.write_fragment(", ");
self
}
pub fn nested_item<T>(&mut self, value: &T) -> &mut Self
where
T: Redact + ?Sized,
{
if !self.admit_item() {
self.write_truncated();
return self;
}
value.write_redacted(self.writer);
self.writer.write_fragment(", ");
self
}
fn admit_item(&mut self) -> bool {
!self.writer.session.domain_frame_is_truncated() && self.writer.session.admit_domain_collection_item()
}
fn write_truncated(&mut self) {
if !self.writer.session.domain_frame_is_truncated() {
self.writer.write_fragment("<truncated>");
self.writer.truncate_without_output_limit();
}
}
}