rskit_logging/masking/
writer.rs1use std::io;
4use std::sync::Arc;
5
6use tracing_subscriber::fmt::MakeWriter;
7
8use super::masker::Masker;
9
10pub struct MaskingMakeWriter<W> {
25 inner: W,
26 masker: Arc<dyn Masker>,
27}
28
29impl<W> MaskingMakeWriter<W> {
30 pub fn new(inner: W, masker: Arc<dyn Masker>) -> Self {
35 Self { inner, masker }
36 }
37}
38
39impl<'a, W: MakeWriter<'a>> MakeWriter<'a> for MaskingMakeWriter<W> {
40 type Writer = MaskingWriter<W::Writer>;
41
42 fn make_writer(&'a self) -> Self::Writer {
43 MaskingWriter {
44 inner: self.inner.make_writer(),
45 masker: Arc::clone(&self.masker),
46 buffer: Vec::with_capacity(256),
47 }
48 }
49
50 fn make_writer_for(&'a self, meta: &tracing::Metadata<'_>) -> Self::Writer {
51 MaskingWriter {
52 inner: self.inner.make_writer_for(meta),
53 masker: Arc::clone(&self.masker),
54 buffer: Vec::with_capacity(256),
55 }
56 }
57}
58
59pub struct MaskingWriter<W: io::Write> {
64 inner: W,
65 masker: Arc<dyn Masker>,
66 buffer: Vec<u8>,
67}
68
69impl<W: io::Write> io::Write for MaskingWriter<W> {
70 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
71 self.buffer.extend_from_slice(buf);
72 Ok(buf.len())
73 }
74
75 fn flush(&mut self) -> io::Result<()> {
76 if !self.buffer.is_empty() {
77 let output = String::from_utf8_lossy(&self.buffer);
78 let masked = self.masker.mask_output(&output);
79 self.inner.write_all(masked.as_bytes())?;
80 self.buffer.clear();
81 }
82 self.inner.flush()
83 }
84}
85
86impl<W: io::Write> Drop for MaskingWriter<W> {
87 fn drop(&mut self) {
88 if !self.buffer.is_empty() {
89 let output = String::from_utf8_lossy(&self.buffer);
92 let masked = self.masker.mask_output(&output);
93 let _ = self.inner.write_all(masked.as_bytes());
94 self.buffer.clear();
95 let _ = self.inner.flush();
96 }
97 }
98}