titan_core/
request.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
use crate::Respondable;
use std::convert::Infallible;
use titan_http::{Parts, Request, Response};

/// Types that can be created from requests.
///
/// Extractors that implement `FromRequest` can consume the request body and can thus only be run
/// once for handlers.
///
/// If your extractor doesn't need to consume the request body then you should implement
/// [`FromRequestParts`] and not [`FromRequest`].
///
///
pub trait FromRequest: Sized {
  type Error: Respondable;
  fn from_request(req: Request) -> Result<Self, Self::Error>;
}

/// Types that can be created from request parts.
///
/// Extractors that implement `FromRequestParts` cannot consume the request body and can thus be
/// run in any order for handlers.
///
/// If your extractor needs to consume the request body then you should implement [`FromRequest`]
/// and not [`FromRequestParts`].
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,))
            }
        }

        // This impl must not be generic over M, otherwise it would conflict with the blanket
        // implementation of `FromRequest<S, Mut>` for `T: FromRequestParts<S>`.
        #[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()),
    ))
  }
}