use super::{core::driver::Driver, *};
use std::io::{self, Read};
#[derive(Debug)]
pub struct FramedEncoderReader<'c, 'input> {
driver: Driver<'c, 'input>,
deferred: Option<FramedEncodeError>,
failed: bool,
}
impl FramedCompressor {
pub fn framed_reader<'c, 'input>(
&'c mut self,
input: FramedInput<'input>,
stream: FramedEncodeStreamConfig,
) -> Result<FramedEncoderReader<'c, 'input>, FramedEncodeError> {
Driver::aggregate(input)?;
Ok(FramedEncoderReader {
driver: Driver::new(self.start(stream)?, input),
deferred: None,
failed: false,
})
}
}
impl<'input> FramedEncoderReader<'_, 'input> {
#[must_use]
pub fn into_inner(self) -> FramedInput<'input> {
self.driver.input
}
}
impl Read for FramedEncoderReader<'_, '_> {
fn read(&mut self, output: &mut [u8]) -> io::Result<usize> {
if output.is_empty() {
return Ok(0);
}
if let Some(error) = self.deferred.take() {
return Err(error.into());
}
if self.failed {
return Err(FramedEncodeError::InvalidState.into());
}
match self.driver.process(output) {
Ok(p) => Ok(p.produced),
Err(e) => {
self.failed = true;
if e.produced != 0 {
self.deferred = Some(e.error);
Ok(e.produced)
} else {
Err(e.error.into())
}
}
}
}
}