fidl_next/protocol/
server.rsuse core::num::NonZeroU32;
use crate::protocol::{decode_header, encode_header, ProtocolError, Transport};
use crate::{Encode, EncodeError, EncoderExt as _};
#[must_use]
pub struct Responder {
txid: NonZeroU32,
}
pub struct ServerSender<T: Transport> {
sender: T::Sender,
}
impl<T: Transport> ServerSender<T> {
pub fn close(&self) {
T::close(&self.sender);
}
pub fn send_event<M>(
&self,
ordinal: u64,
event: &mut M,
) -> Result<T::SendFuture<'_>, EncodeError>
where
M: for<'a> Encode<T::Encoder<'a>>,
{
let mut buffer = T::acquire(&self.sender);
encode_header::<T>(&mut buffer, 0, ordinal)?;
T::encoder(&mut buffer).encode_next(event)?;
Ok(T::send(&self.sender, buffer))
}
pub fn send_response<M>(
&self,
responder: Responder,
ordinal: u64,
response: &mut M,
) -> Result<T::SendFuture<'_>, EncodeError>
where
M: for<'a> Encode<T::Encoder<'a>>,
{
let mut buffer = T::acquire(&self.sender);
encode_header::<T>(&mut buffer, responder.txid.get(), ordinal)?;
T::encoder(&mut buffer).encode_next(response)?;
Ok(T::send(&self.sender, buffer))
}
}
impl<T: Transport> Clone for ServerSender<T> {
fn clone(&self) -> Self {
Self { sender: self.sender.clone() }
}
}
pub trait ServerHandler<T: Transport> {
fn on_one_way(&mut self, sender: &ServerSender<T>, ordinal: u64, buffer: T::RecvBuffer);
fn on_two_way(
&mut self,
sender: &ServerSender<T>,
ordinal: u64,
buffer: T::RecvBuffer,
responder: Responder,
);
}
pub struct Server<T: Transport> {
sender: ServerSender<T>,
receiver: T::Receiver,
}
impl<T: Transport> Server<T> {
pub fn new(transport: T) -> Self {
let (sender, receiver) = transport.split();
Self { sender: ServerSender { sender }, receiver }
}
pub fn sender(&self) -> &ServerSender<T> {
&self.sender
}
pub async fn run<H>(&mut self, mut handler: H) -> Result<(), ProtocolError<T::Error>>
where
H: ServerHandler<T>,
{
while let Some(mut buffer) =
T::recv(&mut self.receiver).await.map_err(ProtocolError::TransportError)?
{
let (txid, ordinal) =
decode_header::<T>(&mut buffer).map_err(ProtocolError::InvalidMessageHeader)?;
if let Some(txid) = NonZeroU32::new(txid) {
handler.on_two_way(&self.sender, ordinal, buffer, Responder { txid });
} else {
handler.on_one_way(&self.sender, ordinal, buffer);
}
}
Ok(())
}
}