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.
45//! FIDL protocol servers.
67use core::num::NonZeroU32;
89use fidl_next_codec::{Encode, EncodeError, EncoderExt as _};
1011use crate::{decode_header, encode_header, ProtocolError, SendFuture, Transport, TransportExt};
1213/// A responder for a two-way message.
14#[must_use]
15pub struct Responder {
16 txid: NonZeroU32,
17}
1819/// A sender for a server endpoint.
20pub struct ServerSender<T: Transport> {
21 sender: T::Sender,
22}
2324impl<T: Transport> ServerSender<T> {
25/// Closes the channel from the server end.
26pub fn close(&self) {
27 T::close(&self.sender);
28 }
2930/// Send an event.
31pub fn send_event<M>(
32&self,
33 ordinal: u64,
34 event: &mut M,
35 ) -> Result<SendFuture<'_, T>, EncodeError>
36where
37M: Encode<T::SendBuffer>,
38 {
39let mut buffer = T::acquire(&self.sender);
40 encode_header::<T>(&mut buffer, 0, ordinal)?;
41 buffer.encode_next(event)?;
42Ok(T::send(&self.sender, buffer))
43 }
4445/// Send a response to a two-way message.
46pub fn send_response<M>(
47&self,
48 responder: Responder,
49 ordinal: u64,
50 response: &mut M,
51 ) -> Result<SendFuture<'_, T>, EncodeError>
52where
53M: Encode<T::SendBuffer>,
54 {
55let mut buffer = T::acquire(&self.sender);
56 encode_header::<T>(&mut buffer, responder.txid.get(), ordinal)?;
57 buffer.encode_next(response)?;
58Ok(T::send(&self.sender, buffer))
59 }
60}
6162impl<T: Transport> Clone for ServerSender<T> {
63fn clone(&self) -> Self {
64Self { sender: self.sender.clone() }
65 }
66}
6768/// 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.
75fn on_one_way(&mut self, sender: &ServerSender<T>, ordinal: u64, buffer: T::RecvBuffer);
7677/// 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.
82fn on_two_way(
83&mut self,
84 sender: &ServerSender<T>,
85 ordinal: u64,
86 buffer: T::RecvBuffer,
87 responder: Responder,
88 );
89}
9091/// A server for an endpoint.
92pub struct Server<T: Transport> {
93 sender: ServerSender<T>,
94 receiver: T::Receiver,
95}
9697impl<T: Transport> Server<T> {
98/// Creates a new server from a transport.
99pub fn new(transport: T) -> Self {
100let (sender, receiver) = transport.split();
101Self { sender: ServerSender { sender }, receiver }
102 }
103104/// Returns the sender for the server.
105pub fn sender(&self) -> &ServerSender<T> {
106&self.sender
107 }
108109/// Runs the server with the provided handler.
110pub async fn run<H>(&mut self, mut handler: H) -> Result<(), ProtocolError<T::Error>>
111where
112H: ServerHandler<T>,
113 {
114while let Some(mut buffer) =
115 T::recv(&mut self.receiver).await.map_err(ProtocolError::TransportError)?
116{
117let (txid, ordinal) =
118 decode_header::<T>(&mut buffer).map_err(ProtocolError::InvalidMessageHeader)?;
119if 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 }
125126Ok(())
127 }
128}