webx_core/mediator/
default.rs1use std::any::Any;
10use std::sync::Arc;
11
12use rust_dix::ScopeFactory;
13
14use super::dispatch;
15use super::{IEventRequest, IMediator, IRequest};
16use crate::error::Result;
17use crate::handler::IEventHandler;
18
19pub struct Mediator {
24 provider: Arc<rust_dix::ServiceProvider>,
25}
26
27impl Mediator {
28 pub fn new(provider: Arc<rust_dix::ServiceProvider>) -> Self {
29 Self { provider }
30 }
31}
32
33#[async_trait::async_trait]
34impl IMediator for Mediator {
35 async fn send<T, R>(&self, req: T) -> Result<R>
36 where
37 T: IRequest<R> + Send + 'static,
38 R: Send + 'static,
39 {
40 dispatch::dispatch(&self.provider, req).await
41 }
42
43 async fn send_boxed(&self, req: Box<dyn Any + Send>) -> Result<Box<dyn Any + Send>> {
44 let type_id = (*req).type_id();
45 let cache = crate::dispatch_runtime::dispatch_handler_cache();
46 let dispatch_fn = cache.boxed_dispatch(type_id).ok_or_else(|| {
47 crate::Error::Di(format!(
48 "No #[handler] with a boxed dispatch bridge is registered for request type {:?}",
49 type_id
50 ))
51 })?;
52 dispatch_fn(Arc::clone(&self.provider), req).await
53 }
54
55 async fn publish<T: IEventRequest>(&self, event: T) -> Result<()> {
56 let scope = self.provider.create_scope();
57 let handlers: Vec<Arc<dyn IEventHandler<T>>> = scope.get_all::<dyn IEventHandler<T>>();
58
59 let mut first_err: Option<crate::error::Error> = None;
60 for handler in handlers {
61 if let Err(e) = handler.handle(event.clone()).await {
62 if first_err.is_none() {
63 first_err = Some(e);
64 }
65 }
66 }
67
68 match first_err {
69 Some(e) => Err(e),
70 None => Ok(()),
71 }
72 }
73}