1use core::future::Future;
6use core::marker::PhantomData;
7use core::ops::Deref;
8
9use fidl_next_protocol::{
10 self as protocol, Body, ClientHandler, Flexibility, LocalClientHandler, ProtocolError,
11 Transport,
12};
13
14use crate::{ClientEnd, HasConnectionHandles, HasTransport};
15
16#[repr(transparent)]
18pub struct Client<P, T: Transport = <P as HasTransport>::Transport> {
19 client: protocol::Client<T>,
20 _protocol: PhantomData<P>,
21}
22
23unsafe impl<P, T> Send for Client<P, T>
24where
25 T: Transport,
26 protocol::Client<T>: Send,
27{
28}
29
30impl<P, T: Transport> Client<P, T> {
31 pub fn from_untyped(client: protocol::Client<T>) -> Self {
33 Self { client, _protocol: PhantomData }
34 }
35
36 pub fn close(&self) {
38 self.client.close();
39 }
40}
41
42impl<P, T: Transport> Clone for Client<P, T> {
43 fn clone(&self) -> Self {
44 Self { client: self.client.clone(), _protocol: PhantomData }
45 }
46}
47
48impl<P: HasConnectionHandles<T>, T: Transport> Deref for Client<P, T> {
49 type Target = P::Client;
50
51 fn deref(&self) -> &Self::Target {
52 unsafe { &*(self as *const Self).cast::<P::Client>() }
55 }
56}
57
58pub trait DispatchLocalClientMessage<H, T: Transport>: Sized + 'static {
63 fn on_event(
65 handler: &mut H,
66 ordinal: u64,
67 flexibility: Flexibility,
68 body: Body<T>,
69 ) -> impl Future<Output = Result<(), ProtocolError<T::Error>>>;
70}
71
72pub trait DispatchClientMessage<H: Send, T: Transport>: Sized + 'static {
74 fn on_event(
76 handler: &mut H,
77 ordinal: u64,
78 flexibility: Flexibility,
79 body: Body<T>,
80 ) -> impl Future<Output = Result<(), ProtocolError<T::Error>>> + Send;
81}
82
83pub struct ClientHandlerToProtocolAdapter<P, H> {
85 handler: H,
86 _protocol: PhantomData<P>,
87}
88
89unsafe impl<P, H> Send for ClientHandlerToProtocolAdapter<P, H> where H: Send {}
90
91impl<P, H> ClientHandlerToProtocolAdapter<P, H> {
92 pub fn from_untyped(handler: H) -> Self {
94 Self { handler, _protocol: PhantomData }
95 }
96}
97
98impl<P, H, T> LocalClientHandler<T> for ClientHandlerToProtocolAdapter<P, H>
99where
100 P: DispatchLocalClientMessage<H, T>,
101 T: Transport,
102{
103 fn on_event(
104 &mut self,
105 ordinal: u64,
106 flexibility: Flexibility,
107 body: Body<T>,
108 ) -> impl Future<Output = Result<(), ProtocolError<T::Error>>> {
109 P::on_event(&mut self.handler, ordinal, flexibility, body)
110 }
111}
112
113impl<P, H, T> ClientHandler<T> for ClientHandlerToProtocolAdapter<P, H>
114where
115 P: DispatchClientMessage<H, T>,
116 H: Send,
117 T: Transport,
118{
119 fn on_event(
120 &mut self,
121 ordinal: u64,
122 flexibility: Flexibility,
123 body: Body<T>,
124 ) -> impl Future<Output = Result<(), ProtocolError<T::Error>>> + Send {
125 P::on_event(&mut self.handler, ordinal, flexibility, body)
126 }
127}
128
129pub struct ClientDispatcher<P, T: Transport = <P as HasTransport>::Transport> {
131 dispatcher: protocol::ClientDispatcher<T>,
132 _protocol: PhantomData<P>,
133}
134
135unsafe impl<P, T> Send for ClientDispatcher<P, T>
136where
137 T: Transport,
138 protocol::Client<T>: Send,
139{
140}
141
142impl<P, T: Transport> ClientDispatcher<P, T> {
143 pub fn new(client_end: ClientEnd<P, T>) -> Self {
145 Self {
146 dispatcher: protocol::ClientDispatcher::new(client_end.into_untyped()),
147 _protocol: PhantomData,
148 }
149 }
150
151 pub fn client(&self) -> Client<P, T> {
153 Client::from_untyped(self.dispatcher.client())
154 }
155
156 pub fn from_untyped(dispatcher: protocol::ClientDispatcher<T>) -> Self {
158 Self { dispatcher, _protocol: PhantomData }
159 }
160
161 pub async fn run<H>(self, handler: H) -> Result<H, ProtocolError<T::Error>>
163 where
164 P: DispatchClientMessage<H, T>,
165 H: Send,
166 {
167 self.dispatcher
168 .run(ClientHandlerToProtocolAdapter { handler, _protocol: PhantomData::<P> })
169 .await
170 .map(|adapter| adapter.handler)
171 }
172
173 pub async fn run_local<H>(self, handler: H) -> Result<H, ProtocolError<T::Error>>
175 where
176 P: DispatchLocalClientMessage<H, T>,
177 {
178 self.dispatcher
179 .run_local(ClientHandlerToProtocolAdapter { handler, _protocol: PhantomData::<P> })
180 .await
181 .map(|adapter| adapter.handler)
182 }
183
184 pub async fn run_client(self) -> Result<(), ProtocolError<T::Error>>
186 where
187 P: DispatchClientMessage<IgnoreEvents, T>,
188 {
189 self.run(IgnoreEvents).await.map(|_| ())
190 }
191}
192
193pub struct IgnoreEvents;