noon/
mediator.rs

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}