aws_smithy_http_server/request/
mod.rs1use std::{
49 convert::Infallible,
50 future::{ready, Future, Ready},
51};
52
53use futures_util::{
54 future::{try_join, MapErr, MapOk, TryJoin},
55 TryFutureExt,
56};
57use http::{request::Parts, Request, StatusCode};
58
59use crate::{
60 body::{empty, BoxBody},
61 rejection::any_rejections,
62 response::IntoResponse,
63};
64
65pub mod connect_info;
66pub mod extension;
67#[cfg(feature = "aws-lambda")]
68#[cfg_attr(docsrs, doc(cfg(feature = "aws-lambda")))]
69pub mod lambda;
70#[cfg(feature = "request-id")]
71#[cfg_attr(docsrs, doc(cfg(feature = "request-id")))]
72pub mod request_id;
73
74fn internal_server_error() -> http::Response<BoxBody> {
75 let mut response = http::Response::new(empty());
76 *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR;
77 response
78}
79
80pub trait FromParts<Protocol>: Sized {
83 type Rejection: IntoResponse<Protocol>;
85
86 fn from_parts(parts: &mut Parts) -> Result<Self, Self::Rejection>;
88}
89
90impl<P> FromParts<P> for () {
91 type Rejection = Infallible;
92
93 fn from_parts(_parts: &mut Parts) -> Result<Self, Self::Rejection> {
94 Ok(())
95 }
96}
97
98impl<P, T> FromParts<P> for (T,)
99where
100 T: FromParts<P>,
101{
102 type Rejection = T::Rejection;
103
104 fn from_parts(parts: &mut Parts) -> Result<Self, Self::Rejection> {
105 Ok((T::from_parts(parts)?,))
106 }
107}
108
109macro_rules! impl_from_parts {
110 ($error_name:ident, $($var:ident),+) => (
111 impl<P, $($var,)*> FromParts<P> for ($($var),*)
112 where
113 $($var: FromParts<P>,)*
114 {
115 type Rejection = any_rejections::$error_name<$($var::Rejection),*>;
116
117 fn from_parts(parts: &mut Parts) -> Result<Self, Self::Rejection> {
118 let tuple = (
119 $($var::from_parts(parts).map_err(any_rejections::$error_name::$var)?,)*
120 );
121 Ok(tuple)
122 }
123 }
124 )
125}
126
127impl_from_parts!(Two, A, B);
128impl_from_parts!(Three, A, B, C);
129impl_from_parts!(Four, A, B, C, D);
130impl_from_parts!(Five, A, B, C, D, E);
131impl_from_parts!(Six, A, B, C, D, E, F);
132impl_from_parts!(Seven, A, B, C, D, E, F, G);
133impl_from_parts!(Eight, A, B, C, D, E, F, G, H);
134
135pub trait FromRequest<Protocol, B>: Sized {
141 type Rejection: IntoResponse<Protocol>;
143 type Future: Future<Output = Result<Self, Self::Rejection>>;
145
146 fn from_request(request: Request<B>) -> Self::Future;
148}
149
150impl<P, B, T1> FromRequest<P, B> for (T1,)
151where
152 T1: FromRequest<P, B>,
153{
154 type Rejection = T1::Rejection;
155 type Future = MapOk<T1::Future, fn(T1) -> (T1,)>;
156
157 fn from_request(request: Request<B>) -> Self::Future {
158 T1::from_request(request).map_ok(|t1| (t1,))
159 }
160}
161
162impl<P, B, T1, T2> FromRequest<P, B> for (T1, T2)
163where
164 T1: FromRequest<P, B>,
165 T2: FromParts<P>,
166 T1::Rejection: std::fmt::Display,
167 T2::Rejection: std::fmt::Display,
168{
169 type Rejection = any_rejections::Two<T1::Rejection, T2::Rejection>;
170 type Future = TryJoin<MapErr<T1::Future, fn(T1::Rejection) -> Self::Rejection>, Ready<Result<T2, Self::Rejection>>>;
171
172 fn from_request(request: Request<B>) -> Self::Future {
173 let (mut parts, body) = request.into_parts();
174 let t2_result: Result<T2, any_rejections::Two<T1::Rejection, T2::Rejection>> = T2::from_parts(&mut parts)
175 .map_err(|e| {
176 tracing::error!(
182 error = %e,
183 "additional parameter for the handler function could not be constructed");
184 any_rejections::Two::B(e)
185 });
186 try_join(
187 T1::from_request(Request::from_parts(parts, body)).map_err(|e| {
188 tracing::debug!(error = %e, "failed to deserialize request into operation's input");
192 any_rejections::Two::A(e)
193 }),
194 ready(t2_result),
195 )
196 }
197}
198
199impl<P, T> FromParts<P> for Option<T>
200where
201 T: FromParts<P>,
202{
203 type Rejection = Infallible;
204
205 fn from_parts(parts: &mut Parts) -> Result<Self, Self::Rejection> {
206 Ok(T::from_parts(parts).ok())
207 }
208}
209
210impl<P, T> FromParts<P> for Result<T, T::Rejection>
211where
212 T: FromParts<P>,
213{
214 type Rejection = Infallible;
215
216 fn from_parts(parts: &mut Parts) -> Result<Self, Self::Rejection> {
217 Ok(T::from_parts(parts))
218 }
219}