use core::marker::PhantomData;
use crate::protocol::{self, DispatcherError, Transport};
use crate::{Encode, EncodeError};
use super::{Method, ServerEnd};
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, ServerDispatcher<T, P>) {
let (server, dispatcher) = protocol::Server::new(server_end.into_untyped());
(Self::from_untyped(server), ServerDispatcher::from_untyped(dispatcher))
}
pub fn from_untyped(server: protocol::Server<T>) -> Self {
Self { server, _protocol: PhantomData }
}
pub fn untyped(&self) -> &protocol::Server<T> {
&self.server
}
}
impl<T: Transport, P> Clone for Server<T, P> {
fn clone(&self) -> Self {
Self { server: self.server.clone(), _protocol: PhantomData }
}
}
pub trait ServerProtocol<T: Transport, H> {
fn on_event(handler: &mut H, ordinal: u64, buffer: T::RecvBuffer);
fn on_transaction(
handler: &mut H,
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_event(&mut self, ordinal: u64, buffer: T::RecvBuffer) {
P::on_event(&mut self.handler, ordinal, buffer)
}
fn on_transaction(
&mut self,
ordinal: u64,
buffer: <T as Transport>::RecvBuffer,
responder: protocol::Responder,
) {
P::on_transaction(&mut self.handler, ordinal, buffer, responder)
}
}
pub struct ServerDispatcher<T: Transport, P> {
dispatcher: protocol::ServerDispatcher<T>,
_protocol: PhantomData<P>,
}
impl<T: Transport, P> ServerDispatcher<T, P> {
pub fn from_untyped(dispatcher: protocol::ServerDispatcher<T>) -> Self {
Self { dispatcher, _protocol: PhantomData }
}
pub async fn run<H>(&mut self, handler: H) -> Result<(), DispatcherError<T::Error>>
where
P: ServerProtocol<T, H>,
{
self.dispatcher.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 Server<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.untyped().send_response(self.responder, M::ORDINAL, response)
}
}