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;
18use crate::route::scan::HandlerCache;
19
20pub struct Mediator {
26 provider: Arc<rust_dix::ServiceProvider>,
27 handler_cache: Arc<HandlerCache>,
28}
29
30impl Mediator {
31 pub fn new(provider: Arc<rust_dix::ServiceProvider>, handler_cache: Arc<HandlerCache>) -> Self {
39 Self {
40 provider,
41 handler_cache,
42 }
43 }
44}
45
46#[async_trait::async_trait]
47impl IMediator for Mediator {
48 async fn send<T, R>(&self, req: T) -> Result<R>
49 where
50 T: IRequest<R> + Send + 'static,
51 R: Send + 'static,
52 {
53 dispatch::dispatch(&self.provider, &self.handler_cache, req).await
54 }
55
56 async fn send_boxed(&self, req: Box<dyn Any + Send>) -> Result<Box<dyn Any + Send>> {
57 let type_id = (*req).type_id();
58 let dispatch_fn = self.handler_cache.boxed_dispatch(type_id).ok_or_else(|| {
59 crate::Error::Di(format!(
60 "No #[handler] with a boxed dispatch bridge is registered for request type {:?}",
61 type_id
62 ))
63 })?;
64 dispatch_fn(
65 Arc::clone(&self.provider),
66 Arc::clone(&self.handler_cache),
67 req,
68 )
69 .await
70 }
71
72 async fn publish<T: IEventRequest>(&self, event: T) -> Result<()> {
73 let scope = self.provider.create_scope();
74 let handlers: Vec<Arc<dyn IEventHandler<T>>> = scope.get_all::<dyn IEventHandler<T>>();
75
76 let mut first_err: Option<crate::error::Error> = None;
77 for handler in handlers {
78 if let Err(e) = handler.handle(event.clone()).await {
79 if first_err.is_none() {
80 first_err = Some(e);
81 }
82 }
83 }
84
85 match first_err {
86 Some(e) => Err(e),
87 None => Ok(()),
88 }
89 }
90}