use std::io::{Read, Result, Write}; pub struct ReadStats { source: R, reads: usize, bytes: usize, } impl ReadStats { pub fn new(wrapped: R) -> ReadStats { ReadStats { source: wrapped, reads: 0, bytes: 0, } } pub fn get_ref(&self) -> &R { &self.source } pub fn bytes_through(&self) -> usize { self.bytes } pub fn reads(&self) -> usize { self.reads } } impl Read for ReadStats { fn read(&mut self, buf: &mut [u8]) -> Result { let bytes = self.source.read(buf)?; self.reads += 1; self.bytes += bytes; Ok(bytes) } } pub struct WriteStats { sink: W, writes: usize, bytes: usize, } impl WriteStats { // _wrapped is ignored because W is not bounded on Debug or Display and therefore // can't be passed through format!(). For actual implementation you will likely // wish to remove the leading underscore so the variable is not ignored. pub fn new(wrapped: W) -> WriteStats { WriteStats { sink: wrapped, writes: 0, bytes: 0, } } pub fn get_ref(&self) -> &W { &self.sink } pub fn bytes_through(&self) -> usize { self.bytes } pub fn writes(&self) -> usize { self.writes } } impl Write for WriteStats { fn write(&mut self, buf: &[u8]) -> Result { let bytes = self.sink.write(buf)?; self.writes += 1; self.bytes += bytes; Ok(bytes) } fn flush(&mut self) -> Result<()> { self.sink.flush() } }