mediator_sys/mediator/synchronous/basic/
basic.rs

1use std::sync::mpsc::{Receiver, Sender, TryRecvError};
2
3use core::fmt::Debug;
4
5use super::*;
6
7/// Basic mediator for synchronous environments with events of type `Ev`.
8///
9/// A [`BasicMediator`] is constructed through its builder.
10/// It receives requests through its [`SyncMediatorInternalHandle::send()`]
11/// interface, which are processed by the user-defined [`RequestHandler`] implementation.
12/// From within this handler, events of type `Ev` can be published using the
13/// [`BasicMediator::publish()`] functionality.
14/// Listeners injected with [`super::BasicBuilder::add_listener()`]
15/// are invoked when the user calls [`BasicMediator::next()`].
16///
17/// # Examples
18///
19/// Basic usage:
20///
21/// ```
22/// use mediator_sys::synchronous::basic::*;
23///
24/// #[derive(Debug, Clone)]
25/// enum MyEvent {
26///     One,
27///     Two
28/// }
29///
30/// struct Request(u32);
31///
32/// impl RequestHandler<Request, MyEvent> for BasicMediator<MyEvent> {
33///     fn handle(&self, req: Request) {
34///         match req.0 {
35///             1 => self.publish(MyEvent::One),
36///             2 => self.publish(MyEvent::Two),
37///             _ => ()
38///         };
39///     }
40/// }
41///
42/// let mediator = BasicMediator::<MyEvent>::builder()
43///     .add_listener(move |ev| {
44///         /* Your listening logic */
45///     })
46///     .add_listener(move |ev| {
47///         /* Your listening logic */
48///     })
49///     .build();
50///
51///     mediator.send(Request(1));
52///     mediator.next().ok();
53///
54#[derive(Debug)]
55pub struct BasicMediator<Ev>
56where
57    Ev: Debug,
58{
59    pub(crate) channel: (Sender<Ev>, Receiver<Ev>),
60    pub(crate) listener: Vec<Box<dyn Listener<Ev>>>,
61}
62
63impl<Ev> SyncMediatorInternal<Ev> for BasicMediator<Ev>
64where
65    Ev: Debug,
66{
67    /// Publishes an event `Ev`.
68    ///
69    /// This method should be used within [`RequestHandler::handle()`]
70    /// to publish a user-defined event.
71    ///
72    /// # Examples
73    ///
74    /// Basic usage:
75    ///
76    /// ```
77    /// use mediator_sys::synchronous::basic::*;
78    ///
79    /// #[derive(Debug, Clone)]
80    /// enum MyEvent {
81    ///     One,
82    ///     Two
83    /// }
84    ///
85    /// struct Request(u32);
86    ///
87    /// impl RequestHandler<Request, MyEvent> for BasicMediator<MyEvent> {
88    ///     fn handle(&self, req: Request) {
89    ///         match req.0 {
90    ///             1 => self.publish(MyEvent::One),
91    ///             2 => self.publish(MyEvent::Two),
92    ///             _ => ()
93    ///         };
94    ///     }
95    /// }
96    ///
97    fn publish(&self, event: Ev) {
98        self.channel.0.send(event).ok();
99    }
100}
101
102impl<Ev> SyncMediatorInternalHandle<Ev> for BasicMediator<Ev>
103where
104    Ev: Debug,
105{
106    /// Send a request of type `Req` to the mediator.
107    ///
108    /// The request will be processed internally by [`RequestHandler::handle()`].
109    /// This is why it is required to implement [`RequestHandler`] for [`BasicMediator`].
110    ///
111    fn send<Req>(&self, req: Req)
112    where
113        Self: RequestHandler<Req, Ev>,
114    {
115        <Self as RequestHandler<Req, Ev>>::handle(self, req);
116    }
117}
118
119impl<Ev> SyncMediatorInternalNext for BasicMediator<Ev>
120where
121    Ev: Debug + Clone,
122{
123    /// Process the next published event `Ev`.
124    ///
125    /// [`SyncMediatorInternalNext::next()`] invokes
126    /// registered listeners with a cloned value
127    /// of the published event.
128    ///
129    fn next(&self) -> Result<(), TryRecvError> {
130        match self.channel.1.try_recv() {
131            Ok(ev) => {
132                for listener in self.listener.iter() {
133                    listener(ev.clone())
134                }
135                Ok(())
136            }
137            Err(err) => Err(err),
138        }
139    }
140}