fidl_next_bind/
client.rs
1use core::future::Future;
6use core::marker::PhantomData;
7use core::pin::Pin;
8use core::task::{Context, Poll};
9
10use fidl_next_protocol::{self as protocol, IgnoreEvents, ProtocolError, Transport};
11
12use super::{ClientEnd, Method, ResponseBuffer};
13
14#[repr(transparent)]
16pub struct ClientSender<T: Transport, P> {
17 sender: protocol::ClientSender<T>,
18 _protocol: PhantomData<P>,
19}
20
21unsafe impl<T, P> Send for ClientSender<T, P>
22where
23 T: Transport,
24 protocol::ClientSender<T>: Send,
25{
26}
27
28impl<T: Transport, P> ClientSender<T, P> {
29 pub fn wrap_untyped(client: &protocol::ClientSender<T>) -> &Self {
31 unsafe { &*(client as *const protocol::ClientSender<T>).cast() }
32 }
33
34 pub fn as_untyped(&self) -> &protocol::ClientSender<T> {
36 &self.sender
37 }
38
39 pub fn close(&self) {
41 self.as_untyped().close();
42 }
43}
44
45impl<T: Transport, P> Clone for ClientSender<T, P> {
46 fn clone(&self) -> Self {
47 Self { sender: self.sender.clone(), _protocol: PhantomData }
48 }
49}
50
51pub trait ClientProtocol<T: Transport, H>: Sized {
53 fn on_event(
55 handler: &mut H,
56 sender: &ClientSender<T, Self>,
57 ordinal: u64,
58 buffer: T::RecvBuffer,
59 );
60}
61
62pub struct ClientAdapter<P, H> {
64 handler: H,
65 _protocol: PhantomData<P>,
66}
67
68unsafe impl<P, H> Send for ClientAdapter<P, H> where H: Send {}
69
70impl<P, H> ClientAdapter<P, H> {
71 pub fn from_untyped(handler: H) -> Self {
73 Self { handler, _protocol: PhantomData }
74 }
75}
76
77impl<T, P, H> protocol::ClientHandler<T> for ClientAdapter<P, H>
78where
79 T: Transport,
80 P: ClientProtocol<T, H>,
81{
82 fn on_event(
83 &mut self,
84 sender: &protocol::ClientSender<T>,
85 ordinal: u64,
86 buffer: T::RecvBuffer,
87 ) {
88 P::on_event(&mut self.handler, ClientSender::wrap_untyped(sender), ordinal, buffer)
89 }
90}
91
92pub struct Client<T: Transport, P> {
94 client: protocol::Client<T>,
95 _protocol: PhantomData<P>,
96}
97
98unsafe impl<T, P> Send for Client<T, P>
99where
100 T: Transport,
101 protocol::Client<T>: Send,
102{
103}
104
105impl<T: Transport, P> Client<T, P> {
106 pub fn new(client_end: ClientEnd<T, P>) -> Self {
108 Self { client: protocol::Client::new(client_end.into_untyped()), _protocol: PhantomData }
109 }
110
111 pub fn sender(&self) -> &ClientSender<T, P> {
113 ClientSender::wrap_untyped(self.client.sender())
114 }
115
116 pub fn from_untyped(client: protocol::Client<T>) -> Self {
118 Self { client, _protocol: PhantomData }
119 }
120
121 pub async fn run<H>(&mut self, handler: H) -> Result<(), ProtocolError<T::Error>>
123 where
124 P: ClientProtocol<T, H>,
125 {
126 self.client.run(ClientAdapter { handler, _protocol: PhantomData::<P> }).await
127 }
128
129 pub async fn run_sender(&mut self) -> Result<(), ProtocolError<T::Error>> {
131 self.client.run(IgnoreEvents).await
132 }
133}
134
135pub struct ResponseFuture<'a, T: Transport, M> {
137 future: protocol::ResponseFuture<'a, T>,
138 _method: PhantomData<M>,
139}
140
141impl<'a, T: Transport, M> ResponseFuture<'a, T, M> {
142 pub fn from_untyped(future: protocol::ResponseFuture<'a, T>) -> Self {
144 Self { future, _method: PhantomData }
145 }
146}
147
148impl<T, M> Future for ResponseFuture<'_, T, M>
149where
150 T: Transport,
151 M: Method,
152{
153 type Output = Result<ResponseBuffer<T, M>, T::Error>;
154
155 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
156 let future = unsafe { self.map_unchecked_mut(|this| &mut this.future) };
159 future.poll(cx).map_ok(ResponseBuffer::from_untyped)
160 }
161}