use crate::Respondable;
use std::convert::Infallible;
use titan_http::{
request::{Parts, Request},
response::Response,
};
pub trait FromRequest: Sized {
type Error: Respondable;
fn from_request(req: Request) -> Result<Self, Self::Error>;
}
pub trait FromRequestParts: Sized {
type Error: Respondable;
fn from_request_parts(req: &mut Parts) -> Result<Self, Self::Error>;
}
impl FromRequest for String {
type Error = ();
fn from_request(req: Request) -> Result<Self, Self::Error> {
let test = req.into_body();
Ok(String::from_utf8_lossy(&test).to_string())
}
}
impl FromRequest for Request {
type Error = Infallible;
fn from_request(req: Request) -> Result<Self, Self::Error> {
Ok(req)
}
}
impl FromRequest for () {
type Error = Infallible;
fn from_request(_: Request) -> Result<Self, Self::Error> {
Ok(())
}
}
impl FromRequestParts for () {
type Error = Infallible;
fn from_request_parts(_: &mut Parts) -> Result<Self, Self::Error> {
Ok(())
}
}
macro_rules! impl_from_request {
(
[$($ty:ident),*], $last:ident
) => {
#[allow(non_snake_case, unused_mut, unused_variables)]
impl<$($ty,)* $last> FromRequestParts for ($($ty,)* $last,)
where
$( $ty: FromRequestParts + Send, )*
$last: FromRequestParts + Send,
{
type Error = Response;
fn from_request_parts(parts: &mut Parts) -> Result<Self, Self::Error> {
$(
let $ty = $ty::from_request_parts(parts)
.map_err(|err| err.respond())?;
)*
let $last = $last::from_request_parts(parts)
.map_err(|err| err.respond())?;
Ok(($($ty,)* $last,))
}
}
#[allow(non_snake_case, unused_mut, unused_variables)]
impl<$($ty,)* $last> FromRequest for ($($ty,)* $last,)
where
$( $ty: FromRequestParts + Send, )*
$last: FromRequest + Send,
{
type Error = Response;
fn from_request(req: Request) -> Result<Self, Self::Error> {
let (mut parts, body) = req.into_parts();
$(
let $ty = $ty::from_request_parts(&mut parts).map_err(|err| err.respond())?;
)*
let req = Request::from_parts(parts, body);
let $last = $last::from_request(req).map_err(|err| err.respond())?;
Ok(($($ty,)* $last,))
}
}
};
}
all_the_tuples!(impl_from_request);