You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

75 lines
1.4 KiB

use std::{
io::{self, Read, Write,},
};
pub struct MulticastStream<T>
where T: Write
{
outputs: Vec<T>,
continue_on_fail: bool,
}
impl<T> MulticastStream<T>
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<T> Write for MulticastStream<T>
where T: Write
{
fn write(&mut self, buf: &[u8]) -> io::Result<usize>
{
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(())
}
}
}