| use bzip2::read::BzEncoder; |
| use bzip2::Compression; |
| use std::io::Read; |
| |
| fn main() { |
| let stdin = std::io::stdin(); |
| let stdin = stdin.lock(); |
| let mut raw_counter = CountingStream::new(stdin); |
| |
| let compressed_count = { |
| let compressor = BzEncoder::new(&mut raw_counter, Compression::Best); |
| let mut compressed_counter = CountingStream::new(compressor); |
| std::io::copy(&mut compressed_counter, &mut std::io::sink()).unwrap(); |
| compressed_counter.count |
| }; |
| |
| println!( |
| "Compressed {} to {} bytes", |
| raw_counter.count, compressed_count |
| ); |
| } |
| |
| struct CountingStream<R: Read> { |
| stream: R, |
| count: usize, |
| } |
| |
| impl<R: Read> CountingStream<R> { |
| fn new(stream: R) -> Self { |
| CountingStream { stream, count: 0 } |
| } |
| } |
| |
| impl<R: Read> Read for CountingStream<R> { |
| fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> { |
| let result = self.stream.read(buf); |
| if let Ok(read_bytes) = result { |
| self.count += read_bytes; |
| } |
| result |
| } |
| } |