1use std::sync::Arc;
2
3use crate::error::ForgeResult;
4use mf_state::{transaction::Transaction, state::State};
5
6#[async_trait::async_trait]
8pub trait Middleware: Send + Sync {
9 fn name(&self) -> String;
11
12 async fn before_dispatch(
14 &self,
15 _transaction: &mut Transaction,
16 ) -> ForgeResult<()> {
17 Ok(())
18 }
19
20 async fn after_dispatch(
23 &self,
24 _state: Option<Arc<State>>,
25 _transactions: &[Transaction],
26 ) -> ForgeResult<Option<Transaction>> {
27 Ok(None)
28 }
29}
30
31pub type ArcMiddleware = Arc<dyn Middleware>;
33
34#[derive(Clone)]
36pub struct MiddlewareStack {
37 pub middlewares: Vec<ArcMiddleware>,
38}
39
40impl MiddlewareStack {
41 pub fn new() -> Self {
42 Self { middlewares: Vec::new() }
43 }
44
45 pub fn add<M>(
46 &mut self,
47 middleware: M,
48 ) where
49 M: Middleware + 'static,
50 {
51 self.middlewares.push(Arc::new(middleware));
52 }
53
54 pub fn is_empty(&self) -> bool {
55 self.middlewares.is_empty()
56 }
57}
58
59impl Default for MiddlewareStack {
60 fn default() -> Self {
61 Self::new()
62 }
63}