use std::sync::Arc;
use entelix_core::{ExecutionContext, Result};
use futures::future::BoxFuture;
use crate::runnable::Runnable;
type LambdaFn<I, O> = dyn Fn(I, ExecutionContext) -> BoxFuture<'static, Result<O>> + Send + Sync;
pub struct RunnableLambda<I, O>
where
I: Send + 'static,
O: Send + 'static,
{
inner: Arc<LambdaFn<I, O>>,
}
impl<I, O> RunnableLambda<I, O>
where
I: Send + 'static,
O: Send + 'static,
{
pub fn new<F, Fut>(f: F) -> Self
where
F: Fn(I, ExecutionContext) -> Fut + Send + Sync + 'static,
Fut: core::future::Future<Output = Result<O>> + Send + 'static,
{
Self {
inner: Arc::new(move |input, ctx| Box::pin(f(input, ctx))),
}
}
}
impl<I, O> Clone for RunnableLambda<I, O>
where
I: Send + 'static,
O: Send + 'static,
{
fn clone(&self) -> Self {
Self {
inner: Arc::clone(&self.inner),
}
}
}
#[async_trait::async_trait]
impl<I, O> Runnable<I, O> for RunnableLambda<I, O>
where
I: Send + 'static,
O: Send + 'static,
{
async fn invoke(&self, input: I, ctx: &ExecutionContext) -> Result<O> {
(self.inner)(input, ctx.clone()).await
}
}