You can simplify it further:
use std::io;
use std::io::Write;
use std::fmt::{Debug, Formatter, Error};
use std::thread;
use std::time::Duration;
use std::sync::{Arc, Mutex};
#[derive(Clone)]
struct Output<W>(Arc<Mutex<W>>);
impl<W: Write> Output<W> {
pub fn new(w: W) -> Self {
Output(Arc::new(Mutex::new(w)))
}
}
impl<W: Write> Write for Output<W> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
(*self.0.lock().unwrap()).write(buf)
}
fn flush(&mut self) -> io::Result<()> {
(*self.0.lock().unwrap()).flush()
}
}
impl<W: Debug> Debug for Output<W> {
fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
(*self.0.lock().unwrap()).fmt(fmt)
}
}
fn main() {
let buffer = Output::new(Vec::new());
write_to(buffer.clone());
thread::sleep(Duration::new(1, 0));
println!("{:?}", buffer);
}
fn write_to<W: Write + Send + 'static>(mut buffer: W) {
thread::spawn(move || buffer.write(b"hello").unwrap());
}
There's no need to specialise write_to
; the whole point of Output
is that it's something that is both Write
and Send
and shareable... but write_to
only needs those first two things. Also, if you are always going to clone, then it's better to just take by-value and let the caller decide if they need to clone or not.