1use core::marker::PhantomData;
6use core::mem::MaybeUninit;
7use core::{concat, stringify};
8
9use fidl_next_codec::{
10 Constrained, Decode, DecodeError, Encode, EncodeError, EncodeOption, FromWire, FromWireOption,
11 FromWireOptionRef, FromWireRef, IntoNatural, Slot, Unconstrained, Wire, munge,
12};
13use fidl_next_protocol::{ProtocolError, Transport};
14
15use crate::{
16 Client, ClientDispatcher, DispatchClientMessage, DispatchServerMessage, Executor, HasExecutor,
17 HasTransport, IgnoreEvents, Server, ServerDispatcher,
18};
19
20macro_rules! endpoint {
21 (
22 #[doc = $doc:literal]
23 $name:ident
24 ) => {
25 #[doc = $doc]
26 #[derive(Debug, PartialEq)]
27 #[repr(transparent)]
28 pub struct $name<
29 P,
30 T = <P as HasTransport>::Transport,
31 > {
32 transport: T,
33 _protocol: PhantomData<P>,
34 }
35
36 unsafe impl<P, T: Send> Send for $name<P, T> {}
37
38 unsafe impl<P, T: Sync> Sync for $name<P, T> {}
39
40 unsafe impl<P: 'static, T: Wire> Wire for $name<P, T> {
49 type Owned<'de> = $name<P, T::Owned<'de>>;
50
51 #[inline]
52 fn zero_padding(out: &mut MaybeUninit<Self>) {
53 munge!(let Self { transport, _protocol: _ } = out);
54 T::zero_padding(transport);
55 }
56 }
57
58 impl<P, T> $name<P, T> {
59 #[doc = concat!(
60 "Converts from `&",
61 stringify!($name),
62 "<P, T>` to `",
63 stringify!($name),
64 "<P, &T>`.",
65 )]
66 pub fn as_ref(&self) -> $name<P, &T> {
67 $name { transport: &self.transport, _protocol: PhantomData }
68 }
69
70 pub fn from_untyped(transport: T) -> Self {
72 Self { transport, _protocol: PhantomData }
73 }
74
75 pub fn into_untyped(self) -> T {
77 self.transport
78 }
79
80 pub fn executor(&self) -> T::Executor
82 where
83 T: HasExecutor,
84 {
85 self.transport.executor()
86 }
87 }
88
89 unsafe impl<D, P, T> Decode<D> for $name<P, T>
92 where
93 D: ?Sized,
94 P: 'static,
95 T: Decode<D>,
96 T: Constrained<Constraint=()>,
97 {
98 fn decode(slot: Slot<'_, Self>, decoder: &mut D, constraint: <Self as Constrained>::Constraint) -> Result<(), DecodeError> {
99 munge!(let Self { transport, _protocol: _ } = slot);
100 T::decode(transport, decoder, constraint)
101 }
102 }
103
104 unsafe impl<W, E, P, T> Encode<$name<P, W>, E> for $name<P, T>
107 where
108 E: ?Sized,
109 P: 'static,
110 T: Encode<W, E>,
111 W: Constrained<Constraint = ()> + Wire,
112 {
113 fn encode(
114 self,
115 encoder: &mut E,
116 out: &mut MaybeUninit<$name<P, W>>,
117 constraint: (),
118 ) -> Result<(), EncodeError> {
119 munge!(let $name { transport, _protocol: _ } = out);
120 self.transport.encode(encoder, transport, constraint)
121 }
122 }
123
124 unsafe impl<'a, W, E, P, T> Encode<$name<P, W>, E> for &'a $name<P, T>
128 where
129 E: ?Sized,
130 P: 'static,
131 &'a T: Encode<W, E>,
132 W: Constrained<Constraint = ()> + Wire,
133 {
134 fn encode(
135 self,
136 encoder: &mut E,
137 out: &mut MaybeUninit<$name<P, W>>,
138 constraint: (),
139 ) -> Result<(), EncodeError> {
140 self.as_ref().encode(encoder, out, constraint)
141 }
142 }
143
144 unsafe impl<W, E, P, T> EncodeOption<$name<P, W>, E> for $name<P, T>
148 where
149 E: ?Sized,
150 P: 'static,
151 T: EncodeOption<W, E>,
152 W: Constrained<Constraint = ()>
153 {
154 fn encode_option(
155 this: Option<Self>,
156 encoder: &mut E,
157 out: &mut MaybeUninit<$name<P, W>>,
158 constraint: (),
159 ) -> Result<(), EncodeError> {
160 munge!(let $name { transport, _protocol: _ } = out);
161 T::encode_option(this.map(|this| this.transport), encoder, transport, constraint)
162 }
163 }
164
165 unsafe impl<'a, W, E, P, T> EncodeOption<$name<P, W>, E> for &'a $name<P, T>
169 where
170 E: ?Sized,
171 P: 'static,
172 &'a T: EncodeOption<W, E>,
173 W: Constrained<Constraint = ()>
174 {
175 fn encode_option(
176 this: Option<Self>,
177 encoder: &mut E,
178 out: &mut MaybeUninit<$name<P, W>>,
179 constraint: (),
180 ) -> Result<(), EncodeError> {
181 munge!(let $name { transport, _protocol: _ } = out);
182 <&T>::encode_option(this.map(|this| &this.transport), encoder, transport, constraint)
183 }
184 }
185
186 impl<P, T: Constrained<Constraint = ()>> Unconstrained for $name<P, T> {}
187
188 impl<P, T, U> FromWire<$name<P, U>> for $name<P, T>
189 where
190 T: FromWire<U>,
191 {
192 #[inline]
193 fn from_wire(wire: $name<P, U>) -> Self {
194 $name {
195 transport: T::from_wire(wire.transport),
196 _protocol: PhantomData,
197 }
198 }
199 }
200
201 impl<P, T: IntoNatural> IntoNatural for $name<P, T> {
202 type Natural = $name<P, T::Natural>;
203 }
204
205 impl<P, T, U> FromWireRef<$name<P, U>> for $name<P, T>
206 where
207 T: FromWireRef<U>,
208 {
209 #[inline]
210 fn from_wire_ref(wire: &$name<P, U>) -> Self {
211 $name {
212 transport: T::from_wire_ref(&wire.transport),
213 _protocol: PhantomData,
214 }
215 }
216 }
217
218 impl<P, T, U> FromWireOption<$name<P, U>> for $name<P, T>
219 where
220 P: 'static,
221 T: FromWireOption<U>,
222 U: Wire,
223 {
224 #[inline]
225 fn from_wire_option(wire: $name<P, U>) -> Option<Self> {
226 T::from_wire_option(wire.transport).map(|transport| $name {
227 transport,
228 _protocol: PhantomData,
229 })
230 }
231 }
232
233 impl<P, T, U> FromWireOptionRef<$name<P, U>> for $name<P, T>
234 where
235 P: 'static,
236 T: FromWireOptionRef<U>,
237 U: Wire,
238 {
239 #[inline]
240 fn from_wire_option_ref(wire: &$name<P, U>) -> Option<Self> {
241 T::from_wire_option_ref(&wire.transport).map(|transport| $name {
242 transport,
243 _protocol: PhantomData,
244 })
245 }
246 }
247 };
248}
249
250endpoint! {
251 ClientEnd
253}
254
255endpoint! {
256 ServerEnd
258}
259
260pub type HandlerJoinHandle<T, H, E = <T as HasExecutor>::Executor> =
262 <E as Executor>::JoinHandle<Result<H, ProtocolError<<T as Transport>::Error>>>;
263
264impl<P, T: Transport> ClientEnd<P, T> {
265 pub fn spawn_handler_full_on_with<H, E>(
270 self,
271 create_handler: impl FnOnce(Client<P, T>) -> H,
272 executor: &E,
273 ) -> (Client<P, T>, HandlerJoinHandle<T, H, E>)
274 where
275 P: DispatchClientMessage<H, T>,
276 T: 'static,
277 H: Send + 'static,
278 E: Executor,
279 {
280 let dispatcher = ClientDispatcher::new(self);
281 let client = dispatcher.client();
282 let handler = create_handler(client.clone());
283 (client, executor.spawn(dispatcher.run(handler)))
284 }
285
286 pub fn spawn_handler_full_on<H, E>(
291 self,
292 handler: H,
293 executor: &E,
294 ) -> (Client<P, T>, HandlerJoinHandle<T, H, E>)
295 where
296 P: DispatchClientMessage<H, T>,
297 T: 'static,
298 H: Send + 'static,
299 E: Executor,
300 {
301 self.spawn_handler_full_on_with(|_| handler, executor)
302 }
303
304 pub fn spawn_handler_on_with<H, E>(
309 self,
310 create_handler: impl FnOnce(Client<P, T>) -> H,
311 executor: &E,
312 ) -> Client<P, T>
313 where
314 P: DispatchClientMessage<H, T>,
315 T: 'static,
316 H: Send + 'static,
317 E: Executor,
318 {
319 Self::spawn_handler_full_on_with(self, create_handler, executor).0
320 }
321
322 pub fn spawn_handler_on<H, E>(self, handler: H, executor: &E) -> Client<P, T>
327 where
328 P: DispatchClientMessage<H, T>,
329 T: 'static,
330 H: Send + 'static,
331 E: Executor,
332 {
333 self.spawn_handler_on_with(|_| handler, executor)
334 }
335
336 pub fn spawn_handler_full_with<H>(
341 self,
342 create_handler: impl FnOnce(Client<P, T>) -> H,
343 ) -> (Client<P, T>, HandlerJoinHandle<T, H>)
344 where
345 P: DispatchClientMessage<H, T>,
346 T: HasExecutor + 'static,
347 H: Send + 'static,
348 {
349 let executor = self.executor();
350 Self::spawn_handler_full_on_with(self, create_handler, &executor)
351 }
352
353 pub fn spawn_handler_full<H>(self, handler: H) -> (Client<P, T>, HandlerJoinHandle<T, H>)
358 where
359 P: DispatchClientMessage<H, T>,
360 T: HasExecutor + 'static,
361 H: Send + 'static,
362 {
363 self.spawn_handler_full_with(|_| handler)
364 }
365
366 pub fn spawn_handler_with<H>(
371 self,
372 create_handler: impl FnOnce(Client<P, T>) -> H,
373 ) -> Client<P, T>
374 where
375 P: DispatchClientMessage<H, T>,
376 T: HasExecutor + 'static,
377 H: Send + 'static,
378 {
379 let executor = self.executor();
380 Self::spawn_handler_on_with(self, create_handler, &executor)
381 }
382
383 pub fn spawn_handler<H>(self, handler: H) -> Client<P, T>
388 where
389 P: DispatchClientMessage<H, T>,
390 T: HasExecutor + 'static,
391 H: Send + 'static,
392 {
393 self.spawn_handler_with(|_| handler)
394 }
395
396 pub fn spawn_full_on<E>(self, executor: &E) -> (Client<P, T>, HandlerJoinHandle<T, (), E>)
401 where
402 P: DispatchClientMessage<IgnoreEvents, T>,
403 T: 'static,
404 E: Executor,
405 {
406 let dispatcher = ClientDispatcher::new(self);
407 let client = dispatcher.client();
408 (client, executor.spawn(dispatcher.run_client()))
409 }
410
411 pub fn spawn_on<E>(self, executor: &E) -> Client<P, T>
416 where
417 P: DispatchClientMessage<IgnoreEvents, T>,
418 T: 'static,
419 E: Executor,
420 {
421 Self::spawn_full_on(self, executor).0
422 }
423
424 pub fn spawn_full(self) -> (Client<P, T>, HandlerJoinHandle<T, ()>)
430 where
431 P: DispatchClientMessage<IgnoreEvents, T>,
432 T: HasExecutor + 'static,
433 {
434 let executor = self.executor();
435 Self::spawn_full_on(self, &executor)
436 }
437
438 pub fn spawn(self) -> Client<P, T>
444 where
445 P: DispatchClientMessage<IgnoreEvents, T>,
446 T: HasExecutor + 'static,
447 {
448 let executor = self.executor();
449 Self::spawn_on(self, &executor)
450 }
451}
452
453impl<P, T: Transport> ServerEnd<P, T> {
454 pub fn spawn_full_on_with<H, E>(
459 self,
460 create_handler: impl FnOnce(Server<P, T>) -> H,
461 executor: &E,
462 ) -> (HandlerJoinHandle<T, H, E>, Server<P, T>)
463 where
464 P: DispatchServerMessage<H, T>,
465 T: 'static,
466 H: Send + 'static,
467 E: Executor,
468 {
469 let dispatcher = ServerDispatcher::new(self);
470 let server = dispatcher.server();
471 let handler = create_handler(server.clone());
472 (executor.spawn(dispatcher.run(handler)), server)
473 }
474
475 pub fn spawn_full_on<H, E>(
480 self,
481 handler: H,
482 executor: &E,
483 ) -> (HandlerJoinHandle<T, H, E>, Server<P, T>)
484 where
485 P: DispatchServerMessage<H, T>,
486 T: 'static,
487 H: Send + 'static,
488 E: Executor,
489 {
490 self.spawn_full_on_with(|_| handler, executor)
491 }
492
493 pub fn spawn_on_with<H, E>(
498 self,
499 create_handler: impl FnOnce(Server<P, T>) -> H,
500 executor: &E,
501 ) -> HandlerJoinHandle<T, H, E>
502 where
503 P: DispatchServerMessage<H, T>,
504 T: 'static,
505 H: Send + 'static,
506 E: Executor,
507 {
508 let dispatcher = ServerDispatcher::new(self);
509 let handler = create_handler(dispatcher.server());
510 executor.spawn(dispatcher.run(handler))
511 }
512
513 pub fn spawn_on<H, E>(self, handler: H, executor: &E) -> HandlerJoinHandle<T, H, E>
518 where
519 P: DispatchServerMessage<H, T>,
520 T: 'static,
521 H: Send + 'static,
522 E: Executor,
523 {
524 self.spawn_on_with(|_| handler, executor)
525 }
526
527 pub fn spawn_full_with<H>(
532 self,
533 create_handler: impl FnOnce(Server<P, T>) -> H,
534 ) -> (HandlerJoinHandle<T, H>, Server<P, T>)
535 where
536 P: DispatchServerMessage<H, T>,
537 T: HasExecutor + 'static,
538 H: Send + 'static,
539 {
540 let executor = self.executor();
541 Self::spawn_full_on_with(self, create_handler, &executor)
542 }
543
544 pub fn spawn_full<H>(self, handler: H) -> (HandlerJoinHandle<T, H>, Server<P, T>)
549 where
550 P: DispatchServerMessage<H, T>,
551 T: HasExecutor + 'static,
552 H: Send + 'static,
553 {
554 self.spawn_full_with(|_| handler)
555 }
556
557 pub fn spawn_with<H>(
562 self,
563 create_handler: impl FnOnce(Server<P, T>) -> H,
564 ) -> HandlerJoinHandle<T, H>
565 where
566 P: DispatchServerMessage<H, T>,
567 T: HasExecutor + 'static,
568 H: Send + 'static,
569 {
570 let executor = self.executor();
571 Self::spawn_on_with(self, create_handler, &executor)
572 }
573
574 pub fn spawn<H>(self, handler: H) -> HandlerJoinHandle<T, H>
579 where
580 P: DispatchServerMessage<H, T>,
581 T: HasExecutor + 'static,
582 H: Send + 'static,
583 {
584 self.spawn_with(|_| handler)
585 }
586}