use std::{ io::{self, Read, Write,}, }; pub struct MulticastStream where T: Write { outputs: Vec, continue_on_fail: bool, } impl MulticastStream where T: Write { pub fn new() -> Self { Self { outputs: Vec::new(), continue_on_fail: false, } } pub fn continue_on_fail(self, set: bool) -> Self { Self { continue_on_fail: set, ..self } } pub fn cast(&mut self, output: T) { self.outputs.push(output); } } impl Write for MulticastStream where T: Write { fn write(&mut self, buf: &[u8]) -> io::Result { let mut sz =0; let mut one_ok = self.outputs.len() < 1; for res in self.outputs.iter_mut().map(|output| output.write(&buf)) { match res { Ok(res) if res > sz => sz = res, Err(err) if !self.continue_on_fail => return Err(err), Err(_) => continue, _ => (), }; one_ok = true; } if !one_ok { Err(io::Error::new(io::ErrorKind::UnexpectedEof, "All write streams failed")) } else { Ok(sz) } } fn flush(&mut self) -> io::Result<()> { let mut errors = 0; for res in self.outputs.iter_mut().map(|output| output.flush()) { if let Err(err) = res { if !self.continue_on_fail { return Err(err); } errors += 1; } } if errors > 0 && errors == self.outputs.len() { Err(io::Error::new(io::ErrorKind::UnexpectedEof, "All write streams failed")) } else { Ok(()) } } }