1 1 | // Code generated by software.amazon.smithy.rust.codegen.smithy-rs. DO NOT EDIT.
|
2 + | const CONTENT_TYPE_OPERATIONWITHNESTEDSTRUCTURE: ::mime::Mime = ::mime::APPLICATION_JSON;
|
3 + | ::pin_project_lite::pin_project! {
|
4 + | /// A [`Future`](std::future::Future) aggregating the body bytes of a [`Request`] and constructing the
|
5 + | /// [`OperationWithNestedStructureInput`](crate::input::OperationWithNestedStructureInput) using modelled bindings.
|
6 + | pub struct OperationWithNestedStructureInputFuture {
|
7 + | inner: std::pin::Pin<Box<dyn std::future::Future<Output = Result<crate::input::OperationWithNestedStructureInput, ::aws_smithy_http_server::protocol::rest_json_1::runtime_error::RuntimeError>> + Send>>
|
8 + | }
|
9 + | }
|
10 + |
|
11 + | impl std::future::Future for OperationWithNestedStructureInputFuture {
|
12 + | type Output = Result<
|
13 + | crate::input::OperationWithNestedStructureInput,
|
14 + | ::aws_smithy_http_server::protocol::rest_json_1::runtime_error::RuntimeError,
|
15 + | >;
|
16 + |
|
17 + | fn poll(
|
18 + | self: std::pin::Pin<&mut Self>,
|
19 + | cx: &mut std::task::Context<'_>,
|
20 + | ) -> std::task::Poll<Self::Output> {
|
21 + | let this = self.project();
|
22 + | this.inner.as_mut().poll(cx)
|
23 + | }
|
24 + | }
|
25 + |
|
26 + | impl<B>
|
27 + | ::aws_smithy_http_server::request::FromRequest<
|
28 + | ::aws_smithy_http_server::protocol::rest_json_1::RestJson1,
|
29 + | B,
|
30 + | > for crate::input::OperationWithNestedStructureInput
|
31 + | where
|
32 + | B: ::aws_smithy_http_server::body::HttpBody + Send,
|
33 + | B: 'static,
|
34 + |
|
35 + | B::Data: Send,
|
36 + | ::aws_smithy_http_server::protocol::rest_json_1::rejection::RequestRejection:
|
37 + | From<<B as ::aws_smithy_http_server::body::HttpBody>::Error>,
|
38 + | {
|
39 + | type Rejection = ::aws_smithy_http_server::protocol::rest_json_1::runtime_error::RuntimeError;
|
40 + | type Future = OperationWithNestedStructureInputFuture;
|
41 + |
|
42 + | fn from_request(request: ::http::Request<B>) -> Self::Future {
|
43 + | let fut = async move {
|
44 + | if !::aws_smithy_http_server::protocol::accept_header_classifier(
|
45 + | request.headers(),
|
46 + | &CONTENT_TYPE_OPERATIONWITHNESTEDSTRUCTURE,
|
47 + | ) {
|
48 + | return Err(::aws_smithy_http_server::protocol::rest_json_1::rejection::RequestRejection::NotAcceptable);
|
49 + | }
|
50 + | crate::protocol_serde::shape_operation_with_nested_structure::de_operation_with_nested_structure_http_request(request)
|
51 + | .await
|
52 + | .map_err(Into::into)
|
53 + | };
|
54 + | use ::futures_util::future::TryFutureExt;
|
55 + | let fut = fut.map_err(
|
56 + | |e: ::aws_smithy_http_server::protocol::rest_json_1::rejection::RequestRejection| {
|
57 + | ::tracing::debug!(error = %e, "failed to deserialize request");
|
58 + | ::aws_smithy_http_server::protocol::rest_json_1::runtime_error::RuntimeError::from(
|
59 + | e,
|
60 + | )
|
61 + | },
|
62 + | );
|
63 + | OperationWithNestedStructureInputFuture {
|
64 + | inner: Box::pin(fut),
|
65 + | }
|
66 + | }
|
67 + | }
|
68 + | impl
|
69 + | ::aws_smithy_http_server::response::IntoResponse<
|
70 + | ::aws_smithy_http_server::protocol::rest_json_1::RestJson1,
|
71 + | > for crate::output::OperationWithNestedStructureOutput
|
72 + | {
|
73 + | fn into_response(self) -> ::aws_smithy_http_server::response::Response {
|
74 + | match crate::protocol_serde::shape_operation_with_nested_structure::ser_operation_with_nested_structure_http_response(self) {
|
75 + | Ok(response) => response,
|
76 + | Err(e) => {
|
77 + | ::tracing::error!(error = %e, "failed to serialize response");
|
78 + | ::aws_smithy_http_server::response::IntoResponse::<::aws_smithy_http_server::protocol::rest_json_1::RestJson1>::into_response(::aws_smithy_http_server::protocol::rest_json_1::runtime_error::RuntimeError::from(e))
|
79 + | }
|
80 + | }
|
81 + | }
|
82 + | }
|
83 + | impl
|
84 + | ::aws_smithy_http_server::response::IntoResponse<
|
85 + | ::aws_smithy_http_server::protocol::rest_json_1::RestJson1,
|
86 + | > for crate::error::OperationWithNestedStructureError
|
87 + | {
|
88 + | fn into_response(self) -> ::aws_smithy_http_server::response::Response {
|
89 + | match crate::protocol_serde::shape_operation_with_nested_structure::ser_operation_with_nested_structure_http_error(&self) {
|
90 + | Ok(mut response) => {
|
91 + | response.extensions_mut().insert(::aws_smithy_http_server::extension::ModeledErrorExtension::new(self.name()));
|
92 + | response
|
93 + | },
|
94 + | Err(e) => {
|
95 + | ::tracing::error!(error = %e, "failed to serialize response");
|
96 + | ::aws_smithy_http_server::response::IntoResponse::<::aws_smithy_http_server::protocol::rest_json_1::RestJson1>::into_response(::aws_smithy_http_server::protocol::rest_json_1::runtime_error::RuntimeError::from(e))
|
97 + | }
|
98 + | }
|
99 + | }
|
100 + | }
|
101 + |
|
102 + | #[allow(unreachable_code, unused_variables)]
|
103 + | #[cfg(test)]
|
104 + | mod operation_with_nested_structure_test {
|
105 + |
|
106 + | /// Server populates nested default values when missing in request body.
|
107 + | /// Test ID: RestJsonServerPopulatesNestedDefaultsWhenMissingInRequestBody
|
108 + | #[::tokio::test]
|
109 + | #[::tracing_test::traced_test]
|
110 + | async fn rest_json_server_populates_nested_defaults_when_missing_in_request_body_request() {
|
111 + | #[allow(unused_mut)]
|
112 + | let mut http_request = http::Request::builder()
|
113 + | .uri("/OperationWithNestedStructure")
|
114 + | .method("POST")
|
115 + | .header("Content-Type", "application/json")
|
116 + | .body(::aws_smithy_http_server::body::Body::from(::bytes::Bytes::from_static("{\n \"topLevel\": {\n \"dialog\": {\n \"language\": \"en\"\n },\n \"dialogList\": [\n {\n },\n {\n \"farewell\": {}\n },\n {\n \"language\": \"it\",\n \"greeting\": \"ciao\",\n \"farewell\": {\n \"phrase\": \"arrivederci\"\n }\n }\n ],\n \"dialogMap\": {\n \"emptyDialog\": {\n },\n \"partialEmptyDialog\": {\n \"language\": \"en\",\n \"farewell\": {}\n },\n \"nonEmptyDialog\": {\n \"greeting\": \"konnichiwa\",\n \"farewell\": {\n \"phrase\": \"sayonara\"\n }\n }\n }\n }\n}".as_bytes()))).unwrap();
|
117 + | #[allow(unused_mut)]
|
118 + | let (sender, mut receiver) = ::tokio::sync::mpsc::channel(1);
|
119 + | let config = crate::service::RestJsonConfig::builder().build();
|
120 + | let service = crate::service::RestJson::builder::<::hyper::body::Body, _, _, _>(config)
|
121 + | .operation_with_nested_structure(
|
122 + | move |input: crate::input::OperationWithNestedStructureInput| {
|
123 + | let sender = sender.clone();
|
124 + | async move {
|
125 + | let result = {
|
126 + | let expected = crate::input::OperationWithNestedStructureInput {
|
127 + | top_level: crate::model::TopLevel {
|
128 + | dialog: crate::model::Dialog {
|
129 + | language: ::std::option::Option::Some("en".to_owned()),
|
130 + | greeting: "hi".to_owned(),
|
131 + | farewell: ::std::option::Option::None,
|
132 + | },
|
133 + | dialog_list: vec![
|
134 + | crate::model::Dialog {
|
135 + | greeting: "hi".to_owned(),
|
136 + | language: ::std::option::Option::None,
|
137 + | farewell: ::std::option::Option::None,
|
138 + | },
|
139 + | crate::model::Dialog {
|
140 + | greeting: "hi".to_owned(),
|
141 + | farewell: ::std::option::Option::Some(
|
142 + | crate::model::Farewell {
|
143 + | phrase: "bye".to_owned(),
|
144 + | },
|
145 + | ),
|
146 + | language: ::std::option::Option::None,
|
147 + | },
|
148 + | crate::model::Dialog {
|
149 + | language: ::std::option::Option::Some("it".to_owned()),
|
150 + | greeting: "ciao".to_owned(),
|
151 + | farewell: ::std::option::Option::Some(
|
152 + | crate::model::Farewell {
|
153 + | phrase: "arrivederci".to_owned(),
|
154 + | },
|
155 + | ),
|
156 + | },
|
157 + | ],
|
158 + | dialog_map: {
|
159 + | let mut ret = ::std::collections::HashMap::new();
|
160 + | ret.insert(
|
161 + | "emptyDialog".to_owned(),
|
162 + | crate::model::Dialog {
|
163 + | greeting: "hi".to_owned(),
|
164 + | language: ::std::option::Option::None,
|
165 + | farewell: ::std::option::Option::None,
|
166 + | },
|
167 + | );
|
168 + | ret.insert(
|
169 + | "partialEmptyDialog".to_owned(),
|
170 + | crate::model::Dialog {
|
171 + | language: ::std::option::Option::Some(
|
172 + | "en".to_owned(),
|
173 + | ),
|
174 + | greeting: "hi".to_owned(),
|
175 + | farewell: ::std::option::Option::Some(
|
176 + | crate::model::Farewell {
|
177 + | phrase: "bye".to_owned(),
|
178 + | },
|
179 + | ),
|
180 + | },
|
181 + | );
|
182 + | ret.insert(
|
183 + | "nonEmptyDialog".to_owned(),
|
184 + | crate::model::Dialog {
|
185 + | greeting: "konnichiwa".to_owned(),
|
186 + | farewell: ::std::option::Option::Some(
|
187 + | crate::model::Farewell {
|
188 + | phrase: "sayonara".to_owned(),
|
189 + | },
|
190 + | ),
|
191 + | language: ::std::option::Option::None,
|
192 + | },
|
193 + | );
|
194 + | ret
|
195 + | },
|
196 + | },
|
197 + | };
|
198 + | ::pretty_assertions::assert_eq!(input, expected);
|
199 + | let response = crate::output::OperationWithNestedStructureOutput {
|
200 + | dialog: crate::model::Dialog {
|
201 + | greeting: "".to_owned(),
|
202 + | language: ::std::option::Option::None,
|
203 + | farewell: ::std::option::Option::None,
|
204 + | },
|
205 + | dialog_list: vec![],
|
206 + | dialog_map: ::std::collections::HashMap::new(),
|
207 + | };
|
208 + | Ok(response)
|
209 + | };
|
210 + | sender.send(()).await.expect("receiver dropped early");
|
211 + | result
|
212 + | }
|
213 + | },
|
214 + | )
|
215 + | .build_unchecked();
|
216 + | let http_response = ::tower::ServiceExt::oneshot(service, http_request)
|
217 + | .await
|
218 + | .expect("unable to make an HTTP request");
|
219 + | assert!(
|
220 + | receiver.recv().await.is_some(),
|
221 + | "we expected operation handler to be invoked but it was not entered"
|
222 + | );
|
223 + | }
|
224 + | /// Server populates nested default values when missing in response params.
|
225 + | /// Test ID: RestJsonServerPopulatesNestedDefaultValuesWhenMissingInInResponseParams
|
226 + | #[::tokio::test]
|
227 + | #[::tracing_test::traced_test]
|
228 + | async fn rest_json_server_populates_nested_default_values_when_missing_in_in_response_params_response(
|
229 + | ) {
|
230 + | let output = crate::output::OperationWithNestedStructureOutput {
|
231 + | dialog: crate::model::Dialog {
|
232 + | greeting: "".to_owned(),
|
233 + | language: ::std::option::Option::Some("en".to_owned()),
|
234 + | farewell: ::std::option::Option::None,
|
235 + | },
|
236 + | dialog_list: vec![
|
237 + | crate::model::Dialog {
|
238 + | greeting: "".to_owned(),
|
239 + | language: ::std::option::Option::None,
|
240 + | farewell: ::std::option::Option::None,
|
241 + | },
|
242 + | crate::model::Dialog {
|
243 + | greeting: "".to_owned(),
|
244 + | farewell: ::std::option::Option::Some(crate::model::Farewell {
|
245 + | phrase: "".to_owned(),
|
246 + | }),
|
247 + | language: ::std::option::Option::None,
|
248 + | },
|
249 + | crate::model::Dialog {
|
250 + | language: ::std::option::Option::Some("it".to_owned()),
|
251 + | greeting: "ciao".to_owned(),
|
252 + | farewell: ::std::option::Option::Some(crate::model::Farewell {
|
253 + | phrase: "arrivederci".to_owned(),
|
254 + | }),
|
255 + | },
|
256 + | ],
|
257 + | dialog_map: {
|
258 + | let mut ret = ::std::collections::HashMap::new();
|
259 + | ret.insert(
|
260 + | "emptyDialog".to_owned(),
|
261 + | crate::model::Dialog {
|
262 + | greeting: "".to_owned(),
|
263 + | language: ::std::option::Option::None,
|
264 + | farewell: ::std::option::Option::None,
|
265 + | },
|
266 + | );
|
267 + | ret.insert(
|
268 + | "partialEmptyDialog".to_owned(),
|
269 + | crate::model::Dialog {
|
270 + | greeting: "".to_owned(),
|
271 + | language: ::std::option::Option::Some("en".to_owned()),
|
272 + | farewell: ::std::option::Option::Some(crate::model::Farewell {
|
273 + | phrase: "".to_owned(),
|
274 + | }),
|
275 + | },
|
276 + | );
|
277 + | ret.insert(
|
278 + | "nonEmptyDialog".to_owned(),
|
279 + | crate::model::Dialog {
|
280 + | greeting: "konnichiwa".to_owned(),
|
281 + | farewell: ::std::option::Option::Some(crate::model::Farewell {
|
282 + | phrase: "sayonara".to_owned(),
|
283 + | }),
|
284 + | language: ::std::option::Option::None,
|
285 + | },
|
286 + | );
|
287 + | ret
|
288 + | },
|
289 + | };
|
290 + | use ::aws_smithy_http_server::response::IntoResponse;
|
291 + | let http_response = output.into_response();
|
292 + | ::pretty_assertions::assert_eq!(
|
293 + | http::StatusCode::from_u16(200).expect("invalid expected HTTP status code"),
|
294 + | http_response.status()
|
295 + | );
|
296 + | let expected_headers = [("Content-Type", "application/json")];
|
297 + | ::aws_smithy_protocol_test::assert_ok(::aws_smithy_protocol_test::validate_headers(
|
298 + | http_response.headers(),
|
299 + | expected_headers,
|
300 + | ));
|
301 + | let body = ::hyper::body::to_bytes(http_response.into_body())
|
302 + | .await
|
303 + | .expect("unable to extract body to bytes");
|
304 + | ::aws_smithy_protocol_test::assert_ok(
|
305 + | ::aws_smithy_protocol_test::validate_body(&body, "{\n \"dialog\": {\n \"language\": \"en\",\n \"greeting\": \"hi\"\n },\n \"dialogList\": [\n {\n \"greeting\": \"hi\"\n },\n {\n \"greeting\": \"hi\",\n \"farewell\": {\n \"phrase\": \"bye\"\n }\n },\n {\n \"language\": \"it\",\n \"greeting\": \"ciao\",\n \"farewell\": {\n \"phrase\": \"arrivederci\"\n }\n }\n ],\n \"dialogMap\": {\n \"emptyDialog\": {\n \"greeting\": \"hi\"\n },\n \"partialEmptyDialog\": {\n \"language\": \"en\",\n \"greeting\": \"hi\",\n \"farewell\": {\n \"phrase\": \"bye\"\n }\n },\n \"nonEmptyDialog\": {\n \"greeting\": \"konnichiwa\",\n \"farewell\": {\n \"phrase\": \"sayonara\"\n }\n }\n }\n}", ::aws_smithy_protocol_test::MediaType::from("application/json"))
|
306 + | );
|
307 + | }
|
308 + | }
|
309 + |
|
310 + | const CONTENT_TYPE_OPERATIONWITHDEFAULTS: ::mime::Mime = ::mime::APPLICATION_JSON;
|
311 + | ::pin_project_lite::pin_project! {
|
312 + | /// A [`Future`](std::future::Future) aggregating the body bytes of a [`Request`] and constructing the
|
313 + | /// [`OperationWithDefaultsInput`](crate::input::OperationWithDefaultsInput) using modelled bindings.
|
314 + | pub struct OperationWithDefaultsInputFuture {
|
315 + | inner: std::pin::Pin<Box<dyn std::future::Future<Output = Result<crate::input::OperationWithDefaultsInput, ::aws_smithy_http_server::protocol::rest_json_1::runtime_error::RuntimeError>> + Send>>
|
316 + | }
|
317 + | }
|
318 + |
|
319 + | impl std::future::Future for OperationWithDefaultsInputFuture {
|
320 + | type Output = Result<
|
321 + | crate::input::OperationWithDefaultsInput,
|
322 + | ::aws_smithy_http_server::protocol::rest_json_1::runtime_error::RuntimeError,
|
323 + | >;
|
324 + |
|
325 + | fn poll(
|
326 + | self: std::pin::Pin<&mut Self>,
|
327 + | cx: &mut std::task::Context<'_>,
|
328 + | ) -> std::task::Poll<Self::Output> {
|
329 + | let this = self.project();
|
330 + | this.inner.as_mut().poll(cx)
|
331 + | }
|
332 + | }
|
333 + |
|
334 + | impl<B>
|
335 + | ::aws_smithy_http_server::request::FromRequest<
|
336 + | ::aws_smithy_http_server::protocol::rest_json_1::RestJson1,
|
337 + | B,
|
338 + | > for crate::input::OperationWithDefaultsInput
|
339 + | where
|
340 + | B: ::aws_smithy_http_server::body::HttpBody + Send,
|
341 + | B: 'static,
|
342 + |
|
343 + | B::Data: Send,
|
344 + | ::aws_smithy_http_server::protocol::rest_json_1::rejection::RequestRejection:
|
345 + | From<<B as ::aws_smithy_http_server::body::HttpBody>::Error>,
|
346 + | {
|
347 + | type Rejection = ::aws_smithy_http_server::protocol::rest_json_1::runtime_error::RuntimeError;
|
348 + | type Future = OperationWithDefaultsInputFuture;
|
349 + |
|
350 + | fn from_request(request: ::http::Request<B>) -> Self::Future {
|
351 + | let fut = async move {
|
352 + | if !::aws_smithy_http_server::protocol::accept_header_classifier(
|
353 + | request.headers(),
|
354 + | &CONTENT_TYPE_OPERATIONWITHDEFAULTS,
|
355 + | ) {
|
356 + | return Err(::aws_smithy_http_server::protocol::rest_json_1::rejection::RequestRejection::NotAcceptable);
|
357 + | }
|
358 + | crate::protocol_serde::shape_operation_with_defaults::de_operation_with_defaults_http_request(request)
|
359 + | .await
|
360 + | .map_err(Into::into)
|
361 + | };
|
362 + | use ::futures_util::future::TryFutureExt;
|
363 + | let fut = fut.map_err(
|
364 + | |e: ::aws_smithy_http_server::protocol::rest_json_1::rejection::RequestRejection| {
|
365 + | ::tracing::debug!(error = %e, "failed to deserialize request");
|
366 + | ::aws_smithy_http_server::protocol::rest_json_1::runtime_error::RuntimeError::from(
|
367 + | e,
|
368 + | )
|
369 + | },
|
370 + | );
|
371 + | OperationWithDefaultsInputFuture {
|
372 + | inner: Box::pin(fut),
|
373 + | }
|
374 + | }
|
375 + | }
|
376 + | impl
|
377 + | ::aws_smithy_http_server::response::IntoResponse<
|
378 + | ::aws_smithy_http_server::protocol::rest_json_1::RestJson1,
|
379 + | > for crate::output::OperationWithDefaultsOutput
|
380 + | {
|
381 + | fn into_response(self) -> ::aws_smithy_http_server::response::Response {
|
382 + | match crate::protocol_serde::shape_operation_with_defaults::ser_operation_with_defaults_http_response(self) {
|
383 + | Ok(response) => response,
|
384 + | Err(e) => {
|
385 + | ::tracing::error!(error = %e, "failed to serialize response");
|
386 + | ::aws_smithy_http_server::response::IntoResponse::<::aws_smithy_http_server::protocol::rest_json_1::RestJson1>::into_response(::aws_smithy_http_server::protocol::rest_json_1::runtime_error::RuntimeError::from(e))
|
387 + | }
|
388 + | }
|
389 + | }
|
390 + | }
|
391 + | impl
|
392 + | ::aws_smithy_http_server::response::IntoResponse<
|
393 + | ::aws_smithy_http_server::protocol::rest_json_1::RestJson1,
|
394 + | > for crate::error::OperationWithDefaultsError
|
395 + | {
|
396 + | fn into_response(self) -> ::aws_smithy_http_server::response::Response {
|
397 + | match crate::protocol_serde::shape_operation_with_defaults::ser_operation_with_defaults_http_error(&self) {
|
398 + | Ok(mut response) => {
|
399 + | response.extensions_mut().insert(::aws_smithy_http_server::extension::ModeledErrorExtension::new(self.name()));
|
400 + | response
|
401 + | },
|
402 + | Err(e) => {
|
403 + | ::tracing::error!(error = %e, "failed to serialize response");
|
404 + | ::aws_smithy_http_server::response::IntoResponse::<::aws_smithy_http_server::protocol::rest_json_1::RestJson1>::into_response(::aws_smithy_http_server::protocol::rest_json_1::runtime_error::RuntimeError::from(e))
|
405 + | }
|
406 + | }
|
407 + | }
|
408 + | }
|
409 + |
|
410 + | #[allow(unreachable_code, unused_variables)]
|
411 + | #[cfg(test)]
|
412 + | mod operation_with_defaults_test {
|
413 + |
|
414 + | /// Server populates default values when missing in request body.
|
415 + | /// Test ID: RestJsonServerPopulatesDefaultsWhenMissingInRequestBody
|
416 + | #[::tokio::test]
|
417 + | #[::tracing_test::traced_test]
|
418 + | async fn rest_json_server_populates_defaults_when_missing_in_request_body_request() {
|
419 + | #[allow(unused_mut)]
|
420 + | let mut http_request = http::Request::builder()
|
421 + | .uri("/OperationWithDefaults")
|
422 + | .method("POST")
|
423 + | .header("Content-Type", "application/json")
|
424 + | .body(::aws_smithy_http_server::body::Body::from(
|
425 + | ::bytes::Bytes::from_static("{\n\"defaults\": {}\n}".as_bytes()),
|
426 + | ))
|
427 + | .unwrap();
|
428 + | #[allow(unused_mut)]
|
429 + | let (sender, mut receiver) = ::tokio::sync::mpsc::channel(1);
|
430 + | let config = crate::service::RestJsonConfig::builder().build();
|
431 + | let service = crate::service::RestJson::builder::<::hyper::body::Body, _, _, _>(config)
|
432 + | .operation_with_defaults(move |input: crate::input::OperationWithDefaultsInput| {
|
433 + | let sender = sender.clone();
|
434 + | async move {
|
435 + | let result = {
|
436 + | let expected = crate::input::OperationWithDefaultsInput {
|
437 + | defaults: ::std::option::Option::Some(crate::model::Defaults {
|
438 + | default_string: "hi".to_owned(),
|
439 + | default_boolean: true,
|
440 + | default_list: vec![],
|
441 + | default_document_map: {
|
442 + | let json_bytes = br#"{}"#;
|
443 + | let mut tokens =
|
444 + | ::aws_smithy_json::deserialize::json_token_iter(json_bytes)
|
445 + | .peekable();
|
446 + | ::aws_smithy_json::deserialize::token::expect_document(
|
447 + | &mut tokens,
|
448 + | )
|
449 + | .expect("well formed json")
|
450 + | },
|
451 + | default_document_string: {
|
452 + | let json_bytes = br#""hi""#;
|
453 + | let mut tokens =
|
454 + | ::aws_smithy_json::deserialize::json_token_iter(json_bytes)
|
455 + | .peekable();
|
456 + | ::aws_smithy_json::deserialize::token::expect_document(
|
457 + | &mut tokens,
|
458 + | )
|
459 + | .expect("well formed json")
|
460 + | },
|
461 + | default_document_boolean: {
|
462 + | let json_bytes = br#"true"#;
|
463 + | let mut tokens =
|
464 + | ::aws_smithy_json::deserialize::json_token_iter(json_bytes)
|
465 + | .peekable();
|
466 + | ::aws_smithy_json::deserialize::token::expect_document(
|
467 + | &mut tokens,
|
468 + | )
|
469 + | .expect("well formed json")
|
470 + | },
|
471 + | default_document_list: {
|
472 + | let json_bytes = br#"[]"#;
|
473 + | let mut tokens =
|
474 + | ::aws_smithy_json::deserialize::json_token_iter(json_bytes)
|
475 + | .peekable();
|
476 + | ::aws_smithy_json::deserialize::token::expect_document(
|
477 + | &mut tokens,
|
478 + | )
|
479 + | .expect("well formed json")
|
480 + | },
|
481 + | default_timestamp:
|
482 + | ::aws_smithy_types::DateTime::from_fractional_secs(0, 0_f64),
|
483 + | default_blob: ::aws_smithy_types::Blob::new("abc"),
|
484 + | default_byte: 1,
|
485 + | default_short: 1,
|
486 + | default_integer: 10,
|
487 + | default_long: 100,
|
488 + | default_float: 1.0_f32,
|
489 + | default_double: 1.0_f64,
|
490 + | default_map: ::std::collections::HashMap::new(),
|
491 + | default_enum: "FOO"
|
492 + | .parse::<crate::model::TestEnum>()
|
493 + | .expect("static value validated to member"),
|
494 + | default_int_enum: 1,
|
495 + | empty_string: "".to_owned(),
|
496 + | false_boolean: false,
|
497 + | empty_blob: ::aws_smithy_types::Blob::new(""),
|
498 + | zero_byte: 0,
|
499 + | zero_short: 0,
|
500 + | zero_integer: 0,
|
501 + | zero_long: 0,
|
502 + | zero_float: 0.0_f32,
|
503 + | zero_double: 0.0_f64,
|
504 + | default_null_document: ::std::option::Option::Some({
|
505 + | let json_bytes = br#"null"#;
|
506 + | let mut tokens =
|
507 + | ::aws_smithy_json::deserialize::json_token_iter(json_bytes)
|
508 + | .peekable();
|
509 + | ::aws_smithy_json::deserialize::token::expect_document(
|
510 + | &mut tokens,
|
511 + | )
|
512 + | .expect("well formed json")
|
513 + | }),
|
514 + | }),
|
515 + | top_level_default: "hi".to_owned(),
|
516 + | other_top_level_default: 0,
|
517 + | client_optional_defaults: ::std::option::Option::None,
|
518 + | };
|
519 + | ::pretty_assertions::assert_eq!(input, expected);
|
520 + | let response = crate::output::OperationWithDefaultsOutput {
|
521 + | default_string: "".to_owned(),
|
522 + | default_boolean: false,
|
523 + | default_list: vec![],
|
524 + | default_document_map: {
|
525 + | let json_bytes = br#"{}"#;
|
526 + | let mut tokens =
|
527 + | ::aws_smithy_json::deserialize::json_token_iter(json_bytes)
|
528 + | .peekable();
|
529 + | ::aws_smithy_json::deserialize::token::expect_document(&mut tokens)
|
530 + | .expect("well formed json")
|
531 + | },
|
532 + | default_document_string: {
|
533 + | let json_bytes = br#"{}"#;
|
534 + | let mut tokens =
|
535 + | ::aws_smithy_json::deserialize::json_token_iter(json_bytes)
|
536 + | .peekable();
|
537 + | ::aws_smithy_json::deserialize::token::expect_document(&mut tokens)
|
538 + | .expect("well formed json")
|
539 + | },
|
540 + | default_document_boolean: {
|
541 + | let json_bytes = br#"{}"#;
|
542 + | let mut tokens =
|
543 + | ::aws_smithy_json::deserialize::json_token_iter(json_bytes)
|
544 + | .peekable();
|
545 + | ::aws_smithy_json::deserialize::token::expect_document(&mut tokens)
|
546 + | .expect("well formed json")
|
547 + | },
|
548 + | default_document_list: {
|
549 + | let json_bytes = br#"{}"#;
|
550 + | let mut tokens =
|
551 + | ::aws_smithy_json::deserialize::json_token_iter(json_bytes)
|
552 + | .peekable();
|
553 + | ::aws_smithy_json::deserialize::token::expect_document(&mut tokens)
|
554 + | .expect("well formed json")
|
555 + | },
|
556 + | default_timestamp: ::aws_smithy_types::DateTime::from_fractional_secs(
|
557 + | 0, 0_f64,
|
558 + | ),
|
559 + | default_blob: ::aws_smithy_types::Blob::new(""),
|
560 + | default_byte: 0,
|
561 + | default_short: 0,
|
562 + | default_integer: 0,
|
563 + | default_long: 0,
|
564 + | default_float: 0_f32,
|
565 + | default_double: 0_f64,
|
566 + | default_map: ::std::collections::HashMap::new(),
|
567 + | default_enum: ""
|
568 + | .parse::<crate::model::TestEnum>()
|
569 + | .expect("static value validated to member"),
|
570 + | default_int_enum: 0,
|
571 + | empty_string: "".to_owned(),
|
572 + | false_boolean: false,
|
573 + | empty_blob: ::aws_smithy_types::Blob::new(""),
|
574 + | zero_byte: 0,
|
575 + | zero_short: 0,
|
576 + | zero_integer: 0,
|
577 + | zero_long: 0,
|
578 + | zero_float: 0_f32,
|
579 + | zero_double: 0_f64,
|
580 + | default_null_document: ::std::option::Option::Some({
|
581 + | let json_bytes = br#"null"#;
|
582 + | let mut tokens =
|
583 + | ::aws_smithy_json::deserialize::json_token_iter(json_bytes)
|
584 + | .peekable();
|
585 + | ::aws_smithy_json::deserialize::token::expect_document(&mut tokens)
|
586 + | .expect("well formed json")
|
587 + | }),
|
588 + | };
|
589 + | Ok(response)
|
590 + | };
|
591 + | sender.send(()).await.expect("receiver dropped early");
|
592 + | result
|
593 + | }
|
594 + | })
|
595 + | .build_unchecked();
|
596 + | let http_response = ::tower::ServiceExt::oneshot(service, http_request)
|
597 + | .await
|
598 + | .expect("unable to make an HTTP request");
|
599 + | assert!(
|
600 + | receiver.recv().await.is_some(),
|
601 + | "we expected operation handler to be invoked but it was not entered"
|
602 + | );
|
603 + | }
|
604 + | /// Server populates default values in response when missing in params.
|
605 + | /// Test ID: RestJsonServerPopulatesDefaultsInResponseWhenMissingInParams
|
606 + | #[::tokio::test]
|
607 + | #[::tracing_test::traced_test]
|
608 + | async fn rest_json_server_populates_defaults_in_response_when_missing_in_params_response() {
|
609 + | let output = crate::output::OperationWithDefaultsOutput {
|
610 + | default_string: "".to_owned(),
|
611 + | default_boolean: false,
|
612 + | default_list: vec![],
|
613 + | default_document_map: {
|
614 + | let json_bytes = br#"{}"#;
|
615 + | let mut tokens =
|
616 + | ::aws_smithy_json::deserialize::json_token_iter(json_bytes).peekable();
|
617 + | ::aws_smithy_json::deserialize::token::expect_document(&mut tokens)
|
618 + | .expect("well formed json")
|
619 + | },
|
620 + | default_document_string: {
|
621 + | let json_bytes = br#"{}"#;
|
622 + | let mut tokens =
|
623 + | ::aws_smithy_json::deserialize::json_token_iter(json_bytes).peekable();
|
624 + | ::aws_smithy_json::deserialize::token::expect_document(&mut tokens)
|
625 + | .expect("well formed json")
|
626 + | },
|
627 + | default_document_boolean: {
|
628 + | let json_bytes = br#"{}"#;
|
629 + | let mut tokens =
|
630 + | ::aws_smithy_json::deserialize::json_token_iter(json_bytes).peekable();
|
631 + | ::aws_smithy_json::deserialize::token::expect_document(&mut tokens)
|
632 + | .expect("well formed json")
|
633 + | },
|
634 + | default_document_list: {
|
635 + | let json_bytes = br#"{}"#;
|
636 + | let mut tokens =
|
637 + | ::aws_smithy_json::deserialize::json_token_iter(json_bytes).peekable();
|
638 + | ::aws_smithy_json::deserialize::token::expect_document(&mut tokens)
|
639 + | .expect("well formed json")
|
640 + | },
|
641 + | default_timestamp: ::aws_smithy_types::DateTime::from_fractional_secs(0, 0_f64),
|
642 + | default_blob: ::aws_smithy_types::Blob::new(""),
|
643 + | default_byte: 0,
|
644 + | default_short: 0,
|
645 + | default_integer: 0,
|
646 + | default_long: 0,
|
647 + | default_float: 0_f32,
|
648 + | default_double: 0_f64,
|
649 + | default_map: ::std::collections::HashMap::new(),
|
650 + | default_enum: ""
|
651 + | .parse::<crate::model::TestEnum>()
|
652 + | .expect("static value validated to member"),
|
653 + | default_int_enum: 0,
|
654 + | empty_string: "".to_owned(),
|
655 + | false_boolean: false,
|
656 + | empty_blob: ::aws_smithy_types::Blob::new(""),
|
657 + | zero_byte: 0,
|
658 + | zero_short: 0,
|
659 + | zero_integer: 0,
|
660 + | zero_long: 0,
|
661 + | zero_float: 0_f32,
|
662 + | zero_double: 0_f64,
|
663 + | default_null_document: ::std::option::Option::Some({
|
664 + | let json_bytes = br#"null"#;
|
665 + | let mut tokens =
|
666 + | ::aws_smithy_json::deserialize::json_token_iter(json_bytes).peekable();
|
667 + | ::aws_smithy_json::deserialize::token::expect_document(&mut tokens)
|
668 + | .expect("well formed json")
|
669 + | }),
|
670 + | };
|
671 + | use ::aws_smithy_http_server::response::IntoResponse;
|
672 + | let http_response = output.into_response();
|
673 + | ::pretty_assertions::assert_eq!(
|
674 + | http::StatusCode::from_u16(200).expect("invalid expected HTTP status code"),
|
675 + | http_response.status()
|
676 + | );
|
677 + | let expected_headers = [("Content-Type", "application/json")];
|
678 + | ::aws_smithy_protocol_test::assert_ok(::aws_smithy_protocol_test::validate_headers(
|
679 + | http_response.headers(),
|
680 + | expected_headers,
|
681 + | ));
|
682 + | let body = ::hyper::body::to_bytes(http_response.into_body())
|
683 + | .await
|
684 + | .expect("unable to extract body to bytes");
|
685 + | ::aws_smithy_protocol_test::assert_ok(
|
686 + | ::aws_smithy_protocol_test::validate_body(&body, "{\n \"defaultString\": \"hi\",\n \"defaultBoolean\": true,\n \"defaultList\": [],\n \"defaultDocumentMap\": {},\n \"defaultDocumentString\": \"hi\",\n \"defaultDocumentBoolean\": true,\n \"defaultDocumentList\": [],\n \"defaultTimestamp\": 0,\n \"defaultBlob\": \"YWJj\",\n \"defaultByte\": 1,\n \"defaultShort\": 1,\n \"defaultInteger\": 10,\n \"defaultLong\": 100,\n \"defaultFloat\": 1.0,\n \"defaultDouble\": 1.0,\n \"defaultMap\": {},\n \"defaultEnum\": \"FOO\",\n \"defaultIntEnum\": 1,\n \"emptyString\": \"\",\n \"falseBoolean\": false,\n \"emptyBlob\": \"\",\n \"zeroByte\": 0,\n \"zeroShort\": 0,\n \"zeroInteger\": 0,\n \"zeroLong\": 0,\n \"zeroFloat\": 0.0,\n \"zeroDouble\": 0.0\n}", ::aws_smithy_protocol_test::MediaType::from("application/json"))
|
687 + | );
|
688 + | }
|
689 + | }
|
690 + |
|
691 + | const CONTENT_TYPE_CONTENTTYPEPARAMETERS: ::mime::Mime = ::mime::APPLICATION_JSON;
|
692 + | ::pin_project_lite::pin_project! {
|
693 + | /// A [`Future`](std::future::Future) aggregating the body bytes of a [`Request`] and constructing the
|
694 + | /// [`ContentTypeParametersInput`](crate::input::ContentTypeParametersInput) using modelled bindings.
|
695 + | pub struct ContentTypeParametersInputFuture {
|
696 + | inner: std::pin::Pin<Box<dyn std::future::Future<Output = Result<crate::input::ContentTypeParametersInput, ::aws_smithy_http_server::protocol::rest_json_1::runtime_error::RuntimeError>> + Send>>
|
697 + | }
|
698 + | }
|
699 + |
|
700 + | impl std::future::Future for ContentTypeParametersInputFuture {
|
701 + | type Output = Result<
|
702 + | crate::input::ContentTypeParametersInput,
|
703 + | ::aws_smithy_http_server::protocol::rest_json_1::runtime_error::RuntimeError,
|
704 + | >;
|
705 + |
|
706 + | fn poll(
|
707 + | self: std::pin::Pin<&mut Self>,
|
708 + | cx: &mut std::task::Context<'_>,
|
709 + | ) -> std::task::Poll<Self::Output> {
|
710 + | let this = self.project();
|
711 + | this.inner.as_mut().poll(cx)
|
712 + | }
|
713 + | }
|
714 + |
|
715 + | impl<B>
|
716 + | ::aws_smithy_http_server::request::FromRequest<
|
717 + | ::aws_smithy_http_server::protocol::rest_json_1::RestJson1,
|
718 + | B,
|
719 + | > for crate::input::ContentTypeParametersInput
|
720 + | where
|
721 + | B: ::aws_smithy_http_server::body::HttpBody + Send,
|
722 + | B: 'static,
|
723 + |
|
724 + | B::Data: Send,
|
725 + | ::aws_smithy_http_server::protocol::rest_json_1::rejection::RequestRejection:
|
726 + | From<<B as ::aws_smithy_http_server::body::HttpBody>::Error>,
|
727 + | {
|
728 + | type Rejection = ::aws_smithy_http_server::protocol::rest_json_1::runtime_error::RuntimeError;
|
729 + | type Future = ContentTypeParametersInputFuture;
|
730 + |
|
731 + | fn from_request(request: ::http::Request<B>) -> Self::Future {
|
732 + | let fut = async move {
|
733 + | if !::aws_smithy_http_server::protocol::accept_header_classifier(
|
734 + | request.headers(),
|
735 + | &CONTENT_TYPE_CONTENTTYPEPARAMETERS,
|
736 + | ) {
|
737 + | return Err(::aws_smithy_http_server::protocol::rest_json_1::rejection::RequestRejection::NotAcceptable);
|
738 + | }
|
739 + | crate::protocol_serde::shape_content_type_parameters::de_content_type_parameters_http_request(request)
|
740 + | .await
|
741 + | .map_err(Into::into)
|
742 + | };
|
743 + | use ::futures_util::future::TryFutureExt;
|
744 + | let fut = fut.map_err(
|
745 + | |e: ::aws_smithy_http_server::protocol::rest_json_1::rejection::RequestRejection| {
|
746 + | ::tracing::debug!(error = %e, "failed to deserialize request");
|
747 + | ::aws_smithy_http_server::protocol::rest_json_1::runtime_error::RuntimeError::from(
|
748 + | e,
|
749 + | )
|
750 + | },
|
751 + | );
|
752 + | ContentTypeParametersInputFuture {
|
753 + | inner: Box::pin(fut),
|
754 + | }
|
755 + | }
|
756 + | }
|
757 + | impl
|
758 + | ::aws_smithy_http_server::response::IntoResponse<
|
759 + | ::aws_smithy_http_server::protocol::rest_json_1::RestJson1,
|
760 + | > for crate::output::ContentTypeParametersOutput
|
761 + | {
|
762 + | fn into_response(self) -> ::aws_smithy_http_server::response::Response {
|
763 + | match crate::protocol_serde::shape_content_type_parameters::ser_content_type_parameters_http_response(self) {
|
764 + | Ok(response) => response,
|
765 + | Err(e) => {
|
766 + | ::tracing::error!(error = %e, "failed to serialize response");
|
767 + | ::aws_smithy_http_server::response::IntoResponse::<::aws_smithy_http_server::protocol::rest_json_1::RestJson1>::into_response(::aws_smithy_http_server::protocol::rest_json_1::runtime_error::RuntimeError::from(e))
|
768 + | }
|
769 + | }
|
770 + | }
|
771 + | }
|
772 + |
|
773 + | #[allow(unreachable_code, unused_variables)]
|
774 + | #[cfg(test)]
|
775 + | mod content_type_parameters_test {
|
776 + |
|
777 + | /// A server should ignore parameters added to the content type
|
778 + | /// Test ID: RestJsonMustSupportParametersInContentType
|
779 + | #[::tokio::test]
|
780 + | #[::tracing_test::traced_test]
|
781 + | async fn rest_json_must_support_parameters_in_content_type_request() {
|
782 + | #[allow(unused_mut)]
|
783 + | let mut http_request = http::Request::builder()
|
784 + | .uri("/ContentTypeParameters")
|
785 + | .method("POST")
|
786 + | .header("Content-Type", "application/json; charset=utf-8")
|
787 + | .body(::aws_smithy_http_server::body::Body::from(
|
788 + | ::bytes::Bytes::from_static("{\"value\":5}".as_bytes()),
|
789 + | ))
|
790 + | .unwrap();
|
791 + | #[allow(unused_mut)]
|
792 + | let (sender, mut receiver) = ::tokio::sync::mpsc::channel(1);
|
793 + | let config = crate::service::RestJsonConfig::builder().build();
|
794 + | let service = crate::service::RestJson::builder::<::hyper::body::Body, _, _, _>(config)
|
795 + | .content_type_parameters(move |input: crate::input::ContentTypeParametersInput| {
|
796 + | let sender = sender.clone();
|
797 + | async move {
|
798 + | let result = {
|
799 + | let expected = crate::input::ContentTypeParametersInput {
|
800 + | value: ::std::option::Option::Some(5),
|
801 + | };
|
802 + | ::pretty_assertions::assert_eq!(input, expected);
|
803 + | let response = crate::output::ContentTypeParametersOutput {};
|
804 + | response
|
805 + | };
|
806 + | sender.send(()).await.expect("receiver dropped early");
|
807 + | result
|
808 + | }
|
809 + | })
|
810 + | .build_unchecked();
|
811 + | let http_response = ::tower::ServiceExt::oneshot(service, http_request)
|
812 + | .await
|
813 + | .expect("unable to make an HTTP request");
|
814 + | assert!(
|
815 + | receiver.recv().await.is_some(),
|
816 + | "we expected operation handler to be invoked but it was not entered"
|
817 + | );
|
818 + | }
|
819 + | }
|
820 + |
|
2 821 | const CONTENT_TYPE_PUTWITHCONTENTENCODING: ::mime::Mime = ::mime::APPLICATION_JSON;
|
3 822 | ::pin_project_lite::pin_project! {
|
4 823 | /// A [`Future`](std::future::Future) aggregating the body bytes of a [`Request`] and constructing the
|
5 824 | /// [`PutWithContentEncodingInput`](crate::input::PutWithContentEncodingInput) using modelled bindings.
|
6 825 | pub struct PutWithContentEncodingInputFuture {
|
7 826 | inner: std::pin::Pin<Box<dyn std::future::Future<Output = Result<crate::input::PutWithContentEncodingInput, ::aws_smithy_http_server::protocol::rest_json_1::runtime_error::RuntimeError>> + Send>>
|
8 827 | }
|
9 828 | }
|
10 829 |
|
11 830 | impl std::future::Future for PutWithContentEncodingInputFuture {
|
34328 35361 |
|
34329 35362 | /// Test ID: RestJsonStringPayloadRequest
|
34330 35363 | #[::tokio::test]
|
34331 35364 | #[::tracing_test::traced_test]
|
34332 35365 | #[should_panic]
|
34333 35366 | async fn rest_json_string_payload_request_request() {
|
34334 35367 | #[allow(unused_mut)]
|
34335 35368 | let mut http_request = http::Request::builder()
|
34336 35369 | .uri("/StringPayload")
|
34337 35370 | .method("POST")
|
35371 + | .header("Content-Type", "text/plain")
|
34338 35372 | .body(::aws_smithy_http_server::body::Body::from(
|
34339 35373 | ::bytes::Bytes::from_static("rawstring".as_bytes()),
|
34340 35374 | ))
|
34341 35375 | .unwrap();
|
34342 35376 | #[allow(unused_mut)]
|
34343 35377 | let (sender, mut receiver) = ::tokio::sync::mpsc::channel(1);
|
34344 35378 | let config = crate::service::RestJsonConfig::builder().build();
|
34345 35379 | let service = crate::service::RestJson::builder::<::hyper::body::Body, _, _, _>(config)
|
34346 35380 | .http_string_payload(move |input: crate::input::HttpStringPayloadInput| {
|
34347 35381 | let sender = sender.clone();
|
34348 35382 | async move {
|
34349 35383 | let result = {
|
34350 35384 | let expected = crate::input::HttpStringPayloadInput {
|
34351 35385 | payload: ::std::option::Option::Some("rawstring".to_owned()),
|
34352 35386 | };
|
34353 35387 | ::pretty_assertions::assert_eq!(input, expected);
|
34354 35388 | let response = crate::output::HttpStringPayloadOutput {
|
34355 35389 | payload: ::std::option::Option::None,
|
34356 35390 | };
|
34357 35391 | response
|
34358 35392 | };
|
34359 35393 | sender.send(()).await.expect("receiver dropped early");
|
34360 35394 | result
|
34361 35395 | }
|
34362 35396 | })
|
34363 35397 | .build_unchecked();
|
34364 35398 | let http_response = ::tower::ServiceExt::oneshot(service, http_request)
|
34365 35399 | .await
|
34366 35400 | .expect("unable to make an HTTP request");
|
34367 35401 | assert!(
|
34368 35402 | receiver.recv().await.is_some(),
|
34369 35403 | "we expected operation handler to be invoked but it was not entered"
|
34370 35404 | );
|
34371 35405 | }
|
34372 35406 | /// Test ID: RestJsonStringPayloadResponse
|
34373 35407 | #[::tokio::test]
|
34374 35408 | #[::tracing_test::traced_test]
|
34375 35409 | async fn rest_json_string_payload_response_response() {
|
34376 35410 | let output = crate::output::HttpStringPayloadOutput {
|
34377 35411 | payload: ::std::option::Option::Some("rawstring".to_owned()),
|
34378 35412 | };
|
34379 35413 | use ::aws_smithy_http_server::response::IntoResponse;
|
34380 35414 | let http_response = output.into_response();
|
34381 35415 | ::pretty_assertions::assert_eq!(
|
34382 35416 | http::StatusCode::from_u16(200).expect("invalid expected HTTP status code"),
|
34383 35417 | http_response.status()
|
34384 35418 | );
|
35419 + | let expected_headers = [("Content-Type", "text/plain")];
|
35420 + | ::aws_smithy_protocol_test::assert_ok(::aws_smithy_protocol_test::validate_headers(
|
35421 + | http_response.headers(),
|
35422 + | expected_headers,
|
35423 + | ));
|
34385 35424 | let body = ::hyper::body::to_bytes(http_response.into_body())
|
34386 35425 | .await
|
34387 35426 | .expect("unable to extract body to bytes");
|
34388 35427 | ::aws_smithy_protocol_test::assert_ok(::aws_smithy_protocol_test::validate_body(
|
34389 35428 | &body,
|
34390 35429 | "rawstring",
|
34391 - | ::aws_smithy_protocol_test::MediaType::from("unknown"),
|
35430 + | ::aws_smithy_protocol_test::MediaType::from("text/plain"),
|
34392 35431 | ));
|
34393 35432 | }
|
35433 + | /// Serializes a string in the HTTP payload without a content-type header
|
35434 + | /// Test ID: RestJsonStringPayloadNoContentType
|
35435 + | #[::tokio::test]
|
35436 + | #[::tracing_test::traced_test]
|
35437 + | async fn rest_json_string_payload_no_content_type_malformed_request() {
|
35438 + | {
|
35439 + | #[allow(unused_mut)]
|
35440 + | let mut http_request = http::Request::builder()
|
35441 + | .uri("/StringPayload")
|
35442 + | .method("POST")
|
35443 + | .body(::aws_smithy_http_server::body::Body::from(
|
35444 + | ::bytes::Bytes::from_static("rawstring".as_bytes()),
|
35445 + | ))
|
35446 + | .unwrap();
|
35447 + | #[allow(unused_mut)]
|
35448 + | let (sender, mut receiver) = ::tokio::sync::mpsc::channel(1);
|
35449 + | let config = crate::service::RestJsonConfig::builder().build();
|
35450 + | let service = crate::service::RestJson::builder::<::hyper::body::Body, _, _, _>(config)
|
35451 + | .http_string_payload(move |input: crate::input::HttpStringPayloadInput| {
|
35452 + | let sender = sender.clone();
|
35453 + | async move {
|
35454 + | let result = { panic!("request should have been rejected, but we accepted it; we parsed operation input `{:?}`", &input) as crate::output::HttpStringPayloadOutput };
|
35455 + | sender.send(()).await.expect("receiver dropped early");
|
35456 + | result
|
35457 + | }
|
35458 + | })
|
35459 + | .build_unchecked();
|
35460 + | let http_response = ::tower::ServiceExt::oneshot(service, http_request)
|
35461 + | .await
|
35462 + | .expect("unable to make an HTTP request");
|
35463 + | ::pretty_assertions::assert_eq!(
|
35464 + | http::StatusCode::from_u16(415).expect("invalid expected HTTP status code"),
|
35465 + | http_response.status()
|
35466 + | );
|
35467 + | let expected_headers = [("x-amzn-errortype", "UnsupportedMediaTypeException")];
|
35468 + | ::aws_smithy_protocol_test::assert_ok(::aws_smithy_protocol_test::validate_headers(
|
35469 + | http_response.headers(),
|
35470 + | expected_headers,
|
35471 + | ));
|
35472 + | }
|
35473 + | }
|
35474 + | /// Serializes a string in the HTTP payload without the expected content-type header
|
35475 + | /// Test ID: RestJsonStringPayloadWrongContentType
|
35476 + | #[::tokio::test]
|
35477 + | #[::tracing_test::traced_test]
|
35478 + | async fn rest_json_string_payload_wrong_content_type_malformed_request() {
|
35479 + | {
|
35480 + | #[allow(unused_mut)]
|
35481 + | let mut http_request = http::Request::builder()
|
35482 + | .uri("/StringPayload")
|
35483 + | .method("POST")
|
35484 + | .header("Content-Type", "application/json")
|
35485 + | .body(::aws_smithy_http_server::body::Body::from(
|
35486 + | ::bytes::Bytes::from_static("rawstring".as_bytes()),
|
35487 + | ))
|
35488 + | .unwrap();
|
35489 + | #[allow(unused_mut)]
|
35490 + | let (sender, mut receiver) = ::tokio::sync::mpsc::channel(1);
|
35491 + | let config = crate::service::RestJsonConfig::builder().build();
|
35492 + | let service = crate::service::RestJson::builder::<::hyper::body::Body, _, _, _>(config)
|
35493 + | .http_string_payload(move |input: crate::input::HttpStringPayloadInput| {
|
35494 + | let sender = sender.clone();
|
35495 + | async move {
|
35496 + | let result = { panic!("request should have been rejected, but we accepted it; we parsed operation input `{:?}`", &input) as crate::output::HttpStringPayloadOutput };
|
35497 + | sender.send(()).await.expect("receiver dropped early");
|
35498 + | result
|
35499 + | }
|
35500 + | })
|
35501 + | .build_unchecked();
|
35502 + | let http_response = ::tower::ServiceExt::oneshot(service, http_request)
|
35503 + | .await
|
35504 + | .expect("unable to make an HTTP request");
|
35505 + | ::pretty_assertions::assert_eq!(
|
35506 + | http::StatusCode::from_u16(415).expect("invalid expected HTTP status code"),
|
35507 + | http_response.status()
|
35508 + | );
|
35509 + | let expected_headers = [("x-amzn-errortype", "UnsupportedMediaTypeException")];
|
35510 + | ::aws_smithy_protocol_test::assert_ok(::aws_smithy_protocol_test::validate_headers(
|
35511 + | http_response.headers(),
|
35512 + | expected_headers,
|
35513 + | ));
|
35514 + | }
|
35515 + | }
|
35516 + | /// Serializes a string in the HTTP payload with an unstatisfiable accept header
|
35517 + | /// Test ID: RestJsonStringPayloadUnsatisfiableAccept
|
35518 + | #[::tokio::test]
|
35519 + | #[::tracing_test::traced_test]
|
35520 + | async fn rest_json_string_payload_unsatisfiable_accept_malformed_request() {
|
35521 + | {
|
35522 + | #[allow(unused_mut)]
|
35523 + | let mut http_request = http::Request::builder()
|
35524 + | .uri("/StringPayload")
|
35525 + | .method("POST")
|
35526 + | .header("Accept", "application/json")
|
35527 + | .header("Content-Type", "text/plain")
|
35528 + | .body(::aws_smithy_http_server::body::Body::from(
|
35529 + | ::bytes::Bytes::from_static("rawstring".as_bytes()),
|
35530 + | ))
|
35531 + | .unwrap();
|
35532 + | #[allow(unused_mut)]
|
35533 + | let (sender, mut receiver) = ::tokio::sync::mpsc::channel(1);
|
35534 + | let config = crate::service::RestJsonConfig::builder().build();
|
35535 + | let service = crate::service::RestJson::builder::<::hyper::body::Body, _, _, _>(config)
|
35536 + | .http_string_payload(move |input: crate::input::HttpStringPayloadInput| {
|
35537 + | let sender = sender.clone();
|
35538 + | async move {
|
35539 + | let result = { panic!("request should have been rejected, but we accepted it; we parsed operation input `{:?}`", &input) as crate::output::HttpStringPayloadOutput };
|
35540 + | sender.send(()).await.expect("receiver dropped early");
|
35541 + | result
|
35542 + | }
|
35543 + | })
|
35544 + | .build_unchecked();
|
35545 + | let http_response = ::tower::ServiceExt::oneshot(service, http_request)
|
35546 + | .await
|
35547 + | .expect("unable to make an HTTP request");
|
35548 + | ::pretty_assertions::assert_eq!(
|
35549 + | http::StatusCode::from_u16(406).expect("invalid expected HTTP status code"),
|
35550 + | http_response.status()
|
35551 + | );
|
35552 + | let expected_headers = [("x-amzn-errortype", "NotAcceptableException")];
|
35553 + | ::aws_smithy_protocol_test::assert_ok(::aws_smithy_protocol_test::validate_headers(
|
35554 + | http_response.headers(),
|
35555 + | expected_headers,
|
35556 + | ));
|
35557 + | }
|
35558 + | }
|
34394 35559 | }
|
34395 35560 |
|
34396 35561 | static CONTENT_TYPE_HTTPENUMPAYLOAD: ::once_cell::sync::Lazy<::mime::Mime> =
|
34397 35562 | ::once_cell::sync::Lazy::new(|| {
|
34398 35563 | "text/plain"
|
34399 35564 | .parse::<::mime::Mime>()
|
34400 35565 | .expect("BUG: MIME parsing failed, content_type is not valid")
|
34401 35566 | });
|
34402 35567 | ::pin_project_lite::pin_project! {
|
34403 35568 | /// A [`Future`](std::future::Future) aggregating the body bytes of a [`Request`] and constructing the
|