1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
use tokio::{spawn, task::JoinHandle};

use crate::{
    icomponent_function::IComponentFunction,
    types::{Input, Output},
    IComponent,
};

/// Обобщенный компонент
pub struct Component<TMessage, TConfig> {
    pub input: Option<Input<TMessage>>,
    pub output: Option<Output<TMessage>>,
    pub config: Option<TConfig>,
    pub function: Box<dyn IComponentFunction<TMessage, TConfig>>,
}

impl<TMessage, TConfig> Component<TMessage, TConfig> {
    pub fn new(
        config: TConfig,
        func: impl IComponentFunction<TMessage, TConfig> + 'static,
    ) -> Self {
        Self {
            input: None,
            output: None,
            config: Some(config),
            function: Box::new(func),
        }
    }
}

impl<TMessage, TConfig> IComponent<TMessage> for Component<TMessage, TConfig> {
    fn set_input(&mut self, stream_input: Input<TMessage>) {
        self.input = Some(stream_input);
    }

    fn set_output(&mut self, stream_output: Output<TMessage>) {
        self.output = Some(stream_output);
    }

    fn spawn(&mut self) -> JoinHandle<()> {
        let input = self.input.take().unwrap();
        let output = self.output.take().unwrap();
        let config = self.config.take().unwrap();
        spawn(self.function.call(input, output, config))
    }
}
// TODO - удалить unwrap. Возможно дропать компонент в spawn()?