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}