use std::io::{self, Read, Write}; use clap::ValueEnum; use flate2::Compression as GzCompression; use flate2::write::GzEncoder; use flate2::read::GzDecoder; use bzip2::Compression as BzCompression; use bzip2::write::BzEncoder; use bzip2::read::BzDecoder; #[derive(Debug, Copy, Clone, Eq, PartialEq, ValueEnum)] pub enum CompressionType { Gzip, Bzip2, } pub enum Encoder { Gzip(GzEncoder), Bzip2(BzEncoder), } impl Encoder { pub fn new(sink: W, alg: CompressionType) -> Self { match alg { CompressionType::Gzip => { let inner = GzEncoder::new(sink, GzCompression::default()); Self::Gzip(inner) }, CompressionType::Bzip2 => { let inner = BzEncoder::new(sink, BzCompression::new(5)); Self::Bzip2(inner) }, } } } impl Write for Encoder { fn write(&mut self, data: &[u8]) -> io::Result { match self { Self::Gzip(inner) => inner.write(data), Self::Bzip2(inner) => inner.write(data), } } fn flush(&mut self) -> io::Result<()> { match self { Self::Gzip(inner) => inner.flush(), Self::Bzip2(inner) => inner.flush(), } } } pub enum Decoder { Gzip(GzDecoder), Bzip2(BzDecoder), } impl Decoder { pub fn new(src: R, alg: CompressionType) -> Self { match alg { CompressionType::Gzip => { let inner = GzDecoder::new(src); Self::Gzip(inner) }, CompressionType::Bzip2 => { let inner = BzDecoder::new(src); Self::Bzip2(inner) }, } } } impl Read for Decoder { fn read(&mut self, buf: &mut [u8]) -> io::Result { match self { Self::Gzip(inner) => inner.read(buf), Self::Bzip2(inner) => inner.read(buf), } } }