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