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 HandlerTask<T, H, E = <T as HasExecutor>::Executor> =
262 <E as Executor>::Task<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>, HandlerTask<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>, HandlerTask<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 let (client, task) = Self::spawn_handler_full_on_with(self, create_handler, executor);
320 executor.detach(task);
321 client
322 }
323
324 pub fn spawn_handler_on<H, E>(self, handler: H, executor: &E) -> Client<P, T>
329 where
330 P: DispatchClientMessage<H, T>,
331 T: 'static,
332 H: Send + 'static,
333 E: Executor,
334 {
335 self.spawn_handler_on_with(|_| handler, executor)
336 }
337
338 pub fn spawn_handler_full_with<H>(
343 self,
344 create_handler: impl FnOnce(Client<P, T>) -> H,
345 ) -> (Client<P, T>, HandlerTask<T, H>)
346 where
347 P: DispatchClientMessage<H, T>,
348 T: HasExecutor + 'static,
349 H: Send + 'static,
350 {
351 let executor = self.executor();
352 Self::spawn_handler_full_on_with(self, create_handler, &executor)
353 }
354
355 pub fn spawn_handler_full<H>(self, handler: H) -> (Client<P, T>, HandlerTask<T, H>)
360 where
361 P: DispatchClientMessage<H, T>,
362 T: HasExecutor + 'static,
363 H: Send + 'static,
364 {
365 self.spawn_handler_full_with(|_| handler)
366 }
367
368 pub fn spawn_handler_with<H>(
373 self,
374 create_handler: impl FnOnce(Client<P, T>) -> H,
375 ) -> Client<P, T>
376 where
377 P: DispatchClientMessage<H, T>,
378 T: HasExecutor + 'static,
379 H: Send + 'static,
380 {
381 let executor = self.executor();
382 Self::spawn_handler_on_with(self, create_handler, &executor)
383 }
384
385 pub fn spawn_handler<H>(self, handler: H) -> Client<P, T>
390 where
391 P: DispatchClientMessage<H, T>,
392 T: HasExecutor + 'static,
393 H: Send + 'static,
394 {
395 self.spawn_handler_with(|_| handler)
396 }
397
398 pub fn spawn_full_on<E>(self, executor: &E) -> (Client<P, T>, HandlerTask<T, (), E>)
403 where
404 P: DispatchClientMessage<IgnoreEvents, T>,
405 T: 'static,
406 E: Executor,
407 {
408 let dispatcher = ClientDispatcher::new(self);
409 let client = dispatcher.client();
410 (client, executor.spawn(dispatcher.run_client()))
411 }
412
413 pub fn spawn_on<E>(self, executor: &E) -> Client<P, T>
418 where
419 P: DispatchClientMessage<IgnoreEvents, T>,
420 T: 'static,
421 E: Executor,
422 {
423 let (client, task) = Self::spawn_full_on(self, executor);
424 executor.detach(task);
425 client
426 }
427
428 pub fn spawn_full(self) -> (Client<P, T>, HandlerTask<T, ()>)
434 where
435 P: DispatchClientMessage<IgnoreEvents, T>,
436 T: HasExecutor + 'static,
437 {
438 let executor = self.executor();
439 Self::spawn_full_on(self, &executor)
440 }
441
442 pub fn spawn(self) -> Client<P, T>
448 where
449 P: DispatchClientMessage<IgnoreEvents, T>,
450 T: HasExecutor + 'static,
451 {
452 let executor = self.executor();
453 Self::spawn_on(self, &executor)
454 }
455}
456
457impl<P, T: Transport> ServerEnd<P, T> {
458 pub fn spawn_full_on_with<H, E>(
463 self,
464 create_handler: impl FnOnce(Server<P, T>) -> H,
465 executor: &E,
466 ) -> (HandlerTask<T, H, E>, Server<P, T>)
467 where
468 P: DispatchServerMessage<H, T>,
469 T: 'static,
470 H: Send + 'static,
471 E: Executor,
472 {
473 let dispatcher = ServerDispatcher::new(self);
474 let server = dispatcher.server();
475 let handler = create_handler(server.clone());
476 (executor.spawn(dispatcher.run(handler)), server)
477 }
478
479 pub fn spawn_full_on<H, E>(
484 self,
485 handler: H,
486 executor: &E,
487 ) -> (HandlerTask<T, H, E>, Server<P, T>)
488 where
489 P: DispatchServerMessage<H, T>,
490 T: 'static,
491 H: Send + 'static,
492 E: Executor,
493 {
494 self.spawn_full_on_with(|_| handler, executor)
495 }
496
497 pub fn spawn_on_with<H, E>(
502 self,
503 create_handler: impl FnOnce(Server<P, T>) -> H,
504 executor: &E,
505 ) -> HandlerTask<T, H, E>
506 where
507 P: DispatchServerMessage<H, T>,
508 T: 'static,
509 H: Send + 'static,
510 E: Executor,
511 {
512 let dispatcher = ServerDispatcher::new(self);
513 let handler = create_handler(dispatcher.server());
514 executor.spawn(dispatcher.run(handler))
515 }
516
517 pub fn spawn_on<H, E>(self, handler: H, executor: &E) -> HandlerTask<T, H, E>
522 where
523 P: DispatchServerMessage<H, T>,
524 T: 'static,
525 H: Send + 'static,
526 E: Executor,
527 {
528 self.spawn_on_with(|_| handler, executor)
529 }
530
531 pub fn spawn_full_with<H>(
536 self,
537 create_handler: impl FnOnce(Server<P, T>) -> H,
538 ) -> (HandlerTask<T, H>, Server<P, T>)
539 where
540 P: DispatchServerMessage<H, T>,
541 T: HasExecutor + 'static,
542 H: Send + 'static,
543 {
544 let executor = self.executor();
545 Self::spawn_full_on_with(self, create_handler, &executor)
546 }
547
548 pub fn spawn_full<H>(self, handler: H) -> (HandlerTask<T, H>, Server<P, T>)
553 where
554 P: DispatchServerMessage<H, T>,
555 T: HasExecutor + 'static,
556 H: Send + 'static,
557 {
558 self.spawn_full_with(|_| handler)
559 }
560
561 pub fn spawn_with<H>(self, create_handler: impl FnOnce(Server<P, T>) -> H) -> HandlerTask<T, H>
566 where
567 P: DispatchServerMessage<H, T>,
568 T: HasExecutor + 'static,
569 H: Send + 'static,
570 {
571 let executor = self.executor();
572 Self::spawn_on_with(self, create_handler, &executor)
573 }
574
575 pub fn spawn<H>(self, handler: H) -> HandlerTask<T, H>
580 where
581 P: DispatchServerMessage<H, T>,
582 T: HasExecutor + 'static,
583 H: Send + 'static,
584 {
585 self.spawn_with(|_| handler)
586 }
587}