tracing_subscriber_multi/
multi_writer.rs

1use std::io::Write;
2
3macro_rules! n_writer {
4    ($name: ident, $($writer: ident, $writer_ty: tt),*) => {
5        /// A best-effort writer that supports multiple sub-writers.
6        ///
7        /// When data is written, if one writer is unable to write the entire
8        /// buffer, the buffer may still be consumed (resulting in data loss to
9        /// one or more of the writers).
10        pub struct $name<$($writer_ty: Write),*> {
11            $($writer: $writer_ty),*
12        }
13
14        impl<$($writer_ty: Write),*> $name<$($writer_ty),*> {
15            /// Initialise a new multi-writer with the provided sub-writers.
16            pub fn new($($writer: $writer_ty),*) -> Self {
17                Self {
18                    $($writer),*
19                }
20            }
21        }
22
23        impl<$($writer_ty: Write),*> Write for $name<$($writer_ty),*> {
24            fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
25                let results = vec![
26                    $(self.$writer.write(buf)?),*
27                ];
28                Ok(results.iter().max().cloned().unwrap_or(0))
29            }
30
31            fn flush(&mut self) -> std::io::Result<()> {
32                $(self.$writer.flush()?;)*
33                Ok(())
34            }
35        }
36    };
37}
38
39n_writer!(DualWriter, writer1, W1, writer2, W2);
40n_writer!(TripleWriter, writer1, W1, writer2, W2, writer3, W3);
41n_writer!(
42    QuadrupleWriter,
43    writer1,
44    W1,
45    writer2,
46    W2,
47    writer3,
48    W3,
49    writer4,
50    W4
51);
52n_writer!(
53    QuintupleWriter,
54    writer1,
55    W1,
56    writer2,
57    W2,
58    writer3,
59    W3,
60    writer4,
61    W4,
62    writer5,
63    W5
64);