use super::{Node, NodeState};
use async_trait::async_trait;
use std::future::Future;
use std::pin::Pin;
use std::sync::Arc;
pub type NodeFn = Arc<
dyn Fn(NodeState) -> Pin<Box<dyn Future<Output = anyhow::Result<NodeState>> + Send>>
+ Send
+ Sync,
>;
pub struct FunctionNode {
name: String,
func: NodeFn,
}
impl FunctionNode {
pub fn new<F, Fut>(name: impl Into<String>, func: F) -> Self
where
F: Fn(NodeState) -> Fut + Send + Sync + 'static,
Fut: Future<Output = anyhow::Result<NodeState>> + Send + 'static,
{
let func = Arc::new(move |state: NodeState| {
let fut = func(state);
Box::pin(fut) as Pin<Box<dyn Future<Output = anyhow::Result<NodeState>> + Send>>
});
Self {
name: name.into(),
func,
}
}
}
#[async_trait]
impl Node for FunctionNode {
fn name(&self) -> &str {
&self.name
}
async fn execute(&self, state: NodeState) -> anyhow::Result<NodeState> {
(self.func)(state).await
}
}