use crate::{CmsError, TransformExecutor};
use std::marker::PhantomData;
pub(crate) trait KatanaInitialStage<W, I> {
fn to_pcs(&self, input: &[I]) -> Result<Vec<W>, CmsError>;
}
pub(crate) trait KatanaFinalStage<W, I> {
fn to_output(&self, src: &mut [W], dst: &mut [I]) -> Result<(), CmsError>;
}
pub(crate) trait KatanaIntermediateStage<W> {
fn stage(&self, input: &mut Vec<W>) -> Result<Vec<W>, CmsError>;
}
pub(crate) struct BlackholeIntermediateStage<W> {
pub(crate) _phantom: PhantomData<W>,
}
impl<W> KatanaIntermediateStage<W> for BlackholeIntermediateStage<W> {
fn stage(&self, input: &mut Vec<W>) -> Result<Vec<W>, CmsError> {
Ok(std::mem::take(input))
}
}
pub(crate) trait KatanaPostFinalizationStage<I> {
fn finalize(&self, src: &[I], dst: &mut [I]) -> Result<(), CmsError>;
}
pub(crate) struct Katana<W, I> {
pub(crate) initial_stage: Box<dyn KatanaInitialStage<W, I> + Send + Sync>,
pub(crate) final_stage: Box<dyn KatanaFinalStage<W, I> + Sync + Send>,
pub(crate) stages: Vec<Box<dyn KatanaIntermediateStage<W> + Send + Sync>>,
pub(crate) post_finalization: Vec<Box<dyn KatanaPostFinalizationStage<I> + Send + Sync>>,
}
impl<W, I: Copy + Default> TransformExecutor<I> for Katana<W, I> {
fn transform(&self, src: &[I], dst: &mut [I]) -> Result<(), CmsError> {
let mut working_vec = self.initial_stage.to_pcs(src)?;
for stage in self.stages.iter() {
working_vec = stage.stage(&mut working_vec)?;
}
self.final_stage.to_output(&mut working_vec, dst)?;
for finalization in self.post_finalization.iter() {
finalization.finalize(src, dst)?;
}
Ok(())
}
}