use super::{core::Tag, *};
use crate::DecodeOperation;
#[derive(Debug)]
pub struct FramedDecodeProgress<'a> {
pub consumed: usize,
pub produced: usize,
pub status: FramedDecoderStatus<'a>,
}
#[derive(Debug)]
pub enum FramedDecoderStatus<'a> {
NeedsInput,
NeedsOutput,
Event(FramedEvent<'a>),
Finished,
}
pub struct FramedDecoderSession<'d, 'dict> {
pub(super) owner: &'d mut FramedDecompressor,
pub(super) resolver: Option<DictionaryResolverRef<'dict>>,
}
impl FramedDecoderSession<'_, '_> {
#[expect(
clippy::result_large_err,
reason = "allocation-independent progress is part of the public contract"
)]
pub fn process<'a>(
&'a mut self,
input: &[u8],
output: &'a mut [u8],
operation: DecodeOperation,
) -> Result<FramedDecodeProgress<'a>, FramedDecodeFailure> {
let (consumed, produced, tag) = self.step(input, output, operation)?;
let status = match tag {
Tag::Input => FramedDecoderStatus::NeedsInput,
Tag::Output => FramedDecoderStatus::NeedsOutput,
Tag::Finished => FramedDecoderStatus::Finished,
_ => FramedDecoderStatus::Event(
self.owner
.engine
.event(tag, &output[..produced])
.ok_or(FramedDecodeFailure {
error: FramedDecodeError::InvalidState,
consumed,
produced,
last_output: None,
})?,
),
};
Ok(FramedDecodeProgress {
consumed,
produced,
status,
})
}
#[expect(
clippy::result_large_err,
reason = "allocation-independent progress is part of the public contract"
)]
pub(super) fn step(
&mut self,
input: &[u8],
output: &mut [u8],
operation: DecodeOperation,
) -> Result<(usize, usize, Tag), FramedDecodeFailure> {
self.owner
.engine
.process(input, output, operation, self.owner.backend, self.resolver)
}
pub const fn total_in(&self) -> u64 {
self.owner.engine.total_in
}
pub const fn total_out(&self) -> u64 {
self.owner.engine.total_out
}
pub const fn total_decoded(&self) -> u64 {
self.owner.engine.total_decoded
}
pub const fn resources_decoded(&self) -> u64 {
self.owner.engine.completed
}
pub const fn is_finished(&self) -> bool {
self.owner.engine.finished
}
pub const fn input_format(&self) -> Option<StreamInfo> {
self.owner.engine.format
}
}
impl Drop for FramedDecoderSession<'_, '_> {
fn drop(&mut self) {
self.owner.cancel();
}
}
impl ::core::fmt::Debug for FramedDecoderSession<'_, '_> {
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
f.debug_struct("FramedDecoderSession")
.field("total_in", &self.total_in())
.field("total_out", &self.total_out())
.field("format", &self.input_format())
.finish_non_exhaustive()
}
}