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, ValidationError, 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 impl<P, T: Constrained> Constrained for $name<P, T> {
41 type Constraint = T::Constraint;
42
43 fn validate(slot: Slot<'_, Self>, constraint: Self::Constraint) -> Result<(), ValidationError> {
44 munge!(let Self { transport, _protocol: _ } = slot);
45
46 T::validate(transport, constraint)
47 }
48 }
49
50 unsafe impl<P: 'static, T: Wire> Wire for $name<P, T> {
59 type Narrowed<'de> = $name<P, T::Narrowed<'de>>;
60
61 #[inline]
62 fn zero_padding(out: &mut MaybeUninit<Self>) {
63 munge!(let Self { transport, _protocol: _ } = out);
64 T::zero_padding(transport);
65 }
66 }
67
68 impl<P, T> $name<P, T> {
69 #[doc = concat!(
70 "Converts from `&",
71 stringify!($name),
72 "<P, T>` to `",
73 stringify!($name),
74 "<P, &T>`.",
75 )]
76 pub fn as_ref(&self) -> $name<P, &T> {
77 $name { transport: &self.transport, _protocol: PhantomData }
78 }
79
80 pub fn from_untyped(transport: T) -> Self {
82 Self { transport, _protocol: PhantomData }
83 }
84
85 pub fn into_untyped(self) -> T {
87 self.transport
88 }
89
90 pub fn executor(&self) -> T::Executor
92 where
93 T: HasExecutor,
94 {
95 self.transport.executor()
96 }
97 }
98
99 unsafe impl<D, P, T> Decode<D> for $name<P, T>
102 where
103 D: ?Sized,
104 P: 'static,
105 T: Decode<D, Constraint=()>,
106 {
107 fn decode(slot: Slot<'_, Self>, decoder: &mut D, constraint: Self::Constraint) -> Result<(), DecodeError> {
108 munge!(let Self { transport, _protocol: _ } = slot);
109 T::decode(transport, decoder, constraint)
110 }
111 }
112
113 unsafe impl<W, E, P, T> Encode<$name<P, W>, E> for $name<P, T>
116 where
117 E: ?Sized,
118 P: 'static,
119 T: Encode<W, E>,
120 W: Wire<Constraint = ()>,
121 {
122 fn encode(
123 self,
124 encoder: &mut E,
125 out: &mut MaybeUninit<$name<P, W>>,
126 constraint: (),
127 ) -> Result<(), EncodeError> {
128 munge!(let $name { transport, _protocol: _ } = out);
129 self.transport.encode(encoder, transport, constraint)
130 }
131 }
132
133 unsafe impl<'a, W, E, P, T> Encode<$name<P, W>, E> for &'a $name<P, T>
137 where
138 E: ?Sized,
139 P: 'static,
140 &'a T: Encode<W, E>,
141 W: Wire<Constraint = ()>,
142 {
143 fn encode(
144 self,
145 encoder: &mut E,
146 out: &mut MaybeUninit<$name<P, W>>,
147 constraint: (),
148 ) -> Result<(), EncodeError> {
149 self.as_ref().encode(encoder, out, constraint)
150 }
151 }
152
153 unsafe impl<W, E, P, T> EncodeOption<$name<P, W>, E> for $name<P, T>
157 where
158 E: ?Sized,
159 P: 'static,
160 T: EncodeOption<W, E>,
161 W: Wire<Constraint = ()>
162 {
163 fn encode_option(
164 this: Option<Self>,
165 encoder: &mut E,
166 out: &mut MaybeUninit<$name<P, W>>,
167 constraint: (),
168 ) -> Result<(), EncodeError> {
169 munge!(let $name { transport, _protocol: _ } = out);
170 T::encode_option(this.map(|this| this.transport), encoder, transport, constraint)
171 }
172 }
173
174 unsafe impl<'a, W, E, P, T> EncodeOption<$name<P, W>, E> for &'a $name<P, T>
178 where
179 E: ?Sized,
180 P: 'static,
181 &'a T: EncodeOption<W, E>,
182 W: Wire<Constraint = ()>
183 {
184 fn encode_option(
185 this: Option<Self>,
186 encoder: &mut E,
187 out: &mut MaybeUninit<$name<P, W>>,
188 constraint: (),
189 ) -> Result<(), EncodeError> {
190 munge!(let $name { transport, _protocol: _ } = out);
191 <&T>::encode_option(this.map(|this| &this.transport), encoder, transport, constraint)
192 }
193 }
194
195 impl<P, T, U> FromWire<$name<P, U>> for $name<P, T>
196 where
197 T: FromWire<U>,
198 {
199 #[inline]
200 fn from_wire(wire: $name<P, U>) -> Self {
201 $name {
202 transport: T::from_wire(wire.transport),
203 _protocol: PhantomData,
204 }
205 }
206 }
207
208 impl<P, T: IntoNatural> IntoNatural for $name<P, T> {
209 type Natural = $name<P, T::Natural>;
210 }
211
212 impl<P, T, U> FromWireRef<$name<P, U>> for $name<P, T>
213 where
214 T: FromWireRef<U>,
215 {
216 #[inline]
217 fn from_wire_ref(wire: &$name<P, U>) -> Self {
218 $name {
219 transport: T::from_wire_ref(&wire.transport),
220 _protocol: PhantomData,
221 }
222 }
223 }
224
225 impl<P, T, U> FromWireOption<$name<P, U>> for $name<P, T>
226 where
227 P: 'static,
228 T: FromWireOption<U>,
229 U: Wire,
230 {
231 #[inline]
232 fn from_wire_option(wire: $name<P, U>) -> Option<Self> {
233 T::from_wire_option(wire.transport).map(|transport| $name {
234 transport,
235 _protocol: PhantomData,
236 })
237 }
238 }
239
240 impl<P, T, U> FromWireOptionRef<$name<P, U>> for $name<P, T>
241 where
242 P: 'static,
243 T: FromWireOptionRef<U>,
244 U: Wire,
245 {
246 #[inline]
247 fn from_wire_option_ref(wire: &$name<P, U>) -> Option<Self> {
248 T::from_wire_option_ref(&wire.transport).map(|transport| $name {
249 transport,
250 _protocol: PhantomData,
251 })
252 }
253 }
254 };
255}
256
257endpoint! {
258 ClientEnd
260}
261
262endpoint! {
263 ServerEnd
265}
266
267pub type HandlerJoinHandle<T, H, E = <T as HasExecutor>::Executor> =
269 <E as Executor>::JoinHandle<Result<H, ProtocolError<<T as Transport>::Error>>>;
270
271impl<P, T: Transport> ClientEnd<P, T> {
272 pub fn spawn_handler_full_on_with<H, E>(
277 self,
278 create_handler: impl FnOnce(Client<P, T>) -> H,
279 executor: &E,
280 ) -> (Client<P, T>, HandlerJoinHandle<T, H, E>)
281 where
282 P: DispatchClientMessage<H, T>,
283 T: 'static,
284 H: Send + 'static,
285 E: Executor,
286 {
287 let dispatcher = ClientDispatcher::new(self);
288 let client = dispatcher.client();
289 let handler = create_handler(client.clone());
290 (client, executor.spawn(dispatcher.run(handler)))
291 }
292
293 pub fn spawn_handler_full_on<H, E>(
298 self,
299 handler: H,
300 executor: &E,
301 ) -> (Client<P, T>, HandlerJoinHandle<T, H, E>)
302 where
303 P: DispatchClientMessage<H, T>,
304 T: 'static,
305 H: Send + 'static,
306 E: Executor,
307 {
308 self.spawn_handler_full_on_with(|_| handler, executor)
309 }
310
311 pub fn spawn_handler_on_with<H, E>(
316 self,
317 create_handler: impl FnOnce(Client<P, T>) -> H,
318 executor: &E,
319 ) -> Client<P, T>
320 where
321 P: DispatchClientMessage<H, T>,
322 T: 'static,
323 H: Send + 'static,
324 E: Executor,
325 {
326 Self::spawn_handler_full_on_with(self, create_handler, executor).0
327 }
328
329 pub fn spawn_handler_on<H, E>(self, handler: H, executor: &E) -> Client<P, T>
334 where
335 P: DispatchClientMessage<H, T>,
336 T: 'static,
337 H: Send + 'static,
338 E: Executor,
339 {
340 self.spawn_handler_on_with(|_| handler, executor)
341 }
342
343 pub fn spawn_handler_full_with<H>(
348 self,
349 create_handler: impl FnOnce(Client<P, T>) -> H,
350 ) -> (Client<P, T>, HandlerJoinHandle<T, H>)
351 where
352 P: DispatchClientMessage<H, T>,
353 T: HasExecutor + 'static,
354 H: Send + 'static,
355 {
356 let executor = self.executor();
357 Self::spawn_handler_full_on_with(self, create_handler, &executor)
358 }
359
360 pub fn spawn_handler_full<H>(self, handler: H) -> (Client<P, T>, HandlerJoinHandle<T, H>)
365 where
366 P: DispatchClientMessage<H, T>,
367 T: HasExecutor + 'static,
368 H: Send + 'static,
369 {
370 self.spawn_handler_full_with(|_| handler)
371 }
372
373 pub fn spawn_handler_with<H>(
378 self,
379 create_handler: impl FnOnce(Client<P, T>) -> H,
380 ) -> Client<P, T>
381 where
382 P: DispatchClientMessage<H, T>,
383 T: HasExecutor + 'static,
384 H: Send + 'static,
385 {
386 let executor = self.executor();
387 Self::spawn_handler_on_with(self, create_handler, &executor)
388 }
389
390 pub fn spawn_handler<H>(self, handler: H) -> Client<P, T>
395 where
396 P: DispatchClientMessage<H, T>,
397 T: HasExecutor + 'static,
398 H: Send + 'static,
399 {
400 self.spawn_handler_with(|_| handler)
401 }
402
403 pub fn spawn_full_on<E>(self, executor: &E) -> (Client<P, T>, HandlerJoinHandle<T, (), E>)
408 where
409 P: DispatchClientMessage<IgnoreEvents, T>,
410 T: 'static,
411 E: Executor,
412 {
413 let dispatcher = ClientDispatcher::new(self);
414 let client = dispatcher.client();
415 (client, executor.spawn(dispatcher.run_client()))
416 }
417
418 pub fn spawn_on<E>(self, executor: &E) -> Client<P, T>
423 where
424 P: DispatchClientMessage<IgnoreEvents, T>,
425 T: 'static,
426 E: Executor,
427 {
428 Self::spawn_full_on(self, executor).0
429 }
430
431 pub fn spawn_full(self) -> (Client<P, T>, HandlerJoinHandle<T, ()>)
437 where
438 P: DispatchClientMessage<IgnoreEvents, T>,
439 T: HasExecutor + 'static,
440 {
441 let executor = self.executor();
442 Self::spawn_full_on(self, &executor)
443 }
444
445 pub fn spawn(self) -> Client<P, T>
451 where
452 P: DispatchClientMessage<IgnoreEvents, T>,
453 T: HasExecutor + 'static,
454 {
455 let executor = self.executor();
456 Self::spawn_on(self, &executor)
457 }
458}
459
460impl<P, T: Transport> ServerEnd<P, T> {
461 pub fn spawn_full_on_with<H, E>(
466 self,
467 create_handler: impl FnOnce(Server<P, T>) -> H,
468 executor: &E,
469 ) -> (HandlerJoinHandle<T, H, E>, Server<P, T>)
470 where
471 P: DispatchServerMessage<H, T>,
472 T: 'static,
473 H: Send + 'static,
474 E: Executor,
475 {
476 let dispatcher = ServerDispatcher::new(self);
477 let server = dispatcher.server();
478 let handler = create_handler(server.clone());
479 (executor.spawn(dispatcher.run(handler)), server)
480 }
481
482 pub fn spawn_full_on<H, E>(
487 self,
488 handler: H,
489 executor: &E,
490 ) -> (HandlerJoinHandle<T, H, E>, Server<P, T>)
491 where
492 P: DispatchServerMessage<H, T>,
493 T: 'static,
494 H: Send + 'static,
495 E: Executor,
496 {
497 self.spawn_full_on_with(|_| handler, executor)
498 }
499
500 pub fn spawn_on_with<H, E>(
505 self,
506 create_handler: impl FnOnce(Server<P, T>) -> H,
507 executor: &E,
508 ) -> HandlerJoinHandle<T, H, E>
509 where
510 P: DispatchServerMessage<H, T>,
511 T: 'static,
512 H: Send + 'static,
513 E: Executor,
514 {
515 let dispatcher = ServerDispatcher::new(self);
516 let handler = create_handler(dispatcher.server());
517 executor.spawn(dispatcher.run(handler))
518 }
519
520 pub fn spawn_on<H, E>(self, handler: H, executor: &E) -> HandlerJoinHandle<T, H, E>
525 where
526 P: DispatchServerMessage<H, T>,
527 T: 'static,
528 H: Send + 'static,
529 E: Executor,
530 {
531 self.spawn_on_with(|_| handler, executor)
532 }
533
534 pub fn spawn_full_with<H>(
539 self,
540 create_handler: impl FnOnce(Server<P, T>) -> H,
541 ) -> (HandlerJoinHandle<T, H>, Server<P, T>)
542 where
543 P: DispatchServerMessage<H, T>,
544 T: HasExecutor + 'static,
545 H: Send + 'static,
546 {
547 let executor = self.executor();
548 Self::spawn_full_on_with(self, create_handler, &executor)
549 }
550
551 pub fn spawn_full<H>(self, handler: H) -> (HandlerJoinHandle<T, H>, Server<P, T>)
556 where
557 P: DispatchServerMessage<H, T>,
558 T: HasExecutor + 'static,
559 H: Send + 'static,
560 {
561 self.spawn_full_with(|_| handler)
562 }
563
564 pub fn spawn_with<H>(
569 self,
570 create_handler: impl FnOnce(Server<P, T>) -> H,
571 ) -> HandlerJoinHandle<T, H>
572 where
573 P: DispatchServerMessage<H, T>,
574 T: HasExecutor + 'static,
575 H: Send + 'static,
576 {
577 let executor = self.executor();
578 Self::spawn_on_with(self, create_handler, &executor)
579 }
580
581 pub fn spawn<H>(self, handler: H) -> HandlerJoinHandle<T, H>
586 where
587 P: DispatchServerMessage<H, T>,
588 T: HasExecutor + 'static,
589 H: Send + 'static,
590 {
591 self.spawn_with(|_| handler)
592 }
593}