1use core::future::Future;
6use core::marker::PhantomData;
7use core::ops::Deref;
8use core::pin::Pin;
9use core::task::{Context, Poll};
10
11use fidl_next_codec::{Decode, DecoderExt as _};
12use fidl_next_protocol::{self as protocol, IgnoreEvents, ProtocolError, Transport};
13
14use crate::{ClientEnd, Error, Method, Protocol, Response};
15
16#[repr(transparent)]
18pub struct ClientSender<
19 P,
20 #[cfg(feature = "fuchsia")] T: Transport = zx::Channel,
21 #[cfg(not(feature = "fuchsia"))] T: Transport,
22> {
23 sender: protocol::ClientSender<T>,
24 _protocol: PhantomData<P>,
25}
26
27unsafe impl<P, T> Send for ClientSender<P, T>
28where
29 T: Transport,
30 protocol::ClientSender<T>: Send,
31{
32}
33
34impl<P, T: Transport> ClientSender<P, T> {
35 pub fn wrap_untyped(client: &protocol::ClientSender<T>) -> &Self {
37 unsafe { &*(client as *const protocol::ClientSender<T>).cast() }
38 }
39
40 pub fn close(&self) {
42 self.sender.close();
43 }
44}
45
46impl<P, T: Transport> Clone for ClientSender<P, T> {
47 fn clone(&self) -> Self {
48 Self { sender: self.sender.clone(), _protocol: PhantomData }
49 }
50}
51
52impl<P: Protocol<T>, T: Transport> Deref for ClientSender<P, T> {
53 type Target = P::ClientSender;
54
55 fn deref(&self) -> &Self::Target {
56 unsafe { &*(self as *const Self).cast::<P::ClientSender>() }
58 }
59}
60
61pub trait ClientProtocol<
63 H,
64 #[cfg(feature = "fuchsia")] T: Transport = zx::Channel,
65 #[cfg(not(feature = "fuchsia"))] T: Transport,
66>: Sized + 'static
67{
68 fn on_event(
70 handler: &mut H,
71 sender: &ClientSender<Self, T>,
72 ordinal: u64,
73 buffer: T::RecvBuffer,
74 ) -> impl Future<Output = ()> + Send;
75}
76
77pub struct ClientAdapter<P, H> {
79 handler: H,
80 _protocol: PhantomData<P>,
81}
82
83unsafe impl<P, H> Send for ClientAdapter<P, H> where H: Send {}
84
85impl<P, H> ClientAdapter<P, H> {
86 pub fn from_untyped(handler: H) -> Self {
88 Self { handler, _protocol: PhantomData }
89 }
90}
91
92impl<P, H, T> protocol::ClientHandler<T> for ClientAdapter<P, H>
93where
94 P: ClientProtocol<H, T>,
95 T: Transport,
96{
97 fn on_event(
98 &mut self,
99 sender: &protocol::ClientSender<T>,
100 ordinal: u64,
101 buffer: T::RecvBuffer,
102 ) -> impl Future<Output = ()> + Send {
103 P::on_event(&mut self.handler, ClientSender::wrap_untyped(sender), ordinal, buffer)
104 }
105}
106
107pub struct Client<
109 P,
110 #[cfg(feature = "fuchsia")] T: Transport = zx::Channel,
111 #[cfg(not(feature = "fuchsia"))] T: Transport,
112> {
113 client: protocol::Client<T>,
114 _protocol: PhantomData<P>,
115}
116
117unsafe impl<P, T> Send for Client<P, T>
118where
119 T: Transport,
120 protocol::Client<T>: Send,
121{
122}
123
124impl<P, T: Transport> Client<P, T> {
125 pub fn new(client_end: ClientEnd<P, T>) -> Self {
127 Self { client: protocol::Client::new(client_end.into_untyped()), _protocol: PhantomData }
128 }
129
130 pub fn sender(&self) -> &ClientSender<P, T> {
132 ClientSender::wrap_untyped(self.client.sender())
133 }
134
135 pub fn from_untyped(client: protocol::Client<T>) -> Self {
137 Self { client, _protocol: PhantomData }
138 }
139
140 pub async fn run<H>(&mut self, handler: H) -> Result<(), ProtocolError<T::Error>>
142 where
143 P: ClientProtocol<H, T>,
144 {
145 self.client.run(ClientAdapter { handler, _protocol: PhantomData::<P> }).await
146 }
147
148 pub async fn run_sender(&mut self) -> Result<(), ProtocolError<T::Error>> {
150 self.client.run(IgnoreEvents).await
151 }
152}
153
154pub struct ResponseFuture<
156 'a,
157 M,
158 #[cfg(feature = "fuchsia")] T: Transport = zx::Channel,
159 #[cfg(not(feature = "fuchsia"))] T: Transport,
160> {
161 future: protocol::ResponseFuture<'a, T>,
162 _method: PhantomData<M>,
163}
164
165impl<'a, M, T: Transport> ResponseFuture<'a, M, T> {
166 pub fn from_untyped(future: protocol::ResponseFuture<'a, T>) -> Self {
168 Self { future, _method: PhantomData }
169 }
170}
171
172impl<M, T> Future for ResponseFuture<'_, M, T>
173where
174 M: Method,
175 M::Response: Decode<T::RecvBuffer>,
176 T: Transport,
177{
178 type Output = Result<Response<M, T>, Error<T::Error>>;
179
180 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
181 let future = unsafe { self.map_unchecked_mut(|this| &mut this.future) };
184 if let Poll::Ready(ready) = future.poll(cx)? {
185 Poll::Ready(ready.decode().map_err(Error::Decode))
186 } else {
187 Poll::Pending
188 }
189 }
190}