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
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(())
|
|
}
|
|
}
|
|
}
|