use core::num::NonZeroUsize;
use super::internal::decode_step::DecodeStep;
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum DecodeAction<Value> {
NeedInput {
required_total: usize,
},
Skip {
consumed: NonZeroUsize,
},
Emit {
value: Value,
consumed: NonZeroUsize,
},
}
impl<Value> DecodeAction<Value> {
#[must_use]
#[inline]
pub(super) fn into_step(
self,
input_index: usize,
available: usize,
) -> DecodeStep<Value> {
match self {
Self::NeedInput { required_total } => DecodeStep::need_input(
Self::missing_input(required_total, available),
available,
),
Self::Skip { consumed } => {
DecodeStep::skipped(Self::bound_consumed(consumed, available))
}
Self::Emit { value, consumed } => DecodeStep::decoded(
value,
Self::bound_consumed(consumed, available),
input_index,
),
}
}
#[must_use]
#[inline(always)]
fn missing_input(required_total: usize, available: usize) -> NonZeroUsize {
assert!(
required_total > available,
"DecodeAction::NeedInput required_total must exceed available input",
);
let additional = required_total - available;
qubit_io::nz(additional)
}
#[must_use]
#[inline(always)]
fn bound_consumed(
consumed: NonZeroUsize,
available: usize,
) -> NonZeroUsize {
assert!(available > 0, "DecodeAction cannot consume empty input");
assert!(
consumed.get() <= available,
"DecodeAction consumed units must not exceed available input",
);
consumed
}
}