fidl_next_bind/
server.rs

1// Copyright 2024 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use core::future::Future;
6use core::marker::PhantomData;
7use core::ops::Deref;
8
9use fidl_next_codec::{Encode, EncodeError};
10use fidl_next_protocol::{self as protocol, ProtocolError, SendFuture, Transport};
11
12use crate::{Method, Protocol, ServerEnd};
13
14/// A strongly typed server sender.
15#[repr(transparent)]
16pub struct ServerSender<
17    P,
18    #[cfg(feature = "fuchsia")] T: Transport = zx::Channel,
19    #[cfg(not(feature = "fuchsia"))] T: Transport,
20> {
21    sender: protocol::ServerSender<T>,
22    _protocol: PhantomData<P>,
23}
24
25unsafe impl<P, T> Send for ServerSender<P, T>
26where
27    protocol::ServerSender<T>: Send,
28    T: Transport,
29{
30}
31
32impl<P, T: Transport> ServerSender<P, T> {
33    /// Wraps an untyped sender reference, returning a typed sender reference.
34    pub fn wrap_untyped(client: &protocol::ServerSender<T>) -> &Self {
35        unsafe { &*(client as *const protocol::ServerSender<T>).cast() }
36    }
37
38    /// Closes the channel from the server end.
39    pub fn close(&self) {
40        self.sender.close();
41    }
42}
43
44impl<P, T: Transport> Clone for ServerSender<P, T> {
45    fn clone(&self) -> Self {
46        Self { sender: self.sender.clone(), _protocol: PhantomData }
47    }
48}
49
50impl<P: Protocol<T>, T: Transport> Deref for ServerSender<P, T> {
51    type Target = P::ServerSender;
52
53    fn deref(&self) -> &Self::Target {
54        // SAFETY: `P::ServerSender` is a `#[repr(transparent)]` wrapper around `ServerSender<T>`.
55        unsafe { &*(self as *const Self).cast::<P::ServerSender>() }
56    }
57}
58
59/// A protocol which supports servers.
60pub trait ServerProtocol<
61    H,
62    #[cfg(feature = "fuchsia")] T: Transport = zx::Channel,
63    #[cfg(not(feature = "fuchsia"))] T: Transport,
64>: Sized + 'static
65{
66    /// Handles a received server one-way message with the given handler.
67    fn on_one_way(
68        handler: &mut H,
69        server: &ServerSender<Self, T>,
70        ordinal: u64,
71        buffer: T::RecvBuffer,
72    ) -> impl Future<Output = ()> + Send;
73
74    /// Handles a received server two-way message with the given handler.
75    fn on_two_way(
76        handler: &mut H,
77        server: &ServerSender<Self, T>,
78        ordinal: u64,
79        buffer: T::RecvBuffer,
80        responder: protocol::Responder,
81    ) -> impl Future<Output = ()> + Send;
82}
83
84/// An adapter for a server protocol handler.
85pub struct ServerAdapter<P, H> {
86    handler: H,
87    _protocol: PhantomData<P>,
88}
89
90unsafe impl<P, H> Send for ServerAdapter<P, H> where H: Send {}
91
92impl<P, H> ServerAdapter<P, H> {
93    /// Creates a new protocol server handler from a supported handler.
94    pub fn from_untyped(handler: H) -> Self {
95        Self { handler, _protocol: PhantomData }
96    }
97}
98
99impl<P, H, T> protocol::ServerHandler<T> for ServerAdapter<P, H>
100where
101    P: ServerProtocol<H, T>,
102    T: Transport,
103{
104    fn on_one_way(
105        &mut self,
106        server: &protocol::ServerSender<T>,
107        ordinal: u64,
108        buffer: T::RecvBuffer,
109    ) -> impl Future<Output = ()> + Send {
110        P::on_one_way(&mut self.handler, ServerSender::wrap_untyped(server), ordinal, buffer)
111    }
112
113    fn on_two_way(
114        &mut self,
115        server: &protocol::ServerSender<T>,
116        ordinal: u64,
117        buffer: <T as Transport>::RecvBuffer,
118        responder: protocol::Responder,
119    ) -> impl Future<Output = ()> + Send {
120        P::on_two_way(
121            &mut self.handler,
122            ServerSender::wrap_untyped(server),
123            ordinal,
124            buffer,
125            responder,
126        )
127    }
128}
129
130/// A strongly typed server.
131pub struct Server<
132    P,
133    #[cfg(feature = "fuchsia")] T: Transport = zx::Channel,
134    #[cfg(not(feature = "fuchsia"))] T: Transport,
135> {
136    server: protocol::Server<T>,
137    _protocol: PhantomData<P>,
138}
139
140unsafe impl<P, T> Send for Server<P, T>
141where
142    protocol::Server<T>: Send,
143    T: Transport,
144{
145}
146
147impl<P, T: Transport> Server<P, T> {
148    /// Creates a new server from a server end.
149    pub fn new(server_end: ServerEnd<P, T>) -> Self {
150        Self { server: protocol::Server::new(server_end.into_untyped()), _protocol: PhantomData }
151    }
152
153    /// Returns the sender for the server.
154    pub fn sender(&self) -> &ServerSender<P, T> {
155        ServerSender::wrap_untyped(self.server.sender())
156    }
157
158    /// Creates a new server from an untyped server.
159    pub fn from_untyped(server: protocol::Server<T>) -> Self {
160        Self { server, _protocol: PhantomData }
161    }
162
163    /// Runs the server with the provided handler.
164    pub async fn run<H>(&mut self, handler: H) -> Result<(), ProtocolError<T::Error>>
165    where
166        P: ServerProtocol<H, T>,
167        H: Send,
168    {
169        self.server.run(ServerAdapter { handler, _protocol: PhantomData::<P> }).await
170    }
171}
172
173/// A strongly typed `Responder`.
174#[must_use]
175pub struct Responder<M> {
176    responder: protocol::Responder,
177    _method: PhantomData<M>,
178}
179
180impl<M> Responder<M> {
181    /// Creates a new responder.
182    pub fn from_untyped(responder: protocol::Responder) -> Self {
183        Self { responder, _method: PhantomData }
184    }
185
186    /// Responds to the client.
187    pub fn respond<'s, P, T, R>(
188        self,
189        server: &'s ServerSender<P, T>,
190        response: R,
191    ) -> Result<SendFuture<'s, T>, EncodeError>
192    where
193        T: Transport,
194        M: Method<Protocol = P>,
195        R: Encode<T::SendBuffer, Encoded = M::Response>,
196    {
197        server.sender.send_response(self.responder, M::ORDINAL, response)
198    }
199}