@@ -112,6 +112,11 @@ impl Into<hyper::Body> for Body {
112
112
}
113
113
}
114
114
115
+ // Small utility function to return a stamped error when we cannot parse a request body
116
+ fn mk_err < T > ( _: T ) -> Response {
117
+ StatusCode :: BAD_REQUEST . into_response ( )
118
+ }
119
+
115
120
/// A wrapper for json (de)serialization of bodies.
116
121
///
117
122
/// This type is usable both as an extractor (argument to an endpoint) and as a response
@@ -126,9 +131,6 @@ impl<T: Send + serde::de::DeserializeOwned + 'static, S: 'static> Extract<S> for
126
131
let mut body = std:: mem:: replace ( req. body_mut ( ) , Body :: empty ( ) ) ;
127
132
FutureObj :: new ( Box :: new (
128
133
async move {
129
- fn mk_err < T > ( _: T ) -> Response {
130
- StatusCode :: BAD_REQUEST . into_response ( )
131
- }
132
134
let body = await ! ( body. read_to_vec( ) ) . map_err ( mk_err) ?;
133
135
let json: T = serde_json:: from_slice ( & body) . map_err ( mk_err) ?;
134
136
Ok ( Json ( json) )
@@ -147,3 +149,56 @@ impl<T: 'static + Send + serde::Serialize> IntoResponse for Json<T> {
147
149
. unwrap ( )
148
150
}
149
151
}
152
+
153
+ pub struct Str ( pub String ) ;
154
+
155
+ impl < S : ' static > Extract < S > for Str {
156
+ type Fut = FutureObj < ' static , Result < Self , Response > > ;
157
+
158
+ fn extract ( data : & mut S , req : & mut Request , params : & RouteMatch < ' _ > ) -> Self :: Fut {
159
+ let mut body = std:: mem:: replace ( req. body_mut ( ) , Body :: empty ( ) ) ;
160
+
161
+ FutureObj :: new ( Box :: new (
162
+ async move {
163
+ let body = await ! ( body. read_to_vec( ) . map_err( mk_err) ) ?;
164
+ let string = String :: from_utf8 ( body) . map_err ( mk_err) ?;
165
+ Ok ( Str ( string) )
166
+ } ,
167
+ ) )
168
+ }
169
+ }
170
+
171
+ pub struct StrLossy ( pub String ) ;
172
+
173
+ impl < S : ' static > Extract < S > for StrLossy {
174
+ type Fut = FutureObj < ' static , Result < Self , Response > > ;
175
+
176
+ fn extract ( data : & mut S , req : & mut Request , params : & RouteMatch < ' _ > ) -> Self :: Fut {
177
+ let mut body = std:: mem:: replace ( req. body_mut ( ) , Body :: empty ( ) ) ;
178
+
179
+ FutureObj :: new ( Box :: new (
180
+ async move {
181
+ let body = await ! ( body. read_to_vec( ) . map_err( mk_err) ) ?;
182
+ let string = String :: from_utf8_lossy ( & body) . to_string ( ) ;
183
+ Ok ( StrLossy ( string) )
184
+ } ,
185
+ ) )
186
+ }
187
+ }
188
+
189
+ pub struct Bytes ( pub Vec < u8 > ) ;
190
+
191
+ impl < S : ' static > Extract < S > for Bytes {
192
+ type Fut = FutureObj < ' static , Result < Self , Response > > ;
193
+
194
+ fn extract ( data : & mut S , req : & mut Request , params : & RouteMatch < ' _ > ) -> Self :: Fut {
195
+ let mut body = std:: mem:: replace ( req. body_mut ( ) , Body :: empty ( ) ) ;
196
+
197
+ FutureObj :: new ( Box :: new (
198
+ async move {
199
+ let body = await ! ( body. read_to_vec( ) . map_err( mk_err) ) ?;
200
+ Ok ( Bytes ( body) )
201
+ } ,
202
+ ) )
203
+ }
204
+ }
0 commit comments