use core::{
fmt,
hash::{
Hash,
Hasher,
},
};
use super::CodecTranscodeConvertHooks;
use crate::{
CapacityError,
Codec,
CodecConvertError,
TranscodeConvertEngine,
TranscodeConverter,
TranscodeError,
TranscodeProgress,
Transcoder,
};
type CodecTranscodeConvertError<D, E> =
CodecConvertError<<D as Codec>::DecodeError, <E as Codec>::EncodeError>;
pub struct CodecTranscodeConverter<D, E>
where
D: Codec,
E: Codec<Value = D::Value>,
{
engine: TranscodeConvertEngine<D, E, CodecTranscodeConvertHooks>,
}
impl<D, E> Clone for CodecTranscodeConverter<D, E>
where
D: Codec,
E: Codec<Value = D::Value>,
TranscodeConvertEngine<D, E, CodecTranscodeConvertHooks>: Clone,
{
#[inline(always)]
fn clone(&self) -> Self {
Self {
engine: self.engine.clone(),
}
}
}
impl<D, E> fmt::Debug for CodecTranscodeConverter<D, E>
where
D: Codec,
E: Codec<Value = D::Value>,
TranscodeConvertEngine<D, E, CodecTranscodeConvertHooks>: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("CodecTranscodeConverter")
.field("engine", &self.engine)
.finish()
}
}
impl<D, E> Default for CodecTranscodeConverter<D, E>
where
D: Codec,
E: Codec<Value = D::Value>,
TranscodeConvertEngine<D, E, CodecTranscodeConvertHooks>: Default,
{
#[inline(always)]
fn default() -> Self {
Self {
engine: TranscodeConvertEngine::default(),
}
}
}
impl<D, E> Eq for CodecTranscodeConverter<D, E>
where
D: Codec,
E: Codec<Value = D::Value>,
TranscodeConvertEngine<D, E, CodecTranscodeConvertHooks>: Eq,
{
}
impl<D, E> Hash for CodecTranscodeConverter<D, E>
where
D: Codec,
E: Codec<Value = D::Value>,
TranscodeConvertEngine<D, E, CodecTranscodeConvertHooks>: Hash,
{
#[inline(always)]
fn hash<S: Hasher>(&self, state: &mut S) {
self.engine.hash(state);
}
}
impl<D, E> PartialEq for CodecTranscodeConverter<D, E>
where
D: Codec,
E: Codec<Value = D::Value>,
TranscodeConvertEngine<D, E, CodecTranscodeConvertHooks>: PartialEq,
{
#[inline(always)]
fn eq(&self, other: &Self) -> bool {
self.engine == other.engine
}
}
impl<D, E> CodecTranscodeConverter<D, E>
where
D: Codec,
E: Codec<Value = D::Value>,
{
#[must_use]
#[inline(always)]
pub fn new(decoder: D, encoder: E) -> Self {
Self {
engine: TranscodeConvertEngine::new(
decoder,
encoder,
CodecTranscodeConvertHooks::new(),
),
}
}
#[must_use = "capacity planning can fail on overflow"]
#[inline(always)]
pub fn max_output_len(
&self,
input_len: usize,
) -> Result<usize, CapacityError> {
self.engine.max_output_len(input_len)
}
#[must_use = "capacity planning can fail on overflow"]
#[inline(always)]
pub fn max_finish_output_len(&self) -> Result<usize, CapacityError> {
self.engine.max_finish_output_len()
}
#[must_use = "capacity planning can fail on overflow"]
#[inline(always)]
pub fn max_reset_output_len(&self) -> Result<usize, CapacityError> {
self.engine.max_reset_output_len()
}
#[inline(always)]
pub fn reset(
&mut self,
output: &mut [E::Unit],
output_index: usize,
) -> Result<usize, TranscodeError<CodecTranscodeConvertError<D, E>>> {
self.engine.reset(output, output_index)
}
#[inline(always)]
pub fn transcode(
&mut self,
input: &[D::Unit],
input_index: usize,
output: &mut [E::Unit],
output_index: usize,
) -> Result<
TranscodeProgress,
TranscodeError<CodecTranscodeConvertError<D, E>>,
> {
self.engine
.transcode(input, input_index, output, output_index)
}
#[inline(always)]
pub fn finish(
&mut self,
output: &mut [E::Unit],
output_index: usize,
) -> Result<usize, TranscodeError<CodecTranscodeConvertError<D, E>>> {
self.engine.finish(output, output_index)
}
}
impl<D, E> Transcoder<D::Unit, E::Unit> for CodecTranscodeConverter<D, E>
where
D: Codec,
E: Codec<Value = D::Value>,
{
type Error = CodecConvertError<D::DecodeError, E::EncodeError>;
#[inline(always)]
fn max_output_len(&self, input_len: usize) -> Result<usize, CapacityError> {
CodecTranscodeConverter::max_output_len(self, input_len)
}
#[inline(always)]
fn max_finish_output_len(&self) -> Result<usize, CapacityError> {
CodecTranscodeConverter::max_finish_output_len(self)
}
#[inline(always)]
fn max_reset_output_len(&self) -> Result<usize, CapacityError> {
CodecTranscodeConverter::max_reset_output_len(self)
}
#[inline(always)]
fn reset(
&mut self,
output: &mut [E::Unit],
output_index: usize,
) -> Result<usize, TranscodeError<Self::Error>> {
CodecTranscodeConverter::reset(self, output, output_index)
}
#[inline(always)]
fn transcode(
&mut self,
input: &[D::Unit],
input_index: usize,
output: &mut [E::Unit],
output_index: usize,
) -> Result<TranscodeProgress, TranscodeError<Self::Error>> {
CodecTranscodeConverter::transcode(
self,
input,
input_index,
output,
output_index,
)
}
#[inline(always)]
fn finish(
&mut self,
output: &mut [E::Unit],
output_index: usize,
) -> Result<usize, TranscodeError<Self::Error>> {
CodecTranscodeConverter::finish(self, output, output_index)
}
}
impl<D, E> TranscodeConverter<D::Unit, E::Unit>
for CodecTranscodeConverter<D, E>
where
D: Codec,
E: Codec<Value = D::Value>,
{
}