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
//! Трейт для функции компонента
//!
//! https://stackoverflow.com/questions/58173711/how-can-i-store-an-async-function-in-a-struct-and-call-it-from-a-struct-instance
//!

use std::future::Future;

use futures::future::BoxFuture;

use crate::{
    error::ComponentError,
    types::{ComponentInput, ComponentOutput},
    Cache,
};

/// Трейт для функции компонента
pub trait IComponentFunction<TMessage, TConfig>: Send {
    fn call(
        &self,
        input: ComponentInput<TMessage>,
        output: ComponentOutput<TMessage>,
        config: TConfig,
        cache: Cache<TMessage>,
    ) -> BoxFuture<'static, Result<(), ComponentError>>;
}

impl<T, F, TMessage, TConfig> IComponentFunction<TMessage, TConfig> for T
where
    T: Fn(ComponentInput<TMessage>, ComponentOutput<TMessage>, TConfig, Cache<TMessage>) -> F
        + Send,
    F: Future<Output = Result<(), ComponentError>> + 'static + Send,
{
    fn call(
        &self,
        input: ComponentInput<TMessage>,
        output: ComponentOutput<TMessage>,
        config: TConfig,
        cache: Cache<TMessage>,
    ) -> BoxFuture<'static, Result<(), ComponentError>> {
        Box::pin(self(input, output, config, cache))
    }
}