1use crate::entry::{
2 ReceiveNotification, ReceiveNotificationAsync, RequestResponse, RequestResponseAsync,
3};
4use crate::hlist::{ContainsAt, HList, HListExt, Cons, Nil};
5use crate::concrete::Mediator;
6
7use std::future::Future;
8use std::pin::Pin;
9
10pub trait Mediate {
11 type Handlers: HList;
12 type NotifyReceivers: HList;
13
14 fn handle<TMsg, TResp, I>(&self, msg: TMsg) -> TResp
15 where
16 Self::Handlers: ContainsAt<RequestResponse<TMsg, TResp>, I>;
17
18 fn handle_async<TMsg: 'static, TResp: 'static, I>(
19 &self,
20 msg: TMsg,
21 ) -> Pin<Box<dyn Future<Output = TResp>>>
22 where
23 Self::Handlers: ContainsAt<RequestResponseAsync<TMsg, TResp>, I>;
24
25 fn notify<TMsg: ?Sized, I>(&self, msg: &TMsg)
26 where
27 Self::NotifyReceivers: ContainsAt<ReceiveNotification<TMsg>, I>;
28
29 fn notify_async<TMsg: Clone + 'static, I>(
30 &self,
31 msg: TMsg,
32 ) -> Pin<Box<dyn Future<Output = ()> + '_>>
33 where
34 Self::NotifyReceivers: ContainsAt<ReceiveNotificationAsync<TMsg>, I>;
35}
36
37pub struct MediatorBuilder<H, N> {
38 contents: H,
39 receivers: N
40}
41
42impl MediatorBuilder<Nil, Nil> {
43 pub fn new() -> Self {
44 Self {
45 contents: Nil,
46 receivers: Nil
47 }
48 }
49}
50
51impl<H: HList, N: HList> MediatorBuilder<H, N> {
52 pub fn add_handler<TMsg, TResp>(
53 self,
54 handler: impl Fn(TMsg) -> TResp + 'static,
55 ) -> MediatorBuilder<Cons<RequestResponse<TMsg, TResp>, H>, N> {
56 let rr = RequestResponse::from(handler);
57 MediatorBuilder {
58 contents: self.contents.push(rr),
59 receivers: self.receivers
60 }
61 }
62
63 pub fn add_async_handler<TMsg, TResp, F, Fut>(
64 self,
65 handler: F
66 ) -> MediatorBuilder<Cons<RequestResponseAsync<TMsg, TResp>, H>, N>
67 where
68 Fut: Future<Output = TResp> + 'static,
69 F: Fn(TMsg) -> Fut + 'static
70 {
71 let rr = RequestResponseAsync::from(handler);
72 MediatorBuilder {
73 contents: self.contents.push(rr),
74 receivers: self.receivers
75 }
76 }
77
78 pub fn listen_for<TMsg: ?Sized>(self) -> MediatorBuilder<H, Cons<ReceiveNotification<TMsg>, N>> {
79 let rn = ReceiveNotification::new();
80 MediatorBuilder {
81 contents: self.contents,
82 receivers: self.receivers.push(rn),
83 }
84 }
85
86 pub fn listen_for_async<TMsg: Clone>(self) -> MediatorBuilder<H, Cons<ReceiveNotificationAsync<TMsg>, N>> {
87 let rn = ReceiveNotificationAsync::new();
88 MediatorBuilder {
89 contents: self.contents,
90 receivers: self.receivers.push(rn),
91 }
92 }
93
94 pub fn add_notification_receiver<TMsg: ?Sized, I>(
95 mut self,
96 receiver: impl Fn(&TMsg) + 'static,
97 ) -> Self
98 where
99 N: ContainsAt<ReceiveNotification<TMsg>, I>,
100 {
101 let receiver_set = self.receivers.take_mut();
102 receiver_set.add(receiver);
103 self
104 }
105
106 pub fn add_async_notification_receiver<TMsg: Clone, I, F, Fut>(
107 mut self,
108 receiver: F
109 ) -> Self
110 where
111 N: ContainsAt<ReceiveNotificationAsync<TMsg>, I>,
112 Fut: Future<Output = ()> + 'static,
113 F: Fn(TMsg) -> Fut + 'static,
114 {
115 let receiver_set = self.receivers.take_mut();
116 receiver_set.add(receiver);
117 self
118 }
119
120 pub fn build(self) -> impl Mediate<Handlers = H, NotifyReceivers = N> {
121 Mediator::new(self.contents, self.receivers)
122 }
123}