use std::borrow::Cow;
use std::fmt::Write;
use crate::DataClass;
use crate::redactors::Redactor;
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum SimpleRedactorMode {
Erase,
EraseAndTag,
Passthrough,
PassthroughAndTag,
Replace(char),
ReplaceAndTag(char),
Insert(Cow<'static, str>),
InsertAndTag(Cow<'static, str>),
}
#[derive(Clone, Debug)]
pub struct SimpleRedactor {
mode: SimpleRedactorMode,
}
impl SimpleRedactor {
#[must_use]
pub const fn new() -> Self {
Self {
mode: SimpleRedactorMode::Replace('*'),
}
}
#[must_use]
pub const fn with_mode(mode: SimpleRedactorMode) -> Self {
Self { mode }
}
#[must_use]
pub const fn mode(&self) -> &SimpleRedactorMode {
&self.mode
}
}
impl Redactor for SimpleRedactor {
#[cfg_attr(test, mutants::skip)]
fn redact(&self, data_class: &DataClass, value: &str, output: &mut dyn Write) -> core::fmt::Result {
const ASTERISKS: &str =
"************************************************************************************************************************";
match &self.mode {
SimpleRedactorMode::Erase => {
Ok(())
}
SimpleRedactorMode::EraseAndTag => {
write!(output, "<{data_class}:>")
}
SimpleRedactorMode::Passthrough => {
write!(output, "{value}")
}
SimpleRedactorMode::PassthroughAndTag => {
write!(output, "<{data_class}:{value}>")
}
#[expect(clippy::string_slice, reason = "No problem with UTF-8 here")]
SimpleRedactorMode::Replace(c) => {
let len = value.len();
if *c == '*' && len < ASTERISKS.len() {
write!(output, "{}", &ASTERISKS[0..len])
} else {
for _ in 0..len {
output.write_char(*c)?;
}
Ok(())
}
}
#[expect(clippy::string_slice, reason = "No problem with UTF-8 here")]
SimpleRedactorMode::ReplaceAndTag(c) => {
let len = value.len();
if *c == '*' && len < ASTERISKS.len() {
write!(output, "<{data_class}:{}>", &ASTERISKS[0..len])
} else {
write!(output, "<{data_class}:")?;
for _ in 0..len {
output.write_char(*c)?;
}
output.write_char('>')
}
}
SimpleRedactorMode::Insert(s) => {
write!(output, "{s}")
}
SimpleRedactorMode::InsertAndTag(s) => {
write!(output, "<{data_class}:{s}>")
}
}
}
}
impl Default for SimpleRedactor {
fn default() -> Self {
Self::new()
}
}