Skip to main content

synaptic_runnables/
lambda.rs

1use std::future::Future;
2use std::pin::Pin;
3
4use async_trait::async_trait;
5use synaptic_core::{RunnableConfig, SynapseError};
6
7use crate::Runnable;
8
9type AsyncFn<I, O> =
10    dyn Fn(I) -> Pin<Box<dyn Future<Output = Result<O, SynapseError>> + Send>> + Send + Sync;
11
12/// Wraps an async closure as a `Runnable`.
13///
14/// ```ignore
15/// let upper = RunnableLambda::new(|s: String| async move {
16///     Ok(s.to_uppercase())
17/// });
18/// ```
19pub struct RunnableLambda<I: Send + 'static, O: Send + 'static> {
20    func: Box<AsyncFn<I, O>>,
21}
22
23impl<I: Send + 'static, O: Send + 'static> RunnableLambda<I, O> {
24    pub fn new<F, Fut>(func: F) -> Self
25    where
26        F: Fn(I) -> Fut + Send + Sync + 'static,
27        Fut: Future<Output = Result<O, SynapseError>> + Send + 'static,
28    {
29        Self {
30            func: Box::new(move |input| Box::pin(func(input))),
31        }
32    }
33}
34
35#[async_trait]
36impl<I: Send + 'static, O: Send + 'static> Runnable<I, O> for RunnableLambda<I, O> {
37    async fn invoke(&self, input: I, _config: &RunnableConfig) -> Result<O, SynapseError> {
38        (self.func)(input).await
39    }
40}