use std::io::{self, Write};
use santh_error::redact_secrets;
pub struct RedactingWriter<W: Write> {
inner: W,
pending: Vec<u8>,
}
impl<W: Write> RedactingWriter<W> {
pub fn new(inner: W) -> Self {
Self {
inner,
pending: Vec::new(),
}
}
fn forward_complete_lines(&mut self) -> io::Result<()> {
while let Some(newline) = self.pending.iter().position(|&b| b == b'\n') {
let line: Vec<u8> = self.pending.drain(..=newline).collect();
let redacted = redact_secrets(&String::from_utf8_lossy(&line));
self.inner.write_all(redacted.as_bytes())?;
}
Ok(())
}
}
impl<W: Write> Write for RedactingWriter<W> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.pending.extend_from_slice(buf);
self.forward_complete_lines()?;
Ok(buf.len())
}
fn flush(&mut self) -> io::Result<()> {
if !self.pending.is_empty() {
let redacted = redact_secrets(&String::from_utf8_lossy(&self.pending));
self.inner.write_all(redacted.as_bytes())?;
self.pending.clear();
}
self.inner.flush()
}
}