1use core::marker::PhantomData;
6use core::mem::MaybeUninit;
7use core::{concat, stringify};
8
9use fidl_next_codec::{
10 Constrained, Decode, DecodeError, Encodable, EncodableOption, Encode, EncodeError,
11 EncodeOption, EncodeOptionRef, EncodeRef, FromWire, FromWireOption, FromWireOptionRef,
12 FromWireRef, IntoNatural, Slot, Unconstrained, Wire, munge,
13};
14use fidl_next_protocol::{ProtocolError, Transport};
15
16use crate::{
17 Client, ClientDispatcher, DispatchClientMessage, DispatchServerMessage, Executor, HasExecutor,
18 HasTransport, IgnoreEvents, 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 T = <P as HasTransport>::Transport,
32 > {
33 transport: T,
34 _protocol: PhantomData<P>,
35 }
36
37 unsafe impl<P, T: Send> Send for $name<P, T> {}
38
39 unsafe impl<P, T: Sync> Sync for $name<P, T> {}
40
41 unsafe impl<P: 'static, T: Wire> Wire for $name<P, T> {
50 type Decoded<'de> = $name<P, T::Decoded<'de>>;
51
52 #[inline]
53 fn zero_padding(out: &mut MaybeUninit<Self>) {
54 munge!(let Self { transport, _protocol: _ } = out);
55 T::zero_padding(transport);
56 }
57 }
58
59 impl<P, T> $name<P, T> {
60 #[doc = concat!(
61 "Converts from `&",
62 stringify!($name),
63 "<P, T>` to `",
64 stringify!($name),
65 "<P, &T>`.",
66 )]
67 pub fn as_ref(&self) -> $name<P, &T> {
68 $name { transport: &self.transport, _protocol: PhantomData }
69 }
70
71 pub fn from_untyped(transport: T) -> Self {
73 Self { transport, _protocol: PhantomData }
74 }
75
76 pub fn into_untyped(self) -> T {
78 self.transport
79 }
80
81 pub fn executor(&self) -> T::Executor
83 where
84 T: HasExecutor,
85 {
86 self.transport.executor()
87 }
88 }
89
90 unsafe impl<D, P, T> Decode<D> for $name<P, T>
93 where
94 D: ?Sized,
95 P: 'static,
96 T: Decode<D>,
97 T: Constrained<Constraint=()>,
98 {
99 fn decode(slot: Slot<'_, Self>, decoder: &mut D, constraint: <Self as Constrained>::Constraint) -> Result<(), DecodeError> {
100 munge!(let Self { transport, _protocol: _ } = slot);
101 T::decode(transport, decoder, constraint)
102 }
103 }
104
105 impl<P, T> Encodable for $name<P, T>
106 where
107 T: Encodable,
108 T::Encoded : Constrained<Constraint=()>,
109 P: 'static,
110 {
111 type Encoded = $name<P, T::Encoded>;
112 }
113
114 impl<P, T> EncodableOption for $name<P, T>
115 where
116 T: EncodableOption,
117 T::EncodedOption: Constrained<Constraint=()>,
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 T::Encoded: Constrained<Constraint=()>
131 {
132 fn encode(
133 self,
134 encoder: &mut E,
135 out: &mut MaybeUninit<Self::Encoded>,
136 constraint: (),
137 ) -> Result<(), EncodeError> {
138 munge!(let Self::Encoded { transport, _protocol: _ } = out);
139 self.transport.encode(encoder, transport, constraint)
140 }
141 }
142
143 unsafe impl<E, P, T> EncodeRef<E> for $name<P, T>
147 where
148 E: ?Sized,
149 P: 'static,
150 T: EncodeRef<E>,
151 T::Encoded: Constrained<Constraint=()>
152 {
153 fn encode_ref(
154 &self,
155 encoder: &mut E,
156 out: &mut MaybeUninit<Self::Encoded>,
157 constraint: (),
158 ) -> Result<(), EncodeError> {
159 self.as_ref().encode(encoder, out, constraint)
160 }
161 }
162
163 unsafe impl<E, P, T> EncodeOption<E> for $name<P, T>
167 where
168 E: ?Sized,
169 P: 'static,
170 T: EncodeOption<E>,
171 T::EncodedOption: Constrained<Constraint=()>
172 {
173 fn encode_option(
174 this: Option<Self>,
175 encoder: &mut E,
176 out: &mut MaybeUninit<Self::EncodedOption>,
177 constraint: (),
178 ) -> Result<(), EncodeError> {
179 munge!(let Self::EncodedOption { transport, _protocol: _ } = out);
180 T::encode_option(this.map(|this| this.transport), encoder, transport, constraint)
181 }
182 }
183
184 unsafe impl<E, P, T> EncodeOptionRef<E> for $name<P, T>
188 where
189 E: ?Sized,
190 P: 'static,
191 T: EncodeOptionRef<E>,
192 T::EncodedOption: Constrained<Constraint=()>
193 {
194 fn encode_option_ref(
195 this: Option<&Self>,
196 encoder: &mut E,
197 out: &mut MaybeUninit<Self::EncodedOption>,
198 constraint: (),
199 ) -> Result<(), EncodeError> {
200 munge!(let Self::EncodedOption { transport, _protocol: _ } = out);
201 T::encode_option_ref(this.map(|this| &this.transport), encoder, transport, constraint)
202 }
203 }
204
205 impl<P, T : Constrained<Constraint=()>> Unconstrained for $name<P, T> {}
206
207 impl<P, T, U> FromWire<$name<P, U>> for $name<P, T>
208 where
209 T: FromWire<U>,
210 {
211 #[inline]
212 fn from_wire(wire: $name<P, U>) -> Self {
213 $name {
214 transport: T::from_wire(wire.transport),
215 _protocol: PhantomData,
216 }
217 }
218 }
219
220 impl<P, T: IntoNatural> IntoNatural for $name<P, T> {
221 type Natural = $name<P, T::Natural>;
222 }
223
224 impl<P, T, U> FromWireRef<$name<P, U>> for $name<P, T>
225 where
226 T: FromWireRef<U>,
227 {
228 #[inline]
229 fn from_wire_ref(wire: &$name<P, U>) -> Self {
230 $name {
231 transport: T::from_wire_ref(&wire.transport),
232 _protocol: PhantomData,
233 }
234 }
235 }
236
237 impl<P, T, U> FromWireOption<$name<P, U>> for $name<P, T>
238 where
239 P: 'static,
240 T: FromWireOption<U>,
241 U: Wire,
242 {
243 #[inline]
244 fn from_wire_option(wire: $name<P, U>) -> Option<Self> {
245 T::from_wire_option(wire.transport).map(|transport| $name {
246 transport,
247 _protocol: PhantomData,
248 })
249 }
250 }
251
252 impl<P, T, U> FromWireOptionRef<$name<P, U>> for $name<P, T>
253 where
254 P: 'static,
255 T: FromWireOptionRef<U>,
256 U: Wire,
257 {
258 #[inline]
259 fn from_wire_option_ref(wire: &$name<P, U>) -> Option<Self> {
260 T::from_wire_option_ref(&wire.transport).map(|transport| $name {
261 transport,
262 _protocol: PhantomData,
263 })
264 }
265 }
266 };
267}
268
269endpoint! {
270 ClientEnd
272}
273
274endpoint! {
275 ServerEnd
277}
278
279pub type HandlerTask<T, H, E = <T as HasExecutor>::Executor> =
281 <E as Executor>::Task<Result<H, ProtocolError<<T as Transport>::Error>>>;
282
283impl<P, T: Transport> ClientEnd<P, T> {
284 pub fn spawn_handler_full_on_with<H, E>(
289 self,
290 create_handler: impl FnOnce(Client<P, T>) -> H,
291 executor: &E,
292 ) -> (Client<P, T>, HandlerTask<T, H, E>)
293 where
294 P: DispatchClientMessage<H, T>,
295 T: 'static,
296 H: Send + 'static,
297 E: Executor,
298 {
299 let dispatcher = ClientDispatcher::new(self);
300 let client = dispatcher.client();
301 let handler = create_handler(client.clone());
302 (client, executor.spawn(dispatcher.run(handler)))
303 }
304
305 pub fn spawn_handler_full_on<H, E>(
310 self,
311 handler: H,
312 executor: &E,
313 ) -> (Client<P, T>, HandlerTask<T, H, E>)
314 where
315 P: DispatchClientMessage<H, T>,
316 T: 'static,
317 H: Send + 'static,
318 E: Executor,
319 {
320 self.spawn_handler_full_on_with(|_| handler, executor)
321 }
322
323 pub fn spawn_handler_on_with<H, E>(
328 self,
329 create_handler: impl FnOnce(Client<P, T>) -> H,
330 executor: &E,
331 ) -> Client<P, T>
332 where
333 P: DispatchClientMessage<H, T>,
334 T: 'static,
335 H: Send + 'static,
336 E: Executor,
337 {
338 let (client, task) = Self::spawn_handler_full_on_with(self, create_handler, executor);
339 executor.detach(task);
340 client
341 }
342
343 pub fn spawn_handler_on<H, E>(self, handler: H, executor: &E) -> Client<P, T>
348 where
349 P: DispatchClientMessage<H, T>,
350 T: 'static,
351 H: Send + 'static,
352 E: Executor,
353 {
354 self.spawn_handler_on_with(|_| handler, executor)
355 }
356
357 pub fn spawn_handler_full_with<H>(
362 self,
363 create_handler: impl FnOnce(Client<P, T>) -> H,
364 ) -> (Client<P, T>, HandlerTask<T, H>)
365 where
366 P: DispatchClientMessage<H, T>,
367 T: HasExecutor + 'static,
368 H: Send + 'static,
369 {
370 let executor = self.executor();
371 Self::spawn_handler_full_on_with(self, create_handler, &executor)
372 }
373
374 pub fn spawn_handler_full<H>(self, handler: H) -> (Client<P, T>, HandlerTask<T, H>)
379 where
380 P: DispatchClientMessage<H, T>,
381 T: HasExecutor + 'static,
382 H: Send + 'static,
383 {
384 self.spawn_handler_full_with(|_| handler)
385 }
386
387 pub fn spawn_handler_with<H>(
392 self,
393 create_handler: impl FnOnce(Client<P, T>) -> H,
394 ) -> Client<P, T>
395 where
396 P: DispatchClientMessage<H, T>,
397 T: HasExecutor + 'static,
398 H: Send + 'static,
399 {
400 let executor = self.executor();
401 Self::spawn_handler_on_with(self, create_handler, &executor)
402 }
403
404 pub fn spawn_handler<H>(self, handler: H) -> Client<P, T>
409 where
410 P: DispatchClientMessage<H, T>,
411 T: HasExecutor + 'static,
412 H: Send + 'static,
413 {
414 self.spawn_handler_with(|_| handler)
415 }
416
417 pub fn spawn_full_on<E>(self, executor: &E) -> (Client<P, T>, HandlerTask<T, (), E>)
422 where
423 P: DispatchClientMessage<IgnoreEvents, T>,
424 T: 'static,
425 E: Executor,
426 {
427 let dispatcher = ClientDispatcher::new(self);
428 let client = dispatcher.client();
429 (client, executor.spawn(dispatcher.run_client()))
430 }
431
432 pub fn spawn_on<E>(self, executor: &E) -> Client<P, T>
437 where
438 P: DispatchClientMessage<IgnoreEvents, T>,
439 T: 'static,
440 E: Executor,
441 {
442 let (client, task) = Self::spawn_full_on(self, executor);
443 executor.detach(task);
444 client
445 }
446
447 pub fn spawn_full(self) -> (Client<P, T>, HandlerTask<T, ()>)
453 where
454 P: DispatchClientMessage<IgnoreEvents, T>,
455 T: HasExecutor + 'static,
456 {
457 let executor = self.executor();
458 Self::spawn_full_on(self, &executor)
459 }
460
461 pub fn spawn(self) -> Client<P, T>
467 where
468 P: DispatchClientMessage<IgnoreEvents, T>,
469 T: HasExecutor + 'static,
470 {
471 let executor = self.executor();
472 Self::spawn_on(self, &executor)
473 }
474}
475
476impl<P, T: Transport> ServerEnd<P, T> {
477 pub fn spawn_full_on_with<H, E>(
482 self,
483 create_handler: impl FnOnce(Server<P, T>) -> H,
484 executor: &E,
485 ) -> (HandlerTask<T, H, E>, Server<P, T>)
486 where
487 P: DispatchServerMessage<H, T>,
488 T: 'static,
489 H: Send + 'static,
490 E: Executor,
491 {
492 let dispatcher = ServerDispatcher::new(self);
493 let server = dispatcher.server();
494 let handler = create_handler(server.clone());
495 (executor.spawn(dispatcher.run(handler)), server)
496 }
497
498 pub fn spawn_full_on<H, E>(
503 self,
504 handler: H,
505 executor: &E,
506 ) -> (HandlerTask<T, H, E>, Server<P, T>)
507 where
508 P: DispatchServerMessage<H, T>,
509 T: 'static,
510 H: Send + 'static,
511 E: Executor,
512 {
513 self.spawn_full_on_with(|_| handler, executor)
514 }
515
516 pub fn spawn_on_with<H, E>(
521 self,
522 create_handler: impl FnOnce(Server<P, T>) -> H,
523 executor: &E,
524 ) -> HandlerTask<T, H, E>
525 where
526 P: DispatchServerMessage<H, T>,
527 T: 'static,
528 H: Send + 'static,
529 E: Executor,
530 {
531 let dispatcher = ServerDispatcher::new(self);
532 let handler = create_handler(dispatcher.server());
533 executor.spawn(dispatcher.run(handler))
534 }
535
536 pub fn spawn_on<H, E>(self, handler: H, executor: &E) -> HandlerTask<T, H, E>
541 where
542 P: DispatchServerMessage<H, T>,
543 T: 'static,
544 H: Send + 'static,
545 E: Executor,
546 {
547 self.spawn_on_with(|_| handler, executor)
548 }
549
550 pub fn spawn_full_with<H>(
555 self,
556 create_handler: impl FnOnce(Server<P, T>) -> H,
557 ) -> (HandlerTask<T, H>, Server<P, T>)
558 where
559 P: DispatchServerMessage<H, T>,
560 T: HasExecutor + 'static,
561 H: Send + 'static,
562 {
563 let executor = self.executor();
564 Self::spawn_full_on_with(self, create_handler, &executor)
565 }
566
567 pub fn spawn_full<H>(self, handler: H) -> (HandlerTask<T, H>, Server<P, T>)
572 where
573 P: DispatchServerMessage<H, T>,
574 T: HasExecutor + 'static,
575 H: Send + 'static,
576 {
577 self.spawn_full_with(|_| handler)
578 }
579
580 pub fn spawn_with<H>(self, create_handler: impl FnOnce(Server<P, T>) -> H) -> HandlerTask<T, H>
585 where
586 P: DispatchServerMessage<H, T>,
587 T: HasExecutor + 'static,
588 H: Send + 'static,
589 {
590 let executor = self.executor();
591 Self::spawn_on_with(self, create_handler, &executor)
592 }
593
594 pub fn spawn<H>(self, handler: H) -> HandlerTask<T, H>
599 where
600 P: DispatchServerMessage<H, T>,
601 T: HasExecutor + 'static,
602 H: Send + 'static,
603 {
604 self.spawn_with(|_| handler)
605 }
606}