Skip to main content

coreon_eip/
choice.rs

1//! Choice — evaluate predicates in order; run the first matching branch,
2//! or the `otherwise` branch if none match. If no otherwise is set, the
3//! exchange passes through unchanged.
4
5use async_trait::async_trait;
6use coreon_core::{processor::Predicate, Exchange, Processor, Result};
7use std::sync::Arc;
8
9pub struct WhenClause {
10    predicate: Arc<dyn Predicate>,
11    then: Arc<dyn Processor>,
12}
13
14impl WhenClause {
15    pub fn new(predicate: Arc<dyn Predicate>, then: Arc<dyn Processor>) -> Self {
16        Self { predicate, then }
17    }
18}
19
20pub struct Choice {
21    clauses: Vec<WhenClause>,
22    otherwise: Option<Arc<dyn Processor>>,
23}
24
25impl Choice {
26    pub fn new(clauses: Vec<WhenClause>, otherwise: Option<Arc<dyn Processor>>) -> Arc<Self> {
27        Arc::new(Self { clauses, otherwise })
28    }
29}
30
31#[async_trait]
32impl Processor for Choice {
33    async fn process(&self, exchange: &mut Exchange) -> Result<()> {
34        for clause in &self.clauses {
35            if clause.predicate.matches(exchange) {
36                return clause.then.process(exchange).await;
37            }
38        }
39        if let Some(o) = &self.otherwise {
40            return o.process(exchange).await;
41        }
42        Ok(())
43    }
44}