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