use core::fmt;
use super::{
DecodeLifecycleOutput,
DecodeLifecycleProgress,
ValueDecoder,
};
use crate::{
Codec,
TranscodeDecodeErrorOf,
TranscodeFailure,
codec::assert_unit_bounds,
value::codec_value_lifecycle::decode_exact_complete_value,
};
pub struct CodecValueDecoder<C>
where
C: Codec,
{
codec: C,
}
impl<C> CodecValueDecoder<C>
where
C: Codec,
{
#[inline]
#[must_use]
pub fn new(codec: C) -> Self {
assert_unit_bounds::<C>();
Self { codec }
}
#[inline(always)]
#[must_use]
pub const fn codec(&self) -> &C {
&self.codec
}
#[inline(always)]
#[must_use]
pub fn codec_mut(&mut self) -> &mut C {
&mut self.codec
}
#[inline(always)]
#[must_use]
pub fn into_codec(self) -> C {
self.codec
}
pub fn decode(
&mut self,
input: &[C::Unit],
) -> Result<C::Value, TranscodeDecodeErrorOf<C>> {
TranscodeFailure::ensure_no_decode_lifecycle_output::<C>()?;
let (value, reset_written, finish_written) =
decode_exact_complete_value(
&mut self.codec,
input,
&mut [],
&mut [],
)?;
debug_assert_eq!(0, reset_written);
debug_assert_eq!(0, finish_written);
Ok(value)
}
pub fn decode_lifecycle(
&mut self,
input: &[C::Unit],
) -> Result<DecodeLifecycleOutput<C::Value>, TranscodeDecodeErrorOf<C>>
where
C::Value: Default,
{
let mut reset = Vec::new();
reset
.try_reserve(C::MAX_DECODE_RESET_VALUES)
.map_err(|_| TranscodeFailure::allocation_failed())?;
reset.resize_with(C::MAX_DECODE_RESET_VALUES, C::Value::default);
let mut finish = Vec::new();
finish
.try_reserve(C::MAX_DECODE_FINISH_VALUES)
.map_err(|_| TranscodeFailure::allocation_failed())?;
finish.resize_with(C::MAX_DECODE_FINISH_VALUES, C::Value::default);
let (value, reset_written, finish_written) = self
.decode_lifecycle_with_scratch(input, &mut reset, &mut finish)?
.into_parts();
reset.truncate(reset_written);
finish.truncate(finish_written);
Ok(DecodeLifecycleOutput::new(reset, value, finish))
}
pub fn decode_lifecycle_with_scratch(
&mut self,
input: &[C::Unit],
reset_output: &mut [C::Value],
finish_output: &mut [C::Value],
) -> Result<DecodeLifecycleProgress<C::Value>, TranscodeDecodeErrorOf<C>>
{
let (value, reset_written, finish_written) =
decode_exact_complete_value(
&mut self.codec,
input,
reset_output,
finish_output,
)?;
Ok(DecodeLifecycleProgress::new(
value,
reset_written,
finish_written,
))
}
}
impl<C> ValueDecoder<[C::Unit]> for CodecValueDecoder<C>
where
C: Codec,
{
type Output = C::Value;
type Error = TranscodeDecodeErrorOf<C>;
#[inline(always)]
fn decode(
&mut self,
input: &[C::Unit],
) -> Result<Self::Output, Self::Error> {
self.decode(input)
}
}
impl<C> fmt::Debug for CodecValueDecoder<C>
where
C: Codec + fmt::Debug,
{
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter
.debug_struct("CodecValueDecoder")
.field("codec", &self.codec)
.finish()
}
}
impl<C> Default for CodecValueDecoder<C>
where
C: Codec + Default,
{
#[inline(always)]
fn default() -> Self {
Self::new(C::default())
}
}