aws_smithy_http_client/test_util/
infallible.rs

1/*
2 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 * SPDX-License-Identifier: Apache-2.0
4 */
5
6use aws_smithy_runtime_api::client::connector_metadata::ConnectorMetadata;
7use aws_smithy_runtime_api::client::http::{
8    HttpClient, HttpConnector, HttpConnectorFuture, HttpConnectorSettings, SharedHttpClient,
9    SharedHttpConnector,
10};
11use aws_smithy_runtime_api::client::orchestrator::{HttpRequest, HttpResponse};
12use aws_smithy_runtime_api::client::result::ConnectorError;
13use aws_smithy_runtime_api::client::runtime_components::RuntimeComponents;
14use aws_smithy_runtime_api::shared::IntoShared;
15use aws_smithy_types::body::SdkBody;
16use std::fmt;
17use std::sync::Arc;
18
19/// Create a [`SharedHttpClient`] from `Fn(http:Request) -> http::Response`
20///
21/// # Examples
22///
23/// ```rust
24/// # use http_1x as http;
25/// use aws_smithy_http_client::test_util::infallible_client_fn;
26/// let http_client = infallible_client_fn(|_req| http::Response::builder().status(200).body("OK!").unwrap());
27/// ```
28pub fn infallible_client_fn<B>(
29    f: impl Fn(http_1x::Request<SdkBody>) -> http_1x::Response<B> + Send + Sync + 'static,
30) -> SharedHttpClient
31where
32    B: Into<SdkBody>,
33{
34    InfallibleClientFn::new(f).into_shared()
35}
36
37#[derive(Clone)]
38struct InfallibleClientFn {
39    #[allow(clippy::type_complexity)]
40    response: Arc<
41        dyn Fn(http_1x::Request<SdkBody>) -> Result<http_1x::Response<SdkBody>, ConnectorError>
42            + Send
43            + Sync,
44    >,
45}
46
47impl fmt::Debug for InfallibleClientFn {
48    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
49        f.debug_struct("InfallibleClientFn").finish()
50    }
51}
52
53impl InfallibleClientFn {
54    fn new<B: Into<SdkBody>>(
55        f: impl Fn(http_1x::Request<SdkBody>) -> http_1x::Response<B> + Send + Sync + 'static,
56    ) -> Self {
57        Self {
58            response: Arc::new(move |request| Ok(f(request).map(|b| b.into()))),
59        }
60    }
61}
62
63impl HttpConnector for InfallibleClientFn {
64    fn call(&self, request: HttpRequest) -> HttpConnectorFuture {
65        HttpConnectorFuture::ready(
66            (self.response)(request.try_into_http1x().unwrap())
67                .map(|res| HttpResponse::try_from(res).unwrap()),
68        )
69    }
70}
71
72impl HttpClient for InfallibleClientFn {
73    fn http_connector(
74        &self,
75        _: &HttpConnectorSettings,
76        _: &RuntimeComponents,
77    ) -> SharedHttpConnector {
78        self.clone().into_shared()
79    }
80
81    fn connector_metadata(&self) -> Option<ConnectorMetadata> {
82        Some(ConnectorMetadata::new("infallible-client", None))
83    }
84}