1use crate::*;
2use std::marker::PhantomData;
3
4pub struct Request<T>(PhantomData<T>);
6
7pub struct FireAndForget(());
9
10pub trait MessageSpecifier<T>: sealed::Sealed {
15 type Output: MessageReply + Send;
20
21 type Payload: Send + 'static;
25
26 fn into_payload(msg: T) -> (Self::Payload, Self::Output);
28
29 fn from_payload(payload: Self::Payload) -> T;
31}
32
33impl<I: Send + 'static, R: Send + 'static> MessageSpecifier<I> for Request<R> {
34 type Output = Rx<R>;
35 type Payload = (I, Tx<R>);
36
37 fn into_payload(msg: I) -> (Self::Payload, Self::Output) {
38 let (tx, rx) = new_request();
39 ((msg, tx), rx)
40 }
41
42 fn from_payload(payload: Self::Payload) -> I {
43 let (msg, _tx) = payload;
44 msg
45 }
46}
47
48impl<I: Send + 'static> MessageSpecifier<I> for FireAndForget {
49 type Output = ();
50 type Payload = I;
51
52 fn into_payload(msg: I) -> (Self::Payload, Self::Output) {
53 (msg, ())
54 }
55
56 fn from_payload(payload: Self::Payload) -> I {
57 payload
58 }
59}
60
61pub trait MessageReply: Sized + sealed::Sealed {
67 type Reply;
69
70 fn receive(self) -> impl Future<Output = Result<Self::Reply, RxError>> + Send;
72
73 fn receive_blocking(self) -> Result<Self::Reply, RxError> {
75 futures::executor::block_on(self.receive())
76 }
77}
78
79impl MessageReply for () {
80 type Reply = ();
81
82 async fn receive(self) -> Result<Self::Reply, RxError> {
83 Ok(())
84 }
85}
86
87impl<T> MessageReply for Rx<T>
88where
89 T: Send + 'static,
90{
91 type Reply = T;
92
93 async fn receive(self) -> Result<Self::Reply, RxError> {
94 self.await
95 }
96}
97
98pub trait Message: Send + 'static + Sized {
102 type Kind: MessageSpecifier<Self>;
104}
105
106pub type Output<T> = <<T as Message>::Kind as MessageSpecifier<T>>::Output;
108
109pub type Reply<T> = <Output<T> as MessageReply>::Reply;
111
112pub type Payload<T> = <<T as Message>::Kind as MessageSpecifier<T>>::Payload;
114
115pub trait MessageExt: Message {
117 fn build_payload(self) -> (Payload<Self>, Output<Self>)
118 where
119 Self: Sized,
120 {
121 <Self::Kind as MessageSpecifier<Self>>::into_payload(self)
122 }
123
124 fn destroy_payload(payload: Payload<Self>) -> Self
125 where
126 Self: Sized,
127 {
128 <Self::Kind as MessageSpecifier<Self>>::from_payload(payload)
129 }
130}
131impl<I> MessageExt for I where I: Message {}
132
133pub(crate) mod sealed {
134 pub trait Sealed {}
135
136 impl<T> Sealed for super::Request<T> {}
137 impl Sealed for super::FireAndForget {}
138
139 impl<T> Sealed for super::Rx<T> where T: Send + 'static {}
140 impl Sealed for () {}
141}
142
143macro_rules! implement_message_for_base_types {
148 ($(
149 $ty:ty
150 ),*) => {
151 $(
152 impl Message for $ty {
153 type Kind = FireAndForget;
154 }
155 )*
156 };
157}
158implement_message_for_base_types! {
159 u8, u16, u32, u64, u128,
160 i8, i16, i32, i64, i128,
161 (),
162 String, &'static str
163}
164
165macro_rules! implement_message_for_wrappers {
166 ($(
167 $wrapper:ty
168 $(where $_:ty: $where:ident)*
169 ,)*) => {
170 $(
171 impl<M> Message for $wrapper
172 where M: Send + 'static + $($where +)*
173 {
174 type Kind = FireAndForget;
175 }
176 )*
177 };
178}
179implement_message_for_wrappers!(
180 Box<M>,
181 std::sync::Arc<M> where M: Sync,
182 Vec<M>,
183 Box<[M]>,
184);
185
186macro_rules! implement_message_kind_and_message_for_tuples {
187 ($(
188 ($($id:ident: $na:ident + $na2:ident),*),
189 )*) => {
190 $(
191 impl<$($id),*> Message for ($($id,)*)
192 where
193 $($id: Message + Send + 'static,)*
194 {
195 type Kind = FireAndForget;
196 }
197 )*
198 };
199}
200implement_message_kind_and_message_for_tuples!(
201 (M1: m1 + m_1),
202 (M1: m1 + m_1, M2: m2 + m_2),
203 (M1: m1 + m_1, M2: m2 + m_2, M3: m3 + m_3),
204 (M1: m1 + m_1, M2: m2 + m_2, M3: m3 + m_3, M4: m4 + m_4),
205 (
206 M1: m1 + m_1,
207 M2: m2 + m_2,
208 M3: m3 + m_3,
209 M4: m4 + m_4,
210 M5: m5 + m_5
211 ),
212 (
213 M1: m1 + m_1,
214 M2: m2 + m_2,
215 M3: m3 + m_3,
216 M4: m4 + m_4,
217 M5: m5 + m_5,
218 M6: m6 + m_6
219 ),
220 (
221 M1: m1 + m_1,
222 M2: m2 + m_2,
223 M3: m3 + m_3,
224 M4: m4 + m_4,
225 M5: m5 + m_5,
226 M6: m6 + m_6,
227 M7: m7 + m_7
228 ),
229 (
230 M1: m1 + m_1,
231 M2: m2 + m_2,
232 M3: m3 + m_3,
233 M4: m4 + m_4,
234 M5: m5 + m_5,
235 M6: m6 + m_6,
236 M7: m7 + m_7,
237 M8: m8 + m_8
238 ),
239 (
240 M1: m1 + m_1,
241 M2: m2 + m_2,
242 M3: m3 + m_3,
243 M4: m4 + m_4,
244 M5: m5 + m_5,
245 M6: m6 + m_6,
246 M7: m7 + m_7,
247 M8: m8 + m_8,
248 M9: m9 + m_9
249 ),
250 (
251 M1: m1 + m_1,
252 M2: m2 + m_2,
253 M3: m3 + m_3,
254 M4: m4 + m_4,
255 M5: m5 + m_5,
256 M6: m6 + m_6,
257 M7: m7 + m_7,
258 M8: m8 + m_8,
259 M9: m9 + m_9,
260 M10: m10 + m_10
261 ),
262);