modulink_rs/chains/
mod.rs1use std::sync::Arc;
18use std::future::Future;
19use std::pin::Pin;
20
21pub struct ChainGeneric<T> {
23 links: Vec<Arc<dyn Fn(T) -> Pin<Box<dyn Future<Output = T> + Send>> + Send + Sync>>,
24 middleware: Vec<Arc<dyn crate::middleware::Middleware<T>>>,
25 pub branches: Vec<Branch<T>>,
26}
27
28pub struct Branch<T> {
29 pub source: usize,
30 pub target: usize,
31 pub condition: Arc<dyn Fn(&T) -> bool + Send + Sync>,
32}
33
34impl<T: 'static + Send> ChainGeneric<T> {
35 pub fn new() -> Self {
36 ChainGeneric { links: Vec::new(), middleware: Vec::new(), branches: Vec::new() }
37 }
38 pub fn add_link(&mut self, link: Arc<dyn Fn(T) -> Pin<Box<dyn Future<Output = T> + Send>> + Send + Sync>) {
39 self.links.push(link);
40 }
41 pub fn use_middleware(&mut self, mw: Arc<dyn crate::middleware::Middleware<T>>) {
42 self.middleware.push(mw);
43 }
44 pub fn link_count(&self) -> usize {
45 self.links.len()
46 }
47 pub fn connect<F>(&mut self, source: usize, target: usize, condition: F)
48 where
49 F: Fn(&T) -> bool + Send + Sync + 'static,
50 {
51 self.branches.push(Branch {
52 source,
53 target,
54 condition: Arc::new(condition),
55 });
56 }
57 pub async fn run(&self, ctx: T) -> T {
58 let mut idx = 0;
59 let mut ctx = ctx;
60 while idx < self.links.len() {
61 for mw in &self.middleware {
62 mw.before(&ctx).await;
63 }
64 ctx = (self.links[idx].clone())(ctx).await;
65 for mw in &self.middleware {
66 mw.after(&ctx).await;
67 }
68 if let Some(branch) = self.branches.iter().find(|b| b.source == idx && (b.condition)(&ctx)) {
70 idx = branch.target;
71 } else {
72 idx += 1;
73 }
74 }
75 ctx
76 }
77}
78
79pub type Chain = ChainGeneric<crate::context::Context>;
81pub type LinkGeneric<C> = crate::links::LinkGeneric<C>;
82pub type Link = crate::links::Link;
83
84