Skip to content

Instantly share code, notes, and snippets.

@mitsuhiko
Created April 27, 2017 13:16
Show Gist options
  • Save mitsuhiko/5f4698f4b045de56a985230f1afb8e84 to your computer and use it in GitHub Desktop.
Save mitsuhiko/5f4698f4b045de56a985230f1afb8e84 to your computer and use it in GitHub Desktop.
pub fn copy_with_progress<R: ?Sized, W: ?Sized>(progress: &ProgressBar,
reader: &mut R, writer: &mut W)
-> io::Result<u64>
where R: Read, W: Write
{
let mut buf = [0; 16384];
let mut written = 0;
loop {
let len = match reader.read(&mut buf) {
Ok(0) => return Ok(written),
Ok(len) => len,
Err(ref e) if e.kind() == io::ErrorKind::Interrupted => continue,
Err(e) => return Err(e),
};
writer.write_all(&buf[..len])?;
written += len as u64;
progress.inc(len as u64);
}
}
impl<R: Read + Seek> ProgressReader<R> {
pub fn new(mut rdr: R) -> Result<ProgressReader<R>> {
let len = rdr.seek(SeekFrom::End(0))?;
rdr.seek(SeekFrom::Start(0))?;
Ok(ProgressReader {
rdr: rdr,
pb: ProgressBar::new(len),
})
}
}
impl<R: Read + Seek> ProgressReader<R> {
pub fn progress(&self) -> &ProgressBar {
&self.pb
}
}
impl<R: Read + Seek> Read for ProgressReader<R> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
let rv = self.rdr.read(buf)?;
self.pb.inc(rv as u64);
Ok(rv)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment