use crate::Respondable;
use std::convert::Infallible;
use titan_http::{Parts, Request, 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(req: Request) -> Result<Self, Self::Error> {
let _ = req;
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);
#[cfg(feature = "deploy-lambda")]
impl FromRequest for lambda_http::http::Request<lambda_http::Body> {
type Error = ();
fn from_request(req: Request) -> Result<Self, Self::Error> {
let (parts, body) = req.into_parts();
Ok(lambda_http::http::Request::from_parts(
parts,
lambda_http::Body::Binary(body.to_vec()),
))
}
}