1#[cfg(feature = "async")]
21#[macro_export]
22macro_rules! __declare_binder_interface {
23 {
24 $interface:path[$descriptor:expr] {
25 native: {
26 $native:ident($on_transact:path),
27 $(adapter: $native_adapter:ident,)?
28 $(r#async: $native_async:ident,)?
29 },
30 proxy: $proxy:ident {
31 $($fname:ident: $fty:ty = $finit:expr),*
32 },
33 $(r#async: $async_interface:ident,)?
34 stability: $stability:expr,
35 }
36 } => {
37 $(
38 pub trait $native_adapter {
39 fn as_sync(&self) -> &dyn $interface;
40 #[allow(dead_code)]
41 fn as_async(&self) -> &dyn $native_async;
42 }
43
44 pub struct $native(Box<dyn $native_adapter + Send + Sync + 'static>);
45
46 impl $native {
47 pub fn new_binder<T: $interface + Sync + Send + 'static>(inner: T) -> $crate::Strong<dyn $interface> {
49 struct Wrapper<T> {
50 _inner: T,
51 }
52 impl<T> $native_adapter for Wrapper<T>
53 where
54 T: $interface + Sync + Send + 'static,
55 {
56 fn as_sync(&self) -> &dyn $interface { &self._inner }
57 fn as_async(&self) -> &dyn $native_async {
58 unreachable!("{} doesn't support async interface.", stringify!($interface))
59 }
60 }
61 let binder = $crate::native::Binder::new_with_stability($native(Box::new(Wrapper {_inner: inner})), $stability);
62 $crate::Strong::new(Box::new(binder))
63 }
64 }
65
66 impl $crate::Remotable for $native {
67 fn descriptor() -> &'static str where Self: Sized {
68 $descriptor
69 }
70
71 fn on_transact(&self, code: $crate::TransactionCode, reader: &mut $crate::Parcel, reply: &mut $crate::Parcel) -> $crate::Result<()> {
72 $on_transact(self.0.as_sync(), code, reader, reply)
73 }
74
75 fn on_dump(&self, _writer: &mut dyn std::io::Write, _args: &[String]) -> $crate::Result<()> {
76 self.0.as_sync().dump(_writer, _args)
77 }
78 }
79 )?
80
81 $(
82 impl<P: $crate::BinderAsyncPool> $crate::FromIBinder for dyn $async_interface<P> {
84 fn try_from(ibinder: $crate::SIBinder) -> std::result::Result<$crate::Strong<dyn $async_interface<P>>, $crate::StatusCode> {
85 match <$proxy as $crate::Proxy>::from_binder(ibinder.clone()) {
86 Some(proxy) => Ok($crate::Strong::new(Box::new(proxy))),
87 None => {
88 match $crate::native::Binder::<$native>::try_from(ibinder) {
89 Ok(native) => {
90 Ok($crate::Strong::new(Box::new(native.clone())))
91 }
92 Err(err) => Err(err),
93 }
94 }
95 }
96 }
97 }
98
99 impl<P: $crate::BinderAsyncPool> $crate::Serialize for dyn $async_interface<P> + '_ {
100 fn serialize(&self, parcel: &mut $crate::Parcel) -> std::result::Result<(), $crate::StatusCode> {
101 let binder = $crate::Interface::as_binder(self);
102 parcel.write(&binder)
103 }
104 }
105
106 impl<P: $crate::BinderAsyncPool> $crate::SerializeOption for dyn $async_interface<P> + '_ {
107 fn serialize_option(this: Option<&Self>, parcel: &mut $crate::Parcel) -> std::result::Result<(), $crate::StatusCode> {
108 parcel.write(&this.map($crate::Interface::as_binder))
109 }
110 }
111
112 impl<P: $crate::BinderAsyncPool> std::fmt::Debug for dyn $async_interface<P> + '_ {
113 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
114 f.pad(stringify!($async_interface))
115 }
116 }
117
118 impl<P: $crate::BinderAsyncPool> $crate::ToAsyncInterface<P> for dyn $interface {
128 type Target = dyn $async_interface<P>;
129 }
130
131 impl<P: $crate::BinderAsyncPool> $crate::ToSyncInterface for dyn $async_interface<P> {
132 type Target = dyn $interface;
133 }
134 )?
135 };
136}
137
138#[cfg(not(feature = "async"))]
139#[macro_export]
140macro_rules! __declare_binder_interface {
141 {
142 $interface:path[$descriptor:expr] {
143 native: {
144 $native:ident($on_transact:path),
145 $(adapter: $native_adapter:ident,)?
146 $(r#async: $native_async:ident,)?
147 },
148 proxy: $proxy:ident {
149 $($fname:ident: $fty:ty = $finit:expr),*
150 },
151 $(r#async: $async_interface:ident,)?
152 stability: $stability:expr,
153 }
154 } => {
155 pub struct $native(Box<dyn $interface + Send + Sync + 'static>);
156
157 impl $native {
158 pub fn new_binder<T: $interface + Sync + Send + 'static>(inner: T) -> $crate::Strong<dyn $interface> {
160 let binder = $crate::native::Binder::new_with_stability($native(Box::new(inner)), $stability);
161 $crate::Strong::new(Box::new(binder))
162 }
163 }
164
165 impl $crate::Remotable for $native {
166 fn descriptor() -> &'static str where Self: Sized {
167 $descriptor
168 }
169
170 fn on_transact(&self, code: $crate::TransactionCode, reader: &mut $crate::Parcel, reply: &mut $crate::Parcel) -> $crate::Result<()> {
171 $on_transact(&*self.0, code, reader, reply)
172 }
173
174 fn on_dump(&self, _writer: &mut dyn std::io::Write, _args: &[String]) -> $crate::Result<()> {
175 self.0.dump(_writer, _args)
176 }
177 }
178 };
179}
180
181#[macro_export]
185macro_rules! declare_binder_interface {
186 {
187 $interface:path[$descriptor:expr] {
188 native: {
189 $native:ident($on_transact:path),
190 $(adapter: $native_adapter:ident,)?
191 $(r#async: $native_async:ident,)?
192 },
193 proxy: $proxy:ident,
194 $(r#async: $async_interface:ident,)?
195 }
196 } => {
197 $crate::declare_binder_interface! {
198 $interface[$descriptor] {
199 native: {
200 $native($on_transact),
201 $(adapter: $native_adapter,)?
202 $(r#async: $native_async,)?
203 },
204 proxy: $proxy {},
205 $(r#async: $async_interface,)?
206 stability: $crate::Stability::default(),
207 }
208 }
209 };
210
211 {
212 $interface:path[$descriptor:expr] {
213 native: {
214 $native:ident($on_transact:path),
215 $(adapter: $native_adapter:ident,)?
216 $(r#async: $native_async:ident,)?
217 },
218 proxy: $proxy:ident,
219 $(r#async: $async_interface:ident,)?
220 stability: $stability:expr,
221 }
222 } => {
223 $crate::declare_binder_interface! {
224 $interface[$descriptor] {
225 native: {
226 $native($on_transact),
227 $(adapter: $native_adapter,)?
228 $(r#async: $native_async,)?
229 },
230 proxy: $proxy {},
231 $(r#async: $async_interface,)?
232 stability: $stability,
233 }
234 }
235 };
236
237 {
238 $interface:path[$descriptor:expr] {
239 native: {
240 $native:ident($on_transact:path),
241 $(adapter: $native_adapter:ident,)?
242 $(r#async: $native_async:ident,)?
243 },
244 proxy: $proxy:ident {
245 $($fname:ident: $fty:ty = $finit:expr),*
246 },
247 $(r#async: $async_interface:ident,)?
248 }
249 } => {
250 $crate::declare_binder_interface! {
251 $interface[$descriptor] {
252 native: {
253 $native($on_transact),
254 $(adapter: $native_adapter,)?
255 $(r#async: $native_async,)?
256 },
257 proxy: $proxy {
258 $($fname: $fty = $finit),*
259 },
260 $(r#async: $async_interface,)?
261 stability: $crate::Stability::default(),
262 }
263 }
264 };
265
266 {
267 $interface:path[$descriptor:expr] {
268 native: {
269 $native:ident($on_transact:path),
270 $(adapter: $native_adapter:ident,)?
271 $(r#async: $native_async:ident,)?
272 },
273 proxy: $proxy:ident {
274 $($fname:ident: $fty:ty = $finit:expr),*
275 },
276 $(r#async: $async_interface:ident,)?
277 stability: $stability:expr,
278 }
279 } => {
280 $crate::declare_binder_interface! {
281 $interface[$descriptor] {
282 @doc[concat!("A binder [`Remotable`]($crate::binder_impl::Remotable) that holds an [`", stringify!($interface), "`] object.")]
283 native: {
284 $native($on_transact),
285 $(adapter: $native_adapter,)?
286 $(r#async: $native_async,)?
287 },
288 @doc[concat!("A binder [`Proxy`]($crate::binder_impl::Proxy) that holds an [`", stringify!($interface), "`] remote interface.")]
289 proxy: $proxy {
290 $($fname: $fty = $finit),*
291 },
292 $(r#async: $async_interface,)?
293 stability: $stability,
294 }
295 }
296 };
297
298 {
299 $interface:path[$descriptor:expr] {
300 @doc[$native_doc:expr]
301 native: {
302 $native:ident($on_transact:path),
303 $(adapter: $native_adapter:ident,)?
304 $(r#async: $native_async:ident,)?
305 },
306 @doc[$proxy_doc:expr]
307 proxy: $proxy:ident {
308 $($fname:ident: $fty:ty = $finit:expr),*
309 },
310 $( r#async: $async_interface:ident, )?
311
312 stability: $stability:expr,
313 }
314 } => {
315 #[doc = $proxy_doc]
316 pub struct $proxy {
317 binder: $crate::SIBinder,
318 $($fname: $fty,)*
319 }
320
321 impl $crate::Interface for $proxy {
322 fn as_binder(&self) -> $crate::SIBinder {
323 self.binder.clone()
324 }
325 }
326
327 impl $crate::Proxy for $proxy
328 where
329 $proxy: $interface,
330 {
331 fn descriptor() -> &'static str {
332 $descriptor
333 }
334
335 fn from_binder(binder: $crate::SIBinder) -> std::option::Option<Self> {
336 if binder.descriptor() != $descriptor {
337 return None
338 }
339 if let Some(_) = binder.as_proxy() {
340 Some(Self { binder, $($fname: $finit),* })
341 } else {
342 None
343 }
344 }
345 }
346
347 $crate::__declare_binder_interface!{
348 $interface[$descriptor] {
349 native: {
350 $native($on_transact),
351 $(adapter: $native_adapter,)?
352 $(r#async: $native_async,)?
353 },
354 proxy: $proxy {
355 $($fname: $fty = $finit),*
356 },
357 $(r#async: $async_interface,)?
358 stability: $stability,
359 }
360 }
361
362 impl $crate::FromIBinder for dyn $interface {
363 fn try_from(binder: $crate::SIBinder) -> $crate::Result<$crate::Strong<dyn $interface>> {
364 match <$proxy as $crate::Proxy>::from_binder(binder.clone()) {
365 Some(proxy) => Ok($crate::Strong::new(Box::new(proxy))),
366 None => {
367 match $crate::native::Binder::<$native>::try_from(binder) {
368 Ok(native) => Ok($crate::Strong::new(Box::new(native.clone()))),
369 Err(err) => Err(err),
370 }
371 }
372 }
373 }
374 }
375
376 impl $crate::parcelable::Serialize for dyn $interface
377 where
378 dyn $interface: $crate::Interface
379 {
380 fn serialize(&self, parcel: &mut $crate::Parcel) -> $crate::Result<()> {
381 let binder = $crate::Interface::as_binder(self);
382 parcel.write(&binder)?;
383 Ok(())
384 }
385 }
386
387 impl $crate::parcelable::SerializeOption for dyn $interface {
388 fn serialize_option(this: Option<&Self>, parcel: &mut $crate::Parcel) -> $crate::Result<()> {
389 parcel.write(&this.map($crate::Interface::as_binder))
390 }
391 }
392
393 impl std::fmt::Debug for dyn $interface + '_ {
394 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
395 f.pad(stringify!($interface))
396 }
397 }
398 }
399}
400
401#[macro_export]
408macro_rules! impl_serialize_for_parcelable {
409 ($parcelable:ident) => {
410 impl $crate::Serialize for $parcelable {
411 fn serialize(&self, parcel: &mut $crate::Parcel) -> $crate::Result<()> {
412 <Self as $crate::SerializeOption>::serialize_option(Some(self), parcel)
413 }
414 }
415
416 impl $crate::SerializeArray for $parcelable {}
417
418 impl $crate::SerializeOption for $parcelable {
419 fn serialize_option(
420 this: Option<&Self>,
421 parcel: &mut $crate::Parcel,
422 ) -> $crate::Result<()> {
423 if let Some(this) = this {
424 use $crate::Parcelable;
425 parcel.write(&$crate::NON_NULL_PARCELABLE_FLAG)?;
426 this.write_to_parcel(parcel)
427 } else {
428 parcel.write(&$crate::NULL_PARCELABLE_FLAG)
429 }
430 }
431 }
432 };
433}
434
435#[macro_export]
442macro_rules! impl_deserialize_for_parcelable {
443 ($parcelable:ident) => {
444 impl $crate::Deserialize for $parcelable {
445 fn deserialize(parcel: &mut $crate::Parcel) -> $crate::Result<Self> {
446 $crate::DeserializeOption::deserialize_option(parcel)
447 .transpose()
448 .unwrap_or(Err($crate::StatusCode::UnexpectedNull.into()))
449 }
450 fn deserialize_from(&mut self, parcel: &mut $crate::Parcel) -> $crate::Result<()> {
451 let status: i32 = parcel.read()?;
452 if status == $crate::NULL_PARCELABLE_FLAG {
453 Err($crate::StatusCode::UnexpectedNull.into())
454 } else {
455 use $crate::Parcelable;
456 self.read_from_parcel(parcel)
457 }
458 }
459 }
460
461 impl $crate::DeserializeArray for $parcelable {}
462
463 impl $crate::DeserializeOption for $parcelable {
464 fn deserialize_option(parcel: &mut $crate::Parcel) -> $crate::Result<Option<Self>> {
465 let mut result = None;
466 Self::deserialize_option_from(&mut result, parcel)?;
467 Ok(result)
468 }
469 fn deserialize_option_from(
470 this: &mut Option<Self>,
471 parcel: &mut $crate::Parcel,
472 ) -> $crate::Result<()> {
473 let status: i32 = parcel.read()?;
474 if status == $crate::NULL_PARCELABLE_FLAG {
475 *this = None;
476 Ok(())
477 } else {
478 use $crate::Parcelable;
479 this.get_or_insert_with(Self::default)
480 .read_from_parcel(parcel)
481 }
482 }
483 }
484 };
485}
486
487#[macro_export]
491macro_rules! declare_binder_enum {
492 {
493 $( #[$attr:meta] )*
494 $enum:ident : [$backing:ty; $size:expr] {
495 $( $( #[$value_attr:meta] )* $name:ident = $value:expr, )*
496 }
497 } => {
498 $( #[$attr] )*
499 #[derive(Debug, Default, Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)]
500 #[allow(missing_docs)]
501 pub struct $enum(pub $backing);
502 impl $enum {
503 $( $( #[$value_attr] )* #[allow(missing_docs)] pub const $name: Self = Self($value); )*
504
505 #[inline(always)]
506 #[allow(missing_docs)]
507 pub const fn enum_values() -> [Self; $size] {
508 [$(Self::$name),*]
509 }
510 }
511
512 impl $crate::Serialize for $enum {
513 fn serialize(&self, parcel: &mut $crate::Parcel) -> $crate::Result<()> {
514 parcel.write(&self.0)
515 }
516 }
517
518 impl $crate::SerializeArray for $enum {
519 fn serialize_array(slice: &[Self], parcel: &mut $crate::Parcel) -> $crate::Result<()> {
520 let v: Vec<$backing> = slice.iter().map(|x| x.0).collect();
521 <$backing as $crate::SerializeArray>::serialize_array(&v[..], parcel)
522 }
523 }
524
525 impl $crate::Deserialize for $enum {
526 fn deserialize(parcel: &mut $crate::Parcel) -> $crate::Result<Self> {
527 let res = parcel.read().map(Self);
528 res
529 }
530 }
531
532 impl $crate::DeserializeArray for $enum {
533 fn deserialize_array(parcel: &mut $crate::Parcel) -> $crate::Result<Option<Vec<Self>>> {
534 let v: Option<Vec<$backing>> =
535 <$backing as $crate::DeserializeArray>::deserialize_array(parcel)?;
536 Ok(v.map(|v| v.into_iter().map(Self).collect()))
537 }
538 }
539 };
540}
541
542#[cfg(test)]
543mod tests {
544 use crate::{Binder, Interface, Parcel, Result, TransactionCode};
545
546 pub trait IEcho: Interface {
547 fn echo(&self, echo: &str) -> Result<String>;
548 }
549
550 pub trait IEchoAsyncService: Interface {
551 #[allow(dead_code)]
552 fn echo(&self, echo: &str) -> Result<String>;
553 }
554
555 declare_binder_interface! {
556 IEcho["my.echo"] {
557 native: {
558 BnEcho(on_transact),
559 adapter: BnEchoAdapter,
560 r#async: IEchoAsyncService,
561 },
562 proxy: BpEcho{},
563 }
564 }
565
566 #[allow(dead_code)]
567 impl IEcho for Binder<BnEcho> {
568 #[cfg(feature = "async")]
569 fn echo(&self, echo: &str) -> Result<String> {
570 self.0.as_sync().echo(echo)
571 }
572 #[cfg(not(feature = "async"))]
573 fn echo(&self, echo: &str) -> Result<String> {
574 self.0.echo(echo)
575 }
576 }
577
578 impl IEcho for BpEcho {
579 fn echo(&self, _echo: &str) -> Result<String> {
580 unimplemented!("BpEcho::echo")
581 }
582 }
583
584 fn on_transact(
585 _service: &dyn IEcho,
586 _code: TransactionCode,
587 _data: &mut Parcel,
588 _reply: &mut Parcel,
589 ) -> Result<()> {
590 Ok(())
592 }
593
594 struct EchoService {}
595
596 impl Interface for EchoService {}
597
598 impl IEcho for EchoService {
599 fn echo(&self, echo: &str) -> Result<String> {
600 Ok(echo.to_owned())
601 }
602 }
603
604 #[test]
605 fn test_declare_binder_interface() {
606 let _ = BnEcho::new_binder(EchoService {});
607 }
608
609 #[cfg(feature = "async")]
610 #[test]
611 fn test_try_from() {
612 use async_trait::async_trait;
613
614 #[allow(dead_code)]
615 pub trait IEcho: Interface + Send {
616 fn echo(&self, echo: &str) -> crate::status::Result<String>;
617 }
618 pub trait IEchoAsync<P>: Interface + Send {
619 #[allow(dead_code)]
620 fn echo<'a>(
621 &'a self,
622 echo: &'a str,
623 ) -> crate::BoxFuture<'a, crate::status::Result<String>>;
624 }
625
626 #[allow(dead_code)]
627 #[async_trait]
628 pub trait IEchoAsyncService: Interface + Send {
629 async fn echo(&self, echo: &str) -> crate::status::Result<String>;
630 }
631 pub struct BpEcho {
632 binder: crate::SIBinder,
633 }
634 impl IEcho for BpEcho {
635 fn echo(&self, _echo: &str) -> crate::status::Result<String> {
636 todo!()
637 }
638 }
639 impl<P: crate::BinderAsyncPool> IEchoAsync<P> for BpEcho {
640 fn echo<'a>(
641 &'a self,
642 _echo: &'a str,
643 ) -> crate::BoxFuture<'a, crate::status::Result<String>> {
644 P::spawn(move || 0, |_| async move { Ok("".to_string()) })
645 }
646 }
647 impl Interface for BpEcho {
648 fn as_binder(&self) -> crate::SIBinder {
649 self.binder.clone()
650 }
651 }
652 impl crate::Proxy for BpEcho
653 where
654 BpEcho: IEcho,
655 {
656 fn descriptor() -> &'static str {
657 "my.echo"
658 }
659
660 fn from_binder(binder: crate::SIBinder) -> std::option::Option<Self> {
661 if binder.descriptor() != Self::descriptor() {
662 return None;
663 }
664 if binder.as_proxy().is_some() {
665 Some(Self { binder })
666 } else {
667 None
668 }
669 }
670 }
671
672 #[allow(dead_code)]
673 pub trait BnEchoAdapter: Send + Sync {
674 fn as_sync(&self) -> &dyn IEcho;
675 fn as_async(&self) -> &dyn IEchoAsyncService;
676 }
677
678 #[allow(dead_code)]
679 struct Wrapper<T, R> {
680 inner: T,
681 rt: R,
682 }
683
684 impl<T, R> Interface for Wrapper<T, R>
685 where
686 T: IEchoAsyncService + Sync + Send + 'static,
687 R: crate::BinderAsyncRuntime + Send + Sync + 'static,
688 {
689 fn as_binder(&self) -> crate::SIBinder {
690 self.inner.as_binder()
691 }
692
693 fn dump(&self, _writer: &mut dyn std::io::Write, _args: &[String]) -> Result<()> {
694 self.inner.dump(_writer, _args)
695 }
696 }
697
698 impl<T, R> IEcho for Wrapper<T, R>
699 where
700 T: IEchoAsyncService + Sync + Send + 'static,
701 R: crate::BinderAsyncRuntime + Send + Sync + 'static,
702 {
703 fn echo(&self, echo: &str) -> crate::status::Result<String> {
704 self.rt.block_on(self.inner.echo(echo))
705 }
706 }
707
708 impl<T, R> BnEchoAdapter for Wrapper<T, R>
709 where
710 T: IEchoAsyncService + Sync + Send + 'static,
711 R: crate::BinderAsyncRuntime + Send + Sync + 'static,
712 {
713 fn as_sync(&self) -> &dyn IEcho {
714 self
715 }
716 fn as_async(&self) -> &dyn IEchoAsyncService {
717 &self.inner
718 }
719 }
720
721 #[allow(dead_code)]
722 pub struct BnEcho(Box<dyn BnEchoAdapter>);
723
724 impl BnEcho {
725 pub fn new_binder<T, R>(inner: T, rt: R) -> crate::Strong<dyn IEcho>
727 where
728 T: IEchoAsyncService + Sync + Send + 'static,
729 R: crate::BinderAsyncRuntime + Send + Sync + 'static,
730 {
731 let bn = BnEcho(Box::new(Wrapper { inner, rt }));
732 let binder =
733 crate::native::Binder::new_with_stability(bn, crate::Stability::default());
734 crate::Strong::new(Box::new(binder))
735 }
736 }
737
738 impl crate::Remotable for BnEcho {
739 fn descriptor() -> &'static str
740 where
741 Self: Sized,
742 {
743 "my.echo"
744 }
745
746 fn on_transact(
747 &self,
748 _code: crate::TransactionCode,
749 _reader: &mut crate::Parcel,
750 _reply: &mut crate::Parcel,
751 ) -> crate::Result<()> {
752 todo!()
753 }
754
755 fn on_dump(
756 &self,
757 _writer: &mut dyn std::io::Write,
758 _args: &[String],
759 ) -> crate::Result<()> {
760 Ok(())
761 }
762 }
763
764 impl IEcho for crate::Binder<BnEcho> {
765 fn echo(&self, echo: &str) -> crate::status::Result<String> {
766 self.0.as_sync().echo(echo)
767 }
768 }
769
770 impl<P: crate::BinderAsyncPool> IEchoAsync<P> for crate::Binder<BnEcho> {
771 fn echo<'a>(
772 &'a self,
773 echo: &'a str,
774 ) -> crate::BoxFuture<'a, crate::status::Result<String>> {
775 self.0.as_async().echo(echo)
776 }
777 }
778
779 impl crate::FromIBinder for dyn IEcho {
780 fn try_from(binder: crate::SIBinder) -> crate::Result<crate::Strong<dyn IEcho>> {
781 match <BpEcho as crate::Proxy>::from_binder(binder.clone()) {
782 Some(proxy) => Ok(crate::Strong::new(Box::new(proxy))),
783 None => match crate::native::Binder::<BnEcho>::try_from(binder) {
784 Ok(native) => Ok(crate::Strong::new(Box::new(native.clone()))),
785 Err(err) => Err(err),
786 },
787 }
788 }
789 }
790
791 impl<P: crate::BinderAsyncPool> crate::FromIBinder for dyn IEchoAsync<P> {
792 fn try_from(
793 binder: crate::SIBinder,
794 ) -> crate::Result<crate::Strong<dyn IEchoAsync<P>>> {
795 match <BpEcho as crate::Proxy>::from_binder(binder.clone()) {
796 Some(proxy) => Ok(crate::Strong::new(Box::new(proxy))),
797 None => {
798 match crate::native::Binder::<BnEcho>::try_from(binder) {
799 Ok(native) => Ok(crate::Strong::new(Box::new(native.clone()))),
800 Err(err) => Err(err),
801 }
802 }
804 }
805 }
806 }
807
808 impl<P: crate::BinderAsyncPool> crate::ToAsyncInterface<P> for dyn IEcho {
809 type Target = dyn IEchoAsync<P>;
810 }
811
812 impl<P: crate::BinderAsyncPool> crate::ToSyncInterface for dyn IEchoAsync<P> {
813 type Target = dyn IEcho;
814 }
815
816 struct MyEcho {}
817 impl Interface for MyEcho {}
818 #[async_trait]
819 impl IEchoAsyncService for MyEcho {
820 async fn echo(&self, echo: &str) -> crate::status::Result<String> {
821 Ok(echo.to_owned())
822 }
823 }
824
825 struct MyRuntime {}
826 impl crate::BinderAsyncRuntime for MyRuntime {
827 fn block_on<F: std::future::Future>(&self, _future: F) -> F::Output {
828 todo!()
829 }
830 }
831
832 let _echo = BnEcho::new_binder(MyEcho {}, MyRuntime {});
833
834 }
836}