use std::sync::Arc;
use crate::error::ForgeResult;
use mf_state::{transaction::Transaction, state::State};
#[async_trait::async_trait]
pub trait Middleware: Send + Sync {
fn name(&self) -> String;
async fn before_dispatch(
&self,
_transaction: &mut Transaction,
) -> ForgeResult<()> {
Ok(())
}
async fn after_dispatch(
&self,
_state: Option<Arc<State>>,
_transactions: &[Arc<Transaction>],
) -> ForgeResult<Option<Transaction>> {
Ok(None)
}
}
pub type ArcMiddleware = Arc<dyn Middleware>;
#[derive(Clone)]
pub struct MiddlewareStack {
pub middlewares: Vec<ArcMiddleware>,
}
impl MiddlewareStack {
pub fn new() -> Self {
Self { middlewares: Vec::new() }
}
pub fn add<M>(
&mut self,
middleware: M,
) where
M: Middleware + 'static,
{
self.middlewares.push(Arc::new(middleware));
}
pub fn is_empty(&self) -> bool {
self.middlewares.is_empty()
}
}
impl Default for MiddlewareStack {
fn default() -> Self {
Self::new()
}
}