use core::marker::PhantomData;
use crate::protocol::{self, ProtocolError, Transport};
use crate::{Encode, EncodeError};
use super::{Method, ServerEnd};
pub struct ServerSender<T: Transport, P> {
sender: protocol::ServerSender<T>,
_protocol: PhantomData<P>,
}
impl<T: Transport, P> ServerSender<T, P> {
pub fn wrap_untyped(client: &protocol::ServerSender<T>) -> &Self {
unsafe { &*(client as *const protocol::ServerSender<T>).cast() }
}
pub fn as_untyped(&self) -> &protocol::ServerSender<T> {
&self.sender
}
pub fn close(&self) {
self.as_untyped().close();
}
}
impl<T: Transport, P> Clone for ServerSender<T, P> {
fn clone(&self) -> Self {
Self { sender: self.sender.clone(), _protocol: PhantomData }
}
}
pub trait ServerProtocol<T: Transport, H>: Sized {
fn on_one_way(
handler: &mut H,
server: &ServerSender<T, Self>,
ordinal: u64,
buffer: T::RecvBuffer,
);
fn on_two_way(
handler: &mut H,
server: &ServerSender<T, Self>,
ordinal: u64,
buffer: T::RecvBuffer,
responder: protocol::Responder,
);
}
pub struct ServerAdapter<P, H> {
handler: H,
_protocol: PhantomData<P>,
}
impl<P, H> ServerAdapter<P, H> {
pub fn from_untyped(handler: H) -> Self {
Self { handler, _protocol: PhantomData }
}
}
impl<T, P, H> protocol::ServerHandler<T> for ServerAdapter<P, H>
where
T: Transport,
P: ServerProtocol<T, H>,
{
fn on_one_way(
&mut self,
server: &protocol::ServerSender<T>,
ordinal: u64,
buffer: T::RecvBuffer,
) {
P::on_one_way(&mut self.handler, ServerSender::wrap_untyped(server), ordinal, buffer)
}
fn on_two_way(
&mut self,
server: &protocol::ServerSender<T>,
ordinal: u64,
buffer: <T as Transport>::RecvBuffer,
responder: protocol::Responder,
) {
P::on_two_way(
&mut self.handler,
ServerSender::wrap_untyped(server),
ordinal,
buffer,
responder,
)
}
}
pub struct Server<T: Transport, P> {
server: protocol::Server<T>,
_protocol: PhantomData<P>,
}
impl<T: Transport, P> Server<T, P> {
pub fn new(server_end: ServerEnd<T, P>) -> Self {
Self { server: protocol::Server::new(server_end.into_untyped()), _protocol: PhantomData }
}
pub fn sender(&self) -> &ServerSender<T, P> {
ServerSender::wrap_untyped(self.server.sender())
}
pub fn from_untyped(server: protocol::Server<T>) -> Self {
Self { server, _protocol: PhantomData }
}
pub async fn run<H>(&mut self, handler: H) -> Result<(), ProtocolError<T::Error>>
where
P: ServerProtocol<T, H>,
{
self.server.run(ServerAdapter { handler, _protocol: PhantomData::<P> }).await
}
}
#[must_use]
pub struct Responder<M> {
responder: protocol::Responder,
_method: PhantomData<M>,
}
impl<M> Responder<M> {
pub fn from_untyped(responder: protocol::Responder) -> Self {
Self { responder, _method: PhantomData }
}
pub fn respond<'s, T, P, R>(
self,
server: &'s ServerSender<T, P>,
response: &mut R,
) -> Result<T::SendFuture<'s>, EncodeError>
where
T: Transport,
M: Method<Protocol = P>,
for<'buf> R: Encode<T::Encoder<'buf>, Encoded<'buf> = M::Response<'buf>>,
{
server.as_untyped().send_response(self.responder, M::ORDINAL, response)
}
}