Skip to main content

enact_core/graph/node/
function.rs

1//! Function node - wraps an async function as a node
2
3use super::{Node, NodeState};
4use async_trait::async_trait;
5use std::future::Future;
6use std::pin::Pin;
7use std::sync::Arc;
8
9/// Type alias for async node functions
10pub type NodeFn = Arc<
11    dyn Fn(NodeState) -> Pin<Box<dyn Future<Output = anyhow::Result<NodeState>> + Send>>
12        + Send
13        + Sync,
14>;
15
16/// Function node - wraps an async closure
17pub struct FunctionNode {
18    name: String,
19    func: NodeFn,
20}
21
22impl FunctionNode {
23    pub fn new<F, Fut>(name: impl Into<String>, func: F) -> Self
24    where
25        F: Fn(NodeState) -> Fut + Send + Sync + 'static,
26        Fut: Future<Output = anyhow::Result<NodeState>> + Send + 'static,
27    {
28        let func = Arc::new(move |state: NodeState| {
29            let fut = func(state);
30            Box::pin(fut) as Pin<Box<dyn Future<Output = anyhow::Result<NodeState>> + Send>>
31        });
32
33        Self {
34            name: name.into(),
35            func,
36        }
37    }
38}
39
40#[async_trait]
41impl Node for FunctionNode {
42    fn name(&self) -> &str {
43        &self.name
44    }
45
46    async fn execute(&self, state: NodeState) -> anyhow::Result<NodeState> {
47        (self.func)(state).await
48    }
49}