1 1 | // Code generated by software.amazon.smithy.rust.codegen.smithy-rs. DO NOT EDIT.
|
2 2 | ::pin_project_lite::pin_project! {
|
3 3 | /// A [`Future`](std::future::Future) aggregating the body bytes of a [`Request`] and constructing the
|
4 - | /// [`QueryIncompatibleOperationInput`](crate::input::QueryIncompatibleOperationInput) using modelled bindings.
|
5 - | pub struct QueryIncompatibleOperationInputFuture {
|
6 - | inner: std::pin::Pin<Box<dyn std::future::Future<Output = Result<crate::input::QueryIncompatibleOperationInput, ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError>> + Send>>
|
4 + | /// [`NoInputAndNoOutputInput`](crate::input::NoInputAndNoOutputInput) using modelled bindings.
|
5 + | pub struct NoInputAndNoOutputInputFuture {
|
6 + | inner: std::pin::Pin<Box<dyn std::future::Future<Output = Result<crate::input::NoInputAndNoOutputInput, ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError>> + Send>>
|
7 7 | }
|
8 8 | }
|
9 9 |
|
10 - | impl std::future::Future for QueryIncompatibleOperationInputFuture {
|
10 + | impl std::future::Future for NoInputAndNoOutputInputFuture {
|
11 11 | type Output = Result<
|
12 - | crate::input::QueryIncompatibleOperationInput,
|
12 + | crate::input::NoInputAndNoOutputInput,
|
13 13 | ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError,
|
14 14 | >;
|
15 15 |
|
16 16 | fn poll(
|
17 17 | self: std::pin::Pin<&mut Self>,
|
18 18 | cx: &mut std::task::Context<'_>,
|
19 19 | ) -> std::task::Poll<Self::Output> {
|
20 20 | let this = self.project();
|
21 21 | this.inner.as_mut().poll(cx)
|
22 22 | }
|
23 23 | }
|
24 24 |
|
25 25 | impl<B>
|
26 26 | ::aws_smithy_legacy_http_server::request::FromRequest<
|
27 27 | ::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0,
|
28 28 | B,
|
29 - | > for crate::input::QueryIncompatibleOperationInput
|
29 + | > for crate::input::NoInputAndNoOutputInput
|
30 30 | where
|
31 31 | B: ::aws_smithy_legacy_http_server::body::HttpBody + Send,
|
32 32 | B: 'static,
|
33 33 |
|
34 34 | B::Data: Send,
|
35 35 | ::aws_smithy_legacy_http_server::protocol::aws_json::rejection::RequestRejection:
|
36 36 | From<<B as ::aws_smithy_legacy_http_server::body::HttpBody>::Error>,
|
37 37 | {
|
38 38 | type Rejection =
|
39 39 | ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError;
|
40 - | type Future = QueryIncompatibleOperationInputFuture;
|
40 + | type Future = NoInputAndNoOutputInputFuture;
|
41 41 |
|
42 42 | fn from_request(request: ::http::Request<B>) -> Self::Future {
|
43 43 | let fut = async move {
|
44 44 | if !::aws_smithy_legacy_http_server::protocol::accept_header_classifier(
|
45 45 | request.headers(),
|
46 46 | &crate::mimes::CONTENT_TYPE_APPLICATION_X_AMZ_JSON_1_0,
|
47 47 | ) {
|
48 48 | return Err(::aws_smithy_legacy_http_server::protocol::aws_json::rejection::RequestRejection::NotAcceptable);
|
49 49 | }
|
50 - | crate::protocol_serde::shape_query_incompatible_operation::de_query_incompatible_operation_http_request(request)
|
50 + | crate::protocol_serde::shape_no_input_and_no_output::de_no_input_and_no_output_http_request(request)
|
51 51 | .await
|
52 52 | };
|
53 53 | use ::futures_util::future::TryFutureExt;
|
54 54 | let fut = fut.map_err(|e: ::aws_smithy_legacy_http_server::protocol::aws_json::rejection::RequestRejection| {
|
55 55 | ::tracing::debug!(error = %e, "failed to deserialize request");
|
56 56 | ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError::from(e)
|
57 57 | });
|
58 - | QueryIncompatibleOperationInputFuture {
|
58 + | NoInputAndNoOutputInputFuture {
|
59 59 | inner: Box::pin(fut),
|
60 60 | }
|
61 61 | }
|
62 62 | }
|
63 63 | impl
|
64 64 | ::aws_smithy_legacy_http_server::response::IntoResponse<
|
65 65 | ::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0,
|
66 - | > for crate::output::QueryIncompatibleOperationOutput
|
66 + | > for crate::output::NoInputAndNoOutputOutput
|
67 67 | {
|
68 68 | fn into_response(self) -> ::aws_smithy_legacy_http_server::response::Response {
|
69 - | match crate::protocol_serde::shape_query_incompatible_operation::ser_query_incompatible_operation_http_response(self) {
|
69 + | match crate::protocol_serde::shape_no_input_and_no_output::ser_no_input_and_no_output_http_response(self) {
|
70 70 | Ok(response) => response,
|
71 71 | Err(e) => {
|
72 72 | ::tracing::error!(error = %e, "failed to serialize response");
|
73 73 | ::aws_smithy_legacy_http_server::response::IntoResponse::<::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0>::into_response(::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError::from(e))
|
74 74 | }
|
75 75 | }
|
76 76 | }
|
77 77 | }
|
78 78 |
|
79 79 | #[allow(unreachable_code, unused_variables)]
|
80 80 | #[cfg(test)]
|
81 - | mod query_incompatible_operation_test {
|
81 + | mod no_input_and_no_output_test {
|
82 82 |
|
83 - | /// The query mode header MUST NOT be set on non-query-compatible services.
|
84 - | /// Test ID: NonQueryCompatibleAwsJson10ForbidsQueryModeHeader
|
83 + | /// Clients must always send an empty JSON object payload for
|
84 + | /// operations with no input (that is, `{}`). While AWS service
|
85 + | /// implementations support requests with no payload or requests
|
86 + | /// that send `{}`, always sending `{}` from the client is
|
87 + | /// preferred for forward compatibility in case input is ever
|
88 + | /// added to an operation.
|
89 + | /// Test ID: AwsJson10MustAlwaysSendEmptyJsonPayload
|
85 90 | #[::tokio::test]
|
86 91 | #[::tracing_test::traced_test]
|
87 - | async fn non_query_compatible_aws_json10_forbids_query_mode_header_request() {
|
92 + | async fn aws_json10_must_always_send_empty_json_payload_request() {
|
88 93 | #[allow(unused_mut)]
|
89 94 | let mut http_request = ::http::Request::builder()
|
90 95 | .uri("/")
|
91 96 | .method("POST")
|
92 97 | .header("Content-Type", "application/x-amz-json-1.0")
|
93 - | .header("X-Amz-Target", "JsonRpc10.QueryIncompatibleOperation")
|
98 + | .header("X-Amz-Target", "JsonRpc10.NoInputAndNoOutput")
|
94 99 | .body(::aws_smithy_legacy_http_server::body::Body::from(
|
95 100 | ::bytes::Bytes::copy_from_slice(&::aws_smithy_protocol_test::decode_body_data(
|
96 101 | "{}".as_bytes(),
|
97 102 | ::aws_smithy_protocol_test::MediaType::from("application/json"),
|
98 103 | )),
|
99 104 | ))
|
100 105 | .unwrap();
|
101 106 | #[allow(unused_mut)]
|
102 107 | let (sender, mut receiver) = ::tokio::sync::mpsc::channel(1);
|
103 108 | let config = crate::service::JsonRpc10Config::builder().build();
|
104 109 | let service = crate::service::JsonRpc10::builder::<::hyper::body::Body, _, _, _>(config)
|
105 - | .query_incompatible_operation(
|
106 - | move |input: crate::input::QueryIncompatibleOperationInput| {
|
110 + | .no_input_and_no_output(move |input: crate::input::NoInputAndNoOutputInput| {
|
107 111 | let sender = sender.clone();
|
108 112 | async move {
|
109 113 | let result = {
|
110 - | let expected = crate::input::QueryIncompatibleOperationInput {};
|
114 + | let expected = crate::input::NoInputAndNoOutputInput {};
|
111 115 | ::pretty_assertions::assert_eq!(input, expected);
|
112 - | let output = crate::output::QueryIncompatibleOperationOutput {};
|
116 + | let output = crate::output::NoInputAndNoOutputOutput {};
|
113 117 | output
|
114 118 | };
|
115 119 | sender.send(()).await.expect("receiver dropped early");
|
116 120 | result
|
117 121 | }
|
118 - | },
|
119 - | )
|
122 + | })
|
123 + | .build_unchecked();
|
124 + | let http_response = ::tower::ServiceExt::oneshot(service, http_request)
|
125 + | .await
|
126 + | .expect("unable to make an HTTP request");
|
127 + | assert!(
|
128 + | receiver.recv().await.is_some(),
|
129 + | "we expected operation handler to be invoked but it was not entered"
|
130 + | );
|
131 + | }
|
132 + |
|
133 + | /// Service implementations must support no payload or an empty
|
134 + | /// object payload for operations that define no input. However,
|
135 + | /// despite the lack of a payload, a Content-Type header is still
|
136 + | /// required in order for the service to properly detect the
|
137 + | /// protocol.
|
138 + | /// Test ID: AwsJson10ServiceSupportsNoPayloadForNoInput
|
139 + | #[::tokio::test]
|
140 + | #[::tracing_test::traced_test]
|
141 + | async fn aws_json10_service_supports_no_payload_for_no_input_request() {
|
142 + | #[allow(unused_mut)]
|
143 + | let mut http_request = ::http::Request::builder()
|
144 + | .uri("/")
|
145 + | .method("POST")
|
146 + | .header("Content-Type", "application/x-amz-json-1.0")
|
147 + | .header("X-Amz-Target", "JsonRpc10.NoInputAndNoOutput")
|
148 + | .body(::aws_smithy_legacy_http_server::body::Body::from(
|
149 + | ::bytes::Bytes::copy_from_slice(&::aws_smithy_protocol_test::decode_body_data(
|
150 + | "".as_bytes(),
|
151 + | ::aws_smithy_protocol_test::MediaType::from("unknown"),
|
152 + | )),
|
153 + | ))
|
154 + | .unwrap();
|
155 + | #[allow(unused_mut)]
|
156 + | let (sender, mut receiver) = ::tokio::sync::mpsc::channel(1);
|
157 + | let config = crate::service::JsonRpc10Config::builder().build();
|
158 + | let service = crate::service::JsonRpc10::builder::<::hyper::body::Body, _, _, _>(config)
|
159 + | .no_input_and_no_output(move |input: crate::input::NoInputAndNoOutputInput| {
|
160 + | let sender = sender.clone();
|
161 + | async move {
|
162 + | let result = {
|
163 + | let expected = crate::input::NoInputAndNoOutputInput {};
|
164 + | ::pretty_assertions::assert_eq!(input, expected);
|
165 + | let output = crate::output::NoInputAndNoOutputOutput {};
|
166 + | output
|
167 + | };
|
168 + | sender.send(()).await.expect("receiver dropped early");
|
169 + | result
|
170 + | }
|
171 + | })
|
120 172 | .build_unchecked();
|
121 173 | let http_response = ::tower::ServiceExt::oneshot(service, http_request)
|
122 174 | .await
|
123 175 | .expect("unable to make an HTTP request");
|
124 176 | assert!(
|
125 177 | receiver.recv().await.is_some(),
|
126 178 | "we expected operation handler to be invoked but it was not entered"
|
127 179 | );
|
128 180 | }
|
181 + |
|
182 + | /// When no output is defined, the service is expected to return
|
183 + | /// an empty payload. Despite the lack of a payload, the service
|
184 + | /// is expected to always send a Content-Type header. Clients must
|
185 + | /// handle cases where a service returns a JSON object and where
|
186 + | /// a service returns no JSON at all.
|
187 + | /// Test ID: AwsJson10ServiceRespondsWithNoPayload
|
188 + | #[::tokio::test]
|
189 + | #[::tracing_test::traced_test]
|
190 + | async fn aws_json10_service_responds_with_no_payload_response() {
|
191 + | let output = crate::output::NoInputAndNoOutputOutput {};
|
192 + | use ::aws_smithy_legacy_http_server::response::IntoResponse;
|
193 + | let http_response = output.into_response();
|
194 + | ::pretty_assertions::assert_eq!(
|
195 + | ::http::StatusCode::from_u16(200).expect("invalid expected HTTP status code"),
|
196 + | http_response.status()
|
197 + | );
|
198 + | let expected_headers = [("Content-Type", "application/x-amz-json-1.0")];
|
199 + | ::aws_smithy_protocol_test::assert_ok(::aws_smithy_protocol_test::validate_headers(
|
200 + | http_response.headers(),
|
201 + | expected_headers,
|
202 + | ));
|
203 + | let body = ::hyper::body::to_bytes(http_response.into_body())
|
204 + | .await
|
205 + | .expect("unable to extract body to bytes");
|
206 + | // No body.
|
207 + | ::pretty_assertions::assert_eq!(&body, &bytes::Bytes::new());
|
208 + | }
|
129 209 | }
|
130 210 |
|
131 211 | ::pin_project_lite::pin_project! {
|
132 212 | /// A [`Future`](std::future::Future) aggregating the body bytes of a [`Request`] and constructing the
|
133 - | /// [`OperationWithRequiredMembersWithDefaultsInput`](crate::input::OperationWithRequiredMembersWithDefaultsInput) using modelled bindings.
|
134 - | pub struct OperationWithRequiredMembersWithDefaultsInputFuture {
|
135 - | inner: std::pin::Pin<Box<dyn std::future::Future<Output = Result<crate::input::OperationWithRequiredMembersWithDefaultsInput, ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError>> + Send>>
|
213 + | /// [`NoInputAndOutputInput`](crate::input::NoInputAndOutputInput) using modelled bindings.
|
214 + | pub struct NoInputAndOutputInputFuture {
|
215 + | inner: std::pin::Pin<Box<dyn std::future::Future<Output = Result<crate::input::NoInputAndOutputInput, ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError>> + Send>>
|
136 216 | }
|
137 217 | }
|
138 218 |
|
139 - | impl std::future::Future for OperationWithRequiredMembersWithDefaultsInputFuture {
|
219 + | impl std::future::Future for NoInputAndOutputInputFuture {
|
140 220 | type Output = Result<
|
141 - | crate::input::OperationWithRequiredMembersWithDefaultsInput,
|
221 + | crate::input::NoInputAndOutputInput,
|
142 222 | ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError,
|
143 223 | >;
|
144 224 |
|
145 225 | fn poll(
|
146 226 | self: std::pin::Pin<&mut Self>,
|
147 227 | cx: &mut std::task::Context<'_>,
|
148 228 | ) -> std::task::Poll<Self::Output> {
|
149 229 | let this = self.project();
|
150 230 | this.inner.as_mut().poll(cx)
|
151 231 | }
|
152 232 | }
|
153 233 |
|
154 234 | impl<B>
|
155 235 | ::aws_smithy_legacy_http_server::request::FromRequest<
|
156 236 | ::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0,
|
157 237 | B,
|
158 - | > for crate::input::OperationWithRequiredMembersWithDefaultsInput
|
238 + | > for crate::input::NoInputAndOutputInput
|
159 239 | where
|
160 240 | B: ::aws_smithy_legacy_http_server::body::HttpBody + Send,
|
161 241 | B: 'static,
|
162 242 |
|
163 243 | B::Data: Send,
|
164 244 | ::aws_smithy_legacy_http_server::protocol::aws_json::rejection::RequestRejection:
|
165 245 | From<<B as ::aws_smithy_legacy_http_server::body::HttpBody>::Error>,
|
166 246 | {
|
167 247 | type Rejection =
|
168 248 | ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError;
|
169 - | type Future = OperationWithRequiredMembersWithDefaultsInputFuture;
|
249 + | type Future = NoInputAndOutputInputFuture;
|
170 250 |
|
171 251 | fn from_request(request: ::http::Request<B>) -> Self::Future {
|
172 252 | let fut = async move {
|
173 253 | if !::aws_smithy_legacy_http_server::protocol::accept_header_classifier(
|
174 254 | request.headers(),
|
175 255 | &crate::mimes::CONTENT_TYPE_APPLICATION_X_AMZ_JSON_1_0,
|
176 256 | ) {
|
177 257 | return Err(::aws_smithy_legacy_http_server::protocol::aws_json::rejection::RequestRejection::NotAcceptable);
|
178 258 | }
|
179 - | crate::protocol_serde::shape_operation_with_required_members_with_defaults::de_operation_with_required_members_with_defaults_http_request(request)
|
259 + | crate::protocol_serde::shape_no_input_and_output::de_no_input_and_output_http_request(
|
260 + | request,
|
261 + | )
|
180 262 | .await
|
181 263 | };
|
182 264 | use ::futures_util::future::TryFutureExt;
|
183 265 | let fut = fut.map_err(|e: ::aws_smithy_legacy_http_server::protocol::aws_json::rejection::RequestRejection| {
|
184 266 | ::tracing::debug!(error = %e, "failed to deserialize request");
|
185 267 | ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError::from(e)
|
186 268 | });
|
187 - | OperationWithRequiredMembersWithDefaultsInputFuture {
|
269 + | NoInputAndOutputInputFuture {
|
188 270 | inner: Box::pin(fut),
|
189 271 | }
|
190 272 | }
|
191 273 | }
|
192 274 | impl
|
193 275 | ::aws_smithy_legacy_http_server::response::IntoResponse<
|
194 276 | ::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0,
|
195 - | > for crate::output::OperationWithRequiredMembersWithDefaultsOutput
|
277 + | > for crate::output::NoInputAndOutputOutput
|
196 278 | {
|
197 279 | fn into_response(self) -> ::aws_smithy_legacy_http_server::response::Response {
|
198 - | match crate::protocol_serde::shape_operation_with_required_members_with_defaults::ser_operation_with_required_members_with_defaults_http_response(self) {
|
280 + | match crate::protocol_serde::shape_no_input_and_output::ser_no_input_and_output_http_response(self) {
|
199 281 | Ok(response) => response,
|
200 282 | Err(e) => {
|
201 283 | ::tracing::error!(error = %e, "failed to serialize response");
|
202 284 | ::aws_smithy_legacy_http_server::response::IntoResponse::<::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0>::into_response(::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError::from(e))
|
203 285 | }
|
204 286 | }
|
205 287 | }
|
206 288 | }
|
207 289 |
|
290 + | #[allow(unreachable_code, unused_variables)]
|
291 + | #[cfg(test)]
|
292 + | mod no_input_and_output_test {
|
293 + |
|
294 + | /// A client should always send and empty JSON object payload.
|
295 + | /// Test ID: AwsJson10NoInputAndOutput
|
296 + | #[::tokio::test]
|
297 + | #[::tracing_test::traced_test]
|
298 + | async fn aws_json10_no_input_and_output_request() {
|
299 + | #[allow(unused_mut)]
|
300 + | let mut http_request = ::http::Request::builder()
|
301 + | .uri("/")
|
302 + | .method("POST")
|
303 + | .header("Content-Type", "application/x-amz-json-1.0")
|
304 + | .header("X-Amz-Target", "JsonRpc10.NoInputAndOutput")
|
305 + | .body(::aws_smithy_legacy_http_server::body::Body::from(
|
306 + | ::bytes::Bytes::copy_from_slice(&::aws_smithy_protocol_test::decode_body_data(
|
307 + | "{}".as_bytes(),
|
308 + | ::aws_smithy_protocol_test::MediaType::from("application/json"),
|
309 + | )),
|
310 + | ))
|
311 + | .unwrap();
|
312 + | #[allow(unused_mut)]
|
313 + | let (sender, mut receiver) = ::tokio::sync::mpsc::channel(1);
|
314 + | let config = crate::service::JsonRpc10Config::builder().build();
|
315 + | let service = crate::service::JsonRpc10::builder::<::hyper::body::Body, _, _, _>(config)
|
316 + | .no_input_and_output(move |input: crate::input::NoInputAndOutputInput| {
|
317 + | let sender = sender.clone();
|
318 + | async move {
|
319 + | let result = {
|
320 + | let expected = crate::input::NoInputAndOutputInput {};
|
321 + | ::pretty_assertions::assert_eq!(input, expected);
|
322 + | let output = crate::output::NoInputAndOutputOutput {};
|
323 + | output
|
324 + | };
|
325 + | sender.send(()).await.expect("receiver dropped early");
|
326 + | result
|
327 + | }
|
328 + | })
|
329 + | .build_unchecked();
|
330 + | let http_response = ::tower::ServiceExt::oneshot(service, http_request)
|
331 + | .await
|
332 + | .expect("unable to make an HTTP request");
|
333 + | assert!(
|
334 + | receiver.recv().await.is_some(),
|
335 + | "we expected operation handler to be invoked but it was not entered"
|
336 + | );
|
337 + | }
|
338 + |
|
339 + | /// Empty output always serializes an empty object payload.
|
340 + | /// Test ID: AwsJson10NoInputAndOutput
|
341 + | #[::tokio::test]
|
342 + | #[::tracing_test::traced_test]
|
343 + | async fn aws_json10_no_input_and_output_response() {
|
344 + | let output = crate::output::NoInputAndOutputOutput {};
|
345 + | use ::aws_smithy_legacy_http_server::response::IntoResponse;
|
346 + | let http_response = output.into_response();
|
347 + | ::pretty_assertions::assert_eq!(
|
348 + | ::http::StatusCode::from_u16(200).expect("invalid expected HTTP status code"),
|
349 + | http_response.status()
|
350 + | );
|
351 + | let expected_headers = [("Content-Type", "application/x-amz-json-1.0")];
|
352 + | ::aws_smithy_protocol_test::assert_ok(::aws_smithy_protocol_test::validate_headers(
|
353 + | http_response.headers(),
|
354 + | expected_headers,
|
355 + | ));
|
356 + | let body = ::hyper::body::to_bytes(http_response.into_body())
|
357 + | .await
|
358 + | .expect("unable to extract body to bytes");
|
359 + | ::aws_smithy_protocol_test::assert_ok(::aws_smithy_protocol_test::validate_body(
|
360 + | &body,
|
361 + | "{}",
|
362 + | ::aws_smithy_protocol_test::MediaType::from("application/json"),
|
363 + | ));
|
364 + | }
|
365 + | }
|
366 + |
|
208 367 | ::pin_project_lite::pin_project! {
|
209 368 | /// A [`Future`](std::future::Future) aggregating the body bytes of a [`Request`] and constructing the
|
210 - | /// [`OperationWithNestedStructureInput`](crate::input::OperationWithNestedStructureInput) using modelled bindings.
|
211 - | pub struct OperationWithNestedStructureInputFuture {
|
212 - | inner: std::pin::Pin<Box<dyn std::future::Future<Output = Result<crate::input::OperationWithNestedStructureInput, ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError>> + Send>>
|
369 + | /// [`EmptyInputAndEmptyOutputInput`](crate::input::EmptyInputAndEmptyOutputInput) using modelled bindings.
|
370 + | pub struct EmptyInputAndEmptyOutputInputFuture {
|
371 + | inner: std::pin::Pin<Box<dyn std::future::Future<Output = Result<crate::input::EmptyInputAndEmptyOutputInput, ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError>> + Send>>
|
213 372 | }
|
214 373 | }
|
215 374 |
|
216 - | impl std::future::Future for OperationWithNestedStructureInputFuture {
|
375 + | impl std::future::Future for EmptyInputAndEmptyOutputInputFuture {
|
217 376 | type Output = Result<
|
218 - | crate::input::OperationWithNestedStructureInput,
|
377 + | crate::input::EmptyInputAndEmptyOutputInput,
|
219 378 | ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError,
|
220 379 | >;
|
221 380 |
|
222 381 | fn poll(
|
223 382 | self: std::pin::Pin<&mut Self>,
|
224 383 | cx: &mut std::task::Context<'_>,
|
225 384 | ) -> std::task::Poll<Self::Output> {
|
226 385 | let this = self.project();
|
227 386 | this.inner.as_mut().poll(cx)
|
228 387 | }
|
229 388 | }
|
230 389 |
|
231 390 | impl<B>
|
232 391 | ::aws_smithy_legacy_http_server::request::FromRequest<
|
233 392 | ::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0,
|
234 393 | B,
|
235 - | > for crate::input::OperationWithNestedStructureInput
|
394 + | > for crate::input::EmptyInputAndEmptyOutputInput
|
236 395 | where
|
237 396 | B: ::aws_smithy_legacy_http_server::body::HttpBody + Send,
|
238 397 | B: 'static,
|
239 398 |
|
240 399 | B::Data: Send,
|
241 400 | ::aws_smithy_legacy_http_server::protocol::aws_json::rejection::RequestRejection:
|
242 401 | From<<B as ::aws_smithy_legacy_http_server::body::HttpBody>::Error>,
|
243 402 | {
|
244 403 | type Rejection =
|
245 404 | ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError;
|
246 - | type Future = OperationWithNestedStructureInputFuture;
|
405 + | type Future = EmptyInputAndEmptyOutputInputFuture;
|
247 406 |
|
248 407 | fn from_request(request: ::http::Request<B>) -> Self::Future {
|
249 408 | let fut = async move {
|
250 409 | if !::aws_smithy_legacy_http_server::protocol::accept_header_classifier(
|
251 410 | request.headers(),
|
252 411 | &crate::mimes::CONTENT_TYPE_APPLICATION_X_AMZ_JSON_1_0,
|
253 412 | ) {
|
254 413 | return Err(::aws_smithy_legacy_http_server::protocol::aws_json::rejection::RequestRejection::NotAcceptable);
|
255 414 | }
|
256 - | crate::protocol_serde::shape_operation_with_nested_structure::de_operation_with_nested_structure_http_request(request)
|
415 + | crate::protocol_serde::shape_empty_input_and_empty_output::de_empty_input_and_empty_output_http_request(request)
|
257 416 | .await
|
258 417 | };
|
259 418 | use ::futures_util::future::TryFutureExt;
|
260 419 | let fut = fut.map_err(|e: ::aws_smithy_legacy_http_server::protocol::aws_json::rejection::RequestRejection| {
|
261 420 | ::tracing::debug!(error = %e, "failed to deserialize request");
|
262 421 | ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError::from(e)
|
263 422 | });
|
264 - | OperationWithNestedStructureInputFuture {
|
423 + | EmptyInputAndEmptyOutputInputFuture {
|
265 424 | inner: Box::pin(fut),
|
266 425 | }
|
267 426 | }
|
268 427 | }
|
269 428 | impl
|
270 429 | ::aws_smithy_legacy_http_server::response::IntoResponse<
|
271 430 | ::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0,
|
272 - | > for crate::output::OperationWithNestedStructureOutput
|
431 + | > for crate::output::EmptyInputAndEmptyOutputOutput
|
273 432 | {
|
274 433 | fn into_response(self) -> ::aws_smithy_legacy_http_server::response::Response {
|
275 - | match crate::protocol_serde::shape_operation_with_nested_structure::ser_operation_with_nested_structure_http_response(self) {
|
434 + | match crate::protocol_serde::shape_empty_input_and_empty_output::ser_empty_input_and_empty_output_http_response(self) {
|
276 435 | Ok(response) => response,
|
277 436 | Err(e) => {
|
278 437 | ::tracing::error!(error = %e, "failed to serialize response");
|
279 438 | ::aws_smithy_legacy_http_server::response::IntoResponse::<::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0>::into_response(::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError::from(e))
|
280 439 | }
|
281 440 | }
|
282 441 | }
|
283 442 | }
|
284 - | impl
|
285 - | ::aws_smithy_legacy_http_server::response::IntoResponse<
|
286 - | ::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0,
|
287 - | > for crate::error::OperationWithNestedStructureError
|
288 - | {
|
289 - | fn into_response(self) -> ::aws_smithy_legacy_http_server::response::Response {
|
290 - | match crate::protocol_serde::shape_operation_with_nested_structure::ser_operation_with_nested_structure_http_error(&self) {
|
291 - | Ok(mut response) => {
|
292 - | response.extensions_mut().insert(::aws_smithy_legacy_http_server::extension::ModeledErrorExtension::new(self.name()));
|
293 - | response
|
294 - | },
|
295 - | Err(e) => {
|
296 - | ::tracing::error!(error = %e, "failed to serialize response");
|
297 - | ::aws_smithy_legacy_http_server::response::IntoResponse::<::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0>::into_response(::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError::from(e))
|
298 - | }
|
299 - | }
|
300 - | }
|
301 - | }
|
302 443 |
|
303 444 | #[allow(unreachable_code, unused_variables)]
|
304 445 | #[cfg(test)]
|
305 - | mod operation_with_nested_structure_test {
|
446 + | mod empty_input_and_empty_output_test {
|
306 447 |
|
307 - | /// Server populates nested default values when missing in request body.
|
308 - | /// Test ID: AwsJson10ServerPopulatesNestedDefaultsWhenMissingInRequestBody
|
448 + | /// Clients must always send an empty object if input is modeled.
|
449 + | /// Test ID: AwsJson10EmptyInputAndEmptyOutput
|
309 450 | #[::tokio::test]
|
310 451 | #[::tracing_test::traced_test]
|
311 - | #[should_panic]
|
312 - | async fn aws_json10_server_populates_nested_defaults_when_missing_in_request_body_request() {
|
452 + | async fn aws_json10_empty_input_and_empty_output_request() {
|
313 453 | #[allow(unused_mut)]
|
314 454 | let mut http_request = ::http::Request::builder()
|
315 455 | .uri("/")
|
316 456 | .method("POST")
|
317 457 | .header("Content-Type", "application/x-amz-json-1.0")
|
458 + | .header("X-Amz-Target", "JsonRpc10.EmptyInputAndEmptyOutput")
|
318 459 | .body(::aws_smithy_legacy_http_server::body::Body::from(
|
319 - | ::bytes::Bytes::copy_from_slice(
|
320 - | &::aws_smithy_protocol_test::decode_body_data("{\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(), ::aws_smithy_protocol_test::MediaType::from("application/json"))
|
321 - | )
|
322 - | )).unwrap();
|
460 + | ::bytes::Bytes::copy_from_slice(&::aws_smithy_protocol_test::decode_body_data(
|
461 + | "{}".as_bytes(),
|
462 + | ::aws_smithy_protocol_test::MediaType::from("application/json"),
|
463 + | )),
|
464 + | ))
|
465 + | .unwrap();
|
323 466 | #[allow(unused_mut)]
|
324 467 | let (sender, mut receiver) = ::tokio::sync::mpsc::channel(1);
|
325 468 | let config = crate::service::JsonRpc10Config::builder().build();
|
326 469 | let service = crate::service::JsonRpc10::builder::<::hyper::body::Body, _, _, _>(config)
|
327 - | .operation_with_nested_structure(
|
328 - | move |input: crate::input::OperationWithNestedStructureInput| {
|
470 + | .empty_input_and_empty_output(
|
471 + | move |input: crate::input::EmptyInputAndEmptyOutputInput| {
|
329 472 | let sender = sender.clone();
|
330 473 | async move {
|
331 474 | let result = {
|
332 - | let expected = crate::input::OperationWithNestedStructureInput {
|
333 - | top_level: crate::model::TopLevel {
|
334 - | dialog: crate::model::Dialog {
|
335 - | language: ::std::option::Option::Some("en".to_owned()),
|
336 - | greeting: "hi".to_owned(),
|
337 - | farewell: ::std::option::Option::None,
|
338 - | },
|
339 - | dialog_list: vec![
|
340 - | crate::model::Dialog {
|
341 - | greeting: "hi".to_owned(),
|
342 - | language: ::std::option::Option::None,
|
343 - | farewell: ::std::option::Option::None,
|
344 - | },
|
345 - | crate::model::Dialog {
|
346 - | greeting: "hi".to_owned(),
|
347 - | farewell: ::std::option::Option::Some(
|
348 - | crate::model::Farewell {
|
349 - | phrase: "bye".to_owned(),
|
350 - | },
|
351 - | ),
|
352 - | language: ::std::option::Option::None,
|
353 - | },
|
354 - | crate::model::Dialog {
|
355 - | language: ::std::option::Option::Some("it".to_owned()),
|
356 - | greeting: "ciao".to_owned(),
|
357 - | farewell: ::std::option::Option::Some(
|
358 - | crate::model::Farewell {
|
359 - | phrase: "arrivederci".to_owned(),
|
360 - | },
|
361 - | ),
|
362 - | },
|
363 - | ],
|
364 - | dialog_map: {
|
365 - | let mut ret = ::std::collections::HashMap::new();
|
366 - | ret.insert(
|
367 - | "emptyDialog".to_owned(),
|
368 - | crate::model::Dialog {
|
369 - | greeting: "hi".to_owned(),
|
370 - | language: ::std::option::Option::None,
|
371 - | farewell: ::std::option::Option::None,
|
372 - | },
|
373 - | );
|
374 - | ret.insert(
|
375 - | "partialEmptyDialog".to_owned(),
|
376 - | crate::model::Dialog {
|
377 - | language: ::std::option::Option::Some(
|
378 - | "en".to_owned(),
|
379 - | ),
|
380 - | greeting: "hi".to_owned(),
|
381 - | farewell: ::std::option::Option::Some(
|
382 - | crate::model::Farewell {
|
383 - | phrase: "bye".to_owned(),
|
384 - | },
|
385 - | ),
|
386 - | },
|
387 - | );
|
388 - | ret.insert(
|
389 - | "nonEmptyDialog".to_owned(),
|
390 - | crate::model::Dialog {
|
391 - | greeting: "konnichiwa".to_owned(),
|
392 - | farewell: ::std::option::Option::Some(
|
393 - | crate::model::Farewell {
|
394 - | phrase: "sayonara".to_owned(),
|
395 - | },
|
396 - | ),
|
397 - | language: ::std::option::Option::None,
|
398 - | },
|
399 - | );
|
400 - | ret
|
401 - | },
|
402 - | },
|
403 - | };
|
475 + | let expected = crate::input::EmptyInputAndEmptyOutputInput {};
|
404 476 | ::pretty_assertions::assert_eq!(input, expected);
|
405 - | let output = crate::output::OperationWithNestedStructureOutput {
|
406 - | dialog: crate::model::Dialog {
|
407 - | greeting: "".to_owned(),
|
408 - | language: ::std::option::Option::None,
|
409 - | farewell: ::std::option::Option::None,
|
410 - | },
|
411 - | dialog_list: vec![],
|
412 - | dialog_map: ::std::collections::HashMap::new(),
|
413 - | };
|
414 - | Ok(output)
|
477 + | let output = crate::output::EmptyInputAndEmptyOutputOutput {};
|
478 + | output
|
415 479 | };
|
416 480 | sender.send(()).await.expect("receiver dropped early");
|
417 481 | result
|
418 482 | }
|
419 483 | },
|
420 484 | )
|
421 485 | .build_unchecked();
|
422 486 | let http_response = ::tower::ServiceExt::oneshot(service, http_request)
|
423 487 | .await
|
424 488 | .expect("unable to make an HTTP request");
|
425 489 | assert!(
|
426 490 | receiver.recv().await.is_some(),
|
427 491 | "we expected operation handler to be invoked but it was not entered"
|
428 492 | );
|
429 493 | }
|
430 494 |
|
431 - | /// Server populates nested default values when missing in response params.
|
432 - | /// Test ID: AwsJson10ServerPopulatesNestedDefaultValuesWhenMissingInInResponseParams
|
495 + | /// A service will always return a JSON object for operations with modeled output.
|
496 + | /// Test ID: AwsJson10EmptyInputAndEmptyOutputSendJsonObject
|
433 497 | #[::tokio::test]
|
434 498 | #[::tracing_test::traced_test]
|
435 - | #[should_panic]
|
436 - | async fn aws_json10_server_populates_nested_default_values_when_missing_in_in_response_params_response(
|
437 - | ) {
|
438 - | let output = crate::output::OperationWithNestedStructureOutput {
|
439 - | dialog: crate::model::Dialog {
|
440 - | greeting: "".to_owned(),
|
441 - | language: ::std::option::Option::Some("en".to_owned()),
|
442 - | farewell: ::std::option::Option::None,
|
443 - | },
|
444 - | dialog_list: vec![
|
445 - | crate::model::Dialog {
|
446 - | greeting: "".to_owned(),
|
447 - | language: ::std::option::Option::None,
|
448 - | farewell: ::std::option::Option::None,
|
449 - | },
|
450 - | crate::model::Dialog {
|
451 - | greeting: "".to_owned(),
|
452 - | farewell: ::std::option::Option::Some(crate::model::Farewell {
|
453 - | phrase: "".to_owned(),
|
454 - | }),
|
455 - | language: ::std::option::Option::None,
|
456 - | },
|
457 - | crate::model::Dialog {
|
458 - | language: ::std::option::Option::Some("it".to_owned()),
|
459 - | greeting: "ciao".to_owned(),
|
460 - | farewell: ::std::option::Option::Some(crate::model::Farewell {
|
461 - | phrase: "arrivederci".to_owned(),
|
462 - | }),
|
463 - | },
|
464 - | ],
|
465 - | dialog_map: {
|
466 - | let mut ret = ::std::collections::HashMap::new();
|
467 - | ret.insert(
|
468 - | "emptyDialog".to_owned(),
|
469 - | crate::model::Dialog {
|
470 - | greeting: "".to_owned(),
|
471 - | language: ::std::option::Option::None,
|
472 - | farewell: ::std::option::Option::None,
|
473 - | },
|
474 - | );
|
475 - | ret.insert(
|
476 - | "partialEmptyDialog".to_owned(),
|
477 - | crate::model::Dialog {
|
478 - | greeting: "".to_owned(),
|
479 - | language: ::std::option::Option::Some("en".to_owned()),
|
480 - | farewell: ::std::option::Option::Some(crate::model::Farewell {
|
481 - | phrase: "".to_owned(),
|
482 - | }),
|
483 - | },
|
484 - | );
|
485 - | ret.insert(
|
486 - | "nonEmptyDialog".to_owned(),
|
487 - | crate::model::Dialog {
|
488 - | greeting: "konnichiwa".to_owned(),
|
489 - | farewell: ::std::option::Option::Some(crate::model::Farewell {
|
490 - | phrase: "sayonara".to_owned(),
|
491 - | }),
|
492 - | language: ::std::option::Option::None,
|
493 - | },
|
494 - | );
|
495 - | ret
|
496 - | },
|
497 - | };
|
499 + | async fn aws_json10_empty_input_and_empty_output_send_json_object_response() {
|
500 + | let output = crate::output::EmptyInputAndEmptyOutputOutput {};
|
498 501 | use ::aws_smithy_legacy_http_server::response::IntoResponse;
|
499 502 | let http_response = output.into_response();
|
500 503 | ::pretty_assertions::assert_eq!(
|
501 504 | ::http::StatusCode::from_u16(200).expect("invalid expected HTTP status code"),
|
502 505 | http_response.status()
|
503 506 | );
|
504 507 | let expected_headers = [("Content-Type", "application/x-amz-json-1.0")];
|
505 508 | ::aws_smithy_protocol_test::assert_ok(::aws_smithy_protocol_test::validate_headers(
|
506 509 | http_response.headers(),
|
507 510 | expected_headers,
|
508 511 | ));
|
509 512 | let body = ::hyper::body::to_bytes(http_response.into_body())
|
510 513 | .await
|
511 514 | .expect("unable to extract body to bytes");
|
512 - | ::aws_smithy_protocol_test::assert_ok(
|
513 - | ::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"))
|
514 - | );
|
515 + | ::aws_smithy_protocol_test::assert_ok(::aws_smithy_protocol_test::validate_body(
|
516 + | &body,
|
517 + | "{}",
|
518 + | ::aws_smithy_protocol_test::MediaType::from("application/json"),
|
519 + | ));
|
515 520 | }
|
516 521 | }
|
517 522 |
|
518 523 | ::pin_project_lite::pin_project! {
|
519 524 | /// A [`Future`](std::future::Future) aggregating the body bytes of a [`Request`] and constructing the
|
520 - | /// [`OperationWithRequiredMembersInput`](crate::input::OperationWithRequiredMembersInput) using modelled bindings.
|
521 - | pub struct OperationWithRequiredMembersInputFuture {
|
522 - | inner: std::pin::Pin<Box<dyn std::future::Future<Output = Result<crate::input::OperationWithRequiredMembersInput, ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError>> + Send>>
|
525 + | /// [`SimpleScalarPropertiesInput`](crate::input::SimpleScalarPropertiesInput) using modelled bindings.
|
526 + | pub struct SimpleScalarPropertiesInputFuture {
|
527 + | inner: std::pin::Pin<Box<dyn std::future::Future<Output = Result<crate::input::SimpleScalarPropertiesInput, ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError>> + Send>>
|
523 528 | }
|
524 529 | }
|
525 530 |
|
526 - | impl std::future::Future for OperationWithRequiredMembersInputFuture {
|
531 + | impl std::future::Future for SimpleScalarPropertiesInputFuture {
|
527 532 | type Output = Result<
|
528 - | crate::input::OperationWithRequiredMembersInput,
|
533 + | crate::input::SimpleScalarPropertiesInput,
|
529 534 | ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError,
|
530 535 | >;
|
531 536 |
|
532 537 | fn poll(
|
533 538 | self: std::pin::Pin<&mut Self>,
|
534 539 | cx: &mut std::task::Context<'_>,
|
535 540 | ) -> std::task::Poll<Self::Output> {
|
536 541 | let this = self.project();
|
537 542 | this.inner.as_mut().poll(cx)
|
538 543 | }
|
539 544 | }
|
540 545 |
|
541 546 | impl<B>
|
542 547 | ::aws_smithy_legacy_http_server::request::FromRequest<
|
543 548 | ::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0,
|
544 549 | B,
|
545 - | > for crate::input::OperationWithRequiredMembersInput
|
550 + | > for crate::input::SimpleScalarPropertiesInput
|
546 551 | where
|
547 552 | B: ::aws_smithy_legacy_http_server::body::HttpBody + Send,
|
548 553 | B: 'static,
|
549 554 |
|
550 555 | B::Data: Send,
|
551 556 | ::aws_smithy_legacy_http_server::protocol::aws_json::rejection::RequestRejection:
|
552 557 | From<<B as ::aws_smithy_legacy_http_server::body::HttpBody>::Error>,
|
553 558 | {
|
554 559 | type Rejection =
|
555 560 | ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError;
|
556 - | type Future = OperationWithRequiredMembersInputFuture;
|
561 + | type Future = SimpleScalarPropertiesInputFuture;
|
557 562 |
|
558 563 | fn from_request(request: ::http::Request<B>) -> Self::Future {
|
559 564 | let fut = async move {
|
560 565 | if !::aws_smithy_legacy_http_server::protocol::accept_header_classifier(
|
561 566 | request.headers(),
|
562 567 | &crate::mimes::CONTENT_TYPE_APPLICATION_X_AMZ_JSON_1_0,
|
563 568 | ) {
|
564 569 | return Err(::aws_smithy_legacy_http_server::protocol::aws_json::rejection::RequestRejection::NotAcceptable);
|
565 570 | }
|
566 - | crate::protocol_serde::shape_operation_with_required_members::de_operation_with_required_members_http_request(request)
|
571 + | crate::protocol_serde::shape_simple_scalar_properties::de_simple_scalar_properties_http_request(request)
|
567 572 | .await
|
568 573 | };
|
569 574 | use ::futures_util::future::TryFutureExt;
|
570 575 | let fut = fut.map_err(|e: ::aws_smithy_legacy_http_server::protocol::aws_json::rejection::RequestRejection| {
|
571 576 | ::tracing::debug!(error = %e, "failed to deserialize request");
|
572 577 | ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError::from(e)
|
573 578 | });
|
574 - | OperationWithRequiredMembersInputFuture {
|
579 + | SimpleScalarPropertiesInputFuture {
|
575 580 | inner: Box::pin(fut),
|
576 581 | }
|
577 582 | }
|
578 583 | }
|
579 584 | impl
|
580 585 | ::aws_smithy_legacy_http_server::response::IntoResponse<
|
581 586 | ::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0,
|
582 - | > for crate::output::OperationWithRequiredMembersOutput
|
587 + | > for crate::output::SimpleScalarPropertiesOutput
|
583 588 | {
|
584 589 | fn into_response(self) -> ::aws_smithy_legacy_http_server::response::Response {
|
585 - | match crate::protocol_serde::shape_operation_with_required_members::ser_operation_with_required_members_http_response(self) {
|
590 + | match crate::protocol_serde::shape_simple_scalar_properties::ser_simple_scalar_properties_http_response(self) {
|
586 591 | Ok(response) => response,
|
587 592 | Err(e) => {
|
588 593 | ::tracing::error!(error = %e, "failed to serialize response");
|
589 594 | ::aws_smithy_legacy_http_server::response::IntoResponse::<::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0>::into_response(::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError::from(e))
|
590 595 | }
|
591 596 | }
|
592 597 | }
|
593 598 | }
|
594 599 |
|
595 - | ::pin_project_lite::pin_project! {
|
596 - | /// A [`Future`](std::future::Future) aggregating the body bytes of a [`Request`] and constructing the
|
597 - | /// [`OperationWithDefaultsInput`](crate::input::OperationWithDefaultsInput) using modelled bindings.
|
598 - | pub struct OperationWithDefaultsInputFuture {
|
599 - | inner: std::pin::Pin<Box<dyn std::future::Future<Output = Result<crate::input::OperationWithDefaultsInput, ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError>> + Send>>
|
600 - | }
|
601 - | }
|
602 - |
|
603 - | impl std::future::Future for OperationWithDefaultsInputFuture {
|
604 - | type Output = Result<
|
605 - | crate::input::OperationWithDefaultsInput,
|
606 - | ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError,
|
607 - | >;
|
608 - |
|
609 - | fn poll(
|
610 - | self: std::pin::Pin<&mut Self>,
|
611 - | cx: &mut std::task::Context<'_>,
|
612 - | ) -> std::task::Poll<Self::Output> {
|
613 - | let this = self.project();
|
614 - | this.inner.as_mut().poll(cx)
|
615 - | }
|
616 - | }
|
617 - |
|
618 - | impl<B>
|
619 - | ::aws_smithy_legacy_http_server::request::FromRequest<
|
620 - | ::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0,
|
621 - | B,
|
622 - | > for crate::input::OperationWithDefaultsInput
|
623 - | where
|
624 - | B: ::aws_smithy_legacy_http_server::body::HttpBody + Send,
|
625 - | B: 'static,
|
600 + | #[allow(unreachable_code, unused_variables)]
|
601 + | #[cfg(test)]
|
602 + | mod simple_scalar_properties_test {
|
626 603 |
|
627 - | B::Data: Send,
|
628 - | ::aws_smithy_legacy_http_server::protocol::aws_json::rejection::RequestRejection:
|
629 - | From<<B as ::aws_smithy_legacy_http_server::body::HttpBody>::Error>,
|
630 - | {
|
631 - | type Rejection =
|
632 - | ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError;
|
633 - | type Future = OperationWithDefaultsInputFuture;
|
634 - |
|
635 - | fn from_request(request: ::http::Request<B>) -> Self::Future {
|
636 - | let fut = async move {
|
637 - | if !::aws_smithy_legacy_http_server::protocol::accept_header_classifier(
|
638 - | request.headers(),
|
639 - | &crate::mimes::CONTENT_TYPE_APPLICATION_X_AMZ_JSON_1_0,
|
640 - | ) {
|
641 - | return Err(::aws_smithy_legacy_http_server::protocol::aws_json::rejection::RequestRejection::NotAcceptable);
|
642 - | }
|
643 - | crate::protocol_serde::shape_operation_with_defaults::de_operation_with_defaults_http_request(request)
|
644 - | .await
|
645 - | };
|
646 - | use ::futures_util::future::TryFutureExt;
|
647 - | let fut = fut.map_err(|e: ::aws_smithy_legacy_http_server::protocol::aws_json::rejection::RequestRejection| {
|
648 - | ::tracing::debug!(error = %e, "failed to deserialize request");
|
649 - | ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError::from(e)
|
650 - | });
|
651 - | OperationWithDefaultsInputFuture {
|
652 - | inner: Box::pin(fut),
|
653 - | }
|
654 - | }
|
655 - | }
|
656 - | impl
|
657 - | ::aws_smithy_legacy_http_server::response::IntoResponse<
|
658 - | ::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0,
|
659 - | > for crate::output::OperationWithDefaultsOutput
|
660 - | {
|
661 - | fn into_response(self) -> ::aws_smithy_legacy_http_server::response::Response {
|
662 - | match crate::protocol_serde::shape_operation_with_defaults::ser_operation_with_defaults_http_response(self) {
|
663 - | Ok(response) => response,
|
664 - | Err(e) => {
|
665 - | ::tracing::error!(error = %e, "failed to serialize response");
|
666 - | ::aws_smithy_legacy_http_server::response::IntoResponse::<::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0>::into_response(::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError::from(e))
|
667 - | }
|
668 - | }
|
669 - | }
|
670 - | }
|
671 - | impl
|
672 - | ::aws_smithy_legacy_http_server::response::IntoResponse<
|
673 - | ::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0,
|
674 - | > for crate::error::OperationWithDefaultsError
|
675 - | {
|
676 - | fn into_response(self) -> ::aws_smithy_legacy_http_server::response::Response {
|
677 - | match crate::protocol_serde::shape_operation_with_defaults::ser_operation_with_defaults_http_error(&self) {
|
678 - | Ok(mut response) => {
|
679 - | response.extensions_mut().insert(::aws_smithy_legacy_http_server::extension::ModeledErrorExtension::new(self.name()));
|
680 - | response
|
681 - | },
|
682 - | Err(e) => {
|
683 - | ::tracing::error!(error = %e, "failed to serialize response");
|
684 - | ::aws_smithy_legacy_http_server::response::IntoResponse::<::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0>::into_response(::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError::from(e))
|
685 - | }
|
686 - | }
|
687 - | }
|
688 - | }
|
689 - |
|
690 - | #[allow(unreachable_code, unused_variables)]
|
691 - | #[cfg(test)]
|
692 - | mod operation_with_defaults_test {
|
693 - |
|
694 - | /// Server populates default values when missing in request body.
|
695 - | /// Test ID: AwsJson10ServerPopulatesDefaultsWhenMissingInRequestBody
|
604 + | /// Supports handling NaN float values.
|
605 + | /// Test ID: AwsJson10SupportsNaNFloatInputs
|
696 606 | #[::tokio::test]
|
697 607 | #[::tracing_test::traced_test]
|
698 - | #[should_panic]
|
699 - | async fn aws_json10_server_populates_defaults_when_missing_in_request_body_request() {
|
608 + | async fn aws_json10_supports_na_n_float_inputs_request() {
|
700 609 | #[allow(unused_mut)]
|
701 610 | let mut http_request = ::http::Request::builder()
|
702 611 | .uri("/")
|
703 612 | .method("POST")
|
704 613 | .header("Content-Type", "application/x-amz-json-1.0")
|
614 + | .header("X-Amz-Target", "JsonRpc10.SimpleScalarProperties")
|
705 615 | .body(::aws_smithy_legacy_http_server::body::Body::from(
|
706 616 | ::bytes::Bytes::copy_from_slice(&::aws_smithy_protocol_test::decode_body_data(
|
707 - | "{\n\"defaults\": {}\n}".as_bytes(),
|
617 + | "{\n \"floatValue\": \"NaN\",\n \"doubleValue\": \"NaN\"\n}".as_bytes(),
|
708 618 | ::aws_smithy_protocol_test::MediaType::from("application/json"),
|
709 619 | )),
|
710 620 | ))
|
711 621 | .unwrap();
|
712 622 | #[allow(unused_mut)]
|
713 623 | let (sender, mut receiver) = ::tokio::sync::mpsc::channel(1);
|
714 624 | let config = crate::service::JsonRpc10Config::builder().build();
|
715 625 | let service = crate::service::JsonRpc10::builder::<::hyper::body::Body, _, _, _>(config)
|
716 - | .operation_with_defaults(move |input: crate::input::OperationWithDefaultsInput| {
|
626 + | .simple_scalar_properties(move |input: crate::input::SimpleScalarPropertiesInput| {
|
717 627 | let sender = sender.clone();
|
718 628 | async move {
|
719 - | let result = {
|
720 - | let expected = crate::input::OperationWithDefaultsInput {
|
721 - | defaults: ::std::option::Option::Some(crate::model::Defaults {
|
722 - | default_string: "hi".to_owned(),
|
723 - | default_boolean: true,
|
724 - | default_list: vec![],
|
725 - | default_document_map: {
|
726 - | let json_bytes = br#"{}"#;
|
727 - | let mut tokens =
|
728 - | ::aws_smithy_json::deserialize::json_token_iter(json_bytes)
|
729 - | .peekable();
|
730 - | ::aws_smithy_json::deserialize::token::expect_document(
|
731 - | &mut tokens,
|
732 - | )
|
733 - | .expect("well formed json")
|
734 - | },
|
735 - | default_document_string: {
|
736 - | let json_bytes = br#""hi""#;
|
737 - | let mut tokens =
|
738 - | ::aws_smithy_json::deserialize::json_token_iter(json_bytes)
|
739 - | .peekable();
|
740 - | ::aws_smithy_json::deserialize::token::expect_document(
|
741 - | &mut tokens,
|
742 - | )
|
743 - | .expect("well formed json")
|
744 - | },
|
745 - | default_document_boolean: {
|
746 - | let json_bytes = br#"true"#;
|
747 - | let mut tokens =
|
748 - | ::aws_smithy_json::deserialize::json_token_iter(json_bytes)
|
749 - | .peekable();
|
750 - | ::aws_smithy_json::deserialize::token::expect_document(
|
751 - | &mut tokens,
|
752 - | )
|
753 - | .expect("well formed json")
|
754 - | },
|
755 - | default_document_list: {
|
756 - | let json_bytes = br#"[]"#;
|
757 - | let mut tokens =
|
758 - | ::aws_smithy_json::deserialize::json_token_iter(json_bytes)
|
759 - | .peekable();
|
760 - | ::aws_smithy_json::deserialize::token::expect_document(
|
761 - | &mut tokens,
|
629 + | let result = { use ::aws_smithy_protocol_test::FloatEquals;
|
630 + | let expected =
|
631 + | crate::input::SimpleScalarPropertiesInput {
|
632 + | float_value:
|
633 + | ::std::option::Option::Some(
|
634 + | <f32 as ::aws_smithy_types::primitive::Parse>::parse_smithy_primitive("NaN").expect("invalid string for number")
|
762 635 | )
|
763 - | .expect("well formed json")
|
764 - | },
|
765 - | default_timestamp:
|
766 - | ::aws_smithy_types::DateTime::from_fractional_secs(0, 0_f64),
|
767 - | default_blob: ::aws_smithy_types::Blob::new("abc"),
|
768 - | default_byte: 1,
|
769 - | default_short: 1,
|
770 - | default_integer: 10,
|
771 - | default_long: 100,
|
772 - | default_float: 1.0_f32,
|
773 - | default_double: 1.0_f64,
|
774 - | default_map: ::std::collections::HashMap::new(),
|
775 - | default_enum: "FOO"
|
776 - | .parse::<crate::model::TestEnum>()
|
777 - | .expect("static value validated to member"),
|
778 - | default_int_enum: 1,
|
779 - | empty_string: "".to_owned(),
|
780 - | false_boolean: false,
|
781 - | empty_blob: ::aws_smithy_types::Blob::new(""),
|
782 - | zero_byte: 0,
|
783 - | zero_short: 0,
|
784 - | zero_integer: 0,
|
785 - | zero_long: 0,
|
786 - | zero_float: 0.0_f32,
|
787 - | zero_double: 0.0_f64,
|
788 - | default_null_document: ::std::option::Option::Some({
|
789 - | let json_bytes = br#"null"#;
|
790 - | let mut tokens =
|
791 - | ::aws_smithy_json::deserialize::json_token_iter(json_bytes)
|
792 - | .peekable();
|
793 - | ::aws_smithy_json::deserialize::token::expect_document(
|
794 - | &mut tokens,
|
636 + | ,
|
637 + | double_value:
|
638 + | ::std::option::Option::Some(
|
639 + | <f64 as ::aws_smithy_types::primitive::Parse>::parse_smithy_primitive("NaN").expect("invalid string for number")
|
795 640 | )
|
796 - | .expect("well formed json")
|
797 - | }),
|
798 - | }),
|
799 - | top_level_default: "hi".to_owned(),
|
800 - | other_top_level_default: 0,
|
801 - | client_optional_defaults: ::std::option::Option::None,
|
802 - | };
|
803 - | ::pretty_assertions::assert_eq!(input, expected);
|
804 - | let output = crate::output::OperationWithDefaultsOutput {
|
805 - | default_string: "".to_owned(),
|
806 - | default_boolean: false,
|
807 - | default_list: vec![],
|
808 - | default_document_map: {
|
809 - | let json_bytes = br#"{}"#;
|
810 - | let mut tokens =
|
811 - | ::aws_smithy_json::deserialize::json_token_iter(json_bytes)
|
812 - | .peekable();
|
813 - | ::aws_smithy_json::deserialize::token::expect_document(&mut tokens)
|
814 - | .expect("well formed json")
|
815 - | },
|
816 - | default_document_string: {
|
817 - | let json_bytes = br#"{}"#;
|
818 - | let mut tokens =
|
819 - | ::aws_smithy_json::deserialize::json_token_iter(json_bytes)
|
820 - | .peekable();
|
821 - | ::aws_smithy_json::deserialize::token::expect_document(&mut tokens)
|
822 - | .expect("well formed json")
|
823 - | },
|
824 - | default_document_boolean: {
|
825 - | let json_bytes = br#"{}"#;
|
826 - | let mut tokens =
|
827 - | ::aws_smithy_json::deserialize::json_token_iter(json_bytes)
|
828 - | .peekable();
|
829 - | ::aws_smithy_json::deserialize::token::expect_document(&mut tokens)
|
830 - | .expect("well formed json")
|
831 - | },
|
832 - | default_document_list: {
|
833 - | let json_bytes = br#"{}"#;
|
834 - | let mut tokens =
|
835 - | ::aws_smithy_json::deserialize::json_token_iter(json_bytes)
|
836 - | .peekable();
|
837 - | ::aws_smithy_json::deserialize::token::expect_document(&mut tokens)
|
838 - | .expect("well formed json")
|
839 - | },
|
840 - | default_timestamp: ::aws_smithy_types::DateTime::from_fractional_secs(
|
841 - | 0, 0_f64,
|
842 - | ),
|
843 - | default_blob: ::aws_smithy_types::Blob::new(""),
|
844 - | default_byte: 0,
|
845 - | default_short: 0,
|
846 - | default_integer: 0,
|
847 - | default_long: 0,
|
848 - | default_float: 0_f32,
|
849 - | default_double: 0_f64,
|
850 - | default_map: ::std::collections::HashMap::new(),
|
851 - | default_enum: ""
|
852 - | .parse::<crate::model::TestEnum>()
|
853 - | .expect("static value validated to member"),
|
854 - | default_int_enum: 0,
|
855 - | empty_string: "".to_owned(),
|
856 - | false_boolean: false,
|
857 - | empty_blob: ::aws_smithy_types::Blob::new(""),
|
858 - | zero_byte: 0,
|
859 - | zero_short: 0,
|
860 - | zero_integer: 0,
|
861 - | zero_long: 0,
|
862 - | zero_float: 0_f32,
|
863 - | zero_double: 0_f64,
|
864 - | default_null_document: ::std::option::Option::Some({
|
865 - | let json_bytes = br#"null"#;
|
866 - | let mut tokens =
|
867 - | ::aws_smithy_json::deserialize::json_token_iter(json_bytes)
|
868 - | .peekable();
|
869 - | ::aws_smithy_json::deserialize::token::expect_document(&mut tokens)
|
870 - | .expect("well formed json")
|
871 - | }),
|
872 - | };
|
873 - | Ok(output)
|
874 - | };
|
641 + | ,
|
642 + | }
|
643 + | ;
|
644 + | assert!(input.float_value.float_equals(&expected.float_value),
|
645 + | "Unexpected value for `float_value` {:?} vs. {:?}", expected.float_value, input.float_value);
|
646 + | assert!(input.double_value.float_equals(&expected.double_value),
|
647 + | "Unexpected value for `double_value` {:?} vs. {:?}", expected.double_value, input.double_value);
|
648 + | let output =
|
649 + | crate::output::SimpleScalarPropertiesOutput {
|
650 + | float_value:
|
651 + | ::std::option::Option::None
|
652 + | ,
|
653 + | double_value:
|
654 + | ::std::option::Option::None
|
655 + | ,
|
656 + | }
|
657 + | ;
|
658 + | output };
|
875 659 | sender.send(()).await.expect("receiver dropped early");
|
876 660 | result
|
877 661 | }
|
878 662 | })
|
879 663 | .build_unchecked();
|
880 664 | let http_response = ::tower::ServiceExt::oneshot(service, http_request)
|
881 665 | .await
|
882 666 | .expect("unable to make an HTTP request");
|
883 667 | assert!(
|
884 668 | receiver.recv().await.is_some(),
|
885 669 | "we expected operation handler to be invoked but it was not entered"
|
886 670 | );
|
887 671 | }
|
888 672 |
|
889 - | /// Server populates default values in response when missing in params.
|
890 - | /// Test ID: AwsJson10ServerPopulatesDefaultsInResponseWhenMissingInParams
|
891 - | #[::tokio::test]
|
892 - | #[::tracing_test::traced_test]
|
893 - | #[should_panic]
|
894 - | async fn aws_json10_server_populates_defaults_in_response_when_missing_in_params_response() {
|
895 - | let output = crate::output::OperationWithDefaultsOutput {
|
896 - | default_string: "".to_owned(),
|
897 - | default_boolean: false,
|
898 - | default_list: vec![],
|
899 - | default_document_map: {
|
900 - | let json_bytes = br#"{}"#;
|
901 - | let mut tokens =
|
902 - | ::aws_smithy_json::deserialize::json_token_iter(json_bytes).peekable();
|
903 - | ::aws_smithy_json::deserialize::token::expect_document(&mut tokens)
|
904 - | .expect("well formed json")
|
905 - | },
|
906 - | default_document_string: {
|
907 - | let json_bytes = br#"{}"#;
|
908 - | let mut tokens =
|
909 - | ::aws_smithy_json::deserialize::json_token_iter(json_bytes).peekable();
|
910 - | ::aws_smithy_json::deserialize::token::expect_document(&mut tokens)
|
911 - | .expect("well formed json")
|
912 - | },
|
913 - | default_document_boolean: {
|
914 - | let json_bytes = br#"{}"#;
|
915 - | let mut tokens =
|
916 - | ::aws_smithy_json::deserialize::json_token_iter(json_bytes).peekable();
|
917 - | ::aws_smithy_json::deserialize::token::expect_document(&mut tokens)
|
918 - | .expect("well formed json")
|
919 - | },
|
920 - | default_document_list: {
|
921 - | let json_bytes = br#"{}"#;
|
922 - | let mut tokens =
|
923 - | ::aws_smithy_json::deserialize::json_token_iter(json_bytes).peekable();
|
924 - | ::aws_smithy_json::deserialize::token::expect_document(&mut tokens)
|
925 - | .expect("well formed json")
|
926 - | },
|
927 - | default_timestamp: ::aws_smithy_types::DateTime::from_fractional_secs(0, 0_f64),
|
928 - | default_blob: ::aws_smithy_types::Blob::new(""),
|
929 - | default_byte: 0,
|
930 - | default_short: 0,
|
931 - | default_integer: 0,
|
932 - | default_long: 0,
|
933 - | default_float: 0_f32,
|
934 - | default_double: 0_f64,
|
935 - | default_map: ::std::collections::HashMap::new(),
|
936 - | default_enum: ""
|
937 - | .parse::<crate::model::TestEnum>()
|
938 - | .expect("static value validated to member"),
|
939 - | default_int_enum: 0,
|
940 - | empty_string: "".to_owned(),
|
941 - | false_boolean: false,
|
942 - | empty_blob: ::aws_smithy_types::Blob::new(""),
|
943 - | zero_byte: 0,
|
944 - | zero_short: 0,
|
945 - | zero_integer: 0,
|
946 - | zero_long: 0,
|
947 - | zero_float: 0_f32,
|
948 - | zero_double: 0_f64,
|
949 - | default_null_document: ::std::option::Option::Some({
|
950 - | let json_bytes = br#"null"#;
|
951 - | let mut tokens =
|
952 - | ::aws_smithy_json::deserialize::json_token_iter(json_bytes).peekable();
|
953 - | ::aws_smithy_json::deserialize::token::expect_document(&mut tokens)
|
954 - | .expect("well formed json")
|
955 - | }),
|
956 - | };
|
957 - | use ::aws_smithy_legacy_http_server::response::IntoResponse;
|
958 - | let http_response = output.into_response();
|
959 - | ::pretty_assertions::assert_eq!(
|
960 - | ::http::StatusCode::from_u16(200).expect("invalid expected HTTP status code"),
|
961 - | http_response.status()
|
962 - | );
|
963 - | let expected_headers = [("Content-Type", "application/x-amz-json-1.0")];
|
964 - | ::aws_smithy_protocol_test::assert_ok(::aws_smithy_protocol_test::validate_headers(
|
965 - | http_response.headers(),
|
966 - | expected_headers,
|
967 - | ));
|
968 - | let body = ::hyper::body::to_bytes(http_response.into_body())
|
969 - | .await
|
970 - | .expect("unable to extract body to bytes");
|
971 - | ::aws_smithy_protocol_test::assert_ok(
|
972 - | ::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"))
|
973 - | );
|
974 - | }
|
975 - | }
|
976 - |
|
977 - | ::pin_project_lite::pin_project! {
|
978 - | /// A [`Future`](std::future::Future) aggregating the body bytes of a [`Request`] and constructing the
|
979 - | /// [`ContentTypeParametersInput`](crate::input::ContentTypeParametersInput) using modelled bindings.
|
980 - | pub struct ContentTypeParametersInputFuture {
|
981 - | inner: std::pin::Pin<Box<dyn std::future::Future<Output = Result<crate::input::ContentTypeParametersInput, ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError>> + Send>>
|
982 - | }
|
983 - | }
|
984 - |
|
985 - | impl std::future::Future for ContentTypeParametersInputFuture {
|
986 - | type Output = Result<
|
987 - | crate::input::ContentTypeParametersInput,
|
988 - | ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError,
|
989 - | >;
|
990 - |
|
991 - | fn poll(
|
992 - | self: std::pin::Pin<&mut Self>,
|
993 - | cx: &mut std::task::Context<'_>,
|
994 - | ) -> std::task::Poll<Self::Output> {
|
995 - | let this = self.project();
|
996 - | this.inner.as_mut().poll(cx)
|
997 - | }
|
998 - | }
|
999 - |
|
1000 - | impl<B>
|
1001 - | ::aws_smithy_legacy_http_server::request::FromRequest<
|
1002 - | ::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0,
|
1003 - | B,
|
1004 - | > for crate::input::ContentTypeParametersInput
|
1005 - | where
|
1006 - | B: ::aws_smithy_legacy_http_server::body::HttpBody + Send,
|
1007 - | B: 'static,
|
1008 - |
|
1009 - | B::Data: Send,
|
1010 - | ::aws_smithy_legacy_http_server::protocol::aws_json::rejection::RequestRejection:
|
1011 - | From<<B as ::aws_smithy_legacy_http_server::body::HttpBody>::Error>,
|
1012 - | {
|
1013 - | type Rejection =
|
1014 - | ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError;
|
1015 - | type Future = ContentTypeParametersInputFuture;
|
1016 - |
|
1017 - | fn from_request(request: ::http::Request<B>) -> Self::Future {
|
1018 - | let fut = async move {
|
1019 - | if !::aws_smithy_legacy_http_server::protocol::accept_header_classifier(
|
1020 - | request.headers(),
|
1021 - | &crate::mimes::CONTENT_TYPE_APPLICATION_X_AMZ_JSON_1_0,
|
1022 - | ) {
|
1023 - | return Err(::aws_smithy_legacy_http_server::protocol::aws_json::rejection::RequestRejection::NotAcceptable);
|
1024 - | }
|
1025 - | crate::protocol_serde::shape_content_type_parameters::de_content_type_parameters_http_request(request)
|
1026 - | .await
|
1027 - | };
|
1028 - | use ::futures_util::future::TryFutureExt;
|
1029 - | let fut = fut.map_err(|e: ::aws_smithy_legacy_http_server::protocol::aws_json::rejection::RequestRejection| {
|
1030 - | ::tracing::debug!(error = %e, "failed to deserialize request");
|
1031 - | ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError::from(e)
|
1032 - | });
|
1033 - | ContentTypeParametersInputFuture {
|
1034 - | inner: Box::pin(fut),
|
1035 - | }
|
1036 - | }
|
1037 - | }
|
1038 - | impl
|
1039 - | ::aws_smithy_legacy_http_server::response::IntoResponse<
|
1040 - | ::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0,
|
1041 - | > for crate::output::ContentTypeParametersOutput
|
1042 - | {
|
1043 - | fn into_response(self) -> ::aws_smithy_legacy_http_server::response::Response {
|
1044 - | match crate::protocol_serde::shape_content_type_parameters::ser_content_type_parameters_http_response(self) {
|
1045 - | Ok(response) => response,
|
1046 - | Err(e) => {
|
1047 - | ::tracing::error!(error = %e, "failed to serialize response");
|
1048 - | ::aws_smithy_legacy_http_server::response::IntoResponse::<::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0>::into_response(::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError::from(e))
|
1049 - | }
|
1050 - | }
|
1051 - | }
|
1052 - | }
|
1053 - |
|
1054 - | #[allow(unreachable_code, unused_variables)]
|
1055 - | #[cfg(test)]
|
1056 - | mod content_type_parameters_test {
|
1057 - |
|
1058 - | /// A server should ignore parameters added to the content type
|
1059 - | /// Test ID: AwsJson10MustSupportParametersInContentType
|
673 + | /// Supports handling Infinity float values.
|
674 + | /// Test ID: AwsJson10SupportsInfinityFloatInputs
|
1060 675 | #[::tokio::test]
|
1061 676 | #[::tracing_test::traced_test]
|
1062 - | async fn aws_json10_must_support_parameters_in_content_type_request() {
|
677 + | async fn aws_json10_supports_infinity_float_inputs_request() {
|
1063 678 | #[allow(unused_mut)]
|
1064 679 | let mut http_request = ::http::Request::builder()
|
1065 680 | .uri("/")
|
1066 681 | .method("POST")
|
1067 - | .header("Content-Type", "application/x-amz-json-1.0; charset=utf-8")
|
1068 - | .header("X-Amz-Target", "JsonRpc10.ContentTypeParameters")
|
682 + | .header("Content-Type", "application/x-amz-json-1.0")
|
683 + | .header("X-Amz-Target", "JsonRpc10.SimpleScalarProperties")
|
1069 684 | .body(::aws_smithy_legacy_http_server::body::Body::from(
|
1070 685 | ::bytes::Bytes::copy_from_slice(&::aws_smithy_protocol_test::decode_body_data(
|
1071 - | "{\"value\":5}".as_bytes(),
|
686 + | "{\n \"floatValue\": \"Infinity\",\n \"doubleValue\": \"Infinity\"\n}"
|
687 + | .as_bytes(),
|
1072 688 | ::aws_smithy_protocol_test::MediaType::from("application/json"),
|
1073 689 | )),
|
1074 690 | ))
|
1075 691 | .unwrap();
|
1076 692 | #[allow(unused_mut)]
|
1077 693 | let (sender, mut receiver) = ::tokio::sync::mpsc::channel(1);
|
1078 694 | let config = crate::service::JsonRpc10Config::builder().build();
|
1079 695 | let service = crate::service::JsonRpc10::builder::<::hyper::body::Body, _, _, _>(config)
|
1080 - | .content_type_parameters(move |input: crate::input::ContentTypeParametersInput| {
|
696 + | .simple_scalar_properties(move |input: crate::input::SimpleScalarPropertiesInput| {
|
1081 697 | let sender = sender.clone();
|
1082 698 | async move {
|
1083 - | let result = {
|
1084 - | let expected = crate::input::ContentTypeParametersInput {
|
1085 - | value: ::std::option::Option::Some(5),
|
1086 - | };
|
1087 - | ::pretty_assertions::assert_eq!(input, expected);
|
1088 - | let output = crate::output::ContentTypeParametersOutput {};
|
1089 - | output
|
1090 - | };
|
1091 - | sender.send(()).await.expect("receiver dropped early");
|
1092 - | result
|
1093 - | }
|
1094 - | })
|
1095 - | .build_unchecked();
|
1096 - | let http_response = ::tower::ServiceExt::oneshot(service, http_request)
|
1097 - | .await
|
1098 - | .expect("unable to make an HTTP request");
|
1099 - | assert!(
|
1100 - | receiver.recv().await.is_some(),
|
1101 - | "we expected operation handler to be invoked but it was not entered"
|
1102 - | );
|
1103 - | }
|
1104 - | }
|
1105 - |
|
1106 - | ::pin_project_lite::pin_project! {
|
1107 - | /// A [`Future`](std::future::Future) aggregating the body bytes of a [`Request`] and constructing the
|
1108 - | /// [`PutWithContentEncodingInput`](crate::input::PutWithContentEncodingInput) using modelled bindings.
|
1109 - | pub struct PutWithContentEncodingInputFuture {
|
1110 - | inner: std::pin::Pin<Box<dyn std::future::Future<Output = Result<crate::input::PutWithContentEncodingInput, ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError>> + Send>>
|
1111 - | }
|
1112 - | }
|
1113 - |
|
1114 - | impl std::future::Future for PutWithContentEncodingInputFuture {
|
1115 - | type Output = Result<
|
1116 - | crate::input::PutWithContentEncodingInput,
|
1117 - | ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError,
|
1118 - | >;
|
1119 - |
|
1120 - | fn poll(
|
1121 - | self: std::pin::Pin<&mut Self>,
|
1122 - | cx: &mut std::task::Context<'_>,
|
1123 - | ) -> std::task::Poll<Self::Output> {
|
1124 - | let this = self.project();
|
1125 - | this.inner.as_mut().poll(cx)
|
1126 - | }
|
1127 - | }
|
1128 - |
|
1129 - | impl<B>
|
1130 - | ::aws_smithy_legacy_http_server::request::FromRequest<
|
1131 - | ::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0,
|
1132 - | B,
|
1133 - | > for crate::input::PutWithContentEncodingInput
|
1134 - | where
|
1135 - | B: ::aws_smithy_legacy_http_server::body::HttpBody + Send,
|
1136 - | B: 'static,
|
1137 - |
|
1138 - | B::Data: Send,
|
1139 - | ::aws_smithy_legacy_http_server::protocol::aws_json::rejection::RequestRejection:
|
1140 - | From<<B as ::aws_smithy_legacy_http_server::body::HttpBody>::Error>,
|
1141 - | {
|
1142 - | type Rejection =
|
1143 - | ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError;
|
1144 - | type Future = PutWithContentEncodingInputFuture;
|
1145 - |
|
1146 - | fn from_request(request: ::http::Request<B>) -> Self::Future {
|
1147 - | let fut = async move {
|
1148 - | if !::aws_smithy_legacy_http_server::protocol::accept_header_classifier(
|
1149 - | request.headers(),
|
1150 - | &crate::mimes::CONTENT_TYPE_APPLICATION_X_AMZ_JSON_1_0,
|
1151 - | ) {
|
1152 - | return Err(::aws_smithy_legacy_http_server::protocol::aws_json::rejection::RequestRejection::NotAcceptable);
|
1153 - | }
|
1154 - | crate::protocol_serde::shape_put_with_content_encoding::de_put_with_content_encoding_http_request(request)
|
1155 - | .await
|
1156 - | };
|
1157 - | use ::futures_util::future::TryFutureExt;
|
1158 - | let fut = fut.map_err(|e: ::aws_smithy_legacy_http_server::protocol::aws_json::rejection::RequestRejection| {
|
1159 - | ::tracing::debug!(error = %e, "failed to deserialize request");
|
1160 - | ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError::from(e)
|
1161 - | });
|
1162 - | PutWithContentEncodingInputFuture {
|
1163 - | inner: Box::pin(fut),
|
1164 - | }
|
1165 - | }
|
1166 - | }
|
1167 - | impl
|
1168 - | ::aws_smithy_legacy_http_server::response::IntoResponse<
|
1169 - | ::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0,
|
1170 - | > for crate::output::PutWithContentEncodingOutput
|
1171 - | {
|
1172 - | fn into_response(self) -> ::aws_smithy_legacy_http_server::response::Response {
|
1173 - | match crate::protocol_serde::shape_put_with_content_encoding::ser_put_with_content_encoding_http_response(self) {
|
1174 - | Ok(response) => response,
|
1175 - | Err(e) => {
|
1176 - | ::tracing::error!(error = %e, "failed to serialize response");
|
1177 - | ::aws_smithy_legacy_http_server::response::IntoResponse::<::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0>::into_response(::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError::from(e))
|
1178 - | }
|
1179 - | }
|
1180 - | }
|
1181 - | }
|
1182 - |
|
1183 - | ::pin_project_lite::pin_project! {
|
1184 - | /// A [`Future`](std::future::Future) aggregating the body bytes of a [`Request`] and constructing the
|
1185 - | /// [`HostWithPathOperationInput`](crate::input::HostWithPathOperationInput) using modelled bindings.
|
1186 - | pub struct HostWithPathOperationInputFuture {
|
1187 - | inner: std::pin::Pin<Box<dyn std::future::Future<Output = Result<crate::input::HostWithPathOperationInput, ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError>> + Send>>
|
1188 - | }
|
1189 - | }
|
1190 - |
|
1191 - | impl std::future::Future for HostWithPathOperationInputFuture {
|
1192 - | type Output = Result<
|
1193 - | crate::input::HostWithPathOperationInput,
|
1194 - | ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError,
|
1195 - | >;
|
1196 - |
|
1197 - | fn poll(
|
1198 - | self: std::pin::Pin<&mut Self>,
|
1199 - | cx: &mut std::task::Context<'_>,
|
1200 - | ) -> std::task::Poll<Self::Output> {
|
1201 - | let this = self.project();
|
1202 - | this.inner.as_mut().poll(cx)
|
1203 - | }
|
1204 - | }
|
1205 - |
|
1206 - | impl<B>
|
1207 - | ::aws_smithy_legacy_http_server::request::FromRequest<
|
1208 - | ::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0,
|
1209 - | B,
|
1210 - | > for crate::input::HostWithPathOperationInput
|
1211 - | where
|
1212 - | B: ::aws_smithy_legacy_http_server::body::HttpBody + Send,
|
1213 - | B: 'static,
|
1214 - |
|
1215 - | B::Data: Send,
|
1216 - | ::aws_smithy_legacy_http_server::protocol::aws_json::rejection::RequestRejection:
|
1217 - | From<<B as ::aws_smithy_legacy_http_server::body::HttpBody>::Error>,
|
1218 - | {
|
1219 - | type Rejection =
|
1220 - | ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError;
|
1221 - | type Future = HostWithPathOperationInputFuture;
|
1222 - |
|
1223 - | fn from_request(request: ::http::Request<B>) -> Self::Future {
|
1224 - | let fut = async move {
|
1225 - | if !::aws_smithy_legacy_http_server::protocol::accept_header_classifier(
|
1226 - | request.headers(),
|
1227 - | &crate::mimes::CONTENT_TYPE_APPLICATION_X_AMZ_JSON_1_0,
|
1228 - | ) {
|
1229 - | return Err(::aws_smithy_legacy_http_server::protocol::aws_json::rejection::RequestRejection::NotAcceptable);
|
1230 - | }
|
1231 - | crate::protocol_serde::shape_host_with_path_operation::de_host_with_path_operation_http_request(request)
|
1232 - | .await
|
1233 - | };
|
1234 - | use ::futures_util::future::TryFutureExt;
|
1235 - | let fut = fut.map_err(|e: ::aws_smithy_legacy_http_server::protocol::aws_json::rejection::RequestRejection| {
|
1236 - | ::tracing::debug!(error = %e, "failed to deserialize request");
|
1237 - | ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError::from(e)
|
1238 - | });
|
1239 - | HostWithPathOperationInputFuture {
|
1240 - | inner: Box::pin(fut),
|
1241 - | }
|
1242 - | }
|
1243 - | }
|
1244 - | impl
|
1245 - | ::aws_smithy_legacy_http_server::response::IntoResponse<
|
1246 - | ::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0,
|
1247 - | > for crate::output::HostWithPathOperationOutput
|
1248 - | {
|
1249 - | fn into_response(self) -> ::aws_smithy_legacy_http_server::response::Response {
|
1250 - | match crate::protocol_serde::shape_host_with_path_operation::ser_host_with_path_operation_http_response(self) {
|
1251 - | Ok(response) => response,
|
1252 - | Err(e) => {
|
1253 - | ::tracing::error!(error = %e, "failed to serialize response");
|
1254 - | ::aws_smithy_legacy_http_server::response::IntoResponse::<::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0>::into_response(::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError::from(e))
|
1255 - | }
|
1256 - | }
|
1257 - | }
|
1258 - | }
|
1259 - |
|
1260 - | ::pin_project_lite::pin_project! {
|
1261 - | /// A [`Future`](std::future::Future) aggregating the body bytes of a [`Request`] and constructing the
|
1262 - | /// [`EndpointWithHostLabelOperationInput`](crate::input::EndpointWithHostLabelOperationInput) using modelled bindings.
|
1263 - | pub struct EndpointWithHostLabelOperationInputFuture {
|
1264 - | inner: std::pin::Pin<Box<dyn std::future::Future<Output = Result<crate::input::EndpointWithHostLabelOperationInput, ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError>> + Send>>
|
1265 - | }
|
1266 - | }
|
1267 - |
|
1268 - | impl std::future::Future for EndpointWithHostLabelOperationInputFuture {
|
1269 - | type Output = Result<
|
1270 - | crate::input::EndpointWithHostLabelOperationInput,
|
1271 - | ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError,
|
1272 - | >;
|
1273 - |
|
1274 - | fn poll(
|
1275 - | self: std::pin::Pin<&mut Self>,
|
1276 - | cx: &mut std::task::Context<'_>,
|
1277 - | ) -> std::task::Poll<Self::Output> {
|
1278 - | let this = self.project();
|
1279 - | this.inner.as_mut().poll(cx)
|
1280 - | }
|
1281 - | }
|
1282 - |
|
1283 - | impl<B>
|
1284 - | ::aws_smithy_legacy_http_server::request::FromRequest<
|
1285 - | ::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0,
|
1286 - | B,
|
1287 - | > for crate::input::EndpointWithHostLabelOperationInput
|
1288 - | where
|
1289 - | B: ::aws_smithy_legacy_http_server::body::HttpBody + Send,
|
1290 - | B: 'static,
|
1291 - |
|
1292 - | B::Data: Send,
|
1293 - | ::aws_smithy_legacy_http_server::protocol::aws_json::rejection::RequestRejection:
|
1294 - | From<<B as ::aws_smithy_legacy_http_server::body::HttpBody>::Error>,
|
1295 - | {
|
1296 - | type Rejection =
|
1297 - | ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError;
|
1298 - | type Future = EndpointWithHostLabelOperationInputFuture;
|
1299 - |
|
1300 - | fn from_request(request: ::http::Request<B>) -> Self::Future {
|
1301 - | let fut = async move {
|
1302 - | if !::aws_smithy_legacy_http_server::protocol::accept_header_classifier(
|
1303 - | request.headers(),
|
1304 - | &crate::mimes::CONTENT_TYPE_APPLICATION_X_AMZ_JSON_1_0,
|
1305 - | ) {
|
1306 - | return Err(::aws_smithy_legacy_http_server::protocol::aws_json::rejection::RequestRejection::NotAcceptable);
|
1307 - | }
|
1308 - | crate::protocol_serde::shape_endpoint_with_host_label_operation::de_endpoint_with_host_label_operation_http_request(request)
|
1309 - | .await
|
1310 - | };
|
1311 - | use ::futures_util::future::TryFutureExt;
|
1312 - | let fut = fut.map_err(|e: ::aws_smithy_legacy_http_server::protocol::aws_json::rejection::RequestRejection| {
|
1313 - | ::tracing::debug!(error = %e, "failed to deserialize request");
|
1314 - | ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError::from(e)
|
1315 - | });
|
1316 - | EndpointWithHostLabelOperationInputFuture {
|
1317 - | inner: Box::pin(fut),
|
1318 - | }
|
1319 - | }
|
1320 - | }
|
1321 - | impl
|
1322 - | ::aws_smithy_legacy_http_server::response::IntoResponse<
|
1323 - | ::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0,
|
1324 - | > for crate::output::EndpointWithHostLabelOperationOutput
|
1325 - | {
|
1326 - | fn into_response(self) -> ::aws_smithy_legacy_http_server::response::Response {
|
1327 - | match crate::protocol_serde::shape_endpoint_with_host_label_operation::ser_endpoint_with_host_label_operation_http_response(self) {
|
1328 - | Ok(response) => response,
|
1329 - | Err(e) => {
|
1330 - | ::tracing::error!(error = %e, "failed to serialize response");
|
1331 - | ::aws_smithy_legacy_http_server::response::IntoResponse::<::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0>::into_response(::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError::from(e))
|
1332 - | }
|
1333 - | }
|
699 + | let result = { use ::aws_smithy_protocol_test::FloatEquals;
|
700 + | let expected =
|
701 + | crate::input::SimpleScalarPropertiesInput {
|
702 + | float_value:
|
703 + | ::std::option::Option::Some(
|
704 + | <f32 as ::aws_smithy_types::primitive::Parse>::parse_smithy_primitive("Infinity").expect("invalid string for number")
|
705 + | )
|
706 + | ,
|
707 + | double_value:
|
708 + | ::std::option::Option::Some(
|
709 + | <f64 as ::aws_smithy_types::primitive::Parse>::parse_smithy_primitive("Infinity").expect("invalid string for number")
|
710 + | )
|
711 + | ,
|
1334 712 | }
|
1335 - | }
|
1336 - | impl
|
1337 - | ::aws_smithy_legacy_http_server::response::IntoResponse<
|
1338 - | ::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0,
|
1339 - | > for crate::error::EndpointWithHostLabelOperationError
|
1340 - | {
|
1341 - | fn into_response(self) -> ::aws_smithy_legacy_http_server::response::Response {
|
1342 - | match crate::protocol_serde::shape_endpoint_with_host_label_operation::ser_endpoint_with_host_label_operation_http_error(&self) {
|
1343 - | Ok(mut response) => {
|
1344 - | response.extensions_mut().insert(::aws_smithy_legacy_http_server::extension::ModeledErrorExtension::new(self.name()));
|
1345 - | response
|
1346 - | },
|
1347 - | Err(e) => {
|
1348 - | ::tracing::error!(error = %e, "failed to serialize response");
|
1349 - | ::aws_smithy_legacy_http_server::response::IntoResponse::<::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0>::into_response(::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError::from(e))
|
713 + | ;
|
714 + | assert!(input.float_value.float_equals(&expected.float_value),
|
715 + | "Unexpected value for `float_value` {:?} vs. {:?}", expected.float_value, input.float_value);
|
716 + | assert!(input.double_value.float_equals(&expected.double_value),
|
717 + | "Unexpected value for `double_value` {:?} vs. {:?}", expected.double_value, input.double_value);
|
718 + | let output =
|
719 + | crate::output::SimpleScalarPropertiesOutput {
|
720 + | float_value:
|
721 + | ::std::option::Option::None
|
722 + | ,
|
723 + | double_value:
|
724 + | ::std::option::Option::None
|
725 + | ,
|
1350 726 | }
|
727 + | ;
|
728 + | output };
|
729 + | sender.send(()).await.expect("receiver dropped early");
|
730 + | result
|
1351 731 | }
|
732 + | })
|
733 + | .build_unchecked();
|
734 + | let http_response = ::tower::ServiceExt::oneshot(service, http_request)
|
735 + | .await
|
736 + | .expect("unable to make an HTTP request");
|
737 + | assert!(
|
738 + | receiver.recv().await.is_some(),
|
739 + | "we expected operation handler to be invoked but it was not entered"
|
740 + | );
|
1352 741 | }
|
1353 - | }
|
1354 742 |
|
1355 - | #[allow(unreachable_code, unused_variables)]
|
1356 - | #[cfg(test)]
|
1357 - | mod endpoint_with_host_label_operation_test {
|
1358 - |
|
1359 - | /// Operations can prepend to the given host if they define the
|
1360 - | /// endpoint trait, and can use the host label trait to define
|
1361 - | /// further customization based on user input.
|
1362 - | /// Test ID: AwsJson10EndpointTraitWithHostLabel
|
743 + | /// Supports handling -Infinity float values.
|
744 + | /// Test ID: AwsJson10SupportsNegativeInfinityFloatInputs
|
1363 745 | #[::tokio::test]
|
1364 746 | #[::tracing_test::traced_test]
|
1365 - | #[should_panic]
|
1366 - | async fn aws_json10_endpoint_trait_with_host_label_request() {
|
747 + | async fn aws_json10_supports_negative_infinity_float_inputs_request() {
|
1367 748 | #[allow(unused_mut)]
|
1368 749 | let mut http_request = ::http::Request::builder()
|
1369 750 | .uri("/")
|
1370 751 | .method("POST")
|
752 + | .header("Content-Type", "application/x-amz-json-1.0")
|
753 + | .header("X-Amz-Target", "JsonRpc10.SimpleScalarProperties")
|
1371 754 | .body(::aws_smithy_legacy_http_server::body::Body::from(
|
1372 755 | ::bytes::Bytes::copy_from_slice(&::aws_smithy_protocol_test::decode_body_data(
|
1373 - | "{\"label\": \"bar\"}".as_bytes(),
|
756 + | "{\n \"floatValue\": \"-Infinity\",\n \"doubleValue\": \"-Infinity\"\n}"
|
757 + | .as_bytes(),
|
1374 758 | ::aws_smithy_protocol_test::MediaType::from("application/json"),
|
1375 759 | )),
|
1376 760 | ))
|
1377 761 | .unwrap();
|
1378 - | todo!("endpoint trait not supported yet");
|
1379 762 | #[allow(unused_mut)]
|
1380 763 | let (sender, mut receiver) = ::tokio::sync::mpsc::channel(1);
|
1381 764 | let config = crate::service::JsonRpc10Config::builder().build();
|
1382 765 | let service = crate::service::JsonRpc10::builder::<::hyper::body::Body, _, _, _>(config)
|
1383 - | .endpoint_with_host_label_operation(
|
1384 - | move |input: crate::input::EndpointWithHostLabelOperationInput| {
|
766 + | .simple_scalar_properties(move |input: crate::input::SimpleScalarPropertiesInput| {
|
1385 767 | let sender = sender.clone();
|
1386 768 | async move {
|
1387 - | let result = {
|
1388 - | let expected = crate::input::EndpointWithHostLabelOperationInput {
|
1389 - | label: "bar".to_owned(),
|
1390 - | };
|
1391 - | ::pretty_assertions::assert_eq!(input, expected);
|
1392 - | let output = crate::output::EndpointWithHostLabelOperationOutput {};
|
1393 - | Ok(output)
|
1394 - | };
|
769 + | let result = { use ::aws_smithy_protocol_test::FloatEquals;
|
770 + | let expected =
|
771 + | crate::input::SimpleScalarPropertiesInput {
|
772 + | float_value:
|
773 + | ::std::option::Option::Some(
|
774 + | <f32 as ::aws_smithy_types::primitive::Parse>::parse_smithy_primitive("-Infinity").expect("invalid string for number")
|
775 + | )
|
776 + | ,
|
777 + | double_value:
|
778 + | ::std::option::Option::Some(
|
779 + | <f64 as ::aws_smithy_types::primitive::Parse>::parse_smithy_primitive("-Infinity").expect("invalid string for number")
|
780 + | )
|
781 + | ,
|
782 + | }
|
783 + | ;
|
784 + | assert!(input.float_value.float_equals(&expected.float_value),
|
785 + | "Unexpected value for `float_value` {:?} vs. {:?}", expected.float_value, input.float_value);
|
786 + | assert!(input.double_value.float_equals(&expected.double_value),
|
787 + | "Unexpected value for `double_value` {:?} vs. {:?}", expected.double_value, input.double_value);
|
788 + | let output =
|
789 + | crate::output::SimpleScalarPropertiesOutput {
|
790 + | float_value:
|
791 + | ::std::option::Option::None
|
792 + | ,
|
793 + | double_value:
|
794 + | ::std::option::Option::None
|
795 + | ,
|
796 + | }
|
797 + | ;
|
798 + | output };
|
1395 799 | sender.send(()).await.expect("receiver dropped early");
|
1396 800 | result
|
1397 801 | }
|
1398 - | },
|
1399 - | )
|
802 + | })
|
1400 803 | .build_unchecked();
|
1401 804 | let http_response = ::tower::ServiceExt::oneshot(service, http_request)
|
1402 805 | .await
|
1403 806 | .expect("unable to make an HTTP request");
|
1404 807 | assert!(
|
1405 808 | receiver.recv().await.is_some(),
|
1406 809 | "we expected operation handler to be invoked but it was not entered"
|
1407 810 | );
|
1408 811 | }
|
812 + |
|
813 + | /// Supports handling NaN float values.
|
814 + | /// Test ID: AwsJson10SupportsNaNFloatInputs
|
815 + | #[::tokio::test]
|
816 + | #[::tracing_test::traced_test]
|
817 + | async fn aws_json10_supports_na_n_float_inputs_response() {
|
818 + | let output = crate::output::SimpleScalarPropertiesOutput {
|
819 + | float_value: ::std::option::Option::Some(
|
820 + | <f32 as ::aws_smithy_types::primitive::Parse>::parse_smithy_primitive("NaN")
|
821 + | .expect("invalid string for number"),
|
822 + | ),
|
823 + | double_value: ::std::option::Option::Some(
|
824 + | <f64 as ::aws_smithy_types::primitive::Parse>::parse_smithy_primitive("NaN")
|
825 + | .expect("invalid string for number"),
|
826 + | ),
|
827 + | };
|
828 + | use ::aws_smithy_legacy_http_server::response::IntoResponse;
|
829 + | let http_response = output.into_response();
|
830 + | ::pretty_assertions::assert_eq!(
|
831 + | ::http::StatusCode::from_u16(200).expect("invalid expected HTTP status code"),
|
832 + | http_response.status()
|
833 + | );
|
834 + | let expected_headers = [("Content-Type", "application/x-amz-json-1.0")];
|
835 + | ::aws_smithy_protocol_test::assert_ok(::aws_smithy_protocol_test::validate_headers(
|
836 + | http_response.headers(),
|
837 + | expected_headers,
|
838 + | ));
|
839 + | let body = ::hyper::body::to_bytes(http_response.into_body())
|
840 + | .await
|
841 + | .expect("unable to extract body to bytes");
|
842 + | ::aws_smithy_protocol_test::assert_ok(::aws_smithy_protocol_test::validate_body(
|
843 + | &body,
|
844 + | "{\n \"floatValue\": \"NaN\",\n \"doubleValue\": \"NaN\"\n}",
|
845 + | ::aws_smithy_protocol_test::MediaType::from("application/json"),
|
846 + | ));
|
847 + | }
|
848 + |
|
849 + | /// Supports handling Infinity float values.
|
850 + | /// Test ID: AwsJson10SupportsInfinityFloatInputs
|
851 + | #[::tokio::test]
|
852 + | #[::tracing_test::traced_test]
|
853 + | async fn aws_json10_supports_infinity_float_inputs_response() {
|
854 + | let output = crate::output::SimpleScalarPropertiesOutput {
|
855 + | float_value: ::std::option::Option::Some(
|
856 + | <f32 as ::aws_smithy_types::primitive::Parse>::parse_smithy_primitive("Infinity")
|
857 + | .expect("invalid string for number"),
|
858 + | ),
|
859 + | double_value: ::std::option::Option::Some(
|
860 + | <f64 as ::aws_smithy_types::primitive::Parse>::parse_smithy_primitive("Infinity")
|
861 + | .expect("invalid string for number"),
|
862 + | ),
|
863 + | };
|
864 + | use ::aws_smithy_legacy_http_server::response::IntoResponse;
|
865 + | let http_response = output.into_response();
|
866 + | ::pretty_assertions::assert_eq!(
|
867 + | ::http::StatusCode::from_u16(200).expect("invalid expected HTTP status code"),
|
868 + | http_response.status()
|
869 + | );
|
870 + | let expected_headers = [("Content-Type", "application/x-amz-json-1.0")];
|
871 + | ::aws_smithy_protocol_test::assert_ok(::aws_smithy_protocol_test::validate_headers(
|
872 + | http_response.headers(),
|
873 + | expected_headers,
|
874 + | ));
|
875 + | let body = ::hyper::body::to_bytes(http_response.into_body())
|
876 + | .await
|
877 + | .expect("unable to extract body to bytes");
|
878 + | ::aws_smithy_protocol_test::assert_ok(::aws_smithy_protocol_test::validate_body(
|
879 + | &body,
|
880 + | "{\n \"floatValue\": \"Infinity\",\n \"doubleValue\": \"Infinity\"\n}",
|
881 + | ::aws_smithy_protocol_test::MediaType::from("application/json"),
|
882 + | ));
|
883 + | }
|
884 + |
|
885 + | /// Supports handling -Infinity float values.
|
886 + | /// Test ID: AwsJson10SupportsNegativeInfinityFloatInputs
|
887 + | #[::tokio::test]
|
888 + | #[::tracing_test::traced_test]
|
889 + | async fn aws_json10_supports_negative_infinity_float_inputs_response() {
|
890 + | let output = crate::output::SimpleScalarPropertiesOutput {
|
891 + | float_value: ::std::option::Option::Some(
|
892 + | <f32 as ::aws_smithy_types::primitive::Parse>::parse_smithy_primitive("-Infinity")
|
893 + | .expect("invalid string for number"),
|
894 + | ),
|
895 + | double_value: ::std::option::Option::Some(
|
896 + | <f64 as ::aws_smithy_types::primitive::Parse>::parse_smithy_primitive("-Infinity")
|
897 + | .expect("invalid string for number"),
|
898 + | ),
|
899 + | };
|
900 + | use ::aws_smithy_legacy_http_server::response::IntoResponse;
|
901 + | let http_response = output.into_response();
|
902 + | ::pretty_assertions::assert_eq!(
|
903 + | ::http::StatusCode::from_u16(200).expect("invalid expected HTTP status code"),
|
904 + | http_response.status()
|
905 + | );
|
906 + | let expected_headers = [("Content-Type", "application/x-amz-json-1.0")];
|
907 + | ::aws_smithy_protocol_test::assert_ok(::aws_smithy_protocol_test::validate_headers(
|
908 + | http_response.headers(),
|
909 + | expected_headers,
|
910 + | ));
|
911 + | let body = ::hyper::body::to_bytes(http_response.into_body())
|
912 + | .await
|
913 + | .expect("unable to extract body to bytes");
|
914 + | ::aws_smithy_protocol_test::assert_ok(::aws_smithy_protocol_test::validate_body(
|
915 + | &body,
|
916 + | "{\n \"floatValue\": \"-Infinity\",\n \"doubleValue\": \"-Infinity\"\n}",
|
917 + | ::aws_smithy_protocol_test::MediaType::from("application/json"),
|
918 + | ));
|
919 + | }
|
1409 920 | }
|
1410 921 |
|
1411 922 | ::pin_project_lite::pin_project! {
|
1412 923 | /// A [`Future`](std::future::Future) aggregating the body bytes of a [`Request`] and constructing the
|
1413 - | /// [`EndpointOperationInput`](crate::input::EndpointOperationInput) using modelled bindings.
|
1414 - | pub struct EndpointOperationInputFuture {
|
1415 - | inner: std::pin::Pin<Box<dyn std::future::Future<Output = Result<crate::input::EndpointOperationInput, ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError>> + Send>>
|
924 + | /// [`GreetingWithErrorsInput`](crate::input::GreetingWithErrorsInput) using modelled bindings.
|
925 + | pub struct GreetingWithErrorsInputFuture {
|
926 + | inner: std::pin::Pin<Box<dyn std::future::Future<Output = Result<crate::input::GreetingWithErrorsInput, ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError>> + Send>>
|
1416 927 | }
|
1417 928 | }
|
1418 929 |
|
1419 - | impl std::future::Future for EndpointOperationInputFuture {
|
930 + | impl std::future::Future for GreetingWithErrorsInputFuture {
|
1420 931 | type Output = Result<
|
1421 - | crate::input::EndpointOperationInput,
|
932 + | crate::input::GreetingWithErrorsInput,
|
1422 933 | ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError,
|
1423 934 | >;
|
1424 935 |
|
1425 936 | fn poll(
|
1426 937 | self: std::pin::Pin<&mut Self>,
|
1427 938 | cx: &mut std::task::Context<'_>,
|
1428 939 | ) -> std::task::Poll<Self::Output> {
|
1429 940 | let this = self.project();
|
1430 941 | this.inner.as_mut().poll(cx)
|
1431 942 | }
|
1432 943 | }
|
1433 944 |
|
1434 945 | impl<B>
|
1435 946 | ::aws_smithy_legacy_http_server::request::FromRequest<
|
1436 947 | ::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0,
|
1437 948 | B,
|
1438 - | > for crate::input::EndpointOperationInput
|
949 + | > for crate::input::GreetingWithErrorsInput
|
1439 950 | where
|
1440 951 | B: ::aws_smithy_legacy_http_server::body::HttpBody + Send,
|
1441 952 | B: 'static,
|
1442 953 |
|
1443 954 | B::Data: Send,
|
1444 955 | ::aws_smithy_legacy_http_server::protocol::aws_json::rejection::RequestRejection:
|
1445 956 | From<<B as ::aws_smithy_legacy_http_server::body::HttpBody>::Error>,
|
1446 957 | {
|
1447 958 | type Rejection =
|
1448 959 | ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError;
|
1449 - | type Future = EndpointOperationInputFuture;
|
960 + | type Future = GreetingWithErrorsInputFuture;
|
1450 961 |
|
1451 962 | fn from_request(request: ::http::Request<B>) -> Self::Future {
|
1452 963 | let fut = async move {
|
1453 964 | if !::aws_smithy_legacy_http_server::protocol::accept_header_classifier(
|
1454 965 | request.headers(),
|
1455 966 | &crate::mimes::CONTENT_TYPE_APPLICATION_X_AMZ_JSON_1_0,
|
1456 967 | ) {
|
1457 968 | return Err(::aws_smithy_legacy_http_server::protocol::aws_json::rejection::RequestRejection::NotAcceptable);
|
1458 969 | }
|
1459 - | crate::protocol_serde::shape_endpoint_operation::de_endpoint_operation_http_request(
|
970 + | crate::protocol_serde::shape_greeting_with_errors::de_greeting_with_errors_http_request(
|
1460 971 | request,
|
1461 972 | )
|
1462 973 | .await
|
1463 974 | };
|
1464 975 | use ::futures_util::future::TryFutureExt;
|
1465 976 | let fut = fut.map_err(|e: ::aws_smithy_legacy_http_server::protocol::aws_json::rejection::RequestRejection| {
|
1466 977 | ::tracing::debug!(error = %e, "failed to deserialize request");
|
1467 978 | ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError::from(e)
|
1468 979 | });
|
1469 - | EndpointOperationInputFuture {
|
980 + | GreetingWithErrorsInputFuture {
|
1470 981 | inner: Box::pin(fut),
|
1471 982 | }
|
1472 983 | }
|
1473 984 | }
|
1474 985 | impl
|
1475 986 | ::aws_smithy_legacy_http_server::response::IntoResponse<
|
1476 987 | ::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0,
|
1477 - | > for crate::output::EndpointOperationOutput
|
988 + | > for crate::output::GreetingWithErrorsOutput
|
1478 989 | {
|
1479 990 | fn into_response(self) -> ::aws_smithy_legacy_http_server::response::Response {
|
1480 - | match crate::protocol_serde::shape_endpoint_operation::ser_endpoint_operation_http_response(
|
1481 - | self,
|
991 + | match crate::protocol_serde::shape_greeting_with_errors::ser_greeting_with_errors_http_response(self) {
|
992 + | Ok(response) => response,
|
993 + | Err(e) => {
|
994 + | ::tracing::error!(error = %e, "failed to serialize response");
|
995 + | ::aws_smithy_legacy_http_server::response::IntoResponse::<::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0>::into_response(::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError::from(e))
|
996 + | }
|
997 + | }
|
998 + | }
|
999 + | }
|
1000 + | impl
|
1001 + | ::aws_smithy_legacy_http_server::response::IntoResponse<
|
1002 + | ::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0,
|
1003 + | > for crate::error::GreetingWithErrorsError
|
1004 + | {
|
1005 + | fn into_response(self) -> ::aws_smithy_legacy_http_server::response::Response {
|
1006 + | match crate::protocol_serde::shape_greeting_with_errors::ser_greeting_with_errors_http_error(
|
1007 + | &self,
|
1482 1008 | ) {
|
1483 - | Ok(response) => response,
|
1009 + | Ok(mut response) => {
|
1010 + | response.extensions_mut().insert(
|
1011 + | ::aws_smithy_legacy_http_server::extension::ModeledErrorExtension::new(
|
1012 + | self.name(),
|
1013 + | ),
|
1014 + | );
|
1015 + | response
|
1016 + | }
|
1484 1017 | Err(e) => {
|
1485 1018 | ::tracing::error!(error = %e, "failed to serialize response");
|
1486 1019 | ::aws_smithy_legacy_http_server::response::IntoResponse::<::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0>::into_response(::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError::from(e))
|
1487 1020 | }
|
1488 1021 | }
|
1489 1022 | }
|
1490 1023 | }
|
1491 1024 |
|
1492 1025 | #[allow(unreachable_code, unused_variables)]
|
1493 1026 | #[cfg(test)]
|
1494 - | mod endpoint_operation_test {
|
1027 + | mod greeting_with_errors_test {
|
1495 1028 |
|
1496 - | /// Operations can prepend to the given host if they define the
|
1497 - | /// endpoint trait.
|
1498 - | /// Test ID: AwsJson10EndpointTrait
|
1029 + | /// Parses simple JSON errors
|
1030 + | /// Test ID: AwsJson10InvalidGreetingError
|
1499 1031 | #[::tokio::test]
|
1500 1032 | #[::tracing_test::traced_test]
|
1501 - | #[should_panic]
|
1502 - | async fn aws_json10_endpoint_trait_request() {
|
1503 - | #[allow(unused_mut)]
|
1504 - | let mut http_request = ::http::Request::builder()
|
1505 - | .uri("/")
|
1506 - | .method("POST")
|
1507 - | .body(::aws_smithy_legacy_http_server::body::Body::from(
|
1508 - | ::bytes::Bytes::copy_from_slice(&::aws_smithy_protocol_test::decode_body_data(
|
1509 - | "{}".as_bytes(),
|
1510 - | ::aws_smithy_protocol_test::MediaType::from("unknown"),
|
1511 - | )),
|
1512 - | ))
|
1513 - | .unwrap();
|
1514 - | todo!("endpoint trait not supported yet");
|
1515 - | #[allow(unused_mut)]
|
1516 - | let (sender, mut receiver) = ::tokio::sync::mpsc::channel(1);
|
1517 - | let config = crate::service::JsonRpc10Config::builder().build();
|
1518 - | let service = crate::service::JsonRpc10::builder::<::hyper::body::Body, _, _, _>(config)
|
1519 - | .endpoint_operation(move |input: crate::input::EndpointOperationInput| {
|
1520 - | let sender = sender.clone();
|
1521 - | async move {
|
1522 - | let result = {
|
1523 - | let expected = crate::input::EndpointOperationInput {};
|
1524 - | ::pretty_assertions::assert_eq!(input, expected);
|
1525 - | let output = crate::output::EndpointOperationOutput {};
|
1526 - | output
|
1033 + | async fn aws_json10_invalid_greeting_error_response() {
|
1034 + | let output = crate::error::InvalidGreeting {
|
1035 + | message: ::std::option::Option::Some("Hi".to_owned()),
|
1527 1036 | };
|
1528 - | sender.send(()).await.expect("receiver dropped early");
|
1529 - | result
|
1037 + | let output = crate::error::GreetingWithErrorsError::InvalidGreeting(output);
|
1038 + | use ::aws_smithy_legacy_http_server::response::IntoResponse;
|
1039 + | let http_response = output.into_response();
|
1040 + | ::pretty_assertions::assert_eq!(
|
1041 + | ::http::StatusCode::from_u16(400).expect("invalid expected HTTP status code"),
|
1042 + | http_response.status()
|
1043 + | );
|
1044 + | let expected_headers = [("Content-Type", "application/x-amz-json-1.0")];
|
1045 + | ::aws_smithy_protocol_test::assert_ok(::aws_smithy_protocol_test::validate_headers(
|
1046 + | http_response.headers(),
|
1047 + | expected_headers,
|
1048 + | ));
|
1049 + | let body = ::hyper::body::to_bytes(http_response.into_body())
|
1050 + | .await
|
1051 + | .expect("unable to extract body to bytes");
|
1052 + | ::aws_smithy_protocol_test::assert_ok(
|
1053 + | ::aws_smithy_protocol_test::validate_body(&body, "{\n \"__type\": \"aws.protocoltests.json10#InvalidGreeting\",\n \"Message\": \"Hi\"\n}", ::aws_smithy_protocol_test::MediaType::from("application/json"))
|
1054 + | );
|
1530 1055 | }
|
1531 - | })
|
1532 - | .build_unchecked();
|
1533 - | let http_response = ::tower::ServiceExt::oneshot(service, http_request)
|
1056 + |
|
1057 + | /// Parses a complex error with no message member
|
1058 + | /// Test ID: AwsJson10ComplexError
|
1059 + | #[::tokio::test]
|
1060 + | #[::tracing_test::traced_test]
|
1061 + | async fn aws_json10_complex_error_response() {
|
1062 + | let output = crate::error::ComplexError {
|
1063 + | top_level: ::std::option::Option::Some("Top level".to_owned()),
|
1064 + | nested: ::std::option::Option::Some(crate::model::ComplexNestedErrorData {
|
1065 + | foo: ::std::option::Option::Some("bar".to_owned()),
|
1066 + | }),
|
1067 + | };
|
1068 + | let output = crate::error::GreetingWithErrorsError::ComplexError(output);
|
1069 + | use ::aws_smithy_legacy_http_server::response::IntoResponse;
|
1070 + | let http_response = output.into_response();
|
1071 + | ::pretty_assertions::assert_eq!(
|
1072 + | ::http::StatusCode::from_u16(400).expect("invalid expected HTTP status code"),
|
1073 + | http_response.status()
|
1074 + | );
|
1075 + | let expected_headers = [("Content-Type", "application/x-amz-json-1.0")];
|
1076 + | ::aws_smithy_protocol_test::assert_ok(::aws_smithy_protocol_test::validate_headers(
|
1077 + | http_response.headers(),
|
1078 + | expected_headers,
|
1079 + | ));
|
1080 + | let body = ::hyper::body::to_bytes(http_response.into_body())
|
1534 1081 | .await
|
1535 - | .expect("unable to make an HTTP request");
|
1536 - | assert!(
|
1537 - | receiver.recv().await.is_some(),
|
1538 - | "we expected operation handler to be invoked but it was not entered"
|
1082 + | .expect("unable to extract body to bytes");
|
1083 + | ::aws_smithy_protocol_test::assert_ok(
|
1084 + | ::aws_smithy_protocol_test::validate_body(&body, "{\n \"__type\": \"aws.protocoltests.json10#ComplexError\",\n \"TopLevel\": \"Top level\",\n \"Nested\": {\n \"Foo\": \"bar\"\n }\n}", ::aws_smithy_protocol_test::MediaType::from("application/json"))
|
1085 + | );
|
1086 + | }
|
1087 + |
|
1088 + | /// Parses a complex error with an empty body
|
1089 + | /// Test ID: AwsJson10EmptyComplexError
|
1090 + | #[::tokio::test]
|
1091 + | #[::tracing_test::traced_test]
|
1092 + | async fn aws_json10_empty_complex_error_response() {
|
1093 + | let output = crate::error::ComplexError {
|
1094 + | top_level: ::std::option::Option::None,
|
1095 + | nested: ::std::option::Option::None,
|
1096 + | };
|
1097 + | let output = crate::error::GreetingWithErrorsError::ComplexError(output);
|
1098 + | use ::aws_smithy_legacy_http_server::response::IntoResponse;
|
1099 + | let http_response = output.into_response();
|
1100 + | ::pretty_assertions::assert_eq!(
|
1101 + | ::http::StatusCode::from_u16(400).expect("invalid expected HTTP status code"),
|
1102 + | http_response.status()
|
1539 1103 | );
|
1104 + | let expected_headers = [("Content-Type", "application/x-amz-json-1.0")];
|
1105 + | ::aws_smithy_protocol_test::assert_ok(::aws_smithy_protocol_test::validate_headers(
|
1106 + | http_response.headers(),
|
1107 + | expected_headers,
|
1108 + | ));
|
1109 + | let body = ::hyper::body::to_bytes(http_response.into_body())
|
1110 + | .await
|
1111 + | .expect("unable to extract body to bytes");
|
1112 + | ::aws_smithy_protocol_test::assert_ok(::aws_smithy_protocol_test::validate_body(
|
1113 + | &body,
|
1114 + | "{\n \"__type\": \"aws.protocoltests.json10#ComplexError\"\n}",
|
1115 + | ::aws_smithy_protocol_test::MediaType::from("application/json"),
|
1116 + | ));
|
1540 1117 | }
|
1541 1118 | }
|
1542 1119 |
|
1543 1120 | ::pin_project_lite::pin_project! {
|
1544 1121 | /// A [`Future`](std::future::Future) aggregating the body bytes of a [`Request`] and constructing the
|
1545 1122 | /// [`JsonUnionsInput`](crate::input::JsonUnionsInput) using modelled bindings.
|
1546 1123 | pub struct JsonUnionsInputFuture {
|
1547 1124 | inner: std::pin::Pin<Box<dyn std::future::Future<Output = Result<crate::input::JsonUnionsInput, ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError>> + Send>>
|
1548 1125 | }
|
1549 1126 | }
|
2309 1886 | http_response.status()
|
2310 1887 | );
|
2311 1888 | let expected_headers = [("Content-Type", "application/x-amz-json-1.0")];
|
2312 1889 | ::aws_smithy_protocol_test::assert_ok(::aws_smithy_protocol_test::validate_headers(
|
2313 1890 | http_response.headers(),
|
2314 1891 | expected_headers,
|
2315 1892 | ));
|
2316 1893 | let body = ::hyper::body::to_bytes(http_response.into_body())
|
2317 1894 | .await
|
2318 1895 | .expect("unable to extract body to bytes");
|
2319 - | ::aws_smithy_protocol_test::assert_ok(::aws_smithy_protocol_test::validate_body(
|
2320 - | &body,
|
2321 - | "{\n \"contents\": {\n \"timestampValue\": 1398796238\n }\n}",
|
2322 - | ::aws_smithy_protocol_test::MediaType::from("application/json"),
|
2323 - | ));
|
1896 + | ::aws_smithy_protocol_test::assert_ok(::aws_smithy_protocol_test::validate_body(
|
1897 + | &body,
|
1898 + | "{\n \"contents\": {\n \"timestampValue\": 1398796238\n }\n}",
|
1899 + | ::aws_smithy_protocol_test::MediaType::from("application/json"),
|
1900 + | ));
|
1901 + | }
|
1902 + |
|
1903 + | /// Deserializes an enum union value
|
1904 + | /// Test ID: AwsJson10DeserializeEnumUnionValue
|
1905 + | #[::tokio::test]
|
1906 + | #[::tracing_test::traced_test]
|
1907 + | async fn aws_json10_deserialize_enum_union_value_response() {
|
1908 + | let output = crate::output::JsonUnionsOutput {
|
1909 + | contents: ::std::option::Option::Some(crate::model::MyUnion::EnumValue(
|
1910 + | "Foo"
|
1911 + | .parse::<crate::model::FooEnum>()
|
1912 + | .expect("static value validated to member"),
|
1913 + | )),
|
1914 + | };
|
1915 + | use ::aws_smithy_legacy_http_server::response::IntoResponse;
|
1916 + | let http_response = output.into_response();
|
1917 + | ::pretty_assertions::assert_eq!(
|
1918 + | ::http::StatusCode::from_u16(200).expect("invalid expected HTTP status code"),
|
1919 + | http_response.status()
|
1920 + | );
|
1921 + | let expected_headers = [("Content-Type", "application/x-amz-json-1.0")];
|
1922 + | ::aws_smithy_protocol_test::assert_ok(::aws_smithy_protocol_test::validate_headers(
|
1923 + | http_response.headers(),
|
1924 + | expected_headers,
|
1925 + | ));
|
1926 + | let body = ::hyper::body::to_bytes(http_response.into_body())
|
1927 + | .await
|
1928 + | .expect("unable to extract body to bytes");
|
1929 + | ::aws_smithy_protocol_test::assert_ok(::aws_smithy_protocol_test::validate_body(
|
1930 + | &body,
|
1931 + | "{\n \"contents\": {\n \"enumValue\": \"Foo\"\n }\n}",
|
1932 + | ::aws_smithy_protocol_test::MediaType::from("application/json"),
|
1933 + | ));
|
1934 + | }
|
1935 + |
|
1936 + | /// Deserializes an intEnum union value
|
1937 + | /// Test ID: AwsJson10DeserializeIntEnumUnionValue
|
1938 + | #[::tokio::test]
|
1939 + | #[::tracing_test::traced_test]
|
1940 + | async fn aws_json10_deserialize_int_enum_union_value_response() {
|
1941 + | let output = crate::output::JsonUnionsOutput {
|
1942 + | contents: ::std::option::Option::Some(crate::model::MyUnion::IntEnumValue(1)),
|
1943 + | };
|
1944 + | use ::aws_smithy_legacy_http_server::response::IntoResponse;
|
1945 + | let http_response = output.into_response();
|
1946 + | ::pretty_assertions::assert_eq!(
|
1947 + | ::http::StatusCode::from_u16(200).expect("invalid expected HTTP status code"),
|
1948 + | http_response.status()
|
1949 + | );
|
1950 + | let expected_headers = [("Content-Type", "application/x-amz-json-1.0")];
|
1951 + | ::aws_smithy_protocol_test::assert_ok(::aws_smithy_protocol_test::validate_headers(
|
1952 + | http_response.headers(),
|
1953 + | expected_headers,
|
1954 + | ));
|
1955 + | let body = ::hyper::body::to_bytes(http_response.into_body())
|
1956 + | .await
|
1957 + | .expect("unable to extract body to bytes");
|
1958 + | ::aws_smithy_protocol_test::assert_ok(::aws_smithy_protocol_test::validate_body(
|
1959 + | &body,
|
1960 + | "{\n \"contents\": {\n \"intEnumValue\": 1\n }\n}",
|
1961 + | ::aws_smithy_protocol_test::MediaType::from("application/json"),
|
1962 + | ));
|
1963 + | }
|
1964 + |
|
1965 + | /// Deserializes a list union value
|
1966 + | /// Test ID: AwsJson10DeserializeListUnionValue
|
1967 + | #[::tokio::test]
|
1968 + | #[::tracing_test::traced_test]
|
1969 + | async fn aws_json10_deserialize_list_union_value_response() {
|
1970 + | let output = crate::output::JsonUnionsOutput {
|
1971 + | contents: ::std::option::Option::Some(crate::model::MyUnion::ListValue(vec![
|
1972 + | "foo".to_owned(),
|
1973 + | "bar".to_owned(),
|
1974 + | ])),
|
1975 + | };
|
1976 + | use ::aws_smithy_legacy_http_server::response::IntoResponse;
|
1977 + | let http_response = output.into_response();
|
1978 + | ::pretty_assertions::assert_eq!(
|
1979 + | ::http::StatusCode::from_u16(200).expect("invalid expected HTTP status code"),
|
1980 + | http_response.status()
|
1981 + | );
|
1982 + | let expected_headers = [("Content-Type", "application/x-amz-json-1.0")];
|
1983 + | ::aws_smithy_protocol_test::assert_ok(::aws_smithy_protocol_test::validate_headers(
|
1984 + | http_response.headers(),
|
1985 + | expected_headers,
|
1986 + | ));
|
1987 + | let body = ::hyper::body::to_bytes(http_response.into_body())
|
1988 + | .await
|
1989 + | .expect("unable to extract body to bytes");
|
1990 + | ::aws_smithy_protocol_test::assert_ok(::aws_smithy_protocol_test::validate_body(
|
1991 + | &body,
|
1992 + | "{\n \"contents\": {\n \"listValue\": [\"foo\", \"bar\"]\n }\n}",
|
1993 + | ::aws_smithy_protocol_test::MediaType::from("application/json"),
|
1994 + | ));
|
1995 + | }
|
1996 + |
|
1997 + | /// Deserializes a map union value
|
1998 + | /// Test ID: AwsJson10DeserializeMapUnionValue
|
1999 + | #[::tokio::test]
|
2000 + | #[::tracing_test::traced_test]
|
2001 + | async fn aws_json10_deserialize_map_union_value_response() {
|
2002 + | let output = crate::output::JsonUnionsOutput {
|
2003 + | contents: ::std::option::Option::Some(crate::model::MyUnion::MapValue({
|
2004 + | let mut ret = ::std::collections::HashMap::new();
|
2005 + | ret.insert("foo".to_owned(), "bar".to_owned());
|
2006 + | ret.insert("spam".to_owned(), "eggs".to_owned());
|
2007 + | ret
|
2008 + | })),
|
2009 + | };
|
2010 + | use ::aws_smithy_legacy_http_server::response::IntoResponse;
|
2011 + | let http_response = output.into_response();
|
2012 + | ::pretty_assertions::assert_eq!(
|
2013 + | ::http::StatusCode::from_u16(200).expect("invalid expected HTTP status code"),
|
2014 + | http_response.status()
|
2015 + | );
|
2016 + | let expected_headers = [("Content-Type", "application/x-amz-json-1.0")];
|
2017 + | ::aws_smithy_protocol_test::assert_ok(::aws_smithy_protocol_test::validate_headers(
|
2018 + | http_response.headers(),
|
2019 + | expected_headers,
|
2020 + | ));
|
2021 + | let body = ::hyper::body::to_bytes(http_response.into_body())
|
2022 + | .await
|
2023 + | .expect("unable to extract body to bytes");
|
2024 + | ::aws_smithy_protocol_test::assert_ok(
|
2025 + | ::aws_smithy_protocol_test::validate_body(&body, "{\n \"contents\": {\n \"mapValue\": {\n \"foo\": \"bar\",\n \"spam\": \"eggs\"\n }\n }\n}", ::aws_smithy_protocol_test::MediaType::from("application/json"))
|
2026 + | );
|
2324 2027 | }
|
2325 2028 |
|
2326 - | /// Deserializes an enum union value
|
2327 - | /// Test ID: AwsJson10DeserializeEnumUnionValue
|
2029 + | /// Deserializes a structure union value
|
2030 + | /// Test ID: AwsJson10DeserializeStructureUnionValue
|
2328 2031 | #[::tokio::test]
|
2329 2032 | #[::tracing_test::traced_test]
|
2330 - | async fn aws_json10_deserialize_enum_union_value_response() {
|
2033 + | async fn aws_json10_deserialize_structure_union_value_response() {
|
2331 2034 | let output = crate::output::JsonUnionsOutput {
|
2332 - | contents: ::std::option::Option::Some(crate::model::MyUnion::EnumValue(
|
2333 - | "Foo"
|
2334 - | .parse::<crate::model::FooEnum>()
|
2335 - | .expect("static value validated to member"),
|
2035 + | contents: ::std::option::Option::Some(crate::model::MyUnion::StructureValue(
|
2036 + | crate::model::GreetingStruct {
|
2037 + | hi: ::std::option::Option::Some("hello".to_owned()),
|
2038 + | },
|
2336 2039 | )),
|
2337 2040 | };
|
2338 2041 | use ::aws_smithy_legacy_http_server::response::IntoResponse;
|
2339 2042 | let http_response = output.into_response();
|
2340 2043 | ::pretty_assertions::assert_eq!(
|
2341 2044 | ::http::StatusCode::from_u16(200).expect("invalid expected HTTP status code"),
|
2342 2045 | http_response.status()
|
2343 2046 | );
|
2344 2047 | let expected_headers = [("Content-Type", "application/x-amz-json-1.0")];
|
2345 2048 | ::aws_smithy_protocol_test::assert_ok(::aws_smithy_protocol_test::validate_headers(
|
2346 2049 | http_response.headers(),
|
2347 2050 | expected_headers,
|
2348 2051 | ));
|
2349 2052 | let body = ::hyper::body::to_bytes(http_response.into_body())
|
2350 2053 | .await
|
2351 2054 | .expect("unable to extract body to bytes");
|
2352 - | ::aws_smithy_protocol_test::assert_ok(::aws_smithy_protocol_test::validate_body(
|
2353 - | &body,
|
2354 - | "{\n \"contents\": {\n \"enumValue\": \"Foo\"\n }\n}",
|
2355 - | ::aws_smithy_protocol_test::MediaType::from("application/json"),
|
2356 - | ));
|
2055 + | ::aws_smithy_protocol_test::assert_ok(
|
2056 + | ::aws_smithy_protocol_test::validate_body(&body, "{\n \"contents\": {\n \"structureValue\": {\n \"hi\": \"hello\"\n }\n }\n}", ::aws_smithy_protocol_test::MediaType::from("application/json"))
|
2057 + | );
|
2058 + | }
|
2059 + | }
|
2060 + |
|
2061 + | ::pin_project_lite::pin_project! {
|
2062 + | /// A [`Future`](std::future::Future) aggregating the body bytes of a [`Request`] and constructing the
|
2063 + | /// [`EndpointOperationInput`](crate::input::EndpointOperationInput) using modelled bindings.
|
2064 + | pub struct EndpointOperationInputFuture {
|
2065 + | inner: std::pin::Pin<Box<dyn std::future::Future<Output = Result<crate::input::EndpointOperationInput, ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError>> + Send>>
|
2066 + | }
|
2067 + | }
|
2068 + |
|
2069 + | impl std::future::Future for EndpointOperationInputFuture {
|
2070 + | type Output = Result<
|
2071 + | crate::input::EndpointOperationInput,
|
2072 + | ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError,
|
2073 + | >;
|
2074 + |
|
2075 + | fn poll(
|
2076 + | self: std::pin::Pin<&mut Self>,
|
2077 + | cx: &mut std::task::Context<'_>,
|
2078 + | ) -> std::task::Poll<Self::Output> {
|
2079 + | let this = self.project();
|
2080 + | this.inner.as_mut().poll(cx)
|
2081 + | }
|
2082 + | }
|
2083 + |
|
2084 + | impl<B>
|
2085 + | ::aws_smithy_legacy_http_server::request::FromRequest<
|
2086 + | ::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0,
|
2087 + | B,
|
2088 + | > for crate::input::EndpointOperationInput
|
2089 + | where
|
2090 + | B: ::aws_smithy_legacy_http_server::body::HttpBody + Send,
|
2091 + | B: 'static,
|
2092 + |
|
2093 + | B::Data: Send,
|
2094 + | ::aws_smithy_legacy_http_server::protocol::aws_json::rejection::RequestRejection:
|
2095 + | From<<B as ::aws_smithy_legacy_http_server::body::HttpBody>::Error>,
|
2096 + | {
|
2097 + | type Rejection =
|
2098 + | ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError;
|
2099 + | type Future = EndpointOperationInputFuture;
|
2100 + |
|
2101 + | fn from_request(request: ::http::Request<B>) -> Self::Future {
|
2102 + | let fut = async move {
|
2103 + | if !::aws_smithy_legacy_http_server::protocol::accept_header_classifier(
|
2104 + | request.headers(),
|
2105 + | &crate::mimes::CONTENT_TYPE_APPLICATION_X_AMZ_JSON_1_0,
|
2106 + | ) {
|
2107 + | return Err(::aws_smithy_legacy_http_server::protocol::aws_json::rejection::RequestRejection::NotAcceptable);
|
2108 + | }
|
2109 + | crate::protocol_serde::shape_endpoint_operation::de_endpoint_operation_http_request(
|
2110 + | request,
|
2111 + | )
|
2112 + | .await
|
2113 + | };
|
2114 + | use ::futures_util::future::TryFutureExt;
|
2115 + | let fut = fut.map_err(|e: ::aws_smithy_legacy_http_server::protocol::aws_json::rejection::RequestRejection| {
|
2116 + | ::tracing::debug!(error = %e, "failed to deserialize request");
|
2117 + | ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError::from(e)
|
2118 + | });
|
2119 + | EndpointOperationInputFuture {
|
2120 + | inner: Box::pin(fut),
|
2121 + | }
|
2122 + | }
|
2123 + | }
|
2124 + | impl
|
2125 + | ::aws_smithy_legacy_http_server::response::IntoResponse<
|
2126 + | ::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0,
|
2127 + | > for crate::output::EndpointOperationOutput
|
2128 + | {
|
2129 + | fn into_response(self) -> ::aws_smithy_legacy_http_server::response::Response {
|
2130 + | match crate::protocol_serde::shape_endpoint_operation::ser_endpoint_operation_http_response(
|
2131 + | self,
|
2132 + | ) {
|
2133 + | Ok(response) => response,
|
2134 + | Err(e) => {
|
2135 + | ::tracing::error!(error = %e, "failed to serialize response");
|
2136 + | ::aws_smithy_legacy_http_server::response::IntoResponse::<::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0>::into_response(::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError::from(e))
|
2137 + | }
|
2138 + | }
|
2139 + | }
|
2140 + | }
|
2141 + |
|
2142 + | #[allow(unreachable_code, unused_variables)]
|
2143 + | #[cfg(test)]
|
2144 + | mod endpoint_operation_test {
|
2145 + |
|
2146 + | /// Operations can prepend to the given host if they define the
|
2147 + | /// endpoint trait.
|
2148 + | /// Test ID: AwsJson10EndpointTrait
|
2149 + | #[::tokio::test]
|
2150 + | #[::tracing_test::traced_test]
|
2151 + | #[should_panic]
|
2152 + | async fn aws_json10_endpoint_trait_request() {
|
2153 + | #[allow(unused_mut)]
|
2154 + | let mut http_request = ::http::Request::builder()
|
2155 + | .uri("/")
|
2156 + | .method("POST")
|
2157 + | .body(::aws_smithy_legacy_http_server::body::Body::from(
|
2158 + | ::bytes::Bytes::copy_from_slice(&::aws_smithy_protocol_test::decode_body_data(
|
2159 + | "{}".as_bytes(),
|
2160 + | ::aws_smithy_protocol_test::MediaType::from("unknown"),
|
2161 + | )),
|
2162 + | ))
|
2163 + | .unwrap();
|
2164 + | todo!("endpoint trait not supported yet");
|
2165 + | #[allow(unused_mut)]
|
2166 + | let (sender, mut receiver) = ::tokio::sync::mpsc::channel(1);
|
2167 + | let config = crate::service::JsonRpc10Config::builder().build();
|
2168 + | let service = crate::service::JsonRpc10::builder::<::hyper::body::Body, _, _, _>(config)
|
2169 + | .endpoint_operation(move |input: crate::input::EndpointOperationInput| {
|
2170 + | let sender = sender.clone();
|
2171 + | async move {
|
2172 + | let result = {
|
2173 + | let expected = crate::input::EndpointOperationInput {};
|
2174 + | ::pretty_assertions::assert_eq!(input, expected);
|
2175 + | let output = crate::output::EndpointOperationOutput {};
|
2176 + | output
|
2177 + | };
|
2178 + | sender.send(()).await.expect("receiver dropped early");
|
2179 + | result
|
2180 + | }
|
2181 + | })
|
2182 + | .build_unchecked();
|
2183 + | let http_response = ::tower::ServiceExt::oneshot(service, http_request)
|
2184 + | .await
|
2185 + | .expect("unable to make an HTTP request");
|
2186 + | assert!(
|
2187 + | receiver.recv().await.is_some(),
|
2188 + | "we expected operation handler to be invoked but it was not entered"
|
2189 + | );
|
2190 + | }
|
2191 + | }
|
2192 + |
|
2193 + | ::pin_project_lite::pin_project! {
|
2194 + | /// A [`Future`](std::future::Future) aggregating the body bytes of a [`Request`] and constructing the
|
2195 + | /// [`EndpointWithHostLabelOperationInput`](crate::input::EndpointWithHostLabelOperationInput) using modelled bindings.
|
2196 + | pub struct EndpointWithHostLabelOperationInputFuture {
|
2197 + | inner: std::pin::Pin<Box<dyn std::future::Future<Output = Result<crate::input::EndpointWithHostLabelOperationInput, ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError>> + Send>>
|
2198 + | }
|
2199 + | }
|
2200 + |
|
2201 + | impl std::future::Future for EndpointWithHostLabelOperationInputFuture {
|
2202 + | type Output = Result<
|
2203 + | crate::input::EndpointWithHostLabelOperationInput,
|
2204 + | ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError,
|
2205 + | >;
|
2206 + |
|
2207 + | fn poll(
|
2208 + | self: std::pin::Pin<&mut Self>,
|
2209 + | cx: &mut std::task::Context<'_>,
|
2210 + | ) -> std::task::Poll<Self::Output> {
|
2211 + | let this = self.project();
|
2212 + | this.inner.as_mut().poll(cx)
|
2213 + | }
|
2214 + | }
|
2215 + |
|
2216 + | impl<B>
|
2217 + | ::aws_smithy_legacy_http_server::request::FromRequest<
|
2218 + | ::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0,
|
2219 + | B,
|
2220 + | > for crate::input::EndpointWithHostLabelOperationInput
|
2221 + | where
|
2222 + | B: ::aws_smithy_legacy_http_server::body::HttpBody + Send,
|
2223 + | B: 'static,
|
2224 + |
|
2225 + | B::Data: Send,
|
2226 + | ::aws_smithy_legacy_http_server::protocol::aws_json::rejection::RequestRejection:
|
2227 + | From<<B as ::aws_smithy_legacy_http_server::body::HttpBody>::Error>,
|
2228 + | {
|
2229 + | type Rejection =
|
2230 + | ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError;
|
2231 + | type Future = EndpointWithHostLabelOperationInputFuture;
|
2232 + |
|
2233 + | fn from_request(request: ::http::Request<B>) -> Self::Future {
|
2234 + | let fut = async move {
|
2235 + | if !::aws_smithy_legacy_http_server::protocol::accept_header_classifier(
|
2236 + | request.headers(),
|
2237 + | &crate::mimes::CONTENT_TYPE_APPLICATION_X_AMZ_JSON_1_0,
|
2238 + | ) {
|
2239 + | return Err(::aws_smithy_legacy_http_server::protocol::aws_json::rejection::RequestRejection::NotAcceptable);
|
2240 + | }
|
2241 + | crate::protocol_serde::shape_endpoint_with_host_label_operation::de_endpoint_with_host_label_operation_http_request(request)
|
2242 + | .await
|
2243 + | };
|
2244 + | use ::futures_util::future::TryFutureExt;
|
2245 + | let fut = fut.map_err(|e: ::aws_smithy_legacy_http_server::protocol::aws_json::rejection::RequestRejection| {
|
2246 + | ::tracing::debug!(error = %e, "failed to deserialize request");
|
2247 + | ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError::from(e)
|
2248 + | });
|
2249 + | EndpointWithHostLabelOperationInputFuture {
|
2250 + | inner: Box::pin(fut),
|
2251 + | }
|
2252 + | }
|
2253 + | }
|
2254 + | impl
|
2255 + | ::aws_smithy_legacy_http_server::response::IntoResponse<
|
2256 + | ::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0,
|
2257 + | > for crate::output::EndpointWithHostLabelOperationOutput
|
2258 + | {
|
2259 + | fn into_response(self) -> ::aws_smithy_legacy_http_server::response::Response {
|
2260 + | match crate::protocol_serde::shape_endpoint_with_host_label_operation::ser_endpoint_with_host_label_operation_http_response(self) {
|
2261 + | Ok(response) => response,
|
2262 + | Err(e) => {
|
2263 + | ::tracing::error!(error = %e, "failed to serialize response");
|
2264 + | ::aws_smithy_legacy_http_server::response::IntoResponse::<::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0>::into_response(::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError::from(e))
|
2265 + | }
|
2266 + | }
|
2267 + | }
|
2268 + | }
|
2269 + | impl
|
2270 + | ::aws_smithy_legacy_http_server::response::IntoResponse<
|
2271 + | ::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0,
|
2272 + | > for crate::error::EndpointWithHostLabelOperationError
|
2273 + | {
|
2274 + | fn into_response(self) -> ::aws_smithy_legacy_http_server::response::Response {
|
2275 + | match crate::protocol_serde::shape_endpoint_with_host_label_operation::ser_endpoint_with_host_label_operation_http_error(&self) {
|
2276 + | Ok(mut response) => {
|
2277 + | response.extensions_mut().insert(::aws_smithy_legacy_http_server::extension::ModeledErrorExtension::new(self.name()));
|
2278 + | response
|
2279 + | },
|
2280 + | Err(e) => {
|
2281 + | ::tracing::error!(error = %e, "failed to serialize response");
|
2282 + | ::aws_smithy_legacy_http_server::response::IntoResponse::<::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0>::into_response(::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError::from(e))
|
2357 2283 | }
|
2358 - |
|
2359 - | /// Deserializes an intEnum union value
|
2360 - | /// Test ID: AwsJson10DeserializeIntEnumUnionValue
|
2361 - | #[::tokio::test]
|
2362 - | #[::tracing_test::traced_test]
|
2363 - | async fn aws_json10_deserialize_int_enum_union_value_response() {
|
2364 - | let output = crate::output::JsonUnionsOutput {
|
2365 - | contents: ::std::option::Option::Some(crate::model::MyUnion::IntEnumValue(1)),
|
2366 - | };
|
2367 - | use ::aws_smithy_legacy_http_server::response::IntoResponse;
|
2368 - | let http_response = output.into_response();
|
2369 - | ::pretty_assertions::assert_eq!(
|
2370 - | ::http::StatusCode::from_u16(200).expect("invalid expected HTTP status code"),
|
2371 - | http_response.status()
|
2372 - | );
|
2373 - | let expected_headers = [("Content-Type", "application/x-amz-json-1.0")];
|
2374 - | ::aws_smithy_protocol_test::assert_ok(::aws_smithy_protocol_test::validate_headers(
|
2375 - | http_response.headers(),
|
2376 - | expected_headers,
|
2377 - | ));
|
2378 - | let body = ::hyper::body::to_bytes(http_response.into_body())
|
2379 - | .await
|
2380 - | .expect("unable to extract body to bytes");
|
2381 - | ::aws_smithy_protocol_test::assert_ok(::aws_smithy_protocol_test::validate_body(
|
2382 - | &body,
|
2383 - | "{\n \"contents\": {\n \"intEnumValue\": 1\n }\n}",
|
2384 - | ::aws_smithy_protocol_test::MediaType::from("application/json"),
|
2385 - | ));
|
2386 2284 | }
|
2387 - |
|
2388 - | /// Deserializes a list union value
|
2389 - | /// Test ID: AwsJson10DeserializeListUnionValue
|
2390 - | #[::tokio::test]
|
2391 - | #[::tracing_test::traced_test]
|
2392 - | async fn aws_json10_deserialize_list_union_value_response() {
|
2393 - | let output = crate::output::JsonUnionsOutput {
|
2394 - | contents: ::std::option::Option::Some(crate::model::MyUnion::ListValue(vec![
|
2395 - | "foo".to_owned(),
|
2396 - | "bar".to_owned(),
|
2397 - | ])),
|
2398 - | };
|
2399 - | use ::aws_smithy_legacy_http_server::response::IntoResponse;
|
2400 - | let http_response = output.into_response();
|
2401 - | ::pretty_assertions::assert_eq!(
|
2402 - | ::http::StatusCode::from_u16(200).expect("invalid expected HTTP status code"),
|
2403 - | http_response.status()
|
2404 - | );
|
2405 - | let expected_headers = [("Content-Type", "application/x-amz-json-1.0")];
|
2406 - | ::aws_smithy_protocol_test::assert_ok(::aws_smithy_protocol_test::validate_headers(
|
2407 - | http_response.headers(),
|
2408 - | expected_headers,
|
2409 - | ));
|
2410 - | let body = ::hyper::body::to_bytes(http_response.into_body())
|
2411 - | .await
|
2412 - | .expect("unable to extract body to bytes");
|
2413 - | ::aws_smithy_protocol_test::assert_ok(::aws_smithy_protocol_test::validate_body(
|
2414 - | &body,
|
2415 - | "{\n \"contents\": {\n \"listValue\": [\"foo\", \"bar\"]\n }\n}",
|
2416 - | ::aws_smithy_protocol_test::MediaType::from("application/json"),
|
2417 - | ));
|
2418 2285 | }
|
2286 + | }
|
2419 2287 |
|
2420 - | /// Deserializes a map union value
|
2421 - | /// Test ID: AwsJson10DeserializeMapUnionValue
|
2422 - | #[::tokio::test]
|
2423 - | #[::tracing_test::traced_test]
|
2424 - | async fn aws_json10_deserialize_map_union_value_response() {
|
2425 - | let output = crate::output::JsonUnionsOutput {
|
2426 - | contents: ::std::option::Option::Some(crate::model::MyUnion::MapValue({
|
2427 - | let mut ret = ::std::collections::HashMap::new();
|
2428 - | ret.insert("foo".to_owned(), "bar".to_owned());
|
2429 - | ret.insert("spam".to_owned(), "eggs".to_owned());
|
2430 - | ret
|
2431 - | })),
|
2432 - | };
|
2433 - | use ::aws_smithy_legacy_http_server::response::IntoResponse;
|
2434 - | let http_response = output.into_response();
|
2435 - | ::pretty_assertions::assert_eq!(
|
2436 - | ::http::StatusCode::from_u16(200).expect("invalid expected HTTP status code"),
|
2437 - | http_response.status()
|
2438 - | );
|
2439 - | let expected_headers = [("Content-Type", "application/x-amz-json-1.0")];
|
2440 - | ::aws_smithy_protocol_test::assert_ok(::aws_smithy_protocol_test::validate_headers(
|
2441 - | http_response.headers(),
|
2442 - | expected_headers,
|
2443 - | ));
|
2444 - | let body = ::hyper::body::to_bytes(http_response.into_body())
|
2445 - | .await
|
2446 - | .expect("unable to extract body to bytes");
|
2447 - | ::aws_smithy_protocol_test::assert_ok(
|
2448 - | ::aws_smithy_protocol_test::validate_body(&body, "{\n \"contents\": {\n \"mapValue\": {\n \"foo\": \"bar\",\n \"spam\": \"eggs\"\n }\n }\n}", ::aws_smithy_protocol_test::MediaType::from("application/json"))
|
2449 - | );
|
2450 - | }
|
2288 + | #[allow(unreachable_code, unused_variables)]
|
2289 + | #[cfg(test)]
|
2290 + | mod endpoint_with_host_label_operation_test {
|
2451 2291 |
|
2452 - | /// Deserializes a structure union value
|
2453 - | /// Test ID: AwsJson10DeserializeStructureUnionValue
|
2292 + | /// Operations can prepend to the given host if they define the
|
2293 + | /// endpoint trait, and can use the host label trait to define
|
2294 + | /// further customization based on user input.
|
2295 + | /// Test ID: AwsJson10EndpointTraitWithHostLabel
|
2454 2296 | #[::tokio::test]
|
2455 2297 | #[::tracing_test::traced_test]
|
2456 - | async fn aws_json10_deserialize_structure_union_value_response() {
|
2457 - | let output = crate::output::JsonUnionsOutput {
|
2458 - | contents: ::std::option::Option::Some(crate::model::MyUnion::StructureValue(
|
2459 - | crate::model::GreetingStruct {
|
2460 - | hi: ::std::option::Option::Some("hello".to_owned()),
|
2461 - | },
|
2298 + | #[should_panic]
|
2299 + | async fn aws_json10_endpoint_trait_with_host_label_request() {
|
2300 + | #[allow(unused_mut)]
|
2301 + | let mut http_request = ::http::Request::builder()
|
2302 + | .uri("/")
|
2303 + | .method("POST")
|
2304 + | .body(::aws_smithy_legacy_http_server::body::Body::from(
|
2305 + | ::bytes::Bytes::copy_from_slice(&::aws_smithy_protocol_test::decode_body_data(
|
2306 + | "{\"label\": \"bar\"}".as_bytes(),
|
2307 + | ::aws_smithy_protocol_test::MediaType::from("application/json"),
|
2462 2308 | )),
|
2309 + | ))
|
2310 + | .unwrap();
|
2311 + | todo!("endpoint trait not supported yet");
|
2312 + | #[allow(unused_mut)]
|
2313 + | let (sender, mut receiver) = ::tokio::sync::mpsc::channel(1);
|
2314 + | let config = crate::service::JsonRpc10Config::builder().build();
|
2315 + | let service = crate::service::JsonRpc10::builder::<::hyper::body::Body, _, _, _>(config)
|
2316 + | .endpoint_with_host_label_operation(
|
2317 + | move |input: crate::input::EndpointWithHostLabelOperationInput| {
|
2318 + | let sender = sender.clone();
|
2319 + | async move {
|
2320 + | let result = {
|
2321 + | let expected = crate::input::EndpointWithHostLabelOperationInput {
|
2322 + | label: "bar".to_owned(),
|
2463 2323 | };
|
2464 - | use ::aws_smithy_legacy_http_server::response::IntoResponse;
|
2465 - | let http_response = output.into_response();
|
2466 - | ::pretty_assertions::assert_eq!(
|
2467 - | ::http::StatusCode::from_u16(200).expect("invalid expected HTTP status code"),
|
2468 - | http_response.status()
|
2469 - | );
|
2470 - | let expected_headers = [("Content-Type", "application/x-amz-json-1.0")];
|
2471 - | ::aws_smithy_protocol_test::assert_ok(::aws_smithy_protocol_test::validate_headers(
|
2472 - | http_response.headers(),
|
2473 - | expected_headers,
|
2474 - | ));
|
2475 - | let body = ::hyper::body::to_bytes(http_response.into_body())
|
2324 + | ::pretty_assertions::assert_eq!(input, expected);
|
2325 + | let output = crate::output::EndpointWithHostLabelOperationOutput {};
|
2326 + | Ok(output)
|
2327 + | };
|
2328 + | sender.send(()).await.expect("receiver dropped early");
|
2329 + | result
|
2330 + | }
|
2331 + | },
|
2332 + | )
|
2333 + | .build_unchecked();
|
2334 + | let http_response = ::tower::ServiceExt::oneshot(service, http_request)
|
2476 2335 | .await
|
2477 - | .expect("unable to extract body to bytes");
|
2478 - | ::aws_smithy_protocol_test::assert_ok(
|
2479 - | ::aws_smithy_protocol_test::validate_body(&body, "{\n \"contents\": {\n \"structureValue\": {\n \"hi\": \"hello\"\n }\n }\n}", ::aws_smithy_protocol_test::MediaType::from("application/json"))
|
2336 + | .expect("unable to make an HTTP request");
|
2337 + | assert!(
|
2338 + | receiver.recv().await.is_some(),
|
2339 + | "we expected operation handler to be invoked but it was not entered"
|
2480 2340 | );
|
2481 2341 | }
|
2482 2342 | }
|
2483 2343 |
|
2484 2344 | ::pin_project_lite::pin_project! {
|
2485 2345 | /// A [`Future`](std::future::Future) aggregating the body bytes of a [`Request`] and constructing the
|
2486 - | /// [`GreetingWithErrorsInput`](crate::input::GreetingWithErrorsInput) using modelled bindings.
|
2487 - | pub struct GreetingWithErrorsInputFuture {
|
2488 - | inner: std::pin::Pin<Box<dyn std::future::Future<Output = Result<crate::input::GreetingWithErrorsInput, ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError>> + Send>>
|
2346 + | /// [`HostWithPathOperationInput`](crate::input::HostWithPathOperationInput) using modelled bindings.
|
2347 + | pub struct HostWithPathOperationInputFuture {
|
2348 + | inner: std::pin::Pin<Box<dyn std::future::Future<Output = Result<crate::input::HostWithPathOperationInput, ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError>> + Send>>
|
2489 2349 | }
|
2490 2350 | }
|
2491 2351 |
|
2492 - | impl std::future::Future for GreetingWithErrorsInputFuture {
|
2352 + | impl std::future::Future for HostWithPathOperationInputFuture {
|
2493 2353 | type Output = Result<
|
2494 - | crate::input::GreetingWithErrorsInput,
|
2354 + | crate::input::HostWithPathOperationInput,
|
2495 2355 | ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError,
|
2496 2356 | >;
|
2497 2357 |
|
2498 2358 | fn poll(
|
2499 2359 | self: std::pin::Pin<&mut Self>,
|
2500 2360 | cx: &mut std::task::Context<'_>,
|
2501 2361 | ) -> std::task::Poll<Self::Output> {
|
2502 2362 | let this = self.project();
|
2503 2363 | this.inner.as_mut().poll(cx)
|
2504 2364 | }
|
2505 2365 | }
|
2506 2366 |
|
2507 2367 | impl<B>
|
2508 2368 | ::aws_smithy_legacy_http_server::request::FromRequest<
|
2509 2369 | ::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0,
|
2510 2370 | B,
|
2511 - | > for crate::input::GreetingWithErrorsInput
|
2371 + | > for crate::input::HostWithPathOperationInput
|
2512 2372 | where
|
2513 2373 | B: ::aws_smithy_legacy_http_server::body::HttpBody + Send,
|
2514 2374 | B: 'static,
|
2515 2375 |
|
2516 2376 | B::Data: Send,
|
2517 2377 | ::aws_smithy_legacy_http_server::protocol::aws_json::rejection::RequestRejection:
|
2518 2378 | From<<B as ::aws_smithy_legacy_http_server::body::HttpBody>::Error>,
|
2519 2379 | {
|
2520 2380 | type Rejection =
|
2521 2381 | ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError;
|
2522 - | type Future = GreetingWithErrorsInputFuture;
|
2382 + | type Future = HostWithPathOperationInputFuture;
|
2523 2383 |
|
2524 2384 | fn from_request(request: ::http::Request<B>) -> Self::Future {
|
2525 2385 | let fut = async move {
|
2526 2386 | if !::aws_smithy_legacy_http_server::protocol::accept_header_classifier(
|
2527 2387 | request.headers(),
|
2528 2388 | &crate::mimes::CONTENT_TYPE_APPLICATION_X_AMZ_JSON_1_0,
|
2529 2389 | ) {
|
2530 2390 | return Err(::aws_smithy_legacy_http_server::protocol::aws_json::rejection::RequestRejection::NotAcceptable);
|
2531 2391 | }
|
2532 - | crate::protocol_serde::shape_greeting_with_errors::de_greeting_with_errors_http_request(
|
2533 - | request,
|
2534 - | )
|
2392 + | crate::protocol_serde::shape_host_with_path_operation::de_host_with_path_operation_http_request(request)
|
2535 2393 | .await
|
2536 2394 | };
|
2537 2395 | use ::futures_util::future::TryFutureExt;
|
2538 2396 | let fut = fut.map_err(|e: ::aws_smithy_legacy_http_server::protocol::aws_json::rejection::RequestRejection| {
|
2539 2397 | ::tracing::debug!(error = %e, "failed to deserialize request");
|
2540 2398 | ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError::from(e)
|
2541 2399 | });
|
2542 - | GreetingWithErrorsInputFuture {
|
2400 + | HostWithPathOperationInputFuture {
|
2543 2401 | inner: Box::pin(fut),
|
2544 2402 | }
|
2545 2403 | }
|
2546 2404 | }
|
2547 2405 | impl
|
2548 2406 | ::aws_smithy_legacy_http_server::response::IntoResponse<
|
2549 2407 | ::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0,
|
2550 - | > for crate::output::GreetingWithErrorsOutput
|
2408 + | > for crate::output::HostWithPathOperationOutput
|
2551 2409 | {
|
2552 2410 | fn into_response(self) -> ::aws_smithy_legacy_http_server::response::Response {
|
2553 - | match crate::protocol_serde::shape_greeting_with_errors::ser_greeting_with_errors_http_response(self) {
|
2411 + | match crate::protocol_serde::shape_host_with_path_operation::ser_host_with_path_operation_http_response(self) {
|
2554 2412 | Ok(response) => response,
|
2555 2413 | Err(e) => {
|
2556 2414 | ::tracing::error!(error = %e, "failed to serialize response");
|
2557 2415 | ::aws_smithy_legacy_http_server::response::IntoResponse::<::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0>::into_response(::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError::from(e))
|
2558 2416 | }
|
2559 2417 | }
|
2560 2418 | }
|
2561 2419 | }
|
2562 - | impl
|
2563 - | ::aws_smithy_legacy_http_server::response::IntoResponse<
|
2420 + |
|
2421 + | ::pin_project_lite::pin_project! {
|
2422 + | /// A [`Future`](std::future::Future) aggregating the body bytes of a [`Request`] and constructing the
|
2423 + | /// [`PutWithContentEncodingInput`](crate::input::PutWithContentEncodingInput) using modelled bindings.
|
2424 + | pub struct PutWithContentEncodingInputFuture {
|
2425 + | inner: std::pin::Pin<Box<dyn std::future::Future<Output = Result<crate::input::PutWithContentEncodingInput, ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError>> + Send>>
|
2426 + | }
|
2427 + | }
|
2428 + |
|
2429 + | impl std::future::Future for PutWithContentEncodingInputFuture {
|
2430 + | type Output = Result<
|
2431 + | crate::input::PutWithContentEncodingInput,
|
2432 + | ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError,
|
2433 + | >;
|
2434 + |
|
2435 + | fn poll(
|
2436 + | self: std::pin::Pin<&mut Self>,
|
2437 + | cx: &mut std::task::Context<'_>,
|
2438 + | ) -> std::task::Poll<Self::Output> {
|
2439 + | let this = self.project();
|
2440 + | this.inner.as_mut().poll(cx)
|
2441 + | }
|
2442 + | }
|
2443 + |
|
2444 + | impl<B>
|
2445 + | ::aws_smithy_legacy_http_server::request::FromRequest<
|
2564 2446 | ::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0,
|
2565 - | > for crate::error::GreetingWithErrorsError
|
2447 + | B,
|
2448 + | > for crate::input::PutWithContentEncodingInput
|
2449 + | where
|
2450 + | B: ::aws_smithy_legacy_http_server::body::HttpBody + Send,
|
2451 + | B: 'static,
|
2452 + |
|
2453 + | B::Data: Send,
|
2454 + | ::aws_smithy_legacy_http_server::protocol::aws_json::rejection::RequestRejection:
|
2455 + | From<<B as ::aws_smithy_legacy_http_server::body::HttpBody>::Error>,
|
2566 2456 | {
|
2567 - | fn into_response(self) -> ::aws_smithy_legacy_http_server::response::Response {
|
2568 - | match crate::protocol_serde::shape_greeting_with_errors::ser_greeting_with_errors_http_error(
|
2569 - | &self,
|
2457 + | type Rejection =
|
2458 + | ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError;
|
2459 + | type Future = PutWithContentEncodingInputFuture;
|
2460 + |
|
2461 + | fn from_request(request: ::http::Request<B>) -> Self::Future {
|
2462 + | let fut = async move {
|
2463 + | if !::aws_smithy_legacy_http_server::protocol::accept_header_classifier(
|
2464 + | request.headers(),
|
2465 + | &crate::mimes::CONTENT_TYPE_APPLICATION_X_AMZ_JSON_1_0,
|
2570 2466 | ) {
|
2571 - | Ok(mut response) => {
|
2572 - | response.extensions_mut().insert(
|
2573 - | ::aws_smithy_legacy_http_server::extension::ModeledErrorExtension::new(
|
2574 - | self.name(),
|
2575 - | ),
|
2576 - | );
|
2577 - | response
|
2467 + | return Err(::aws_smithy_legacy_http_server::protocol::aws_json::rejection::RequestRejection::NotAcceptable);
|
2468 + | }
|
2469 + | crate::protocol_serde::shape_put_with_content_encoding::de_put_with_content_encoding_http_request(request)
|
2470 + | .await
|
2471 + | };
|
2472 + | use ::futures_util::future::TryFutureExt;
|
2473 + | let fut = fut.map_err(|e: ::aws_smithy_legacy_http_server::protocol::aws_json::rejection::RequestRejection| {
|
2474 + | ::tracing::debug!(error = %e, "failed to deserialize request");
|
2475 + | ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError::from(e)
|
2476 + | });
|
2477 + | PutWithContentEncodingInputFuture {
|
2478 + | inner: Box::pin(fut),
|
2479 + | }
|
2578 2480 | }
|
2481 + | }
|
2482 + | impl
|
2483 + | ::aws_smithy_legacy_http_server::response::IntoResponse<
|
2484 + | ::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0,
|
2485 + | > for crate::output::PutWithContentEncodingOutput
|
2486 + | {
|
2487 + | fn into_response(self) -> ::aws_smithy_legacy_http_server::response::Response {
|
2488 + | match crate::protocol_serde::shape_put_with_content_encoding::ser_put_with_content_encoding_http_response(self) {
|
2489 + | Ok(response) => response,
|
2579 2490 | Err(e) => {
|
2580 2491 | ::tracing::error!(error = %e, "failed to serialize response");
|
2581 2492 | ::aws_smithy_legacy_http_server::response::IntoResponse::<::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0>::into_response(::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError::from(e))
|
2582 2493 | }
|
2583 2494 | }
|
2584 2495 | }
|
2585 2496 | }
|
2586 2497 |
|
2587 - | #[allow(unreachable_code, unused_variables)]
|
2588 - | #[cfg(test)]
|
2589 - | mod greeting_with_errors_test {
|
2590 - |
|
2591 - | /// Parses simple JSON errors
|
2592 - | /// Test ID: AwsJson10InvalidGreetingError
|
2593 - | #[::tokio::test]
|
2594 - | #[::tracing_test::traced_test]
|
2595 - | async fn aws_json10_invalid_greeting_error_response() {
|
2596 - | let output = crate::error::InvalidGreeting {
|
2597 - | message: ::std::option::Option::Some("Hi".to_owned()),
|
2598 - | };
|
2599 - | let output = crate::error::GreetingWithErrorsError::InvalidGreeting(output);
|
2600 - | use ::aws_smithy_legacy_http_server::response::IntoResponse;
|
2601 - | let http_response = output.into_response();
|
2602 - | ::pretty_assertions::assert_eq!(
|
2603 - | ::http::StatusCode::from_u16(400).expect("invalid expected HTTP status code"),
|
2604 - | http_response.status()
|
2605 - | );
|
2606 - | let expected_headers = [("Content-Type", "application/x-amz-json-1.0")];
|
2607 - | ::aws_smithy_protocol_test::assert_ok(::aws_smithy_protocol_test::validate_headers(
|
2608 - | http_response.headers(),
|
2609 - | expected_headers,
|
2610 - | ));
|
2611 - | let body = ::hyper::body::to_bytes(http_response.into_body())
|
2612 - | .await
|
2613 - | .expect("unable to extract body to bytes");
|
2614 - | ::aws_smithy_protocol_test::assert_ok(
|
2615 - | ::aws_smithy_protocol_test::validate_body(&body, "{\n \"__type\": \"aws.protocoltests.json10#InvalidGreeting\",\n \"Message\": \"Hi\"\n}", ::aws_smithy_protocol_test::MediaType::from("application/json"))
|
2616 - | );
|
2617 - | }
|
2618 - |
|
2619 - | /// Parses a complex error with no message member
|
2620 - | /// Test ID: AwsJson10ComplexError
|
2621 - | #[::tokio::test]
|
2622 - | #[::tracing_test::traced_test]
|
2623 - | async fn aws_json10_complex_error_response() {
|
2624 - | let output = crate::error::ComplexError {
|
2625 - | top_level: ::std::option::Option::Some("Top level".to_owned()),
|
2626 - | nested: ::std::option::Option::Some(crate::model::ComplexNestedErrorData {
|
2627 - | foo: ::std::option::Option::Some("bar".to_owned()),
|
2628 - | }),
|
2629 - | };
|
2630 - | let output = crate::error::GreetingWithErrorsError::ComplexError(output);
|
2631 - | use ::aws_smithy_legacy_http_server::response::IntoResponse;
|
2632 - | let http_response = output.into_response();
|
2633 - | ::pretty_assertions::assert_eq!(
|
2634 - | ::http::StatusCode::from_u16(400).expect("invalid expected HTTP status code"),
|
2635 - | http_response.status()
|
2636 - | );
|
2637 - | let expected_headers = [("Content-Type", "application/x-amz-json-1.0")];
|
2638 - | ::aws_smithy_protocol_test::assert_ok(::aws_smithy_protocol_test::validate_headers(
|
2639 - | http_response.headers(),
|
2640 - | expected_headers,
|
2641 - | ));
|
2642 - | let body = ::hyper::body::to_bytes(http_response.into_body())
|
2643 - | .await
|
2644 - | .expect("unable to extract body to bytes");
|
2645 - | ::aws_smithy_protocol_test::assert_ok(
|
2646 - | ::aws_smithy_protocol_test::validate_body(&body, "{\n \"__type\": \"aws.protocoltests.json10#ComplexError\",\n \"TopLevel\": \"Top level\",\n \"Nested\": {\n \"Foo\": \"bar\"\n }\n}", ::aws_smithy_protocol_test::MediaType::from("application/json"))
|
2647 - | );
|
2648 - | }
|
2649 - |
|
2650 - | /// Parses a complex error with an empty body
|
2651 - | /// Test ID: AwsJson10EmptyComplexError
|
2652 - | #[::tokio::test]
|
2653 - | #[::tracing_test::traced_test]
|
2654 - | async fn aws_json10_empty_complex_error_response() {
|
2655 - | let output = crate::error::ComplexError {
|
2656 - | top_level: ::std::option::Option::None,
|
2657 - | nested: ::std::option::Option::None,
|
2658 - | };
|
2659 - | let output = crate::error::GreetingWithErrorsError::ComplexError(output);
|
2660 - | use ::aws_smithy_legacy_http_server::response::IntoResponse;
|
2661 - | let http_response = output.into_response();
|
2662 - | ::pretty_assertions::assert_eq!(
|
2663 - | ::http::StatusCode::from_u16(400).expect("invalid expected HTTP status code"),
|
2664 - | http_response.status()
|
2665 - | );
|
2666 - | let expected_headers = [("Content-Type", "application/x-amz-json-1.0")];
|
2667 - | ::aws_smithy_protocol_test::assert_ok(::aws_smithy_protocol_test::validate_headers(
|
2668 - | http_response.headers(),
|
2669 - | expected_headers,
|
2670 - | ));
|
2671 - | let body = ::hyper::body::to_bytes(http_response.into_body())
|
2672 - | .await
|
2673 - | .expect("unable to extract body to bytes");
|
2674 - | ::aws_smithy_protocol_test::assert_ok(::aws_smithy_protocol_test::validate_body(
|
2675 - | &body,
|
2676 - | "{\n \"__type\": \"aws.protocoltests.json10#ComplexError\"\n}",
|
2677 - | ::aws_smithy_protocol_test::MediaType::from("application/json"),
|
2678 - | ));
|
2679 - | }
|
2680 - | }
|
2681 - |
|
2682 2498 | ::pin_project_lite::pin_project! {
|
2683 2499 | /// A [`Future`](std::future::Future) aggregating the body bytes of a [`Request`] and constructing the
|
2684 - | /// [`SimpleScalarPropertiesInput`](crate::input::SimpleScalarPropertiesInput) using modelled bindings.
|
2685 - | pub struct SimpleScalarPropertiesInputFuture {
|
2686 - | inner: std::pin::Pin<Box<dyn std::future::Future<Output = Result<crate::input::SimpleScalarPropertiesInput, ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError>> + Send>>
|
2500 + | /// [`ContentTypeParametersInput`](crate::input::ContentTypeParametersInput) using modelled bindings.
|
2501 + | pub struct ContentTypeParametersInputFuture {
|
2502 + | inner: std::pin::Pin<Box<dyn std::future::Future<Output = Result<crate::input::ContentTypeParametersInput, ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError>> + Send>>
|
2687 2503 | }
|
2688 2504 | }
|
2689 2505 |
|
2690 - | impl std::future::Future for SimpleScalarPropertiesInputFuture {
|
2506 + | impl std::future::Future for ContentTypeParametersInputFuture {
|
2691 2507 | type Output = Result<
|
2692 - | crate::input::SimpleScalarPropertiesInput,
|
2508 + | crate::input::ContentTypeParametersInput,
|
2693 2509 | ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError,
|
2694 2510 | >;
|
2695 2511 |
|
2696 2512 | fn poll(
|
2697 2513 | self: std::pin::Pin<&mut Self>,
|
2698 2514 | cx: &mut std::task::Context<'_>,
|
2699 2515 | ) -> std::task::Poll<Self::Output> {
|
2700 2516 | let this = self.project();
|
2701 2517 | this.inner.as_mut().poll(cx)
|
2702 2518 | }
|
2703 2519 | }
|
2704 2520 |
|
2705 2521 | impl<B>
|
2706 2522 | ::aws_smithy_legacy_http_server::request::FromRequest<
|
2707 2523 | ::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0,
|
2708 2524 | B,
|
2709 - | > for crate::input::SimpleScalarPropertiesInput
|
2525 + | > for crate::input::ContentTypeParametersInput
|
2710 2526 | where
|
2711 2527 | B: ::aws_smithy_legacy_http_server::body::HttpBody + Send,
|
2712 2528 | B: 'static,
|
2713 2529 |
|
2714 2530 | B::Data: Send,
|
2715 2531 | ::aws_smithy_legacy_http_server::protocol::aws_json::rejection::RequestRejection:
|
2716 2532 | From<<B as ::aws_smithy_legacy_http_server::body::HttpBody>::Error>,
|
2717 2533 | {
|
2718 2534 | type Rejection =
|
2719 2535 | ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError;
|
2720 - | type Future = SimpleScalarPropertiesInputFuture;
|
2536 + | type Future = ContentTypeParametersInputFuture;
|
2721 2537 |
|
2722 2538 | fn from_request(request: ::http::Request<B>) -> Self::Future {
|
2723 2539 | let fut = async move {
|
2724 2540 | if !::aws_smithy_legacy_http_server::protocol::accept_header_classifier(
|
2725 2541 | request.headers(),
|
2726 2542 | &crate::mimes::CONTENT_TYPE_APPLICATION_X_AMZ_JSON_1_0,
|
2727 2543 | ) {
|
2728 2544 | return Err(::aws_smithy_legacy_http_server::protocol::aws_json::rejection::RequestRejection::NotAcceptable);
|
2729 2545 | }
|
2730 - | crate::protocol_serde::shape_simple_scalar_properties::de_simple_scalar_properties_http_request(request)
|
2546 + | crate::protocol_serde::shape_content_type_parameters::de_content_type_parameters_http_request(request)
|
2731 2547 | .await
|
2732 2548 | };
|
2733 2549 | use ::futures_util::future::TryFutureExt;
|
2734 2550 | let fut = fut.map_err(|e: ::aws_smithy_legacy_http_server::protocol::aws_json::rejection::RequestRejection| {
|
2735 2551 | ::tracing::debug!(error = %e, "failed to deserialize request");
|
2736 2552 | ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError::from(e)
|
2737 2553 | });
|
2738 - | SimpleScalarPropertiesInputFuture {
|
2554 + | ContentTypeParametersInputFuture {
|
2739 2555 | inner: Box::pin(fut),
|
2740 2556 | }
|
2741 2557 | }
|
2742 2558 | }
|
2743 2559 | impl
|
2744 2560 | ::aws_smithy_legacy_http_server::response::IntoResponse<
|
2745 2561 | ::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0,
|
2746 - | > for crate::output::SimpleScalarPropertiesOutput
|
2562 + | > for crate::output::ContentTypeParametersOutput
|
2747 2563 | {
|
2748 2564 | fn into_response(self) -> ::aws_smithy_legacy_http_server::response::Response {
|
2749 - | match crate::protocol_serde::shape_simple_scalar_properties::ser_simple_scalar_properties_http_response(self) {
|
2565 + | match crate::protocol_serde::shape_content_type_parameters::ser_content_type_parameters_http_response(self) {
|
2750 2566 | Ok(response) => response,
|
2751 2567 | Err(e) => {
|
2752 2568 | ::tracing::error!(error = %e, "failed to serialize response");
|
2753 2569 | ::aws_smithy_legacy_http_server::response::IntoResponse::<::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0>::into_response(::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError::from(e))
|
2754 2570 | }
|
2755 2571 | }
|
2756 2572 | }
|
2757 2573 | }
|
2758 2574 |
|
2759 2575 | #[allow(unreachable_code, unused_variables)]
|
2760 2576 | #[cfg(test)]
|
2761 - | mod simple_scalar_properties_test {
|
2762 - |
|
2763 - | /// Supports handling NaN float values.
|
2764 - | /// Test ID: AwsJson10SupportsNaNFloatInputs
|
2765 - | #[::tokio::test]
|
2766 - | #[::tracing_test::traced_test]
|
2767 - | async fn aws_json10_supports_na_n_float_inputs_request() {
|
2768 - | #[allow(unused_mut)]
|
2769 - | let mut http_request = ::http::Request::builder()
|
2770 - | .uri("/")
|
2771 - | .method("POST")
|
2772 - | .header("Content-Type", "application/x-amz-json-1.0")
|
2773 - | .header("X-Amz-Target", "JsonRpc10.SimpleScalarProperties")
|
2774 - | .body(::aws_smithy_legacy_http_server::body::Body::from(
|
2775 - | ::bytes::Bytes::copy_from_slice(&::aws_smithy_protocol_test::decode_body_data(
|
2776 - | "{\n \"floatValue\": \"NaN\",\n \"doubleValue\": \"NaN\"\n}".as_bytes(),
|
2777 - | ::aws_smithy_protocol_test::MediaType::from("application/json"),
|
2778 - | )),
|
2779 - | ))
|
2780 - | .unwrap();
|
2781 - | #[allow(unused_mut)]
|
2782 - | let (sender, mut receiver) = ::tokio::sync::mpsc::channel(1);
|
2783 - | let config = crate::service::JsonRpc10Config::builder().build();
|
2784 - | let service = crate::service::JsonRpc10::builder::<::hyper::body::Body, _, _, _>(config)
|
2785 - | .simple_scalar_properties(move |input: crate::input::SimpleScalarPropertiesInput| {
|
2786 - | let sender = sender.clone();
|
2787 - | async move {
|
2788 - | let result = { use ::aws_smithy_protocol_test::FloatEquals;
|
2789 - | let expected =
|
2790 - | crate::input::SimpleScalarPropertiesInput {
|
2791 - | float_value:
|
2792 - | ::std::option::Option::Some(
|
2793 - | <f32 as ::aws_smithy_types::primitive::Parse>::parse_smithy_primitive("NaN").expect("invalid string for number")
|
2794 - | )
|
2795 - | ,
|
2796 - | double_value:
|
2797 - | ::std::option::Option::Some(
|
2798 - | <f64 as ::aws_smithy_types::primitive::Parse>::parse_smithy_primitive("NaN").expect("invalid string for number")
|
2799 - | )
|
2800 - | ,
|
2801 - | }
|
2802 - | ;
|
2803 - | assert!(input.float_value.float_equals(&expected.float_value),
|
2804 - | "Unexpected value for `float_value` {:?} vs. {:?}", expected.float_value, input.float_value);
|
2805 - | assert!(input.double_value.float_equals(&expected.double_value),
|
2806 - | "Unexpected value for `double_value` {:?} vs. {:?}", expected.double_value, input.double_value);
|
2807 - | let output =
|
2808 - | crate::output::SimpleScalarPropertiesOutput {
|
2809 - | float_value:
|
2810 - | ::std::option::Option::None
|
2811 - | ,
|
2812 - | double_value:
|
2813 - | ::std::option::Option::None
|
2814 - | ,
|
2815 - | }
|
2816 - | ;
|
2817 - | output };
|
2818 - | sender.send(()).await.expect("receiver dropped early");
|
2819 - | result
|
2820 - | }
|
2821 - | })
|
2822 - | .build_unchecked();
|
2823 - | let http_response = ::tower::ServiceExt::oneshot(service, http_request)
|
2824 - | .await
|
2825 - | .expect("unable to make an HTTP request");
|
2826 - | assert!(
|
2827 - | receiver.recv().await.is_some(),
|
2828 - | "we expected operation handler to be invoked but it was not entered"
|
2829 - | );
|
2830 - | }
|
2577 + | mod content_type_parameters_test {
|
2831 2578 |
|
2832 - | /// Supports handling Infinity float values.
|
2833 - | /// Test ID: AwsJson10SupportsInfinityFloatInputs
|
2579 + | /// A server should ignore parameters added to the content type
|
2580 + | /// Test ID: AwsJson10MustSupportParametersInContentType
|
2834 2581 | #[::tokio::test]
|
2835 - | #[::tracing_test::traced_test]
|
2836 - | async fn aws_json10_supports_infinity_float_inputs_request() {
|
2837 - | #[allow(unused_mut)]
|
2838 - | let mut http_request = ::http::Request::builder()
|
2839 - | .uri("/")
|
2840 - | .method("POST")
|
2841 - | .header("Content-Type", "application/x-amz-json-1.0")
|
2842 - | .header("X-Amz-Target", "JsonRpc10.SimpleScalarProperties")
|
2843 - | .body(::aws_smithy_legacy_http_server::body::Body::from(
|
2844 - | ::bytes::Bytes::copy_from_slice(&::aws_smithy_protocol_test::decode_body_data(
|
2845 - | "{\n \"floatValue\": \"Infinity\",\n \"doubleValue\": \"Infinity\"\n}"
|
2846 - | .as_bytes(),
|
2847 - | ::aws_smithy_protocol_test::MediaType::from("application/json"),
|
2848 - | )),
|
2849 - | ))
|
2850 - | .unwrap();
|
2851 - | #[allow(unused_mut)]
|
2852 - | let (sender, mut receiver) = ::tokio::sync::mpsc::channel(1);
|
2853 - | let config = crate::service::JsonRpc10Config::builder().build();
|
2854 - | let service = crate::service::JsonRpc10::builder::<::hyper::body::Body, _, _, _>(config)
|
2855 - | .simple_scalar_properties(move |input: crate::input::SimpleScalarPropertiesInput| {
|
2856 - | let sender = sender.clone();
|
2857 - | async move {
|
2858 - | let result = { use ::aws_smithy_protocol_test::FloatEquals;
|
2859 - | let expected =
|
2860 - | crate::input::SimpleScalarPropertiesInput {
|
2861 - | float_value:
|
2862 - | ::std::option::Option::Some(
|
2863 - | <f32 as ::aws_smithy_types::primitive::Parse>::parse_smithy_primitive("Infinity").expect("invalid string for number")
|
2864 - | )
|
2865 - | ,
|
2866 - | double_value:
|
2867 - | ::std::option::Option::Some(
|
2868 - | <f64 as ::aws_smithy_types::primitive::Parse>::parse_smithy_primitive("Infinity").expect("invalid string for number")
|
2869 - | )
|
2870 - | ,
|
2871 - | }
|
2872 - | ;
|
2873 - | assert!(input.float_value.float_equals(&expected.float_value),
|
2874 - | "Unexpected value for `float_value` {:?} vs. {:?}", expected.float_value, input.float_value);
|
2875 - | assert!(input.double_value.float_equals(&expected.double_value),
|
2876 - | "Unexpected value for `double_value` {:?} vs. {:?}", expected.double_value, input.double_value);
|
2877 - | let output =
|
2878 - | crate::output::SimpleScalarPropertiesOutput {
|
2879 - | float_value:
|
2880 - | ::std::option::Option::None
|
2881 - | ,
|
2882 - | double_value:
|
2883 - | ::std::option::Option::None
|
2884 - | ,
|
2885 - | }
|
2886 - | ;
|
2887 - | output };
|
2582 + | #[::tracing_test::traced_test]
|
2583 + | async fn aws_json10_must_support_parameters_in_content_type_request() {
|
2584 + | #[allow(unused_mut)]
|
2585 + | let mut http_request = ::http::Request::builder()
|
2586 + | .uri("/")
|
2587 + | .method("POST")
|
2588 + | .header("Content-Type", "application/x-amz-json-1.0; charset=utf-8")
|
2589 + | .header("X-Amz-Target", "JsonRpc10.ContentTypeParameters")
|
2590 + | .body(::aws_smithy_legacy_http_server::body::Body::from(
|
2591 + | ::bytes::Bytes::copy_from_slice(&::aws_smithy_protocol_test::decode_body_data(
|
2592 + | "{\"value\":5}".as_bytes(),
|
2593 + | ::aws_smithy_protocol_test::MediaType::from("application/json"),
|
2594 + | )),
|
2595 + | ))
|
2596 + | .unwrap();
|
2597 + | #[allow(unused_mut)]
|
2598 + | let (sender, mut receiver) = ::tokio::sync::mpsc::channel(1);
|
2599 + | let config = crate::service::JsonRpc10Config::builder().build();
|
2600 + | let service = crate::service::JsonRpc10::builder::<::hyper::body::Body, _, _, _>(config)
|
2601 + | .content_type_parameters(move |input: crate::input::ContentTypeParametersInput| {
|
2602 + | let sender = sender.clone();
|
2603 + | async move {
|
2604 + | let result = {
|
2605 + | let expected = crate::input::ContentTypeParametersInput {
|
2606 + | value: ::std::option::Option::Some(5),
|
2607 + | };
|
2608 + | ::pretty_assertions::assert_eq!(input, expected);
|
2609 + | let output = crate::output::ContentTypeParametersOutput {};
|
2610 + | output
|
2611 + | };
|
2888 2612 | sender.send(()).await.expect("receiver dropped early");
|
2889 2613 | result
|
2890 2614 | }
|
2891 2615 | })
|
2892 2616 | .build_unchecked();
|
2893 2617 | let http_response = ::tower::ServiceExt::oneshot(service, http_request)
|
2894 2618 | .await
|
2895 2619 | .expect("unable to make an HTTP request");
|
2896 2620 | assert!(
|
2897 2621 | receiver.recv().await.is_some(),
|
2898 2622 | "we expected operation handler to be invoked but it was not entered"
|
2899 2623 | );
|
2900 2624 | }
|
2625 + | }
|
2901 2626 |
|
2902 - | /// Supports handling -Infinity float values.
|
2903 - | /// Test ID: AwsJson10SupportsNegativeInfinityFloatInputs
|
2627 + | ::pin_project_lite::pin_project! {
|
2628 + | /// A [`Future`](std::future::Future) aggregating the body bytes of a [`Request`] and constructing the
|
2629 + | /// [`OperationWithDefaultsInput`](crate::input::OperationWithDefaultsInput) using modelled bindings.
|
2630 + | pub struct OperationWithDefaultsInputFuture {
|
2631 + | inner: std::pin::Pin<Box<dyn std::future::Future<Output = Result<crate::input::OperationWithDefaultsInput, ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError>> + Send>>
|
2632 + | }
|
2633 + | }
|
2634 + |
|
2635 + | impl std::future::Future for OperationWithDefaultsInputFuture {
|
2636 + | type Output = Result<
|
2637 + | crate::input::OperationWithDefaultsInput,
|
2638 + | ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError,
|
2639 + | >;
|
2640 + |
|
2641 + | fn poll(
|
2642 + | self: std::pin::Pin<&mut Self>,
|
2643 + | cx: &mut std::task::Context<'_>,
|
2644 + | ) -> std::task::Poll<Self::Output> {
|
2645 + | let this = self.project();
|
2646 + | this.inner.as_mut().poll(cx)
|
2647 + | }
|
2648 + | }
|
2649 + |
|
2650 + | impl<B>
|
2651 + | ::aws_smithy_legacy_http_server::request::FromRequest<
|
2652 + | ::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0,
|
2653 + | B,
|
2654 + | > for crate::input::OperationWithDefaultsInput
|
2655 + | where
|
2656 + | B: ::aws_smithy_legacy_http_server::body::HttpBody + Send,
|
2657 + | B: 'static,
|
2658 + |
|
2659 + | B::Data: Send,
|
2660 + | ::aws_smithy_legacy_http_server::protocol::aws_json::rejection::RequestRejection:
|
2661 + | From<<B as ::aws_smithy_legacy_http_server::body::HttpBody>::Error>,
|
2662 + | {
|
2663 + | type Rejection =
|
2664 + | ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError;
|
2665 + | type Future = OperationWithDefaultsInputFuture;
|
2666 + |
|
2667 + | fn from_request(request: ::http::Request<B>) -> Self::Future {
|
2668 + | let fut = async move {
|
2669 + | if !::aws_smithy_legacy_http_server::protocol::accept_header_classifier(
|
2670 + | request.headers(),
|
2671 + | &crate::mimes::CONTENT_TYPE_APPLICATION_X_AMZ_JSON_1_0,
|
2672 + | ) {
|
2673 + | return Err(::aws_smithy_legacy_http_server::protocol::aws_json::rejection::RequestRejection::NotAcceptable);
|
2674 + | }
|
2675 + | crate::protocol_serde::shape_operation_with_defaults::de_operation_with_defaults_http_request(request)
|
2676 + | .await
|
2677 + | };
|
2678 + | use ::futures_util::future::TryFutureExt;
|
2679 + | let fut = fut.map_err(|e: ::aws_smithy_legacy_http_server::protocol::aws_json::rejection::RequestRejection| {
|
2680 + | ::tracing::debug!(error = %e, "failed to deserialize request");
|
2681 + | ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError::from(e)
|
2682 + | });
|
2683 + | OperationWithDefaultsInputFuture {
|
2684 + | inner: Box::pin(fut),
|
2685 + | }
|
2686 + | }
|
2687 + | }
|
2688 + | impl
|
2689 + | ::aws_smithy_legacy_http_server::response::IntoResponse<
|
2690 + | ::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0,
|
2691 + | > for crate::output::OperationWithDefaultsOutput
|
2692 + | {
|
2693 + | fn into_response(self) -> ::aws_smithy_legacy_http_server::response::Response {
|
2694 + | match crate::protocol_serde::shape_operation_with_defaults::ser_operation_with_defaults_http_response(self) {
|
2695 + | Ok(response) => response,
|
2696 + | Err(e) => {
|
2697 + | ::tracing::error!(error = %e, "failed to serialize response");
|
2698 + | ::aws_smithy_legacy_http_server::response::IntoResponse::<::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0>::into_response(::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError::from(e))
|
2699 + | }
|
2700 + | }
|
2701 + | }
|
2702 + | }
|
2703 + | impl
|
2704 + | ::aws_smithy_legacy_http_server::response::IntoResponse<
|
2705 + | ::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0,
|
2706 + | > for crate::error::OperationWithDefaultsError
|
2707 + | {
|
2708 + | fn into_response(self) -> ::aws_smithy_legacy_http_server::response::Response {
|
2709 + | match crate::protocol_serde::shape_operation_with_defaults::ser_operation_with_defaults_http_error(&self) {
|
2710 + | Ok(mut response) => {
|
2711 + | response.extensions_mut().insert(::aws_smithy_legacy_http_server::extension::ModeledErrorExtension::new(self.name()));
|
2712 + | response
|
2713 + | },
|
2714 + | Err(e) => {
|
2715 + | ::tracing::error!(error = %e, "failed to serialize response");
|
2716 + | ::aws_smithy_legacy_http_server::response::IntoResponse::<::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0>::into_response(::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError::from(e))
|
2717 + | }
|
2718 + | }
|
2719 + | }
|
2720 + | }
|
2721 + |
|
2722 + | #[allow(unreachable_code, unused_variables)]
|
2723 + | #[cfg(test)]
|
2724 + | mod operation_with_defaults_test {
|
2725 + |
|
2726 + | /// Server populates default values when missing in request body.
|
2727 + | /// Test ID: AwsJson10ServerPopulatesDefaultsWhenMissingInRequestBody
|
2904 2728 | #[::tokio::test]
|
2905 2729 | #[::tracing_test::traced_test]
|
2906 - | async fn aws_json10_supports_negative_infinity_float_inputs_request() {
|
2730 + | #[should_panic]
|
2731 + | async fn aws_json10_server_populates_defaults_when_missing_in_request_body_request() {
|
2907 2732 | #[allow(unused_mut)]
|
2908 2733 | let mut http_request = ::http::Request::builder()
|
2909 2734 | .uri("/")
|
2910 2735 | .method("POST")
|
2911 2736 | .header("Content-Type", "application/x-amz-json-1.0")
|
2912 - | .header("X-Amz-Target", "JsonRpc10.SimpleScalarProperties")
|
2913 2737 | .body(::aws_smithy_legacy_http_server::body::Body::from(
|
2914 2738 | ::bytes::Bytes::copy_from_slice(&::aws_smithy_protocol_test::decode_body_data(
|
2915 - | "{\n \"floatValue\": \"-Infinity\",\n \"doubleValue\": \"-Infinity\"\n}"
|
2916 - | .as_bytes(),
|
2739 + | "{\n\"defaults\": {}\n}".as_bytes(),
|
2917 2740 | ::aws_smithy_protocol_test::MediaType::from("application/json"),
|
2918 2741 | )),
|
2919 2742 | ))
|
2920 2743 | .unwrap();
|
2921 2744 | #[allow(unused_mut)]
|
2922 2745 | let (sender, mut receiver) = ::tokio::sync::mpsc::channel(1);
|
2923 2746 | let config = crate::service::JsonRpc10Config::builder().build();
|
2924 2747 | let service = crate::service::JsonRpc10::builder::<::hyper::body::Body, _, _, _>(config)
|
2925 - | .simple_scalar_properties(move |input: crate::input::SimpleScalarPropertiesInput| {
|
2748 + | .operation_with_defaults(move |input: crate::input::OperationWithDefaultsInput| {
|
2926 2749 | let sender = sender.clone();
|
2927 2750 | async move {
|
2928 - | let result = { use ::aws_smithy_protocol_test::FloatEquals;
|
2929 - | let expected =
|
2930 - | crate::input::SimpleScalarPropertiesInput {
|
2931 - | float_value:
|
2932 - | ::std::option::Option::Some(
|
2933 - | <f32 as ::aws_smithy_types::primitive::Parse>::parse_smithy_primitive("-Infinity").expect("invalid string for number")
|
2751 + | let result = {
|
2752 + | let expected = crate::input::OperationWithDefaultsInput {
|
2753 + | defaults: ::std::option::Option::Some(crate::model::Defaults {
|
2754 + | default_string: "hi".to_owned(),
|
2755 + | default_boolean: true,
|
2756 + | default_list: vec![],
|
2757 + | default_document_map: {
|
2758 + | let json_bytes = br#"{}"#;
|
2759 + | let mut tokens =
|
2760 + | ::aws_smithy_json::deserialize::json_token_iter(json_bytes)
|
2761 + | .peekable();
|
2762 + | ::aws_smithy_json::deserialize::token::expect_document(
|
2763 + | &mut tokens,
|
2934 2764 | )
|
2935 - | ,
|
2936 - | double_value:
|
2937 - | ::std::option::Option::Some(
|
2938 - | <f64 as ::aws_smithy_types::primitive::Parse>::parse_smithy_primitive("-Infinity").expect("invalid string for number")
|
2765 + | .expect("well formed json")
|
2766 + | },
|
2767 + | default_document_string: {
|
2768 + | let json_bytes = br#""hi""#;
|
2769 + | let mut tokens =
|
2770 + | ::aws_smithy_json::deserialize::json_token_iter(json_bytes)
|
2771 + | .peekable();
|
2772 + | ::aws_smithy_json::deserialize::token::expect_document(
|
2773 + | &mut tokens,
|
2939 2774 | )
|
2940 - | ,
|
2941 - | }
|
2942 - | ;
|
2943 - | assert!(input.float_value.float_equals(&expected.float_value),
|
2944 - | "Unexpected value for `float_value` {:?} vs. {:?}", expected.float_value, input.float_value);
|
2945 - | assert!(input.double_value.float_equals(&expected.double_value),
|
2946 - | "Unexpected value for `double_value` {:?} vs. {:?}", expected.double_value, input.double_value);
|
2947 - | let output =
|
2948 - | crate::output::SimpleScalarPropertiesOutput {
|
2949 - | float_value:
|
2950 - | ::std::option::Option::None
|
2951 - | ,
|
2952 - | double_value:
|
2953 - | ::std::option::Option::None
|
2954 - | ,
|
2955 - | }
|
2956 - | ;
|
2957 - | output };
|
2775 + | .expect("well formed json")
|
2776 + | },
|
2777 + | default_document_boolean: {
|
2778 + | let json_bytes = br#"true"#;
|
2779 + | let mut tokens =
|
2780 + | ::aws_smithy_json::deserialize::json_token_iter(json_bytes)
|
2781 + | .peekable();
|
2782 + | ::aws_smithy_json::deserialize::token::expect_document(
|
2783 + | &mut tokens,
|
2784 + | )
|
2785 + | .expect("well formed json")
|
2786 + | },
|
2787 + | default_document_list: {
|
2788 + | let json_bytes = br#"[]"#;
|
2789 + | let mut tokens =
|
2790 + | ::aws_smithy_json::deserialize::json_token_iter(json_bytes)
|
2791 + | .peekable();
|
2792 + | ::aws_smithy_json::deserialize::token::expect_document(
|
2793 + | &mut tokens,
|
2794 + | )
|
2795 + | .expect("well formed json")
|
2796 + | },
|
2797 + | default_timestamp:
|
2798 + | ::aws_smithy_types::DateTime::from_fractional_secs(0, 0_f64),
|
2799 + | default_blob: ::aws_smithy_types::Blob::new("abc"),
|
2800 + | default_byte: 1,
|
2801 + | default_short: 1,
|
2802 + | default_integer: 10,
|
2803 + | default_long: 100,
|
2804 + | default_float: 1.0_f32,
|
2805 + | default_double: 1.0_f64,
|
2806 + | default_map: ::std::collections::HashMap::new(),
|
2807 + | default_enum: "FOO"
|
2808 + | .parse::<crate::model::TestEnum>()
|
2809 + | .expect("static value validated to member"),
|
2810 + | default_int_enum: 1,
|
2811 + | empty_string: "".to_owned(),
|
2812 + | false_boolean: false,
|
2813 + | empty_blob: ::aws_smithy_types::Blob::new(""),
|
2814 + | zero_byte: 0,
|
2815 + | zero_short: 0,
|
2816 + | zero_integer: 0,
|
2817 + | zero_long: 0,
|
2818 + | zero_float: 0.0_f32,
|
2819 + | zero_double: 0.0_f64,
|
2820 + | default_null_document: ::std::option::Option::Some({
|
2821 + | let json_bytes = br#"null"#;
|
2822 + | let mut tokens =
|
2823 + | ::aws_smithy_json::deserialize::json_token_iter(json_bytes)
|
2824 + | .peekable();
|
2825 + | ::aws_smithy_json::deserialize::token::expect_document(
|
2826 + | &mut tokens,
|
2827 + | )
|
2828 + | .expect("well formed json")
|
2829 + | }),
|
2830 + | }),
|
2831 + | top_level_default: "hi".to_owned(),
|
2832 + | other_top_level_default: 0,
|
2833 + | client_optional_defaults: ::std::option::Option::None,
|
2834 + | };
|
2835 + | ::pretty_assertions::assert_eq!(input, expected);
|
2836 + | let output = crate::output::OperationWithDefaultsOutput {
|
2837 + | default_string: "".to_owned(),
|
2838 + | default_boolean: false,
|
2839 + | default_list: vec![],
|
2840 + | default_document_map: {
|
2841 + | let json_bytes = br#"{}"#;
|
2842 + | let mut tokens =
|
2843 + | ::aws_smithy_json::deserialize::json_token_iter(json_bytes)
|
2844 + | .peekable();
|
2845 + | ::aws_smithy_json::deserialize::token::expect_document(&mut tokens)
|
2846 + | .expect("well formed json")
|
2847 + | },
|
2848 + | default_document_string: {
|
2849 + | let json_bytes = br#"{}"#;
|
2850 + | let mut tokens =
|
2851 + | ::aws_smithy_json::deserialize::json_token_iter(json_bytes)
|
2852 + | .peekable();
|
2853 + | ::aws_smithy_json::deserialize::token::expect_document(&mut tokens)
|
2854 + | .expect("well formed json")
|
2855 + | },
|
2856 + | default_document_boolean: {
|
2857 + | let json_bytes = br#"{}"#;
|
2858 + | let mut tokens =
|
2859 + | ::aws_smithy_json::deserialize::json_token_iter(json_bytes)
|
2860 + | .peekable();
|
2861 + | ::aws_smithy_json::deserialize::token::expect_document(&mut tokens)
|
2862 + | .expect("well formed json")
|
2863 + | },
|
2864 + | default_document_list: {
|
2865 + | let json_bytes = br#"{}"#;
|
2866 + | let mut tokens =
|
2867 + | ::aws_smithy_json::deserialize::json_token_iter(json_bytes)
|
2868 + | .peekable();
|
2869 + | ::aws_smithy_json::deserialize::token::expect_document(&mut tokens)
|
2870 + | .expect("well formed json")
|
2871 + | },
|
2872 + | default_timestamp: ::aws_smithy_types::DateTime::from_fractional_secs(
|
2873 + | 0, 0_f64,
|
2874 + | ),
|
2875 + | default_blob: ::aws_smithy_types::Blob::new(""),
|
2876 + | default_byte: 0,
|
2877 + | default_short: 0,
|
2878 + | default_integer: 0,
|
2879 + | default_long: 0,
|
2880 + | default_float: 0_f32,
|
2881 + | default_double: 0_f64,
|
2882 + | default_map: ::std::collections::HashMap::new(),
|
2883 + | default_enum: ""
|
2884 + | .parse::<crate::model::TestEnum>()
|
2885 + | .expect("static value validated to member"),
|
2886 + | default_int_enum: 0,
|
2887 + | empty_string: "".to_owned(),
|
2888 + | false_boolean: false,
|
2889 + | empty_blob: ::aws_smithy_types::Blob::new(""),
|
2890 + | zero_byte: 0,
|
2891 + | zero_short: 0,
|
2892 + | zero_integer: 0,
|
2893 + | zero_long: 0,
|
2894 + | zero_float: 0_f32,
|
2895 + | zero_double: 0_f64,
|
2896 + | default_null_document: ::std::option::Option::Some({
|
2897 + | let json_bytes = br#"null"#;
|
2898 + | let mut tokens =
|
2899 + | ::aws_smithy_json::deserialize::json_token_iter(json_bytes)
|
2900 + | .peekable();
|
2901 + | ::aws_smithy_json::deserialize::token::expect_document(&mut tokens)
|
2902 + | .expect("well formed json")
|
2903 + | }),
|
2904 + | };
|
2905 + | Ok(output)
|
2906 + | };
|
2958 2907 | sender.send(()).await.expect("receiver dropped early");
|
2959 2908 | result
|
2960 2909 | }
|
2961 2910 | })
|
2962 2911 | .build_unchecked();
|
2963 2912 | let http_response = ::tower::ServiceExt::oneshot(service, http_request)
|
2964 2913 | .await
|
2965 2914 | .expect("unable to make an HTTP request");
|
2966 2915 | assert!(
|
2967 2916 | receiver.recv().await.is_some(),
|
2968 2917 | "we expected operation handler to be invoked but it was not entered"
|
2969 2918 | );
|
2970 2919 | }
|
2971 2920 |
|
2972 - | /// Supports handling NaN float values.
|
2973 - | /// Test ID: AwsJson10SupportsNaNFloatInputs
|
2921 + | /// Server populates default values in response when missing in params.
|
2922 + | /// Test ID: AwsJson10ServerPopulatesDefaultsInResponseWhenMissingInParams
|
2974 2923 | #[::tokio::test]
|
2975 2924 | #[::tracing_test::traced_test]
|
2976 - | async fn aws_json10_supports_na_n_float_inputs_response() {
|
2977 - | let output = crate::output::SimpleScalarPropertiesOutput {
|
2978 - | float_value: ::std::option::Option::Some(
|
2979 - | <f32 as ::aws_smithy_types::primitive::Parse>::parse_smithy_primitive("NaN")
|
2980 - | .expect("invalid string for number"),
|
2981 - | ),
|
2982 - | double_value: ::std::option::Option::Some(
|
2983 - | <f64 as ::aws_smithy_types::primitive::Parse>::parse_smithy_primitive("NaN")
|
2984 - | .expect("invalid string for number"),
|
2985 - | ),
|
2925 + | #[should_panic]
|
2926 + | async fn aws_json10_server_populates_defaults_in_response_when_missing_in_params_response() {
|
2927 + | let output = crate::output::OperationWithDefaultsOutput {
|
2928 + | default_string: "".to_owned(),
|
2929 + | default_boolean: false,
|
2930 + | default_list: vec![],
|
2931 + | default_document_map: {
|
2932 + | let json_bytes = br#"{}"#;
|
2933 + | let mut tokens =
|
2934 + | ::aws_smithy_json::deserialize::json_token_iter(json_bytes).peekable();
|
2935 + | ::aws_smithy_json::deserialize::token::expect_document(&mut tokens)
|
2936 + | .expect("well formed json")
|
2937 + | },
|
2938 + | default_document_string: {
|
2939 + | let json_bytes = br#"{}"#;
|
2940 + | let mut tokens =
|
2941 + | ::aws_smithy_json::deserialize::json_token_iter(json_bytes).peekable();
|
2942 + | ::aws_smithy_json::deserialize::token::expect_document(&mut tokens)
|
2943 + | .expect("well formed json")
|
2944 + | },
|
2945 + | default_document_boolean: {
|
2946 + | let json_bytes = br#"{}"#;
|
2947 + | let mut tokens =
|
2948 + | ::aws_smithy_json::deserialize::json_token_iter(json_bytes).peekable();
|
2949 + | ::aws_smithy_json::deserialize::token::expect_document(&mut tokens)
|
2950 + | .expect("well formed json")
|
2951 + | },
|
2952 + | default_document_list: {
|
2953 + | let json_bytes = br#"{}"#;
|
2954 + | let mut tokens =
|
2955 + | ::aws_smithy_json::deserialize::json_token_iter(json_bytes).peekable();
|
2956 + | ::aws_smithy_json::deserialize::token::expect_document(&mut tokens)
|
2957 + | .expect("well formed json")
|
2958 + | },
|
2959 + | default_timestamp: ::aws_smithy_types::DateTime::from_fractional_secs(0, 0_f64),
|
2960 + | default_blob: ::aws_smithy_types::Blob::new(""),
|
2961 + | default_byte: 0,
|
2962 + | default_short: 0,
|
2963 + | default_integer: 0,
|
2964 + | default_long: 0,
|
2965 + | default_float: 0_f32,
|
2966 + | default_double: 0_f64,
|
2967 + | default_map: ::std::collections::HashMap::new(),
|
2968 + | default_enum: ""
|
2969 + | .parse::<crate::model::TestEnum>()
|
2970 + | .expect("static value validated to member"),
|
2971 + | default_int_enum: 0,
|
2972 + | empty_string: "".to_owned(),
|
2973 + | false_boolean: false,
|
2974 + | empty_blob: ::aws_smithy_types::Blob::new(""),
|
2975 + | zero_byte: 0,
|
2976 + | zero_short: 0,
|
2977 + | zero_integer: 0,
|
2978 + | zero_long: 0,
|
2979 + | zero_float: 0_f32,
|
2980 + | zero_double: 0_f64,
|
2981 + | default_null_document: ::std::option::Option::Some({
|
2982 + | let json_bytes = br#"null"#;
|
2983 + | let mut tokens =
|
2984 + | ::aws_smithy_json::deserialize::json_token_iter(json_bytes).peekable();
|
2985 + | ::aws_smithy_json::deserialize::token::expect_document(&mut tokens)
|
2986 + | .expect("well formed json")
|
2987 + | }),
|
2986 2988 | };
|
2987 2989 | use ::aws_smithy_legacy_http_server::response::IntoResponse;
|
2988 2990 | let http_response = output.into_response();
|
2989 2991 | ::pretty_assertions::assert_eq!(
|
2990 2992 | ::http::StatusCode::from_u16(200).expect("invalid expected HTTP status code"),
|
2991 2993 | http_response.status()
|
2992 2994 | );
|
2993 2995 | let expected_headers = [("Content-Type", "application/x-amz-json-1.0")];
|
2994 2996 | ::aws_smithy_protocol_test::assert_ok(::aws_smithy_protocol_test::validate_headers(
|
2995 2997 | http_response.headers(),
|
2996 2998 | expected_headers,
|
2997 2999 | ));
|
2998 3000 | let body = ::hyper::body::to_bytes(http_response.into_body())
|
2999 3001 | .await
|
3000 3002 | .expect("unable to extract body to bytes");
|
3001 - | ::aws_smithy_protocol_test::assert_ok(::aws_smithy_protocol_test::validate_body(
|
3002 - | &body,
|
3003 - | "{\n \"floatValue\": \"NaN\",\n \"doubleValue\": \"NaN\"\n}",
|
3004 - | ::aws_smithy_protocol_test::MediaType::from("application/json"),
|
3005 - | ));
|
3003 + | ::aws_smithy_protocol_test::assert_ok(
|
3004 + | ::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"))
|
3005 + | );
|
3006 3006 | }
|
3007 + | }
|
3007 3008 |
|
3008 - | /// Supports handling Infinity float values.
|
3009 - | /// Test ID: AwsJson10SupportsInfinityFloatInputs
|
3010 - | #[::tokio::test]
|
3011 - | #[::tracing_test::traced_test]
|
3012 - | async fn aws_json10_supports_infinity_float_inputs_response() {
|
3013 - | let output = crate::output::SimpleScalarPropertiesOutput {
|
3014 - | float_value: ::std::option::Option::Some(
|
3015 - | <f32 as ::aws_smithy_types::primitive::Parse>::parse_smithy_primitive("Infinity")
|
3016 - | .expect("invalid string for number"),
|
3017 - | ),
|
3018 - | double_value: ::std::option::Option::Some(
|
3019 - | <f64 as ::aws_smithy_types::primitive::Parse>::parse_smithy_primitive("Infinity")
|
3020 - | .expect("invalid string for number"),
|
3021 - | ),
|
3022 - | };
|
3023 - | use ::aws_smithy_legacy_http_server::response::IntoResponse;
|
3024 - | let http_response = output.into_response();
|
3025 - | ::pretty_assertions::assert_eq!(
|
3026 - | ::http::StatusCode::from_u16(200).expect("invalid expected HTTP status code"),
|
3027 - | http_response.status()
|
3028 - | );
|
3029 - | let expected_headers = [("Content-Type", "application/x-amz-json-1.0")];
|
3030 - | ::aws_smithy_protocol_test::assert_ok(::aws_smithy_protocol_test::validate_headers(
|
3031 - | http_response.headers(),
|
3032 - | expected_headers,
|
3033 - | ));
|
3034 - | let body = ::hyper::body::to_bytes(http_response.into_body())
|
3035 - | .await
|
3036 - | .expect("unable to extract body to bytes");
|
3037 - | ::aws_smithy_protocol_test::assert_ok(::aws_smithy_protocol_test::validate_body(
|
3038 - | &body,
|
3039 - | "{\n \"floatValue\": \"Infinity\",\n \"doubleValue\": \"Infinity\"\n}",
|
3040 - | ::aws_smithy_protocol_test::MediaType::from("application/json"),
|
3041 - | ));
|
3009 + | ::pin_project_lite::pin_project! {
|
3010 + | /// A [`Future`](std::future::Future) aggregating the body bytes of a [`Request`] and constructing the
|
3011 + | /// [`OperationWithRequiredMembersInput`](crate::input::OperationWithRequiredMembersInput) using modelled bindings.
|
3012 + | pub struct OperationWithRequiredMembersInputFuture {
|
3013 + | inner: std::pin::Pin<Box<dyn std::future::Future<Output = Result<crate::input::OperationWithRequiredMembersInput, ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError>> + Send>>
|
3042 3014 | }
|
3015 + | }
|
3043 3016 |
|
3044 - | /// Supports handling -Infinity float values.
|
3045 - | /// Test ID: AwsJson10SupportsNegativeInfinityFloatInputs
|
3046 - | #[::tokio::test]
|
3047 - | #[::tracing_test::traced_test]
|
3048 - | async fn aws_json10_supports_negative_infinity_float_inputs_response() {
|
3049 - | let output = crate::output::SimpleScalarPropertiesOutput {
|
3050 - | float_value: ::std::option::Option::Some(
|
3051 - | <f32 as ::aws_smithy_types::primitive::Parse>::parse_smithy_primitive("-Infinity")
|
3052 - | .expect("invalid string for number"),
|
3053 - | ),
|
3054 - | double_value: ::std::option::Option::Some(
|
3055 - | <f64 as ::aws_smithy_types::primitive::Parse>::parse_smithy_primitive("-Infinity")
|
3056 - | .expect("invalid string for number"),
|
3057 - | ),
|
3058 - | };
|
3059 - | use ::aws_smithy_legacy_http_server::response::IntoResponse;
|
3060 - | let http_response = output.into_response();
|
3061 - | ::pretty_assertions::assert_eq!(
|
3062 - | ::http::StatusCode::from_u16(200).expect("invalid expected HTTP status code"),
|
3063 - | http_response.status()
|
3064 - | );
|
3065 - | let expected_headers = [("Content-Type", "application/x-amz-json-1.0")];
|
3066 - | ::aws_smithy_protocol_test::assert_ok(::aws_smithy_protocol_test::validate_headers(
|
3067 - | http_response.headers(),
|
3068 - | expected_headers,
|
3069 - | ));
|
3070 - | let body = ::hyper::body::to_bytes(http_response.into_body())
|
3017 + | impl std::future::Future for OperationWithRequiredMembersInputFuture {
|
3018 + | type Output = Result<
|
3019 + | crate::input::OperationWithRequiredMembersInput,
|
3020 + | ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError,
|
3021 + | >;
|
3022 + |
|
3023 + | fn poll(
|
3024 + | self: std::pin::Pin<&mut Self>,
|
3025 + | cx: &mut std::task::Context<'_>,
|
3026 + | ) -> std::task::Poll<Self::Output> {
|
3027 + | let this = self.project();
|
3028 + | this.inner.as_mut().poll(cx)
|
3029 + | }
|
3030 + | }
|
3031 + |
|
3032 + | impl<B>
|
3033 + | ::aws_smithy_legacy_http_server::request::FromRequest<
|
3034 + | ::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0,
|
3035 + | B,
|
3036 + | > for crate::input::OperationWithRequiredMembersInput
|
3037 + | where
|
3038 + | B: ::aws_smithy_legacy_http_server::body::HttpBody + Send,
|
3039 + | B: 'static,
|
3040 + |
|
3041 + | B::Data: Send,
|
3042 + | ::aws_smithy_legacy_http_server::protocol::aws_json::rejection::RequestRejection:
|
3043 + | From<<B as ::aws_smithy_legacy_http_server::body::HttpBody>::Error>,
|
3044 + | {
|
3045 + | type Rejection =
|
3046 + | ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError;
|
3047 + | type Future = OperationWithRequiredMembersInputFuture;
|
3048 + |
|
3049 + | fn from_request(request: ::http::Request<B>) -> Self::Future {
|
3050 + | let fut = async move {
|
3051 + | if !::aws_smithy_legacy_http_server::protocol::accept_header_classifier(
|
3052 + | request.headers(),
|
3053 + | &crate::mimes::CONTENT_TYPE_APPLICATION_X_AMZ_JSON_1_0,
|
3054 + | ) {
|
3055 + | return Err(::aws_smithy_legacy_http_server::protocol::aws_json::rejection::RequestRejection::NotAcceptable);
|
3056 + | }
|
3057 + | crate::protocol_serde::shape_operation_with_required_members::de_operation_with_required_members_http_request(request)
|
3071 3058 | .await
|
3072 - | .expect("unable to extract body to bytes");
|
3073 - | ::aws_smithy_protocol_test::assert_ok(::aws_smithy_protocol_test::validate_body(
|
3074 - | &body,
|
3075 - | "{\n \"floatValue\": \"-Infinity\",\n \"doubleValue\": \"-Infinity\"\n}",
|
3076 - | ::aws_smithy_protocol_test::MediaType::from("application/json"),
|
3077 - | ));
|
3059 + | };
|
3060 + | use ::futures_util::future::TryFutureExt;
|
3061 + | let fut = fut.map_err(|e: ::aws_smithy_legacy_http_server::protocol::aws_json::rejection::RequestRejection| {
|
3062 + | ::tracing::debug!(error = %e, "failed to deserialize request");
|
3063 + | ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError::from(e)
|
3064 + | });
|
3065 + | OperationWithRequiredMembersInputFuture {
|
3066 + | inner: Box::pin(fut),
|
3067 + | }
|
3068 + | }
|
3069 + | }
|
3070 + | impl
|
3071 + | ::aws_smithy_legacy_http_server::response::IntoResponse<
|
3072 + | ::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0,
|
3073 + | > for crate::output::OperationWithRequiredMembersOutput
|
3074 + | {
|
3075 + | fn into_response(self) -> ::aws_smithy_legacy_http_server::response::Response {
|
3076 + | match crate::protocol_serde::shape_operation_with_required_members::ser_operation_with_required_members_http_response(self) {
|
3077 + | Ok(response) => response,
|
3078 + | Err(e) => {
|
3079 + | ::tracing::error!(error = %e, "failed to serialize response");
|
3080 + | ::aws_smithy_legacy_http_server::response::IntoResponse::<::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0>::into_response(::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError::from(e))
|
3081 + | }
|
3082 + | }
|
3078 3083 | }
|
3079 3084 | }
|
3080 3085 |
|
3081 3086 | ::pin_project_lite::pin_project! {
|
3082 3087 | /// A [`Future`](std::future::Future) aggregating the body bytes of a [`Request`] and constructing the
|
3083 - | /// [`EmptyInputAndEmptyOutputInput`](crate::input::EmptyInputAndEmptyOutputInput) using modelled bindings.
|
3084 - | pub struct EmptyInputAndEmptyOutputInputFuture {
|
3085 - | inner: std::pin::Pin<Box<dyn std::future::Future<Output = Result<crate::input::EmptyInputAndEmptyOutputInput, ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError>> + Send>>
|
3088 + | /// [`OperationWithNestedStructureInput`](crate::input::OperationWithNestedStructureInput) using modelled bindings.
|
3089 + | pub struct OperationWithNestedStructureInputFuture {
|
3090 + | inner: std::pin::Pin<Box<dyn std::future::Future<Output = Result<crate::input::OperationWithNestedStructureInput, ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError>> + Send>>
|
3086 3091 | }
|
3087 3092 | }
|
3088 3093 |
|
3089 - | impl std::future::Future for EmptyInputAndEmptyOutputInputFuture {
|
3094 + | impl std::future::Future for OperationWithNestedStructureInputFuture {
|
3090 3095 | type Output = Result<
|
3091 - | crate::input::EmptyInputAndEmptyOutputInput,
|
3096 + | crate::input::OperationWithNestedStructureInput,
|
3092 3097 | ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError,
|
3093 3098 | >;
|
3094 3099 |
|
3095 3100 | fn poll(
|
3096 3101 | self: std::pin::Pin<&mut Self>,
|
3097 3102 | cx: &mut std::task::Context<'_>,
|
3098 3103 | ) -> std::task::Poll<Self::Output> {
|
3099 3104 | let this = self.project();
|
3100 3105 | this.inner.as_mut().poll(cx)
|
3101 3106 | }
|
3102 3107 | }
|
3103 3108 |
|
3104 3109 | impl<B>
|
3105 3110 | ::aws_smithy_legacy_http_server::request::FromRequest<
|
3106 3111 | ::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0,
|
3107 3112 | B,
|
3108 - | > for crate::input::EmptyInputAndEmptyOutputInput
|
3113 + | > for crate::input::OperationWithNestedStructureInput
|
3109 3114 | where
|
3110 3115 | B: ::aws_smithy_legacy_http_server::body::HttpBody + Send,
|
3111 3116 | B: 'static,
|
3112 3117 |
|
3113 3118 | B::Data: Send,
|
3114 3119 | ::aws_smithy_legacy_http_server::protocol::aws_json::rejection::RequestRejection:
|
3115 3120 | From<<B as ::aws_smithy_legacy_http_server::body::HttpBody>::Error>,
|
3116 3121 | {
|
3117 3122 | type Rejection =
|
3118 3123 | ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError;
|
3119 - | type Future = EmptyInputAndEmptyOutputInputFuture;
|
3124 + | type Future = OperationWithNestedStructureInputFuture;
|
3120 3125 |
|
3121 3126 | fn from_request(request: ::http::Request<B>) -> Self::Future {
|
3122 3127 | let fut = async move {
|
3123 3128 | if !::aws_smithy_legacy_http_server::protocol::accept_header_classifier(
|
3124 3129 | request.headers(),
|
3125 3130 | &crate::mimes::CONTENT_TYPE_APPLICATION_X_AMZ_JSON_1_0,
|
3126 3131 | ) {
|
3127 3132 | return Err(::aws_smithy_legacy_http_server::protocol::aws_json::rejection::RequestRejection::NotAcceptable);
|
3128 3133 | }
|
3129 - | crate::protocol_serde::shape_empty_input_and_empty_output::de_empty_input_and_empty_output_http_request(request)
|
3134 + | crate::protocol_serde::shape_operation_with_nested_structure::de_operation_with_nested_structure_http_request(request)
|
3130 3135 | .await
|
3131 3136 | };
|
3132 3137 | use ::futures_util::future::TryFutureExt;
|
3133 3138 | let fut = fut.map_err(|e: ::aws_smithy_legacy_http_server::protocol::aws_json::rejection::RequestRejection| {
|
3134 3139 | ::tracing::debug!(error = %e, "failed to deserialize request");
|
3135 3140 | ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError::from(e)
|
3136 3141 | });
|
3137 - | EmptyInputAndEmptyOutputInputFuture {
|
3142 + | OperationWithNestedStructureInputFuture {
|
3138 3143 | inner: Box::pin(fut),
|
3139 3144 | }
|
3140 3145 | }
|
3141 3146 | }
|
3142 3147 | impl
|
3143 3148 | ::aws_smithy_legacy_http_server::response::IntoResponse<
|
3144 3149 | ::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0,
|
3145 - | > for crate::output::EmptyInputAndEmptyOutputOutput
|
3150 + | > for crate::output::OperationWithNestedStructureOutput
|
3146 3151 | {
|
3147 3152 | fn into_response(self) -> ::aws_smithy_legacy_http_server::response::Response {
|
3148 - | match crate::protocol_serde::shape_empty_input_and_empty_output::ser_empty_input_and_empty_output_http_response(self) {
|
3153 + | match crate::protocol_serde::shape_operation_with_nested_structure::ser_operation_with_nested_structure_http_response(self) {
|
3149 3154 | Ok(response) => response,
|
3150 3155 | Err(e) => {
|
3151 3156 | ::tracing::error!(error = %e, "failed to serialize response");
|
3152 3157 | ::aws_smithy_legacy_http_server::response::IntoResponse::<::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0>::into_response(::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError::from(e))
|
3153 3158 | }
|
3154 3159 | }
|
3155 3160 | }
|
3156 3161 | }
|
3162 + | impl
|
3163 + | ::aws_smithy_legacy_http_server::response::IntoResponse<
|
3164 + | ::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0,
|
3165 + | > for crate::error::OperationWithNestedStructureError
|
3166 + | {
|
3167 + | fn into_response(self) -> ::aws_smithy_legacy_http_server::response::Response {
|
3168 + | match crate::protocol_serde::shape_operation_with_nested_structure::ser_operation_with_nested_structure_http_error(&self) {
|
3169 + | Ok(mut response) => {
|
3170 + | response.extensions_mut().insert(::aws_smithy_legacy_http_server::extension::ModeledErrorExtension::new(self.name()));
|
3171 + | response
|
3172 + | },
|
3173 + | Err(e) => {
|
3174 + | ::tracing::error!(error = %e, "failed to serialize response");
|
3175 + | ::aws_smithy_legacy_http_server::response::IntoResponse::<::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0>::into_response(::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError::from(e))
|
3176 + | }
|
3177 + | }
|
3178 + | }
|
3179 + | }
|
3157 3180 |
|
3158 3181 | #[allow(unreachable_code, unused_variables)]
|
3159 3182 | #[cfg(test)]
|
3160 - | mod empty_input_and_empty_output_test {
|
3183 + | mod operation_with_nested_structure_test {
|
3161 3184 |
|
3162 - | /// Clients must always send an empty object if input is modeled.
|
3163 - | /// Test ID: AwsJson10EmptyInputAndEmptyOutput
|
3185 + | /// Server populates nested default values when missing in request body.
|
3186 + | /// Test ID: AwsJson10ServerPopulatesNestedDefaultsWhenMissingInRequestBody
|
3164 3187 | #[::tokio::test]
|
3165 3188 | #[::tracing_test::traced_test]
|
3166 - | async fn aws_json10_empty_input_and_empty_output_request() {
|
3189 + | #[should_panic]
|
3190 + | async fn aws_json10_server_populates_nested_defaults_when_missing_in_request_body_request() {
|
3167 3191 | #[allow(unused_mut)]
|
3168 3192 | let mut http_request = ::http::Request::builder()
|
3169 3193 | .uri("/")
|
3170 3194 | .method("POST")
|
3171 3195 | .header("Content-Type", "application/x-amz-json-1.0")
|
3172 - | .header("X-Amz-Target", "JsonRpc10.EmptyInputAndEmptyOutput")
|
3173 3196 | .body(::aws_smithy_legacy_http_server::body::Body::from(
|
3174 - | ::bytes::Bytes::copy_from_slice(&::aws_smithy_protocol_test::decode_body_data(
|
3175 - | "{}".as_bytes(),
|
3176 - | ::aws_smithy_protocol_test::MediaType::from("application/json"),
|
3177 - | )),
|
3178 - | ))
|
3179 - | .unwrap();
|
3197 + | ::bytes::Bytes::copy_from_slice(
|
3198 + | &::aws_smithy_protocol_test::decode_body_data("{\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(), ::aws_smithy_protocol_test::MediaType::from("application/json"))
|
3199 + | )
|
3200 + | )).unwrap();
|
3180 3201 | #[allow(unused_mut)]
|
3181 3202 | let (sender, mut receiver) = ::tokio::sync::mpsc::channel(1);
|
3182 3203 | let config = crate::service::JsonRpc10Config::builder().build();
|
3183 3204 | let service = crate::service::JsonRpc10::builder::<::hyper::body::Body, _, _, _>(config)
|
3184 - | .empty_input_and_empty_output(
|
3185 - | move |input: crate::input::EmptyInputAndEmptyOutputInput| {
|
3205 + | .operation_with_nested_structure(
|
3206 + | move |input: crate::input::OperationWithNestedStructureInput| {
|
3186 3207 | let sender = sender.clone();
|
3187 3208 | async move {
|
3188 3209 | let result = {
|
3189 - | let expected = crate::input::EmptyInputAndEmptyOutputInput {};
|
3210 + | let expected = crate::input::OperationWithNestedStructureInput {
|
3211 + | top_level: crate::model::TopLevel {
|
3212 + | dialog: crate::model::Dialog {
|
3213 + | language: ::std::option::Option::Some("en".to_owned()),
|
3214 + | greeting: "hi".to_owned(),
|
3215 + | farewell: ::std::option::Option::None,
|
3216 + | },
|
3217 + | dialog_list: vec![
|
3218 + | crate::model::Dialog {
|
3219 + | greeting: "hi".to_owned(),
|
3220 + | language: ::std::option::Option::None,
|
3221 + | farewell: ::std::option::Option::None,
|
3222 + | },
|
3223 + | crate::model::Dialog {
|
3224 + | greeting: "hi".to_owned(),
|
3225 + | farewell: ::std::option::Option::Some(
|
3226 + | crate::model::Farewell {
|
3227 + | phrase: "bye".to_owned(),
|
3228 + | },
|
3229 + | ),
|
3230 + | language: ::std::option::Option::None,
|
3231 + | },
|
3232 + | crate::model::Dialog {
|
3233 + | language: ::std::option::Option::Some("it".to_owned()),
|
3234 + | greeting: "ciao".to_owned(),
|
3235 + | farewell: ::std::option::Option::Some(
|
3236 + | crate::model::Farewell {
|
3237 + | phrase: "arrivederci".to_owned(),
|
3238 + | },
|
3239 + | ),
|
3240 + | },
|
3241 + | ],
|
3242 + | dialog_map: {
|
3243 + | let mut ret = ::std::collections::HashMap::new();
|
3244 + | ret.insert(
|
3245 + | "emptyDialog".to_owned(),
|
3246 + | crate::model::Dialog {
|
3247 + | greeting: "hi".to_owned(),
|
3248 + | language: ::std::option::Option::None,
|
3249 + | farewell: ::std::option::Option::None,
|
3250 + | },
|
3251 + | );
|
3252 + | ret.insert(
|
3253 + | "partialEmptyDialog".to_owned(),
|
3254 + | crate::model::Dialog {
|
3255 + | language: ::std::option::Option::Some(
|
3256 + | "en".to_owned(),
|
3257 + | ),
|
3258 + | greeting: "hi".to_owned(),
|
3259 + | farewell: ::std::option::Option::Some(
|
3260 + | crate::model::Farewell {
|
3261 + | phrase: "bye".to_owned(),
|
3262 + | },
|
3263 + | ),
|
3264 + | },
|
3265 + | );
|
3266 + | ret.insert(
|
3267 + | "nonEmptyDialog".to_owned(),
|
3268 + | crate::model::Dialog {
|
3269 + | greeting: "konnichiwa".to_owned(),
|
3270 + | farewell: ::std::option::Option::Some(
|
3271 + | crate::model::Farewell {
|
3272 + | phrase: "sayonara".to_owned(),
|
3273 + | },
|
3274 + | ),
|
3275 + | language: ::std::option::Option::None,
|
3276 + | },
|
3277 + | );
|
3278 + | ret
|
3279 + | },
|
3280 + | },
|
3281 + | };
|
3190 3282 | ::pretty_assertions::assert_eq!(input, expected);
|
3191 - | let output = crate::output::EmptyInputAndEmptyOutputOutput {};
|
3192 - | output
|
3283 + | let output = crate::output::OperationWithNestedStructureOutput {
|
3284 + | dialog: crate::model::Dialog {
|
3285 + | greeting: "".to_owned(),
|
3286 + | language: ::std::option::Option::None,
|
3287 + | farewell: ::std::option::Option::None,
|
3288 + | },
|
3289 + | dialog_list: vec![],
|
3290 + | dialog_map: ::std::collections::HashMap::new(),
|
3291 + | };
|
3292 + | Ok(output)
|
3193 3293 | };
|
3194 3294 | sender.send(()).await.expect("receiver dropped early");
|
3195 3295 | result
|
3196 3296 | }
|
3197 3297 | },
|
3198 - | )
|
3199 - | .build_unchecked();
|
3200 - | let http_response = ::tower::ServiceExt::oneshot(service, http_request)
|
3201 - | .await
|
3202 - | .expect("unable to make an HTTP request");
|
3203 - | assert!(
|
3204 - | receiver.recv().await.is_some(),
|
3205 - | "we expected operation handler to be invoked but it was not entered"
|
3298 + | )
|
3299 + | .build_unchecked();
|
3300 + | let http_response = ::tower::ServiceExt::oneshot(service, http_request)
|
3301 + | .await
|
3302 + | .expect("unable to make an HTTP request");
|
3303 + | assert!(
|
3304 + | receiver.recv().await.is_some(),
|
3305 + | "we expected operation handler to be invoked but it was not entered"
|
3306 + | );
|
3307 + | }
|
3308 + |
|
3309 + | /// Server populates nested default values when missing in response params.
|
3310 + | /// Test ID: AwsJson10ServerPopulatesNestedDefaultValuesWhenMissingInInResponseParams
|
3311 + | #[::tokio::test]
|
3312 + | #[::tracing_test::traced_test]
|
3313 + | #[should_panic]
|
3314 + | async fn aws_json10_server_populates_nested_default_values_when_missing_in_in_response_params_response(
|
3315 + | ) {
|
3316 + | let output = crate::output::OperationWithNestedStructureOutput {
|
3317 + | dialog: crate::model::Dialog {
|
3318 + | greeting: "".to_owned(),
|
3319 + | language: ::std::option::Option::Some("en".to_owned()),
|
3320 + | farewell: ::std::option::Option::None,
|
3321 + | },
|
3322 + | dialog_list: vec![
|
3323 + | crate::model::Dialog {
|
3324 + | greeting: "".to_owned(),
|
3325 + | language: ::std::option::Option::None,
|
3326 + | farewell: ::std::option::Option::None,
|
3327 + | },
|
3328 + | crate::model::Dialog {
|
3329 + | greeting: "".to_owned(),
|
3330 + | farewell: ::std::option::Option::Some(crate::model::Farewell {
|
3331 + | phrase: "".to_owned(),
|
3332 + | }),
|
3333 + | language: ::std::option::Option::None,
|
3334 + | },
|
3335 + | crate::model::Dialog {
|
3336 + | language: ::std::option::Option::Some("it".to_owned()),
|
3337 + | greeting: "ciao".to_owned(),
|
3338 + | farewell: ::std::option::Option::Some(crate::model::Farewell {
|
3339 + | phrase: "arrivederci".to_owned(),
|
3340 + | }),
|
3341 + | },
|
3342 + | ],
|
3343 + | dialog_map: {
|
3344 + | let mut ret = ::std::collections::HashMap::new();
|
3345 + | ret.insert(
|
3346 + | "emptyDialog".to_owned(),
|
3347 + | crate::model::Dialog {
|
3348 + | greeting: "".to_owned(),
|
3349 + | language: ::std::option::Option::None,
|
3350 + | farewell: ::std::option::Option::None,
|
3351 + | },
|
3352 + | );
|
3353 + | ret.insert(
|
3354 + | "partialEmptyDialog".to_owned(),
|
3355 + | crate::model::Dialog {
|
3356 + | greeting: "".to_owned(),
|
3357 + | language: ::std::option::Option::Some("en".to_owned()),
|
3358 + | farewell: ::std::option::Option::Some(crate::model::Farewell {
|
3359 + | phrase: "".to_owned(),
|
3360 + | }),
|
3361 + | },
|
3362 + | );
|
3363 + | ret.insert(
|
3364 + | "nonEmptyDialog".to_owned(),
|
3365 + | crate::model::Dialog {
|
3366 + | greeting: "konnichiwa".to_owned(),
|
3367 + | farewell: ::std::option::Option::Some(crate::model::Farewell {
|
3368 + | phrase: "sayonara".to_owned(),
|
3369 + | }),
|
3370 + | language: ::std::option::Option::None,
|
3371 + | },
|
3206 3372 | );
|
3207 - | }
|
3208 - |
|
3209 - | /// A service will always return a JSON object for operations with modeled output.
|
3210 - | /// Test ID: AwsJson10EmptyInputAndEmptyOutputSendJsonObject
|
3211 - | #[::tokio::test]
|
3212 - | #[::tracing_test::traced_test]
|
3213 - | async fn aws_json10_empty_input_and_empty_output_send_json_object_response() {
|
3214 - | let output = crate::output::EmptyInputAndEmptyOutputOutput {};
|
3373 + | ret
|
3374 + | },
|
3375 + | };
|
3215 3376 | use ::aws_smithy_legacy_http_server::response::IntoResponse;
|
3216 3377 | let http_response = output.into_response();
|
3217 3378 | ::pretty_assertions::assert_eq!(
|
3218 3379 | ::http::StatusCode::from_u16(200).expect("invalid expected HTTP status code"),
|
3219 3380 | http_response.status()
|
3220 3381 | );
|
3221 3382 | let expected_headers = [("Content-Type", "application/x-amz-json-1.0")];
|
3222 3383 | ::aws_smithy_protocol_test::assert_ok(::aws_smithy_protocol_test::validate_headers(
|
3223 3384 | http_response.headers(),
|
3224 3385 | expected_headers,
|
3225 3386 | ));
|
3226 3387 | let body = ::hyper::body::to_bytes(http_response.into_body())
|
3227 3388 | .await
|
3228 3389 | .expect("unable to extract body to bytes");
|
3229 - | ::aws_smithy_protocol_test::assert_ok(::aws_smithy_protocol_test::validate_body(
|
3230 - | &body,
|
3231 - | "{}",
|
3232 - | ::aws_smithy_protocol_test::MediaType::from("application/json"),
|
3233 - | ));
|
3390 + | ::aws_smithy_protocol_test::assert_ok(
|
3391 + | ::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"))
|
3392 + | );
|
3234 3393 | }
|
3235 3394 | }
|
3236 3395 |
|
3237 3396 | ::pin_project_lite::pin_project! {
|
3238 3397 | /// A [`Future`](std::future::Future) aggregating the body bytes of a [`Request`] and constructing the
|
3239 - | /// [`NoInputAndOutputInput`](crate::input::NoInputAndOutputInput) using modelled bindings.
|
3240 - | pub struct NoInputAndOutputInputFuture {
|
3241 - | inner: std::pin::Pin<Box<dyn std::future::Future<Output = Result<crate::input::NoInputAndOutputInput, ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError>> + Send>>
|
3398 + | /// [`OperationWithRequiredMembersWithDefaultsInput`](crate::input::OperationWithRequiredMembersWithDefaultsInput) using modelled bindings.
|
3399 + | pub struct OperationWithRequiredMembersWithDefaultsInputFuture {
|
3400 + | inner: std::pin::Pin<Box<dyn std::future::Future<Output = Result<crate::input::OperationWithRequiredMembersWithDefaultsInput, ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError>> + Send>>
|
3242 3401 | }
|
3243 3402 | }
|
3244 3403 |
|
3245 - | impl std::future::Future for NoInputAndOutputInputFuture {
|
3404 + | impl std::future::Future for OperationWithRequiredMembersWithDefaultsInputFuture {
|
3246 3405 | type Output = Result<
|
3247 - | crate::input::NoInputAndOutputInput,
|
3406 + | crate::input::OperationWithRequiredMembersWithDefaultsInput,
|
3248 3407 | ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError,
|
3249 3408 | >;
|
3250 3409 |
|
3251 3410 | fn poll(
|
3252 3411 | self: std::pin::Pin<&mut Self>,
|
3253 3412 | cx: &mut std::task::Context<'_>,
|
3254 3413 | ) -> std::task::Poll<Self::Output> {
|
3255 3414 | let this = self.project();
|
3256 3415 | this.inner.as_mut().poll(cx)
|
3257 3416 | }
|
3258 3417 | }
|
3259 3418 |
|
3260 3419 | impl<B>
|
3261 3420 | ::aws_smithy_legacy_http_server::request::FromRequest<
|
3262 3421 | ::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0,
|
3263 3422 | B,
|
3264 - | > for crate::input::NoInputAndOutputInput
|
3423 + | > for crate::input::OperationWithRequiredMembersWithDefaultsInput
|
3265 3424 | where
|
3266 3425 | B: ::aws_smithy_legacy_http_server::body::HttpBody + Send,
|
3267 3426 | B: 'static,
|
3268 3427 |
|
3269 3428 | B::Data: Send,
|
3270 3429 | ::aws_smithy_legacy_http_server::protocol::aws_json::rejection::RequestRejection:
|
3271 3430 | From<<B as ::aws_smithy_legacy_http_server::body::HttpBody>::Error>,
|
3272 3431 | {
|
3273 3432 | type Rejection =
|
3274 3433 | ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError;
|
3275 - | type Future = NoInputAndOutputInputFuture;
|
3434 + | type Future = OperationWithRequiredMembersWithDefaultsInputFuture;
|
3276 3435 |
|
3277 3436 | fn from_request(request: ::http::Request<B>) -> Self::Future {
|
3278 3437 | let fut = async move {
|
3279 3438 | if !::aws_smithy_legacy_http_server::protocol::accept_header_classifier(
|
3280 3439 | request.headers(),
|
3281 3440 | &crate::mimes::CONTENT_TYPE_APPLICATION_X_AMZ_JSON_1_0,
|
3282 3441 | ) {
|
3283 3442 | return Err(::aws_smithy_legacy_http_server::protocol::aws_json::rejection::RequestRejection::NotAcceptable);
|
3284 3443 | }
|
3285 - | crate::protocol_serde::shape_no_input_and_output::de_no_input_and_output_http_request(
|
3286 - | request,
|
3287 - | )
|
3444 + | crate::protocol_serde::shape_operation_with_required_members_with_defaults::de_operation_with_required_members_with_defaults_http_request(request)
|
3288 3445 | .await
|
3289 3446 | };
|
3290 3447 | use ::futures_util::future::TryFutureExt;
|
3291 3448 | let fut = fut.map_err(|e: ::aws_smithy_legacy_http_server::protocol::aws_json::rejection::RequestRejection| {
|
3292 3449 | ::tracing::debug!(error = %e, "failed to deserialize request");
|
3293 3450 | ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError::from(e)
|
3294 3451 | });
|
3295 - | NoInputAndOutputInputFuture {
|
3452 + | OperationWithRequiredMembersWithDefaultsInputFuture {
|
3296 3453 | inner: Box::pin(fut),
|
3297 3454 | }
|
3298 3455 | }
|
3299 3456 | }
|
3300 3457 | impl
|
3301 3458 | ::aws_smithy_legacy_http_server::response::IntoResponse<
|
3302 3459 | ::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0,
|
3303 - | > for crate::output::NoInputAndOutputOutput
|
3460 + | > for crate::output::OperationWithRequiredMembersWithDefaultsOutput
|
3304 3461 | {
|
3305 3462 | fn into_response(self) -> ::aws_smithy_legacy_http_server::response::Response {
|
3306 - | match crate::protocol_serde::shape_no_input_and_output::ser_no_input_and_output_http_response(self) {
|
3463 + | match crate::protocol_serde::shape_operation_with_required_members_with_defaults::ser_operation_with_required_members_with_defaults_http_response(self) {
|
3307 3464 | Ok(response) => response,
|
3308 3465 | Err(e) => {
|
3309 3466 | ::tracing::error!(error = %e, "failed to serialize response");
|
3310 3467 | ::aws_smithy_legacy_http_server::response::IntoResponse::<::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0>::into_response(::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError::from(e))
|
3311 3468 | }
|
3312 3469 | }
|
3313 3470 | }
|
3314 3471 | }
|
3315 3472 |
|
3316 - | #[allow(unreachable_code, unused_variables)]
|
3317 - | #[cfg(test)]
|
3318 - | mod no_input_and_output_test {
|
3319 - |
|
3320 - | /// A client should always send and empty JSON object payload.
|
3321 - | /// Test ID: AwsJson10NoInputAndOutput
|
3322 - | #[::tokio::test]
|
3323 - | #[::tracing_test::traced_test]
|
3324 - | async fn aws_json10_no_input_and_output_request() {
|
3325 - | #[allow(unused_mut)]
|
3326 - | let mut http_request = ::http::Request::builder()
|
3327 - | .uri("/")
|
3328 - | .method("POST")
|
3329 - | .header("Content-Type", "application/x-amz-json-1.0")
|
3330 - | .header("X-Amz-Target", "JsonRpc10.NoInputAndOutput")
|
3331 - | .body(::aws_smithy_legacy_http_server::body::Body::from(
|
3332 - | ::bytes::Bytes::copy_from_slice(&::aws_smithy_protocol_test::decode_body_data(
|
3333 - | "{}".as_bytes(),
|
3334 - | ::aws_smithy_protocol_test::MediaType::from("application/json"),
|
3335 - | )),
|
3336 - | ))
|
3337 - | .unwrap();
|
3338 - | #[allow(unused_mut)]
|
3339 - | let (sender, mut receiver) = ::tokio::sync::mpsc::channel(1);
|
3340 - | let config = crate::service::JsonRpc10Config::builder().build();
|
3341 - | let service = crate::service::JsonRpc10::builder::<::hyper::body::Body, _, _, _>(config)
|
3342 - | .no_input_and_output(move |input: crate::input::NoInputAndOutputInput| {
|
3343 - | let sender = sender.clone();
|
3344 - | async move {
|
3345 - | let result = {
|
3346 - | let expected = crate::input::NoInputAndOutputInput {};
|
3347 - | ::pretty_assertions::assert_eq!(input, expected);
|
3348 - | let output = crate::output::NoInputAndOutputOutput {};
|
3349 - | output
|
3350 - | };
|
3351 - | sender.send(()).await.expect("receiver dropped early");
|
3352 - | result
|
3353 - | }
|
3354 - | })
|
3355 - | .build_unchecked();
|
3356 - | let http_response = ::tower::ServiceExt::oneshot(service, http_request)
|
3357 - | .await
|
3358 - | .expect("unable to make an HTTP request");
|
3359 - | assert!(
|
3360 - | receiver.recv().await.is_some(),
|
3361 - | "we expected operation handler to be invoked but it was not entered"
|
3362 - | );
|
3363 - | }
|
3364 - |
|
3365 - | /// Empty output always serializes an empty object payload.
|
3366 - | /// Test ID: AwsJson10NoInputAndOutput
|
3367 - | #[::tokio::test]
|
3368 - | #[::tracing_test::traced_test]
|
3369 - | async fn aws_json10_no_input_and_output_response() {
|
3370 - | let output = crate::output::NoInputAndOutputOutput {};
|
3371 - | use ::aws_smithy_legacy_http_server::response::IntoResponse;
|
3372 - | let http_response = output.into_response();
|
3373 - | ::pretty_assertions::assert_eq!(
|
3374 - | ::http::StatusCode::from_u16(200).expect("invalid expected HTTP status code"),
|
3375 - | http_response.status()
|
3376 - | );
|
3377 - | let expected_headers = [("Content-Type", "application/x-amz-json-1.0")];
|
3378 - | ::aws_smithy_protocol_test::assert_ok(::aws_smithy_protocol_test::validate_headers(
|
3379 - | http_response.headers(),
|
3380 - | expected_headers,
|
3381 - | ));
|
3382 - | let body = ::hyper::body::to_bytes(http_response.into_body())
|
3383 - | .await
|
3384 - | .expect("unable to extract body to bytes");
|
3385 - | ::aws_smithy_protocol_test::assert_ok(::aws_smithy_protocol_test::validate_body(
|
3386 - | &body,
|
3387 - | "{}",
|
3388 - | ::aws_smithy_protocol_test::MediaType::from("application/json"),
|
3389 - | ));
|
3390 - | }
|
3391 - | }
|
3392 - |
|
3393 3473 | ::pin_project_lite::pin_project! {
|
3394 3474 | /// A [`Future`](std::future::Future) aggregating the body bytes of a [`Request`] and constructing the
|
3395 - | /// [`NoInputAndNoOutputInput`](crate::input::NoInputAndNoOutputInput) using modelled bindings.
|
3396 - | pub struct NoInputAndNoOutputInputFuture {
|
3397 - | inner: std::pin::Pin<Box<dyn std::future::Future<Output = Result<crate::input::NoInputAndNoOutputInput, ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError>> + Send>>
|
3475 + | /// [`QueryIncompatibleOperationInput`](crate::input::QueryIncompatibleOperationInput) using modelled bindings.
|
3476 + | pub struct QueryIncompatibleOperationInputFuture {
|
3477 + | inner: std::pin::Pin<Box<dyn std::future::Future<Output = Result<crate::input::QueryIncompatibleOperationInput, ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError>> + Send>>
|
3398 3478 | }
|
3399 3479 | }
|
3400 3480 |
|
3401 - | impl std::future::Future for NoInputAndNoOutputInputFuture {
|
3481 + | impl std::future::Future for QueryIncompatibleOperationInputFuture {
|
3402 3482 | type Output = Result<
|
3403 - | crate::input::NoInputAndNoOutputInput,
|
3483 + | crate::input::QueryIncompatibleOperationInput,
|
3404 3484 | ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError,
|
3405 3485 | >;
|
3406 3486 |
|
3407 3487 | fn poll(
|
3408 3488 | self: std::pin::Pin<&mut Self>,
|
3409 3489 | cx: &mut std::task::Context<'_>,
|
3410 3490 | ) -> std::task::Poll<Self::Output> {
|
3411 3491 | let this = self.project();
|
3412 3492 | this.inner.as_mut().poll(cx)
|
3413 3493 | }
|
3414 3494 | }
|
3415 3495 |
|
3416 3496 | impl<B>
|
3417 3497 | ::aws_smithy_legacy_http_server::request::FromRequest<
|
3418 3498 | ::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0,
|
3419 3499 | B,
|
3420 - | > for crate::input::NoInputAndNoOutputInput
|
3500 + | > for crate::input::QueryIncompatibleOperationInput
|
3421 3501 | where
|
3422 3502 | B: ::aws_smithy_legacy_http_server::body::HttpBody + Send,
|
3423 3503 | B: 'static,
|
3424 3504 |
|
3425 3505 | B::Data: Send,
|
3426 3506 | ::aws_smithy_legacy_http_server::protocol::aws_json::rejection::RequestRejection:
|
3427 3507 | From<<B as ::aws_smithy_legacy_http_server::body::HttpBody>::Error>,
|
3428 3508 | {
|
3429 3509 | type Rejection =
|
3430 3510 | ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError;
|
3431 - | type Future = NoInputAndNoOutputInputFuture;
|
3511 + | type Future = QueryIncompatibleOperationInputFuture;
|
3432 3512 |
|
3433 3513 | fn from_request(request: ::http::Request<B>) -> Self::Future {
|
3434 3514 | let fut = async move {
|
3435 3515 | if !::aws_smithy_legacy_http_server::protocol::accept_header_classifier(
|
3436 3516 | request.headers(),
|
3437 3517 | &crate::mimes::CONTENT_TYPE_APPLICATION_X_AMZ_JSON_1_0,
|
3438 3518 | ) {
|
3439 3519 | return Err(::aws_smithy_legacy_http_server::protocol::aws_json::rejection::RequestRejection::NotAcceptable);
|
3440 3520 | }
|
3441 - | crate::protocol_serde::shape_no_input_and_no_output::de_no_input_and_no_output_http_request(request)
|
3521 + | crate::protocol_serde::shape_query_incompatible_operation::de_query_incompatible_operation_http_request(request)
|
3442 3522 | .await
|
3443 3523 | };
|
3444 3524 | use ::futures_util::future::TryFutureExt;
|
3445 3525 | let fut = fut.map_err(|e: ::aws_smithy_legacy_http_server::protocol::aws_json::rejection::RequestRejection| {
|
3446 3526 | ::tracing::debug!(error = %e, "failed to deserialize request");
|
3447 3527 | ::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError::from(e)
|
3448 3528 | });
|
3449 - | NoInputAndNoOutputInputFuture {
|
3529 + | QueryIncompatibleOperationInputFuture {
|
3450 3530 | inner: Box::pin(fut),
|
3451 3531 | }
|
3452 3532 | }
|
3453 3533 | }
|
3454 3534 | impl
|
3455 3535 | ::aws_smithy_legacy_http_server::response::IntoResponse<
|
3456 3536 | ::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0,
|
3457 - | > for crate::output::NoInputAndNoOutputOutput
|
3537 + | > for crate::output::QueryIncompatibleOperationOutput
|
3458 3538 | {
|
3459 3539 | fn into_response(self) -> ::aws_smithy_legacy_http_server::response::Response {
|
3460 - | match crate::protocol_serde::shape_no_input_and_no_output::ser_no_input_and_no_output_http_response(self) {
|
3540 + | match crate::protocol_serde::shape_query_incompatible_operation::ser_query_incompatible_operation_http_response(self) {
|
3461 3541 | Ok(response) => response,
|
3462 3542 | Err(e) => {
|
3463 3543 | ::tracing::error!(error = %e, "failed to serialize response");
|
3464 3544 | ::aws_smithy_legacy_http_server::response::IntoResponse::<::aws_smithy_legacy_http_server::protocol::aws_json_10::AwsJson1_0>::into_response(::aws_smithy_legacy_http_server::protocol::aws_json::runtime_error::RuntimeError::from(e))
|
3465 3545 | }
|
3466 3546 | }
|
3467 3547 | }
|
3468 3548 | }
|
3469 3549 |
|
3470 3550 | #[allow(unreachable_code, unused_variables)]
|
3471 3551 | #[cfg(test)]
|
3472 - | mod no_input_and_no_output_test {
|
3552 + | mod query_incompatible_operation_test {
|
3473 3553 |
|
3474 - | /// Clients must always send an empty JSON object payload for
|
3475 - | /// operations with no input (that is, `{}`). While AWS service
|
3476 - | /// implementations support requests with no payload or requests
|
3477 - | /// that send `{}`, always sending `{}` from the client is
|
3478 - | /// preferred for forward compatibility in case input is ever
|
3479 - | /// added to an operation.
|
3480 - | /// Test ID: AwsJson10MustAlwaysSendEmptyJsonPayload
|
3554 + | /// The query mode header MUST NOT be set on non-query-compatible services.
|
3555 + | /// Test ID: NonQueryCompatibleAwsJson10ForbidsQueryModeHeader
|
3481 3556 | #[::tokio::test]
|
3482 3557 | #[::tracing_test::traced_test]
|
3483 - | async fn aws_json10_must_always_send_empty_json_payload_request() {
|
3558 + | async fn non_query_compatible_aws_json10_forbids_query_mode_header_request() {
|
3484 3559 | #[allow(unused_mut)]
|
3485 3560 | let mut http_request = ::http::Request::builder()
|
3486 3561 | .uri("/")
|
3487 3562 | .method("POST")
|
3488 3563 | .header("Content-Type", "application/x-amz-json-1.0")
|
3489 - | .header("X-Amz-Target", "JsonRpc10.NoInputAndNoOutput")
|
3564 + | .header("X-Amz-Target", "JsonRpc10.QueryIncompatibleOperation")
|
3490 3565 | .body(::aws_smithy_legacy_http_server::body::Body::from(
|
3491 3566 | ::bytes::Bytes::copy_from_slice(&::aws_smithy_protocol_test::decode_body_data(
|
3492 3567 | "{}".as_bytes(),
|
3493 3568 | ::aws_smithy_protocol_test::MediaType::from("application/json"),
|
3494 3569 | )),
|
3495 3570 | ))
|
3496 3571 | .unwrap();
|
3497 3572 | #[allow(unused_mut)]
|
3498 3573 | let (sender, mut receiver) = ::tokio::sync::mpsc::channel(1);
|
3499 3574 | let config = crate::service::JsonRpc10Config::builder().build();
|
3500 3575 | let service = crate::service::JsonRpc10::builder::<::hyper::body::Body, _, _, _>(config)
|
3501 - | .no_input_and_no_output(move |input: crate::input::NoInputAndNoOutputInput| {
|
3502 - | let sender = sender.clone();
|
3503 - | async move {
|
3504 - | let result = {
|
3505 - | let expected = crate::input::NoInputAndNoOutputInput {};
|
3506 - | ::pretty_assertions::assert_eq!(input, expected);
|
3507 - | let output = crate::output::NoInputAndNoOutputOutput {};
|
3508 - | output
|
3509 - | };
|
3510 - | sender.send(()).await.expect("receiver dropped early");
|
3511 - | result
|
3512 - | }
|
3513 - | })
|
3514 - | .build_unchecked();
|
3515 - | let http_response = ::tower::ServiceExt::oneshot(service, http_request)
|
3516 - | .await
|
3517 - | .expect("unable to make an HTTP request");
|
3518 - | assert!(
|
3519 - | receiver.recv().await.is_some(),
|
3520 - | "we expected operation handler to be invoked but it was not entered"
|
3521 - | );
|
3522 - | }
|
3523 - |
|
3524 - | /// Service implementations must support no payload or an empty
|
3525 - | /// object payload for operations that define no input. However,
|
3526 - | /// despite the lack of a payload, a Content-Type header is still
|
3527 - | /// required in order for the service to properly detect the
|
3528 - | /// protocol.
|
3529 - | /// Test ID: AwsJson10ServiceSupportsNoPayloadForNoInput
|
3530 - | #[::tokio::test]
|
3531 - | #[::tracing_test::traced_test]
|
3532 - | async fn aws_json10_service_supports_no_payload_for_no_input_request() {
|
3533 - | #[allow(unused_mut)]
|
3534 - | let mut http_request = ::http::Request::builder()
|
3535 - | .uri("/")
|
3536 - | .method("POST")
|
3537 - | .header("Content-Type", "application/x-amz-json-1.0")
|
3538 - | .header("X-Amz-Target", "JsonRpc10.NoInputAndNoOutput")
|
3539 - | .body(::aws_smithy_legacy_http_server::body::Body::from(
|
3540 - | ::bytes::Bytes::copy_from_slice(&::aws_smithy_protocol_test::decode_body_data(
|
3541 - | "".as_bytes(),
|
3542 - | ::aws_smithy_protocol_test::MediaType::from("unknown"),
|
3543 - | )),
|
3544 - | ))
|
3545 - | .unwrap();
|
3546 - | #[allow(unused_mut)]
|
3547 - | let (sender, mut receiver) = ::tokio::sync::mpsc::channel(1);
|
3548 - | let config = crate::service::JsonRpc10Config::builder().build();
|
3549 - | let service = crate::service::JsonRpc10::builder::<::hyper::body::Body, _, _, _>(config)
|
3550 - | .no_input_and_no_output(move |input: crate::input::NoInputAndNoOutputInput| {
|
3576 + | .query_incompatible_operation(
|
3577 + | move |input: crate::input::QueryIncompatibleOperationInput| {
|
3551 3578 | let sender = sender.clone();
|
3552 3579 | async move {
|
3553 3580 | let result = {
|
3554 - | let expected = crate::input::NoInputAndNoOutputInput {};
|
3581 + | let expected = crate::input::QueryIncompatibleOperationInput {};
|
3555 3582 | ::pretty_assertions::assert_eq!(input, expected);
|
3556 - | let output = crate::output::NoInputAndNoOutputOutput {};
|
3583 + | let output = crate::output::QueryIncompatibleOperationOutput {};
|
3557 3584 | output
|
3558 3585 | };
|
3559 3586 | sender.send(()).await.expect("receiver dropped early");
|
3560 3587 | result
|
3561 3588 | }
|
3562 - | })
|
3589 + | },
|
3590 + | )
|
3563 3591 | .build_unchecked();
|
3564 3592 | let http_response = ::tower::ServiceExt::oneshot(service, http_request)
|
3565 3593 | .await
|
3566 3594 | .expect("unable to make an HTTP request");
|
3567 3595 | assert!(
|
3568 3596 | receiver.recv().await.is_some(),
|
3569 3597 | "we expected operation handler to be invoked but it was not entered"
|
3570 3598 | );
|
3571 3599 | }
|
3572 - |
|
3573 - | /// When no output is defined, the service is expected to return
|
3574 - | /// an empty payload. Despite the lack of a payload, the service
|
3575 - | /// is expected to always send a Content-Type header. Clients must
|
3576 - | /// handle cases where a service returns a JSON object and where
|
3577 - | /// a service returns no JSON at all.
|
3578 - | /// Test ID: AwsJson10ServiceRespondsWithNoPayload
|
3579 - | #[::tokio::test]
|
3580 - | #[::tracing_test::traced_test]
|
3581 - | async fn aws_json10_service_responds_with_no_payload_response() {
|
3582 - | let output = crate::output::NoInputAndNoOutputOutput {};
|
3583 - | use ::aws_smithy_legacy_http_server::response::IntoResponse;
|
3584 - | let http_response = output.into_response();
|
3585 - | ::pretty_assertions::assert_eq!(
|
3586 - | ::http::StatusCode::from_u16(200).expect("invalid expected HTTP status code"),
|
3587 - | http_response.status()
|
3588 - | );
|
3589 - | let expected_headers = [("Content-Type", "application/x-amz-json-1.0")];
|
3590 - | ::aws_smithy_protocol_test::assert_ok(::aws_smithy_protocol_test::validate_headers(
|
3591 - | http_response.headers(),
|
3592 - | expected_headers,
|
3593 - | ));
|
3594 - | let body = ::hyper::body::to_bytes(http_response.into_body())
|
3595 - | .await
|
3596 - | .expect("unable to extract body to bytes");
|
3597 - | // No body.
|
3598 - | ::pretty_assertions::assert_eq!(&body, &bytes::Bytes::new());
|
3599 - | }
|
3600 3600 | }
|