use crate::{
io::Read,
request::{Path, Request, RequestParts},
ResponseSent,
};
use super::{MethodHandler, PathRouter, ResponseWriter};
mod sealed {
pub trait NextIsSealed {}
}
pub trait Next<'a, R: Read + 'a, State, PathParameters>: sealed::NextIsSealed + Sized {
async fn run<W: ResponseWriter<Error = R::Error>>(
self,
state: &State,
path_parameters: PathParameters,
response_writer: W,
) -> Result<ResponseSent, W::Error>;
fn into_request(self) -> Request<'a, R>;
async fn into_connection(
self,
) -> Result<crate::response::Connection<'a, impl Read<Error = R::Error>>, R::Error> {
self.into_request().body_connection.finalize().await
}
}
pub trait Layer<State, PathParameters> {
type NextState;
type NextPathParameters;
async fn call_layer<
'a,
R: Read + 'a,
NextLayer: Next<'a, R, Self::NextState, Self::NextPathParameters>,
W: ResponseWriter<Error = R::Error>,
>(
&self,
next: NextLayer,
state: &State,
path_parameters: PathParameters,
request_parts: RequestParts<'_>,
response_writer: W,
) -> Result<ResponseSent, W::Error>;
}
struct NextMethodRouterLayer<'a, R: Read, N> {
next: &'a N,
request: Request<'a, R>,
}
impl<R: Read, N> sealed::NextIsSealed for NextMethodRouterLayer<'_, R, N> {}
impl<'a, R: Read, State, PathParameters, N: MethodHandler<State, PathParameters>>
Next<'a, R, State, PathParameters> for NextMethodRouterLayer<'a, R, N>
{
async fn run<W: ResponseWriter<Error = R::Error>>(
self,
state: &State,
path_parameters: PathParameters,
response_writer: W,
) -> Result<ResponseSent, W::Error> {
self.next
.call_method_handler(state, path_parameters, self.request, response_writer)
.await
}
fn into_request(self) -> Request<'a, R> {
self.request
}
}
pub(crate) struct MethodRouterLayer<L, I> {
pub(crate) layer: L,
pub(crate) inner: I,
}
impl<L, I> super::sealed::MethodHandlerIsSealed for MethodRouterLayer<L, I> {}
impl<
L: Layer<State, PathParameters>,
I: MethodHandler<L::NextState, L::NextPathParameters>,
State,
PathParameters,
> MethodHandler<State, PathParameters> for MethodRouterLayer<L, I>
{
async fn call_method_handler<R: Read, W: ResponseWriter<Error = R::Error>>(
&self,
state: &State,
path_parameters: PathParameters,
request: Request<'_, R>,
response_writer: W,
) -> Result<ResponseSent, W::Error> {
let request_parts = request.parts;
self.layer
.call_layer(
NextMethodRouterLayer {
next: &self.inner,
request,
},
state,
path_parameters,
request_parts,
response_writer,
)
.await
}
}
struct NextPathRouterLayer<'a, R: Read, N> {
next: &'a N,
path: Path<'a>,
request: Request<'a, R>,
}
impl<R: Read, N> sealed::NextIsSealed for NextPathRouterLayer<'_, R, N> {}
impl<'a, R: Read, State, CurrentPathParameters, N: PathRouter<State, CurrentPathParameters>>
Next<'a, R, State, CurrentPathParameters> for NextPathRouterLayer<'a, R, N>
{
async fn run<W: ResponseWriter<Error = R::Error>>(
self,
state: &State,
current_path_parameters: CurrentPathParameters,
response_writer: W,
) -> Result<ResponseSent, W::Error> {
self.next
.call_path_router(
state,
current_path_parameters,
self.path,
self.request,
response_writer,
)
.await
}
fn into_request(self) -> Request<'a, R> {
self.request
}
}
pub(crate) struct PathRouterLayer<L, I> {
pub(crate) layer: L,
pub(crate) inner: I,
}
impl<L, I> super::sealed::PathRouterIsSealed for PathRouterLayer<L, I> {}
impl<
L: Layer<State, CurrentPathParameters>,
I: PathRouter<L::NextState, L::NextPathParameters>,
State,
CurrentPathParameters,
> PathRouter<State, CurrentPathParameters> for PathRouterLayer<L, I>
{
async fn call_path_router<R: Read, W: ResponseWriter<Error = R::Error>>(
&self,
state: &State,
current_path_parameters: CurrentPathParameters,
path: Path<'_>,
request: Request<'_, R>,
response_writer: W,
) -> Result<ResponseSent, W::Error> {
let request_parts = request.parts;
self.layer
.call_layer(
NextPathRouterLayer {
next: &self.inner,
path,
request,
},
state,
current_path_parameters,
request_parts,
response_writer,
)
.await
}
}