Skip to main content

synaptic_runnables/
branch.rs

1use async_trait::async_trait;
2use synaptic_core::{RunnableConfig, SynapseError};
3
4use crate::runnable::{BoxRunnable, Runnable};
5
6type BranchCondition<I> = Box<dyn Fn(&I) -> bool + Send + Sync>;
7
8/// Routes input to different runnables based on condition functions.
9/// The first matching condition's runnable is invoked. If none match,
10/// the default runnable is used.
11pub struct RunnableBranch<I: Send + 'static, O: Send + 'static> {
12    branches: Vec<(BranchCondition<I>, BoxRunnable<I, O>)>,
13    default: BoxRunnable<I, O>,
14}
15
16impl<I: Send + 'static, O: Send + 'static> RunnableBranch<I, O> {
17    pub fn new(
18        branches: Vec<(BranchCondition<I>, BoxRunnable<I, O>)>,
19        default: BoxRunnable<I, O>,
20    ) -> Self {
21        Self { branches, default }
22    }
23}
24
25#[async_trait]
26impl<I: Send + 'static, O: Send + 'static> Runnable<I, O> for RunnableBranch<I, O> {
27    async fn invoke(&self, input: I, config: &RunnableConfig) -> Result<O, SynapseError> {
28        for (condition, runnable) in &self.branches {
29            if condition(&input) {
30                return runnable.invoke(input, config).await;
31            }
32        }
33        self.default.invoke(input, config).await
34    }
35}