use core::fmt;
use qubit_utils::try_reserve_vec;
use super::DecodeLifecycleOutput;
use super::DecodeLifecycleProgress;
use super::ValueDecoder;
use crate::Codec;
use crate::TranscodeDecodeErrorOf;
use crate::TranscodeFailure;
use crate::codec::assert_unit_bounds;
use crate::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]
#[must_use]
pub const fn codec(&self) -> &C {
&self.codec
}
#[inline]
#[must_use]
pub fn codec_mut(&mut self) -> &mut C {
&mut self.codec
}
#[inline]
#[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();
try_reserve_vec(&mut reset, 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();
try_reserve_vec(&mut finish, 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]
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,
{
fn default() -> Self {
Self::new(C::default())
}
}