use std::io;
use flate2::read::ZlibDecoder;
use lzma_rust2::LzmaReader;
use crate::LzmaStreamHeader;
pub enum Decoder<R: io::Read> {
Stored(R),
Zlib(ZlibDecoder<R>),
Lzma1(Box<LzmaReader<R>>),
}
impl<R: io::Read> Decoder<R> {
pub fn new_lzma1(reader: R, header: LzmaStreamHeader) -> lzma_rust2::Result<Self> {
LzmaReader::new_with_props(
reader,
u64::MAX,
header.props(),
header.dictionary_size(),
None,
)
.map(|reader| Self::Lzma1(Box::new(reader)))
}
pub fn new_zlib(reader: R) -> Self {
Self::Zlib(ZlibDecoder::new(reader))
}
#[must_use]
#[inline]
pub const fn is_compressed(&self) -> bool {
!self.is_stored()
}
#[must_use]
#[inline]
pub const fn is_stored(&self) -> bool {
matches!(self, Self::Stored(_))
}
#[must_use]
#[inline]
pub const fn is_zlib(&self) -> bool {
matches!(self, Self::Zlib(_))
}
#[must_use]
#[inline]
pub const fn is_lzma1(&self) -> bool {
matches!(self, Self::Lzma1(_))
}
#[must_use]
pub fn get_ref(&self) -> &R {
match self {
Self::Stored(reader) => reader,
Self::Zlib(reader) => reader.get_ref(),
Self::Lzma1(reader) => reader.inner(),
}
}
#[must_use]
pub fn get_mut(&mut self) -> &mut R {
match self {
Self::Stored(reader) => reader,
Self::Zlib(reader) => reader.get_mut(),
Self::Lzma1(reader) => reader.inner_mut(),
}
}
#[must_use]
pub fn into_inner(self) -> R {
match self {
Self::Stored(reader) => reader,
Self::Zlib(reader) => reader.into_inner(),
Self::Lzma1(reader) => reader.into_inner(),
}
}
}
impl<R: io::Read> io::Read for Decoder<R> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
match self {
Self::Stored(reader) => reader.read(buf),
Self::Zlib(reader) => reader.read(buf),
Self::Lzma1(reader) => reader.read(buf),
}
}
}