use core::num::NonZeroUsize;
use super::super::engine::DecodeContext;
use super::super::engine::DecodeOutcome;
use super::super::transcode_progress::TranscodeProgress;
use super::transcode_state::TranscodeState;
pub(in crate::transcode) struct DecodeState<'a, Unit, Value> {
state: TranscodeState<'a, Unit, Value>,
}
impl<'a, Unit, Value> DecodeState<'a, Unit, Value> {
#[inline]
#[must_use]
pub(in crate::transcode) fn new(
input: &'a [Unit],
input_index: usize,
output: &'a mut [Value],
output_index: usize,
) -> Self {
Self {
state: TranscodeState::new(input, input_index, output, output_index),
}
}
#[inline]
#[must_use]
pub(in crate::transcode) fn output_mut(&mut self) -> &mut [Value] {
self.state.output_mut()
}
#[inline]
#[must_use]
pub(in crate::transcode) fn output_cursor(&self) -> usize {
self.state.output_cursor()
}
#[inline]
#[must_use]
pub(in crate::transcode) fn has_input(&self) -> bool {
self.state.has_input()
}
#[inline]
#[must_use]
pub(in crate::transcode) fn needs_output(&self) -> bool {
self.state.needs_output()
}
#[inline]
#[must_use]
pub(in crate::transcode) fn context(&self) -> DecodeContext {
DecodeContext::new(
self.state.input_start(),
self.state.input_cursor(),
self.state.output_start(),
self.state.output_cursor(),
self.available(),
)
}
#[inline]
pub(in crate::transcode) fn complete_progress(&self) -> TranscodeProgress {
self.state.complete_progress()
}
#[inline]
pub(in crate::transcode) fn need_output_progress(&self) -> TranscodeProgress {
self.state.need_output_progress(NonZeroUsize::MIN)
}
#[inline]
pub(in crate::transcode) fn need_input_progress_with(&self, required: NonZeroUsize) -> TranscodeProgress {
self.state.need_input_progress(required)
}
#[inline]
pub(in crate::transcode) fn skip(&mut self, read: NonZeroUsize) {
let read = read.get();
assert!(
read <= self.available(),
"DecodeOutcome::Skipped read beyond available input",
);
self.state.advance_input(read);
}
#[inline]
pub(in crate::transcode) fn accept_emitted(&mut self, read: NonZeroUsize, emitted: NonZeroUsize) {
let read = read.get();
let emitted = emitted.get();
assert!(
read <= self.available(),
"DecodeOutcome::Emitted read beyond available input",
);
assert!(
emitted <= self.state.available_output(),
"DecodeOutcome::Emitted exceeded available output",
);
self.state.advance(read, emitted);
}
#[inline]
pub(in crate::transcode) fn apply_decode_outcome(&mut self, outcome: DecodeOutcome) -> Option<TranscodeProgress> {
match outcome {
DecodeOutcome::Emitted { read, emitted } => {
self.accept_emitted(read, emitted);
None
}
DecodeOutcome::Skipped { read } => {
self.skip(read);
None
}
DecodeOutcome::NeedInput { required } => Some(self.need_input_progress_with(required)),
}
}
#[inline]
#[must_use]
fn available(&self) -> usize {
self.state.available_input()
}
}