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,
12 IntoNatural, Slot, Wire, munge,
13};
14use fidl_next_protocol::{ProtocolError, Transport};
15
16use crate::{
17 Client, ClientDispatcher, DispatchClientMessage, DispatchServerMessage, Executor, HasExecutor,
18 Server, ServerDispatcher,
19};
20
21macro_rules! endpoint {
22 (
23 #[doc = $doc:literal]
24 $name:ident
25 ) => {
26 #[doc = $doc]
27 #[derive(Debug, PartialEq)]
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: IntoNatural> IntoNatural for $name<P, T> {
211 type Natural = $name<P, T::Natural>;
212 }
213
214 impl<P, T, U> FromWireRef<$name<P, U>> for $name<P, T>
215 where
216 T: FromWireRef<U>,
217 {
218 #[inline]
219 fn from_wire_ref(wire: &$name<P, U>) -> Self {
220 $name {
221 transport: T::from_wire_ref(&wire.transport),
222 _protocol: PhantomData,
223 }
224 }
225 }
226
227 impl<P, T, U> FromWireOption<$name<P, U>> for $name<P, T>
228 where
229 P: 'static,
230 T: FromWireOption<U>,
231 U: Wire,
232 {
233 #[inline]
234 fn from_wire_option(wire: $name<P, U>) -> Option<Self> {
235 T::from_wire_option(wire.transport).map(|transport| $name {
236 transport,
237 _protocol: PhantomData,
238 })
239 }
240 }
241
242 impl<P, T, U> FromWireOptionRef<$name<P, U>> for $name<P, T>
243 where
244 P: 'static,
245 T: FromWireOptionRef<U>,
246 U: Wire,
247 {
248 #[inline]
249 fn from_wire_option_ref(wire: &$name<P, U>) -> Option<Self> {
250 T::from_wire_option_ref(&wire.transport).map(|transport| $name {
251 transport,
252 _protocol: PhantomData,
253 })
254 }
255 }
256 };
257}
258
259endpoint! {
260 ClientEnd
262}
263
264endpoint! {
265 ServerEnd
267}
268
269pub type HandlerTask<T, H, E = <T as HasExecutor>::Executor> =
271 <E as Executor>::Task<Result<H, ProtocolError<<T as Transport>::Error>>>;
272
273impl<P, T: Transport> ClientEnd<P, T> {
274 pub fn spawn_handler_full_on_with<H, E>(
279 self,
280 create_handler: impl FnOnce(Client<P, T>) -> H,
281 executor: &E,
282 ) -> (Client<P, T>, HandlerTask<T, H, E>)
283 where
284 P: DispatchClientMessage<H, T>,
285 T: 'static,
286 H: Send + 'static,
287 E: Executor,
288 {
289 let dispatcher = ClientDispatcher::new(self);
290 let client = dispatcher.client();
291 let handler = create_handler(client.clone());
292 (client, executor.spawn(dispatcher.run(handler)))
293 }
294
295 pub fn spawn_handler_full_on<H, E>(
300 self,
301 handler: H,
302 executor: &E,
303 ) -> (Client<P, T>, HandlerTask<T, H, E>)
304 where
305 P: DispatchClientMessage<H, T>,
306 T: 'static,
307 H: Send + 'static,
308 E: Executor,
309 {
310 self.spawn_handler_full_on_with(|_| handler, executor)
311 }
312
313 pub fn spawn_handler_on_with<H, E>(
318 self,
319 create_handler: impl FnOnce(Client<P, T>) -> H,
320 executor: &E,
321 ) -> Client<P, T>
322 where
323 P: DispatchClientMessage<H, T>,
324 T: 'static,
325 H: Send + 'static,
326 E: Executor,
327 {
328 let (client, task) = Self::spawn_handler_full_on_with(self, create_handler, executor);
329 executor.detach(task);
330 client
331 }
332
333 pub fn spawn_handler_on<H, E>(self, handler: H, executor: &E) -> Client<P, T>
338 where
339 P: DispatchClientMessage<H, T>,
340 T: 'static,
341 H: Send + 'static,
342 E: Executor,
343 {
344 self.spawn_handler_on_with(|_| handler, executor)
345 }
346
347 pub fn spawn_handler_full_with<H>(
352 self,
353 create_handler: impl FnOnce(Client<P, T>) -> H,
354 ) -> (Client<P, T>, HandlerTask<T, H>)
355 where
356 P: DispatchClientMessage<H, T>,
357 T: HasExecutor + 'static,
358 H: Send + 'static,
359 {
360 let executor = self.executor();
361 Self::spawn_handler_full_on_with(self, create_handler, &executor)
362 }
363
364 pub fn spawn_handler_full<H>(self, handler: H) -> (Client<P, T>, HandlerTask<T, H>)
369 where
370 P: DispatchClientMessage<H, T>,
371 T: HasExecutor + 'static,
372 H: Send + 'static,
373 {
374 self.spawn_handler_full_with(|_| handler)
375 }
376
377 pub fn spawn_handler_with<H>(
382 self,
383 create_handler: impl FnOnce(Client<P, T>) -> H,
384 ) -> Client<P, T>
385 where
386 P: DispatchClientMessage<H, T>,
387 T: HasExecutor + 'static,
388 H: Send + 'static,
389 {
390 let executor = self.executor();
391 Self::spawn_handler_on_with(self, create_handler, &executor)
392 }
393
394 pub fn spawn_handler<H>(self, handler: H) -> Client<P, T>
399 where
400 P: DispatchClientMessage<H, T>,
401 T: HasExecutor + 'static,
402 H: Send + 'static,
403 {
404 self.spawn_handler_with(|_| handler)
405 }
406
407 pub fn spawn_full_on<E>(self, executor: &E) -> (Client<P, T>, HandlerTask<T, (), E>)
412 where
413 P: 'static,
414 T: 'static,
415 E: Executor,
416 {
417 let dispatcher = ClientDispatcher::new(self);
418 let client = dispatcher.client();
419 (client, executor.spawn(dispatcher.run_client()))
420 }
421
422 pub fn spawn_on<E>(self, executor: &E) -> Client<P, T>
427 where
428 P: 'static,
429 T: 'static,
430 E: Executor,
431 {
432 let (client, task) = Self::spawn_full_on(self, executor);
433 executor.detach(task);
434 client
435 }
436
437 pub fn spawn_full(self) -> (Client<P, T>, HandlerTask<T, ()>)
443 where
444 P: 'static,
445 T: HasExecutor + 'static,
446 {
447 let executor = self.executor();
448 Self::spawn_full_on(self, &executor)
449 }
450
451 pub fn spawn(self) -> Client<P, T>
457 where
458 P: 'static,
459 T: HasExecutor + 'static,
460 {
461 let executor = self.executor();
462 Self::spawn_on(self, &executor)
463 }
464}
465
466impl<P, T: Transport> ServerEnd<P, T> {
467 pub fn spawn_full_on_with<H, E>(
472 self,
473 create_handler: impl FnOnce(Server<P, T>) -> H,
474 executor: &E,
475 ) -> (HandlerTask<T, H, E>, Server<P, T>)
476 where
477 P: DispatchServerMessage<H, T>,
478 T: 'static,
479 H: Send + 'static,
480 E: Executor,
481 {
482 let dispatcher = ServerDispatcher::new(self);
483 let server = dispatcher.server();
484 let handler = create_handler(server.clone());
485 (executor.spawn(dispatcher.run(handler)), server)
486 }
487
488 pub fn spawn_full_on<H, E>(
493 self,
494 handler: H,
495 executor: &E,
496 ) -> (HandlerTask<T, H, E>, Server<P, T>)
497 where
498 P: DispatchServerMessage<H, T>,
499 T: 'static,
500 H: Send + 'static,
501 E: Executor,
502 {
503 self.spawn_full_on_with(|_| handler, executor)
504 }
505
506 pub fn spawn_on_with<H, E>(
511 self,
512 create_handler: impl FnOnce(Server<P, T>) -> H,
513 executor: &E,
514 ) -> HandlerTask<T, H, E>
515 where
516 P: DispatchServerMessage<H, T>,
517 T: 'static,
518 H: Send + 'static,
519 E: Executor,
520 {
521 let dispatcher = ServerDispatcher::new(self);
522 let handler = create_handler(dispatcher.server());
523 executor.spawn(dispatcher.run(handler))
524 }
525
526 pub fn spawn_on<H, E>(self, handler: H, executor: &E) -> HandlerTask<T, H, E>
531 where
532 P: DispatchServerMessage<H, T>,
533 T: 'static,
534 H: Send + 'static,
535 E: Executor,
536 {
537 self.spawn_on_with(|_| handler, executor)
538 }
539
540 pub fn spawn_full_with<H>(
545 self,
546 create_handler: impl FnOnce(Server<P, T>) -> H,
547 ) -> (HandlerTask<T, H>, Server<P, T>)
548 where
549 P: DispatchServerMessage<H, T>,
550 T: HasExecutor + 'static,
551 H: Send + 'static,
552 {
553 let executor = self.executor();
554 Self::spawn_full_on_with(self, create_handler, &executor)
555 }
556
557 pub fn spawn_full<H>(self, handler: H) -> (HandlerTask<T, H>, Server<P, T>)
562 where
563 P: DispatchServerMessage<H, T>,
564 T: HasExecutor + 'static,
565 H: Send + 'static,
566 {
567 self.spawn_full_with(|_| handler)
568 }
569
570 pub fn spawn_with<H>(self, create_handler: impl FnOnce(Server<P, T>) -> H) -> HandlerTask<T, H>
575 where
576 P: DispatchServerMessage<H, T>,
577 T: HasExecutor + 'static,
578 H: Send + 'static,
579 {
580 let executor = self.executor();
581 Self::spawn_on_with(self, create_handler, &executor)
582 }
583
584 pub fn spawn<H>(self, handler: H) -> HandlerTask<T, H>
589 where
590 P: DispatchServerMessage<H, T>,
591 T: HasExecutor + 'static,
592 H: Send + 'static,
593 {
594 self.spawn_with(|_| handler)
595 }
596}