use std::io::{self, Read, Write};
pub struct TeeReader<R: Read, W: Write> {
source: R,
dest: W,
}
impl<R: Read, W: Write> TeeReader<R, W> {
pub fn new(source: R, dest: W) -> Self {
Self { source, dest }
}
pub fn into_inner(self) -> (R, W) {
(self.source, self.dest)
}
}
impl<R: Read, W: Write> Read for TeeReader<R, W> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
if buf.is_empty() {
return Ok(0);
}
let count = self.source.read(buf)?;
self.dest.write_all(&buf[..count])?;
Ok(count)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn tee_reader() {
const COUNT: usize = 100;
let src: Vec<u8> = (0..COUNT as u8).collect();
let mut buf = [0; 2 * COUNT];
let mut off = 0;
let mut tee = TeeReader::new(&*src, Vec::new());
for i in 2.. {
off += tee.read(&mut buf[off..off + i]).unwrap();
assert!(off <= COUNT);
if off == COUNT {
break;
}
}
assert_eq!(src, buf[..COUNT]);
let (_, dest) = tee.into_inner();
assert_eq!(src, dest);
}
}