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