pictorus_blocks/core_blocks/
passthrough_block.rs1extern crate alloc;
5
6use crate::traits::DefaultStorage;
7use pictorus_block_data::{BlockData as OldBlockData, FromPass};
8use pictorus_traits::{PassBy, ProcessBlock};
9
10#[doc(hidden)]
15pub struct PassthroughBlock<T: DefaultStorage>
16where
17 OldBlockData: FromPass<T>,
18{
19 pub data: OldBlockData,
20 buffer: T::Storage,
21}
22
23impl<T: DefaultStorage> Default for PassthroughBlock<T>
24where
25 OldBlockData: FromPass<T>,
26{
27 fn default() -> Self {
28 Self {
29 data: <OldBlockData as FromPass<T>>::from_pass(<T as DefaultStorage>::from_storage(
30 &T::default_storage(),
31 )),
32 buffer: T::default_storage(),
33 }
34 }
35}
36
37#[doc(hidden)]
38#[derive(Default)]
39pub struct Parameters;
40
41impl Parameters {
42 pub fn new() -> Parameters {
43 Parameters {}
44 }
45}
46
47impl<T: DefaultStorage> ProcessBlock for PassthroughBlock<T>
48where
49 OldBlockData: FromPass<T>,
50{
51 type Parameters = Parameters;
52 type Inputs = T;
53 type Output = T;
54
55 fn process<'b>(
56 &'b mut self,
57 _parameters: &Self::Parameters,
58 _context: &dyn pictorus_traits::Context,
59 input: PassBy<'_, Self::Inputs>,
60 ) -> pictorus_traits::PassBy<'b, Self::Output> {
61 T::copy_into(input, &mut self.buffer);
62 let res = <T as DefaultStorage>::from_storage(&self.buffer);
63 self.data = <OldBlockData as FromPass<T>>::from_pass(res);
64 res
65 }
66}
67
68#[cfg(test)]
69mod tests {
70 use crate::testing::StubContext;
71 use pictorus_traits::{ByteSliceSignal, Matrix, Pass};
72
73 use super::*;
74
75 #[test]
76 fn test_passthrough_block_scalar() {
77 let ctxt = StubContext::default();
78 let params = Parameters;
79 let mut block = PassthroughBlock::<f64>::default();
80
81 let input = 99.999;
82 let output = block.process(¶ms, &ctxt, input.as_by());
83 assert_eq!(output, input);
84 assert_eq!(block.data.scalar(), input);
85 }
86
87 #[test]
88 fn test_passthrough_block_bytes() {
89 let ctxt = StubContext::default();
90 let params = Parameters;
91 let mut block = PassthroughBlock::<ByteSliceSignal>::default();
92
93 let input = b"hello world";
94 let output = block.process(¶ms, &ctxt, input.as_slice());
95 assert_eq!(output, input);
96 assert_eq!(block.data.to_raw_bytes(), input);
97
98 let input = b"";
99 let output = block.process(¶ms, &ctxt, input.as_slice());
100 assert_eq!(output, input);
101 assert_eq!(block.data.to_raw_bytes(), input);
102 }
103
104 #[test]
105 fn test_passthrough_block_matrix() {
106 let ctxt = StubContext::default();
107 let params = Parameters;
108 let mut block = PassthroughBlock::<Matrix<2, 2, f64>>::default();
109
110 let input = Matrix {
111 data: [[1.0, 2.0], [3.0, 4.0]],
112 };
113 let output = block.process(¶ms, &ctxt, input.as_by());
114 assert_eq!(output, &input);
115 assert_eq!(block.data.get_data().as_slice(), input.data.as_flattened());
116 }
117}