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}