use std::io::{self, Read, Write};
pub const DEFAULT_BUF_LEN: usize = 4000;
pub fn stream(from: &mut impl Read, to: &mut impl Write) -> io::Result<()> {
let mut buffer = [0u8; DEFAULT_BUF_LEN];
loop {
let read_len = from.read(&mut buffer)?;
to.write(&buffer[..read_len])?;
if read_len != DEFAULT_BUF_LEN {
break;
}
}
Ok(())
}
pub struct Chain<R1: Read, R2: Read> {
first: Option<R1>,
second: R2,
}
impl<R1: Read, R2: Read> Chain<R1, R2> {
pub fn new(first: R1, second: R2) -> Self {
Chain {
first: Some(first),
second,
}
}
}
impl<R1: Read, R2: Read> Read for Chain<R1, R2> {
fn read(&mut self, mut buf: &mut [u8]) -> io::Result<usize> {
match &mut self.first {
Some(first) => {
let buf_len = buf.len();
match first.read(&mut buf)? {
n if n < buf_len => {
let mut from_second = vec![0u8; buf_len - n];
let n2 = self.second.read(&mut from_second)?;
buf.write(&[&buf[..n], &from_second].concat())?;
self.first = None;
Ok(n + n2)
}
n => Ok(n),
}
}
None => Ok(self.second.read(buf)?),
}
}
}