use async_trait::async_trait;
use floxide::workflow;
use floxide::{FloxideError, Node, SplitNode, Transition, Workflow, WorkflowCtx};
#[derive(Clone, Debug)]
pub struct PrintNode;
#[async_trait]
impl Node<()> for PrintNode {
type Input = i32;
type Output = i32;
async fn process(
&self,
_ctx: &(),
input: i32,
) -> Result<Transition<Self::Output>, FloxideError> {
tracing::info!("PrintNode received: {}", input);
Ok(Transition::Next(input))
}
}
#[derive(Clone, Debug)]
pub struct TerminalNode;
#[async_trait]
impl Node<()> for TerminalNode {
type Input = i32;
type Output = i32;
async fn process(
&self,
_ctx: &(),
input: i32,
) -> Result<Transition<Self::Output>, FloxideError> {
Ok(Transition::Next(input))
}
}
fn splitter(n: i32) -> Vec<i32> {
vec![n - 1, n, n + 1]
}
workflow! {
pub struct SplitWorkflow {
split: SplitNode<i32, i32, fn(i32) -> Vec<i32>>,
print: PrintNode,
terminal: TerminalNode,
}
context = ();
start = split;
edges {
split => { [print] };
print => { [terminal] };
terminal => { [] };
}
}
async fn run_split_example() -> Result<(), FloxideError> {
let wf = SplitWorkflow {
split: SplitNode::new(splitter),
print: PrintNode,
terminal: TerminalNode,
};
let ctx = WorkflowCtx::new(());
wf.run(&ctx, 10).await?;
Ok(())
}
#[tokio::main]
async fn main() -> Result<(), FloxideError> {
tracing_subscriber::fmt()
.with_max_level(tracing::Level::DEBUG)
.init();
run_split_example().await?;
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn test_split_example() {
run_split_example().await.expect("split example failed");
}
}