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 ClientSender<
16 P,
17 #[cfg(feature = "fuchsia")] T: Transport = zx::Channel,
18 #[cfg(not(feature = "fuchsia"))] T: Transport,
19> {
20 sender: protocol::ClientSender<T>,
21 _protocol: PhantomData<P>,
22}
23
24unsafe impl<P, T> Send for ClientSender<P, T>
25where
26 T: Transport,
27 protocol::ClientSender<T>: Send,
28{
29}
30
31impl<P, T: Transport> ClientSender<P, T> {
32 pub fn wrap_untyped(client: &protocol::ClientSender<T>) -> &Self {
34 unsafe { &*(client as *const protocol::ClientSender<T>).cast() }
35 }
36
37 pub fn close(&self) {
39 self.sender.close();
40 }
41}
42
43impl<P, T: Transport> Clone for ClientSender<P, T> {
44 fn clone(&self) -> Self {
45 Self { sender: self.sender.clone(), _protocol: PhantomData }
46 }
47}
48
49impl<P: Protocol<T>, T: Transport> Deref for ClientSender<P, T> {
50 type Target = P::ClientSender;
51
52 fn deref(&self) -> &Self::Target {
53 unsafe { &*(self as *const Self).cast::<P::ClientSender>() }
55 }
56}
57
58pub trait DispatchClientMessage<
60 H,
61 #[cfg(feature = "fuchsia")] T: Transport = zx::Channel,
62 #[cfg(not(feature = "fuchsia"))] T: Transport,
63>: Sized + 'static
64{
65 fn on_event(
67 handler: &mut H,
68 sender: &ClientSender<Self, T>,
69 ordinal: u64,
70 buffer: T::RecvBuffer,
71 ) -> impl Future<Output = ()> + 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 sender: &protocol::ClientSender<T>,
97 ordinal: u64,
98 buffer: T::RecvBuffer,
99 ) -> impl Future<Output = ()> + Send {
100 P::on_event(&mut self.handler, ClientSender::wrap_untyped(sender), ordinal, buffer)
101 }
102}
103
104pub struct Client<
106 P,
107 #[cfg(feature = "fuchsia")] T: Transport = zx::Channel,
108 #[cfg(not(feature = "fuchsia"))] T: Transport,
109> {
110 client: protocol::Client<T>,
111 _protocol: PhantomData<P>,
112}
113
114unsafe impl<P, T> Send for Client<P, T>
115where
116 T: Transport,
117 protocol::Client<T>: Send,
118{
119}
120
121impl<P, T: Transport> Client<P, T> {
122 pub fn new(client_end: ClientEnd<P, T>) -> Self {
124 Self { client: protocol::Client::new(client_end.into_untyped()), _protocol: PhantomData }
125 }
126
127 pub fn sender(&self) -> &ClientSender<P, T> {
129 ClientSender::wrap_untyped(self.client.sender())
130 }
131
132 pub fn from_untyped(client: protocol::Client<T>) -> Self {
134 Self { client, _protocol: PhantomData }
135 }
136
137 pub async fn run<H>(self, handler: H) -> Result<H, ProtocolError<T::Error>>
139 where
140 P: DispatchClientMessage<H, T>,
141 {
142 self.client
143 .run(ClientHandlerAdapter { handler, _protocol: PhantomData::<P> })
144 .await
145 .map(|adapter| adapter.handler)
146 }
147
148 pub async fn run_sender(self) -> Result<(), ProtocolError<T::Error>> {
150 self.client.run(IgnoreEvents).await.map(|_| ())
151 }
152}