use crate::di::scan::HandlerCache;
use crate::error::{Error, Result};
use crate::handler::IEventHandler;
use crate::mediator::{IEventRequest, IMediator, IRequest};
use lrdi::ServiceProvider;
use std::sync::Arc;
pub struct Mediator {
cache: Arc<HandlerCache>,
provider: Arc<ServiceProvider>,
}
impl Mediator {
pub fn new(cache: Arc<HandlerCache>, provider: Arc<ServiceProvider>) -> Self {
Self { cache, provider }
}
}
#[async_trait::async_trait]
impl IMediator for Mediator {
async fn send<T, R>(&self, req: T) -> Result<R>
where
T: IRequest<R> + Send + 'static,
R: serde::Serialize + serde::de::DeserializeOwned + Send + 'static,
{
let req_type_name = std::any::type_name::<T>();
let entry = self.cache.get(req_type_name).ok_or_else(|| {
Error::Di(format!(
"No handler registered for request {} → {}",
req_type_name,
std::any::type_name::<R>(),
))
})?;
let request_boxed: Box<dyn std::any::Any + Send> = Box::new(req);
let response = (entry.call)(&entry.handler, request_boxed, None).await?;
let result: R = serde_json::from_slice(&response.body).map_err(Error::Serialization)?;
Ok(result)
}
async fn publish<T: IEventRequest>(&self, event: T) -> Result<()> {
let handlers: Vec<Arc<dyn IEventHandler<T>>> =
self.provider.get_all::<dyn IEventHandler<T>>();
for handler in handlers {
handler.handle(event.clone()).await?;
}
Ok(())
}
}