use crate::{
routes::HandlerArgs, types::Response, HandlerCtx, ResponsePayload, Route, RpcRecv, RpcSend,
};
use serde_json::value::RawValue;
use std::{convert::Infallible, future::Future, marker::PhantomData, pin::Pin, task};
macro_rules! convert_result {
($res:expr) => {{
match $res {
Ok(val) => ResponsePayload::Success(val),
Err(err) => ResponsePayload::internal_error_with_obj(err),
}
}};
}
#[cfg_attr(
feature = "pubsub",
doc = "see the [`Listener`] documetnation for more information."
)]
#[cfg_attr(feature = "pubsub", doc = " [`Listener`]: crate::pubsub::Listener")]
pub trait Handler<T, S>: Clone + Send + Sync + Sized + 'static {
type Future: Future<Output = Box<RawValue>> + Send + 'static;
fn call_with_state(self, args: HandlerArgs, state: S) -> Self::Future;
}
pub(crate) trait HandlerInternal<T, S>: Handler<T, S> {
fn with_state(self, state: S) -> HandlerService<Self, T, S> {
HandlerService::new(self, state)
}
#[allow(private_interfaces)]
fn into_route(self, state: S) -> Route
where
T: Send + 'static,
S: Clone + Send + Sync + 'static,
{
Route::new(self.with_state(state))
}
}
impl<T, S, H> HandlerInternal<T, S> for H where H: Handler<T, S> {}
#[derive(Debug)]
pub(crate) struct HandlerService<H, T, S> {
handler: H,
state: S,
_marker: std::marker::PhantomData<fn() -> T>,
}
impl<H, T, S> Clone for HandlerService<H, T, S>
where
H: Clone,
S: Clone,
{
fn clone(&self) -> Self {
Self {
handler: self.handler.clone(),
state: self.state.clone(),
_marker: PhantomData,
}
}
}
impl<H, T, S> HandlerService<H, T, S> {
pub(crate) const fn new(handler: H, state: S) -> Self {
Self {
handler,
state,
_marker: PhantomData,
}
}
}
impl<H, T, S> tower::Service<HandlerArgs> for HandlerService<H, T, S>
where
Self: Clone,
H: Handler<T, S>,
T: Send + 'static,
S: Clone + Send + Sync + 'static,
{
type Response = Box<RawValue>;
type Error = Infallible;
type Future = Pin<Box<dyn Future<Output = Result<Box<RawValue>, Infallible>> + Send>>;
fn poll_ready(&mut self, _cx: &mut task::Context<'_>) -> task::Poll<Result<(), Self::Error>> {
task::Poll::Ready(Ok(()))
}
fn call(&mut self, args: HandlerArgs) -> Self::Future {
let this = self.clone();
Box::pin(async move { Ok(this.handler.call_with_state(args, this.state.clone()).await) })
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct OutputResult {
_sealed: (),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct OutputResponsePayload {
_sealed: (),
}
impl<F, Fut, Payload, ErrData, S> Handler<(OutputResponsePayload,), S> for F
where
F: FnOnce() -> Fut + Clone + Send + Sync + 'static,
Fut: Future<Output = ResponsePayload<Payload, ErrData>> + Send + 'static,
Payload: RpcSend,
ErrData: RpcSend,
{
type Future = Pin<Box<dyn Future<Output = Box<RawValue>> + Send>>;
fn call_with_state(self, args: HandlerArgs, _state: S) -> Self::Future {
let id = args.req.id_owned();
Box::pin(async move {
let payload = self().await;
Response {
id,
payload: &payload,
}
.to_json()
})
}
}
impl<F, Fut, Payload, ErrData, S> Handler<(OutputResponsePayload, HandlerCtx), S> for F
where
F: FnOnce(HandlerCtx) -> Fut + Clone + Send + Sync + 'static,
Fut: Future<Output = ResponsePayload<Payload, ErrData>> + Send + 'static,
Payload: RpcSend,
ErrData: RpcSend,
{
type Future = Pin<Box<dyn Future<Output = Box<RawValue>> + Send>>;
fn call_with_state(self, args: HandlerArgs, _state: S) -> Self::Future {
let id = args.req.id_owned();
let ctx = args.ctx;
Box::pin(async move {
let payload = self(ctx).await;
Response {
id,
payload: &payload,
}
.to_json()
})
}
}
impl<F, Fut, Params, Payload, ErrData, S> Handler<(OutputResponsePayload, Params), S> for F
where
F: FnOnce(Params) -> Fut + Clone + Send + Sync + 'static,
Fut: Future<Output = ResponsePayload<Payload, ErrData>> + Send + 'static,
Params: RpcRecv,
Payload: RpcSend,
ErrData: RpcSend,
{
type Future = Pin<Box<dyn Future<Output = Box<RawValue>> + Send>>;
fn call_with_state(self, args: HandlerArgs, _state: S) -> Self::Future {
let HandlerArgs { req, .. } = args;
Box::pin(async move {
let id = req.id_owned();
let Ok(params) = req.deser_params() else {
return Response::invalid_params(id);
};
let payload = self(params).await;
Response {
id,
payload: &payload,
}
.to_json()
})
}
}
impl<F, Fut, Params, Payload, ErrData, S> Handler<(OutputResponsePayload, HandlerCtx, Params), S>
for F
where
F: FnOnce(HandlerCtx, Params) -> Fut + Clone + Send + Sync + 'static,
Fut: Future<Output = ResponsePayload<Payload, ErrData>> + Send + 'static,
Params: RpcRecv,
Payload: RpcSend,
ErrData: RpcSend,
{
type Future = Pin<Box<dyn Future<Output = Box<RawValue>> + Send>>;
fn call_with_state(self, args: HandlerArgs, _state: S) -> Self::Future {
Box::pin(async move {
let HandlerArgs { ctx, req } = args;
let id = req.id_owned();
let Ok(params) = req.deser_params() else {
return Response::invalid_params(id);
};
drop(req);
let payload = self(ctx, params).await;
Response {
id,
payload: &payload,
}
.to_json()
})
}
}
impl<F, Fut, Params, Payload, ErrData, S> Handler<(OutputResponsePayload, Params, S), S> for F
where
F: FnOnce(Params, S) -> Fut + Clone + Send + Sync + 'static,
Fut: Future<Output = ResponsePayload<Payload, ErrData>> + Send + 'static,
Params: RpcRecv,
Payload: RpcSend,
ErrData: RpcSend,
S: Send + Sync + 'static,
{
type Future = Pin<Box<dyn Future<Output = Box<RawValue>> + Send>>;
fn call_with_state(self, args: HandlerArgs, state: S) -> Self::Future {
Box::pin(async move {
let HandlerArgs { req, .. } = args;
let id = req.id_owned();
let Ok(params) = req.deser_params() else {
return Response::invalid_params(id);
};
drop(req);
Response {
id,
payload: &self(params, state).await,
}
.to_json()
})
}
}
impl<F, Fut, Payload, ErrData, S> Handler<(OutputResponsePayload, S, HandlerCtx), S> for F
where
F: FnOnce(HandlerCtx, S) -> Fut + Clone + Send + Sync + 'static,
Fut: Future<Output = ResponsePayload<Payload, ErrData>> + Send + 'static,
Payload: RpcSend,
ErrData: RpcSend,
S: Send + Sync + 'static,
{
type Future = Pin<Box<dyn Future<Output = Box<RawValue>> + Send>>;
fn call_with_state(self, args: HandlerArgs, state: S) -> Self::Future {
Box::pin(async move {
let HandlerArgs { ctx, req } = args;
let id = req.id_owned();
drop(req);
Response {
id,
payload: &self(ctx, state).await,
}
.to_json()
})
}
}
impl<F, Fut, Params, Payload, ErrData, S> Handler<(OutputResponsePayload, HandlerCtx, Params, S), S>
for F
where
F: FnOnce(HandlerCtx, Params, S) -> Fut + Clone + Send + Sync + 'static,
Fut: Future<Output = ResponsePayload<Payload, ErrData>> + Send + 'static,
Params: RpcRecv,
Payload: RpcSend,
ErrData: RpcSend,
S: Send + Sync + 'static,
{
type Future = Pin<Box<dyn Future<Output = Box<RawValue>> + Send>>;
fn call_with_state(self, args: HandlerArgs, state: S) -> Self::Future {
Box::pin(async move {
let HandlerArgs { ctx, req } = args;
let id = req.id_owned();
let Ok(params) = req.deser_params() else {
return Response::invalid_params(id);
};
drop(req);
Response {
id,
payload: &self(ctx, params, state).await,
}
.to_json()
})
}
}
impl<F, Fut, Payload, ErrData, S> Handler<(OutputResult,), S> for F
where
F: FnOnce() -> Fut + Clone + Send + Sync + 'static,
Fut: Future<Output = Result<Payload, ErrData>> + Send + 'static,
Payload: RpcSend,
ErrData: RpcSend,
{
type Future = Pin<Box<dyn Future<Output = Box<RawValue>> + Send>>;
fn call_with_state(self, args: HandlerArgs, _state: S) -> Self::Future {
let id = args.req.id_owned();
drop(args);
Box::pin(async move {
Response {
id,
payload: &convert_result!(self().await),
}
.to_json()
})
}
}
impl<F, Fut, Payload, ErrData, S> Handler<(OutputResult, HandlerCtx), S> for F
where
F: FnOnce(HandlerCtx) -> Fut + Clone + Send + Sync + 'static,
Fut: Future<Output = Result<Payload, ErrData>> + Send + 'static,
Payload: RpcSend,
ErrData: RpcSend,
{
type Future = Pin<Box<dyn Future<Output = Box<RawValue>> + Send>>;
fn call_with_state(self, args: HandlerArgs, _state: S) -> Self::Future {
let HandlerArgs { ctx, req } = args;
let id = req.id_owned();
drop(req);
Box::pin(async move {
Response {
id,
payload: &convert_result!(self(ctx).await),
}
.to_json()
})
}
}
impl<F, Fut, Params, Payload, ErrData, S> Handler<(OutputResult, Params), S> for F
where
F: FnOnce(Params) -> Fut + Clone + Send + Sync + 'static,
Fut: Future<Output = Result<Payload, ErrData>> + Send + 'static,
Params: RpcRecv,
Payload: RpcSend,
ErrData: RpcSend,
{
type Future = Pin<Box<dyn Future<Output = Box<RawValue>> + Send>>;
fn call_with_state(self, args: HandlerArgs, _state: S) -> Self::Future {
Box::pin(async move {
let HandlerArgs { req, .. } = args;
let id = req.id_owned();
let Ok(params) = req.deser_params() else {
return Response::invalid_params(id);
};
drop(req);
Response {
id,
payload: &convert_result!(self(params).await),
}
.to_json()
})
}
}
impl<F, Fut, Params, Payload, ErrData, S> Handler<(OutputResult, HandlerCtx, Params), S> for F
where
F: FnOnce(HandlerCtx, Params) -> Fut + Clone + Send + Sync + 'static,
Fut: Future<Output = Result<Payload, ErrData>> + Send + 'static,
Params: RpcRecv,
Payload: RpcSend,
ErrData: RpcSend,
{
type Future = Pin<Box<dyn Future<Output = Box<RawValue>> + Send>>;
fn call_with_state(self, args: HandlerArgs, _state: S) -> Self::Future {
Box::pin(async move {
let HandlerArgs { ctx, req } = args;
let id = req.id_owned();
let Ok(params) = req.deser_params() else {
return Response::invalid_params(id);
};
drop(req);
Response {
id,
payload: &convert_result!(self(ctx, params).await),
}
.to_json()
})
}
}
impl<F, Fut, Params, Payload, ErrData, S> Handler<(OutputResult, Params, S), S> for F
where
F: FnOnce(Params, S) -> Fut + Clone + Send + Sync + 'static,
Fut: Future<Output = Result<Payload, ErrData>> + Send + 'static,
Params: RpcRecv,
Payload: RpcSend,
ErrData: RpcSend,
S: Send + Sync + 'static,
{
type Future = Pin<Box<dyn Future<Output = Box<RawValue>> + Send>>;
fn call_with_state(self, args: HandlerArgs, state: S) -> Self::Future {
Box::pin(async move {
let HandlerArgs { req, .. } = args;
let id = req.id_owned();
let Ok(params) = req.deser_params() else {
return Response::invalid_params(id);
};
drop(req);
Response {
id,
payload: &convert_result!(self(params, state).await),
}
.to_json()
})
}
}
impl<F, Fut, Payload, ErrData, S> Handler<(OutputResult, S, HandlerCtx), S> for F
where
F: FnOnce(HandlerCtx, S) -> Fut + Clone + Send + Sync + 'static,
Fut: Future<Output = Result<Payload, ErrData>> + Send + 'static,
Payload: RpcSend,
ErrData: RpcSend,
S: Send + Sync + 'static,
{
type Future = Pin<Box<dyn Future<Output = Box<RawValue>> + Send>>;
fn call_with_state(self, args: HandlerArgs, state: S) -> Self::Future {
let HandlerArgs { ctx, req } = args;
let id = req.id_owned();
drop(req);
Box::pin(async move {
Response {
id,
payload: &convert_result!(self(ctx, state).await),
}
.to_json()
})
}
}
impl<F, Fut, Params, Payload, ErrData, S> Handler<(OutputResult, HandlerCtx, Params, S), S> for F
where
F: FnOnce(HandlerCtx, Params, S) -> Fut + Clone + Send + Sync + 'static,
Fut: Future<Output = Result<Payload, ErrData>> + Send + 'static,
Params: RpcRecv,
Payload: RpcSend,
ErrData: RpcSend,
S: Send + Sync + 'static,
{
type Future = Pin<Box<dyn Future<Output = Box<RawValue>> + Send>>;
fn call_with_state(self, args: HandlerArgs, state: S) -> Self::Future {
Box::pin(async move {
let HandlerArgs { ctx, req } = args;
let id = req.id_owned();
let Ok(params) = req.deser_params() else {
return Response::invalid_params(id);
};
drop(req);
Response {
id,
payload: &convert_result!(self(ctx, params, state).await),
}
.to_json()
})
}
}