tracing-subscriber-multi 0.1.0

Configure multiple log destinations for tracing_subscriber.
Documentation
use std::io::Write;

macro_rules! n_writer {
    ($name: ident, $($writer: ident, $writer_ty: tt),*) => {
        /// A best-effort writer that supports multiple sub-writers.
        ///
        /// When data is written, if one writer is unable to write the entire
        /// buffer, the buffer may still be consumed (resulting in data loss to
        /// one or more of the writers).
        pub struct $name<$($writer_ty: Write),*> {
            $($writer: $writer_ty),*
        }

        impl<$($writer_ty: Write),*> $name<$($writer_ty),*> {
            /// Initialise a new multi-writer with the provided sub-writers.
            pub fn new($($writer: $writer_ty),*) -> Self {
                Self {
                    $($writer),*
                }
            }
        }

        impl<$($writer_ty: Write),*> Write for $name<$($writer_ty),*> {
            fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
                let results = vec![
                    $(self.$writer.write(buf)?),*
                ];
                Ok(results.iter().max().cloned().unwrap_or(0))
            }

            fn flush(&mut self) -> std::io::Result<()> {
                $(self.$writer.flush()?;)*
                Ok(())
            }
        }
    };
}

n_writer!(DualWriter, writer1, W1, writer2, W2);
n_writer!(TripleWriter, writer1, W1, writer2, W2, writer3, W3);
n_writer!(
    QuadrupleWriter,
    writer1,
    W1,
    writer2,
    W2,
    writer3,
    W3,
    writer4,
    W4
);
n_writer!(
    QuintupleWriter,
    writer1,
    W1,
    writer2,
    W2,
    writer3,
    W3,
    writer4,
    W4,
    writer5,
    W5
);