fidl_next_protocol/
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
5//! FIDL protocol servers.
6
7use core::future::Future;
8use core::num::NonZeroU32;
9
10use fidl_next_codec::{Encode, EncodeError, EncoderExt as _};
11
12use crate::{decode_header, encode_header, ProtocolError, SendFuture, Transport, TransportExt};
13
14/// A responder for a two-way message.
15#[must_use]
16pub struct Responder {
17    txid: NonZeroU32,
18}
19
20/// A sender for a server endpoint.
21pub struct ServerSender<T: Transport> {
22    sender: T::Sender,
23}
24
25impl<T: Transport> ServerSender<T> {
26    /// Closes the channel from the server end.
27    pub fn close(&self) {
28        T::close(&self.sender);
29    }
30
31    /// Send an event.
32    pub fn send_event<M>(&self, ordinal: u64, event: M) -> Result<SendFuture<'_, T>, EncodeError>
33    where
34        M: Encode<T::SendBuffer>,
35    {
36        let mut buffer = T::acquire(&self.sender);
37        encode_header::<T>(&mut buffer, 0, ordinal)?;
38        buffer.encode_next(event)?;
39        Ok(T::send(&self.sender, buffer))
40    }
41
42    /// Send a response to a two-way message.
43    pub fn send_response<M>(
44        &self,
45        responder: Responder,
46        ordinal: u64,
47        response: M,
48    ) -> Result<SendFuture<'_, T>, EncodeError>
49    where
50        M: Encode<T::SendBuffer>,
51    {
52        let mut buffer = T::acquire(&self.sender);
53        encode_header::<T>(&mut buffer, responder.txid.get(), ordinal)?;
54        buffer.encode_next(response)?;
55        Ok(T::send(&self.sender, buffer))
56    }
57}
58
59impl<T: Transport> Clone for ServerSender<T> {
60    fn clone(&self) -> Self {
61        Self { sender: self.sender.clone() }
62    }
63}
64
65/// A type which handles incoming events for a server.
66///
67/// The futures returned by `on_one_way` and `on_two_way` are required to be `Send`. See
68/// `LocalServerHandler` for a version of this trait which does not require the returned futures to
69/// be `Send`.
70pub trait ServerHandler<T: Transport> {
71    /// Handles a received one-way server message.
72    ///
73    /// The server cannot handle more messages until `on_one_way` completes. If `on_one_way` may
74    /// block, perform asynchronous work, or take a long time to process a message, it should
75    /// offload work to an async task.
76    fn on_one_way(
77        &mut self,
78        sender: &ServerSender<T>,
79        ordinal: u64,
80        buffer: T::RecvBuffer,
81    ) -> impl Future<Output = ()> + Send;
82
83    /// Handles a received two-way server message.
84    ///
85    /// The server cannot handle more messages until `on_two_way` completes. If `on_two_way` may
86    /// block, perform asynchronous work, or take a long time to process a message, it should
87    /// offload work to an async task.
88    fn on_two_way(
89        &mut self,
90        sender: &ServerSender<T>,
91        ordinal: u64,
92        buffer: T::RecvBuffer,
93        responder: Responder,
94    ) -> impl Future<Output = ()> + Send;
95}
96
97/// A server for an endpoint.
98pub struct Server<T: Transport> {
99    sender: ServerSender<T>,
100    receiver: T::Receiver,
101}
102
103impl<T: Transport> Server<T> {
104    /// Creates a new server from a transport.
105    pub fn new(transport: T) -> Self {
106        let (sender, receiver) = transport.split();
107        Self { sender: ServerSender { sender }, receiver }
108    }
109
110    /// Returns the sender for the server.
111    pub fn sender(&self) -> &ServerSender<T> {
112        &self.sender
113    }
114
115    /// Runs the server with the provided handler.
116    pub async fn run<H>(&mut self, mut handler: H) -> Result<(), ProtocolError<T::Error>>
117    where
118        H: ServerHandler<T>,
119    {
120        while let Some(mut buffer) =
121            T::recv(&mut self.receiver).await.map_err(ProtocolError::TransportError)?
122        {
123            let (txid, ordinal) =
124                decode_header::<T>(&mut buffer).map_err(ProtocolError::InvalidMessageHeader)?;
125            if let Some(txid) = NonZeroU32::new(txid) {
126                handler.on_two_way(&self.sender, ordinal, buffer, Responder { txid }).await;
127            } else {
128                handler.on_one_way(&self.sender, ordinal, buffer).await;
129            }
130        }
131
132        Ok(())
133    }
134}