1use core::marker::PhantomData;
6use core::mem::MaybeUninit;
7use core::{concat, stringify};
8
9use fidl_next_codec::{
10 Decode, DecodeError, Encodable, EncodableOption, Encode, EncodeError, EncodeOption,
11 EncodeOptionRef, EncodeRef, FromWire, FromWireOption, FromWireOptionRef, FromWireRef, Slot,
12 Wire, munge,
13};
14use fidl_next_protocol::{ProtocolError, Transport};
15
16use crate::{
17 Client, ClientSender, DispatchClientMessage, DispatchServerMessage, Executor, HasExecutor,
18 Server, ServerSender,
19};
20
21macro_rules! endpoint {
22 (
23 #[doc = $doc:literal]
24 $name:ident
25 ) => {
26 #[doc = $doc]
27 #[derive(Debug)]
28 #[repr(transparent)]
29 pub struct $name<
30 P,
31 #[cfg(feature = "fuchsia")]
32 T = zx::Channel,
33 #[cfg(not(feature = "fuchsia"))]
34 T,
35 > {
36 transport: T,
37 _protocol: PhantomData<P>,
38 }
39
40 unsafe impl<P, T: Send> Send for $name<P, T> {}
41
42 unsafe impl<P, T: Sync> Sync for $name<P, T> {}
43
44 unsafe impl<P: 'static, T: Wire> Wire for $name<P, T> {
53 type Decoded<'de> = $name<P, T::Decoded<'de>>;
54
55 #[inline]
56 fn zero_padding(out: &mut MaybeUninit<Self>) {
57 munge!(let Self { transport, _protocol: _ } = out);
58 T::zero_padding(transport);
59 }
60 }
61
62 impl<P, T> $name<P, T> {
63 #[doc = concat!(
64 "Converts from `&",
65 stringify!($name),
66 "<P, T>` to `",
67 stringify!($name),
68 "<P, &T>`.",
69 )]
70 pub fn as_ref(&self) -> $name<P, &T> {
71 $name { transport: &self.transport, _protocol: PhantomData }
72 }
73
74 pub fn from_untyped(transport: T) -> Self {
76 Self { transport, _protocol: PhantomData }
77 }
78
79 pub fn into_untyped(self) -> T {
81 self.transport
82 }
83
84 pub fn executor(&self) -> T::Executor
86 where
87 T: HasExecutor,
88 {
89 self.transport.executor()
90 }
91 }
92
93 unsafe impl<D, P, T> Decode<D> for $name<P, T>
96 where
97 D: ?Sized,
98 P: 'static,
99 T: Decode<D>,
100 {
101 fn decode(slot: Slot<'_, Self>, decoder: &mut D) -> Result<(), DecodeError> {
102 munge!(let Self { transport, _protocol: _ } = slot);
103 T::decode(transport, decoder)
104 }
105 }
106
107 impl<P, T> Encodable for $name<P, T>
108 where
109 T: Encodable,
110 P: 'static,
111 {
112 type Encoded = $name<P, T::Encoded>;
113 }
114
115 impl<P, T> EncodableOption for $name<P, T>
116 where
117 T: EncodableOption,
118 P: 'static,
119 {
120 type EncodedOption = $name<P, T::EncodedOption>;
121 }
122
123 unsafe impl<E, P, T> Encode<E> for $name<P, T>
126 where
127 E: ?Sized,
128 P: 'static,
129 T: Encode<E>,
130 {
131 fn encode(
132 self,
133 encoder: &mut E,
134 out: &mut MaybeUninit<Self::Encoded>,
135 ) -> Result<(), EncodeError> {
136 munge!(let Self::Encoded { transport, _protocol: _ } = out);
137 self.transport.encode(encoder, transport)
138 }
139 }
140
141 unsafe impl<E, P, T> EncodeRef<E> for $name<P, T>
145 where
146 E: ?Sized,
147 P: 'static,
148 T: EncodeRef<E>,
149 {
150 fn encode_ref(
151 &self,
152 encoder: &mut E,
153 out: &mut MaybeUninit<Self::Encoded>,
154 ) -> Result<(), EncodeError> {
155 self.as_ref().encode(encoder, out)
156 }
157 }
158
159 unsafe impl<E, P, T> EncodeOption<E> for $name<P, T>
163 where
164 E: ?Sized,
165 P: 'static,
166 T: EncodeOption<E>,
167 {
168 fn encode_option(
169 this: Option<Self>,
170 encoder: &mut E,
171 out: &mut MaybeUninit<Self::EncodedOption>,
172 ) -> Result<(), EncodeError> {
173 munge!(let Self::EncodedOption { transport, _protocol: _ } = out);
174 T::encode_option(this.map(|this| this.transport), encoder, transport)
175 }
176 }
177
178 unsafe impl<E, P, T> EncodeOptionRef<E> for $name<P, T>
182 where
183 E: ?Sized,
184 P: 'static,
185 T: EncodeOptionRef<E>,
186 {
187 fn encode_option_ref(
188 this: Option<&Self>,
189 encoder: &mut E,
190 out: &mut MaybeUninit<Self::EncodedOption>,
191 ) -> Result<(), EncodeError> {
192 munge!(let Self::EncodedOption { transport, _protocol: _ } = out);
193 T::encode_option_ref(this.map(|this| &this.transport), encoder, transport)
194 }
195 }
196
197 impl<P, T, U> FromWire<$name<P, U>> for $name<P, T>
198 where
199 T: FromWire<U>,
200 {
201 #[inline]
202 fn from_wire(wire: $name<P, U>) -> Self {
203 $name {
204 transport: T::from_wire(wire.transport),
205 _protocol: PhantomData,
206 }
207 }
208 }
209
210 impl<P, T, U> FromWireRef<$name<P, U>> for $name<P, T>
211 where
212 T: FromWireRef<U>,
213 {
214 #[inline]
215 fn from_wire_ref(wire: &$name<P, U>) -> Self {
216 $name {
217 transport: T::from_wire_ref(&wire.transport),
218 _protocol: PhantomData,
219 }
220 }
221 }
222
223 impl<P, T, U> FromWireOption<$name<P, U>> for $name<P, T>
224 where
225 P: 'static,
226 T: FromWireOption<U>,
227 U: Wire,
228 {
229 #[inline]
230 fn from_wire_option(wire: $name<P, U>) -> Option<Self> {
231 T::from_wire_option(wire.transport).map(|transport| $name {
232 transport,
233 _protocol: PhantomData,
234 })
235 }
236 }
237
238 impl<P, T, U> FromWireOptionRef<$name<P, U>> for $name<P, T>
239 where
240 P: 'static,
241 T: FromWireOptionRef<U>,
242 U: Wire,
243 {
244 #[inline]
245 fn from_wire_option_ref(wire: &$name<P, U>) -> Option<Self> {
246 T::from_wire_option_ref(&wire.transport).map(|transport| $name {
247 transport,
248 _protocol: PhantomData,
249 })
250 }
251 }
252 };
253}
254
255endpoint! {
256 ClientEnd
258}
259
260endpoint! {
261 ServerEnd
263}
264
265pub type HandlerTask<T, H, E = <T as HasExecutor>::Executor> =
267 <E as Executor>::Task<Result<H, ProtocolError<<T as Transport>::Error>>>;
268
269impl<P, T: Transport> ClientEnd<P, T> {
270 pub fn spawn_full_with_handler_on<H, E>(
274 self,
275 handler: H,
276 executor: &E,
277 ) -> (ClientSender<P, T>, HandlerTask<T, H, E>)
278 where
279 P: DispatchClientMessage<H, T>,
280 T: 'static,
281 H: Send + 'static,
282 E: Executor,
283 {
284 let client = Client::new(self);
285 let sender = client.sender().clone();
286 (sender, executor.spawn(client.run(handler)))
287 }
288
289 pub fn spawn_with_handler_on<H, E>(self, handler: H, executor: &E) -> ClientSender<P, T>
293 where
294 P: DispatchClientMessage<H, T>,
295 T: 'static,
296 H: Send + 'static,
297 E: Executor,
298 {
299 let (sender, task) = Self::spawn_full_with_handler_on(self, handler, executor);
300 executor.detach(task);
301 sender
302 }
303
304 pub fn spawn_full_with_handler<H>(self, handler: H) -> (ClientSender<P, T>, HandlerTask<T, H>)
309 where
310 P: DispatchClientMessage<H, T>,
311 T: HasExecutor + 'static,
312 H: Send + 'static,
313 {
314 let executor = self.executor();
315 Self::spawn_full_with_handler_on(self, handler, &executor)
316 }
317
318 pub fn spawn_with_handler<H>(self, handler: H) -> ClientSender<P, T>
323 where
324 P: DispatchClientMessage<H, T>,
325 T: HasExecutor + 'static,
326 H: Send + 'static,
327 {
328 let executor = self.executor();
329 Self::spawn_with_handler_on(self, handler, &executor)
330 }
331
332 pub fn spawn_full_on<E>(self, executor: &E) -> (ClientSender<P, T>, HandlerTask<T, (), E>)
337 where
338 P: 'static,
339 T: 'static,
340 E: Executor,
341 {
342 let client = Client::new(self);
343 let sender = client.sender().clone();
344 (sender, executor.spawn(client.run_sender()))
345 }
346
347 pub fn spawn_on<E>(self, executor: &E) -> ClientSender<P, T>
352 where
353 P: 'static,
354 T: 'static,
355 E: Executor,
356 {
357 let (sender, task) = Self::spawn_full_on(self, executor);
358 executor.detach(task);
359 sender
360 }
361
362 pub fn spawn_full(self) -> (ClientSender<P, T>, HandlerTask<T, ()>)
368 where
369 P: 'static,
370 T: HasExecutor + 'static,
371 {
372 let executor = self.executor();
373 Self::spawn_full_on(self, &executor)
374 }
375
376 pub fn spawn(self) -> ClientSender<P, T>
382 where
383 P: 'static,
384 T: HasExecutor + 'static,
385 {
386 let executor = self.executor();
387 Self::spawn_on(self, &executor)
388 }
389}
390
391impl<P, T: Transport> ServerEnd<P, T> {
392 pub fn spawn_full_on<H, E>(
396 self,
397 handler: H,
398 executor: &E,
399 ) -> (HandlerTask<T, H, E>, ServerSender<P, T>)
400 where
401 P: DispatchServerMessage<H, T>,
402 T: 'static,
403 H: Send + 'static,
404 E: Executor,
405 {
406 let server = Server::new(self);
407 let sender = server.sender().clone();
408 (executor.spawn(server.run(handler)), sender)
409 }
410
411 pub fn spawn_on<H, E>(self, handler: H, executor: &E) -> HandlerTask<T, H, E>
415 where
416 P: DispatchServerMessage<H, T>,
417 T: 'static,
418 H: Send + 'static,
419 E: Executor,
420 {
421 executor.spawn(Server::new(self).run(handler))
422 }
423
424 pub fn spawn_full<H>(self, handler: H) -> (HandlerTask<T, H>, ServerSender<P, T>)
429 where
430 P: DispatchServerMessage<H, T>,
431 T: HasExecutor + 'static,
432 H: Send + 'static,
433 {
434 let executor = self.executor();
435 Self::spawn_full_on(self, handler, &executor)
436 }
437
438 pub fn spawn<H>(self, handler: H) -> HandlerTask<T, H>
443 where
444 P: DispatchServerMessage<H, T>,
445 T: HasExecutor + 'static,
446 H: Send + 'static,
447 {
448 let executor = self.executor();
449 Self::spawn_on(self, handler, &executor)
450 }
451}