mediator_sys/mediator/asynchronous/basic/basic.rs
1use std::sync::mpsc::TryRecvError;
2
3use async_std::sync::Mutex;
4use async_trait::async_trait;
5use std::fmt::Debug;
6
7use super::*;
8use crate::synchronous::basic::{BasicMediator, SyncMediatorInternal, SyncMediatorInternalNext};
9
10/// Basic async mediator for asynchronous environments with events of type `Ev`.
11///
12/// A [`BasicAsyncMediator`] is constructed through its builder.
13/// It receives requests through its [`AsyncMediatorInternalHandle::send()`]
14/// interface, which are processed by the user-defined [`AsyncRequestHandler`] implementation.
15/// From within this `async` handler, events of type `Ev` can be published using the
16/// [`BasicAsyncMediator::publish()`] functionality.
17/// Listeners injected with [`super::BasicAsyncBuilder::add_listener()`]
18/// are invoked when the user calls [`BasicAsyncMediator::next()`].
19///
20/// # Examples
21///
22/// Basic usage:
23///
24/// ```
25/// use mediator_sys::asynchronous::basic::*;
26/// use async_trait::async_trait;
27/// use async_std;
28///
29/// #[derive(Debug, Clone)]
30/// enum MyEvent {
31/// One,
32/// Two
33/// }
34///
35/// struct Request(u32);
36///
37/// #[async_trait]
38/// impl AsyncRequestHandler<Request, MyEvent> for BasicAsyncMediator<MyEvent> {
39/// async fn handle(&self, req: Request) {
40/// match req.0 {
41/// 1 => self.publish(MyEvent::One).await,
42/// 2 => self.publish(MyEvent::Two).await,
43/// _ => ()
44/// };
45/// }
46/// }
47///
48/// async_std::task::block_on(async {
49/// let mediator = BasicAsyncMediator::<MyEvent>::builder()
50/// .add_listener(move |ev| {
51/// /* Your listening logic */
52/// })
53/// .add_listener(move |ev| {
54/// /* Your listening logic */
55/// })
56/// .build();
57///
58/// mediator.send(Request(1)).await;
59/// mediator.next().await.ok();
60/// });
61///
62#[cfg(feature = "async")]
63#[derive(Debug)]
64pub struct BasicAsyncMediator<Ev>
65where
66 Ev: Debug,
67{
68 pub(crate) basic: Mutex<BasicMediator<Ev>>,
69}
70
71#[async_trait]
72impl<Ev> AsyncMediatorInternal<Ev> for BasicAsyncMediator<Ev>
73where
74 Ev: Debug + Send,
75{
76 /// Publishes an event `Ev` asynchronously.
77 ///
78 /// This method locks the `Mutex` and instructs
79 /// the underlying [`BasicMediator`] to publish an event.
80 /// Best used within [`AsyncRequestHandler::handle()`].
81 ///
82 /// You need to await the `Future` using `.await`.
83 ///
84 /// # Examples
85 ///
86 /// Basic usage:
87 ///
88 /// ```
89 /// use mediator_sys::asynchronous::basic::*;
90 /// use async_trait::async_trait;
91 ///
92 /// #[derive(Debug, Clone)]
93 /// enum MyEvent {
94 /// One,
95 /// Two
96 /// }
97 ///
98 /// struct Request(u32);
99 ///
100 /// #[async_trait]
101 /// impl AsyncRequestHandler<Request, MyEvent> for BasicAsyncMediator<MyEvent> {
102 /// async fn handle(&self, req: Request) {
103 /// match req.0 {
104 /// 1 => self.publish(MyEvent::One).await,
105 /// 2 => self.publish(MyEvent::Two).await,
106 /// _ => ()
107 /// };
108 /// }
109 /// }
110 ///
111 async fn publish(&self, event: Ev) {
112 let m = self.basic.lock().await;
113 m.publish(event)
114 }
115}
116
117#[async_trait]
118impl<Ev> AsyncMediatorInternalHandle<Ev> for BasicAsyncMediator<Ev>
119where
120 Ev: Debug,
121{
122 /// Send a request of type `Req` to the mediator asynchronously.
123 ///
124 /// The request will be processed internally by [`AsyncRequestHandler::handle()`].
125 /// This is why it is required to implement [`AsyncRequestHandler`] for [`BasicAsyncMediator`].
126 ///
127 /// You need to await the `Future` using `.await`.
128 ///
129 async fn send<Req>(&self, req: Req)
130 where
131 Self: AsyncRequestHandler<Req, Ev>,
132 Req: Send,
133 {
134 <Self as AsyncRequestHandler<Req, Ev>>::handle(self, req).await
135 }
136}
137
138#[async_trait]
139impl<Ev> AsyncMediatorInternalNext for BasicAsyncMediator<Ev>
140where
141 Ev: Debug + Clone + Send,
142{
143 /// Process the next published event `Ev` asynchronously.
144 ///
145 /// This method locks the `Mutex` and instructs
146 /// the underlying [`BasicMediator`] to process the next event.
147 ///
148 /// See [`BasicMediator::next()`] for more info.
149 ///
150 /// You need to await the `Future` using `.await`.
151 ///
152 async fn next(&self) -> Result<(), TryRecvError> {
153 let m = self.basic.lock().await;
154 m.next()
155 }
156}