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