futuresdr/blocks/
copy.rs

1use crate::prelude::*;
2
3/// Copy input samples to the output.
4#[derive(Block)]
5pub struct Copy<
6    T: Send + Sync + 'static,
7    I: CpuBufferReader<Item = T> = DefaultCpuReader<T>,
8    O: CpuBufferWriter<Item = T> = DefaultCpuWriter<T>,
9> {
10    #[input]
11    input: I,
12    #[output]
13    output: O,
14}
15
16impl<T, I, O> Copy<T, I, O>
17where
18    T: Send + Sync + 'static,
19    I: CpuBufferReader<Item = T>,
20    O: CpuBufferWriter<Item = T>,
21{
22    /// Create [`struct@Copy`] block
23    pub fn new() -> Self {
24        Self {
25            input: I::default(),
26            output: O::default(),
27        }
28    }
29}
30
31impl<T, I, O> Default for Copy<T, I, O>
32where
33    T: Send + Sync + 'static,
34    I: CpuBufferReader<Item = T>,
35    O: CpuBufferWriter<Item = T>,
36{
37    fn default() -> Self {
38        Self::new()
39    }
40}
41
42#[doc(hidden)]
43impl<T, I, O> Kernel for Copy<T, I, O>
44where
45    T: std::marker::Copy + Send + Sync + 'static,
46    I: CpuBufferReader<Item = T>,
47    O: CpuBufferWriter<Item = T>,
48{
49    async fn work(
50        &mut self,
51        io: &mut WorkIo,
52        _mio: &mut MessageOutputs,
53        _meta: &mut BlockMeta,
54    ) -> Result<()> {
55        let i = self.input.slice();
56        let o = self.output.slice();
57        let i_len = i.len();
58
59        let m = std::cmp::min(i.len(), o.len());
60        if m > 0 {
61            o[..m].copy_from_slice(&i[..m]);
62            self.input.consume(m);
63            self.output.produce(m);
64        }
65
66        if self.input.finished() && m == i_len {
67            io.finished = true;
68        }
69
70        Ok(())
71    }
72}