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>(&self, ordinal: u64, event: M) -> Result<SendFuture<'_, T>, EncodeError>
32where
33M: Encode<T::SendBuffer>,
34 {
35let mut buffer = T::acquire(&self.sender);
36 encode_header::<T>(&mut buffer, 0, ordinal)?;
37 buffer.encode_next(event)?;
38Ok(T::send(&self.sender, buffer))
39 }
4041/// Send a response to a two-way message.
42pub fn send_response<M>(
43&self,
44 responder: Responder,
45 ordinal: u64,
46 response: M,
47 ) -> Result<SendFuture<'_, T>, EncodeError>
48where
49M: Encode<T::SendBuffer>,
50 {
51let mut buffer = T::acquire(&self.sender);
52 encode_header::<T>(&mut buffer, responder.txid.get(), ordinal)?;
53 buffer.encode_next(response)?;
54Ok(T::send(&self.sender, buffer))
55 }
56}
5758impl<T: Transport> Clone for ServerSender<T> {
59fn clone(&self) -> Self {
60Self { sender: self.sender.clone() }
61 }
62}
6364/// 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.
71fn on_one_way(&mut self, sender: &ServerSender<T>, ordinal: u64, buffer: T::RecvBuffer);
7273/// 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.
78fn on_two_way(
79&mut self,
80 sender: &ServerSender<T>,
81 ordinal: u64,
82 buffer: T::RecvBuffer,
83 responder: Responder,
84 );
85}
8687/// A server for an endpoint.
88pub struct Server<T: Transport> {
89 sender: ServerSender<T>,
90 receiver: T::Receiver,
91}
9293impl<T: Transport> Server<T> {
94/// Creates a new server from a transport.
95pub fn new(transport: T) -> Self {
96let (sender, receiver) = transport.split();
97Self { sender: ServerSender { sender }, receiver }
98 }
99100/// Returns the sender for the server.
101pub fn sender(&self) -> &ServerSender<T> {
102&self.sender
103 }
104105/// Runs the server with the provided handler.
106pub async fn run<H>(&mut self, mut handler: H) -> Result<(), ProtocolError<T::Error>>
107where
108H: ServerHandler<T>,
109 {
110while let Some(mut buffer) =
111 T::recv(&mut self.receiver).await.map_err(ProtocolError::TransportError)?
112{
113let (txid, ordinal) =
114 decode_header::<T>(&mut buffer).map_err(ProtocolError::InvalidMessageHeader)?;
115if 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 }
121122Ok(())
123 }
124}