extern crate alloc;
use crate::traits::DefaultStorage;
use pictorus_block_data::{BlockData as OldBlockData, FromPass};
use pictorus_traits::{PassBy, ProcessBlock};
#[doc(hidden)]
pub struct PassthroughBlock<T: DefaultStorage>
where
OldBlockData: FromPass<T>,
{
pub data: OldBlockData,
buffer: T::Storage,
}
impl<T: DefaultStorage> Default for PassthroughBlock<T>
where
OldBlockData: FromPass<T>,
{
fn default() -> Self {
Self {
data: <OldBlockData as FromPass<T>>::from_pass(<T as DefaultStorage>::from_storage(
&T::default_storage(),
)),
buffer: T::default_storage(),
}
}
}
#[doc(hidden)]
#[derive(Default)]
pub struct Parameters;
impl Parameters {
pub fn new() -> Parameters {
Parameters {}
}
}
impl<T: DefaultStorage> ProcessBlock for PassthroughBlock<T>
where
OldBlockData: FromPass<T>,
{
type Parameters = Parameters;
type Inputs = T;
type Output = T;
fn process<'b>(
&'b mut self,
_parameters: &Self::Parameters,
_context: &dyn pictorus_traits::Context,
input: PassBy<'_, Self::Inputs>,
) -> pictorus_traits::PassBy<'b, Self::Output> {
T::copy_into(input, &mut self.buffer);
let res = <T as DefaultStorage>::from_storage(&self.buffer);
self.data = <OldBlockData as FromPass<T>>::from_pass(res);
res
}
}
#[cfg(test)]
mod tests {
use crate::testing::StubContext;
use pictorus_traits::{ByteSliceSignal, Matrix, Pass};
use super::*;
#[test]
fn test_passthrough_block_scalar() {
let ctxt = StubContext::default();
let params = Parameters;
let mut block = PassthroughBlock::<f64>::default();
let input = 99.999;
let output = block.process(¶ms, &ctxt, input.as_by());
assert_eq!(output, input);
assert_eq!(block.data.scalar(), input);
}
#[test]
fn test_passthrough_block_bytes() {
let ctxt = StubContext::default();
let params = Parameters;
let mut block = PassthroughBlock::<ByteSliceSignal>::default();
let input = b"hello world";
let output = block.process(¶ms, &ctxt, input.as_slice());
assert_eq!(output, input);
assert_eq!(block.data.to_raw_bytes(), input);
let input = b"";
let output = block.process(¶ms, &ctxt, input.as_slice());
assert_eq!(output, input);
assert_eq!(block.data.to_raw_bytes(), input);
}
#[test]
fn test_passthrough_block_matrix() {
let ctxt = StubContext::default();
let params = Parameters;
let mut block = PassthroughBlock::<Matrix<2, 2, f64>>::default();
let input = Matrix {
data: [[1.0, 2.0], [3.0, 4.0]],
};
let output = block.process(¶ms, &ctxt, input.as_by());
assert_eq!(output, &input);
assert_eq!(block.data.get_data().as_slice(), input.data.as_flattened());
}
}