1use core::future::Future;
6use core::marker::PhantomData;
7use core::ops::Deref;
8
9use fidl_next_protocol::{self as protocol, ClientHandler, IgnoreEvents, ProtocolError, Transport};
10
11use crate::{ClientEnd, Protocol};
12
13#[repr(transparent)]
15pub struct Client<
16 P,
17 #[cfg(feature = "fuchsia")] T: Transport = zx::Channel,
18 #[cfg(not(feature = "fuchsia"))] T: Transport,
19> {
20 client: protocol::Client<T>,
21 _protocol: PhantomData<P>,
22}
23
24unsafe impl<P, T> Send for Client<P, T>
25where
26 T: Transport,
27 protocol::Client<T>: Send,
28{
29}
30
31impl<P, T: Transport> Client<P, T> {
32 pub fn from_untyped(client: protocol::Client<T>) -> Self {
34 Self { client, _protocol: PhantomData }
35 }
36
37 pub fn close(&self) {
39 self.client.close();
40 }
41}
42
43impl<P, T: Transport> Clone for Client<P, T> {
44 fn clone(&self) -> Self {
45 Self { client: self.client.clone(), _protocol: PhantomData }
46 }
47}
48
49impl<P: Protocol<T>, T: Transport> Deref for Client<P, T> {
50 type Target = P::Client;
51
52 fn deref(&self) -> &Self::Target {
53 unsafe { &*(self as *const Self).cast::<P::Client>() }
56 }
57}
58
59pub trait DispatchClientMessage<
61 H,
62 #[cfg(feature = "fuchsia")] T: Transport = zx::Channel,
63 #[cfg(not(feature = "fuchsia"))] T: Transport,
64>: Sized + 'static
65{
66 fn on_event(
68 handler: &mut H,
69 ordinal: u64,
70 buffer: T::RecvBuffer,
71 ) -> impl Future<Output = Result<(), ProtocolError<T::Error>>> + Send;
72}
73
74pub struct ClientHandlerAdapter<P, H> {
76 handler: H,
77 _protocol: PhantomData<P>,
78}
79
80unsafe impl<P, H> Send for ClientHandlerAdapter<P, H> where H: Send {}
81
82impl<P, H> ClientHandlerAdapter<P, H> {
83 pub fn from_untyped(handler: H) -> Self {
85 Self { handler, _protocol: PhantomData }
86 }
87}
88
89impl<P, H, T> ClientHandler<T> for ClientHandlerAdapter<P, H>
90where
91 P: DispatchClientMessage<H, T>,
92 T: Transport,
93{
94 fn on_event(
95 &mut self,
96 ordinal: u64,
97 buffer: T::RecvBuffer,
98 ) -> impl Future<Output = Result<(), ProtocolError<T::Error>>> + Send {
99 P::on_event(&mut self.handler, ordinal, buffer)
100 }
101}
102
103pub struct ClientDispatcher<
105 P,
106 #[cfg(feature = "fuchsia")] T: Transport = zx::Channel,
107 #[cfg(not(feature = "fuchsia"))] T: Transport,
108> {
109 dispatcher: protocol::ClientDispatcher<T>,
110 _protocol: PhantomData<P>,
111}
112
113unsafe impl<P, T> Send for ClientDispatcher<P, T>
114where
115 T: Transport,
116 protocol::Client<T>: Send,
117{
118}
119
120impl<P, T: Transport> ClientDispatcher<P, T> {
121 pub fn new(client_end: ClientEnd<P, T>) -> Self {
123 Self {
124 dispatcher: protocol::ClientDispatcher::new(client_end.into_untyped()),
125 _protocol: PhantomData,
126 }
127 }
128
129 pub fn client(&self) -> Client<P, T> {
131 Client::from_untyped(self.dispatcher.client())
132 }
133
134 pub fn from_untyped(dispatcher: protocol::ClientDispatcher<T>) -> Self {
136 Self { dispatcher, _protocol: PhantomData }
137 }
138
139 pub async fn run<H>(self, handler: H) -> Result<H, ProtocolError<T::Error>>
141 where
142 P: DispatchClientMessage<H, T>,
143 {
144 self.dispatcher
145 .run(ClientHandlerAdapter { handler, _protocol: PhantomData::<P> })
146 .await
147 .map(|adapter| adapter.handler)
148 }
149
150 pub async fn run_client(self) -> Result<(), ProtocolError<T::Error>> {
152 self.dispatcher.run(IgnoreEvents).await.map(|_| ())
153 }
154}