use crate::box_error::BoxError;
use crate::client::connector_metadata::ConnectorMetadata;
use crate::client::orchestrator::{HttpRequest, HttpResponse};
use crate::client::result::ConnectorError;
use crate::client::runtime_components::sealed::ValidateConfig;
use crate::client::runtime_components::{RuntimeComponents, RuntimeComponentsBuilder};
use crate::impl_shared_conversions;
use aws_smithy_types::config_bag::ConfigBag;
use std::fmt;
use std::sync::Arc;
use std::time::Duration;
new_type_future! {
#[doc = "Future for [`HttpConnector::call`]."]
pub struct HttpConnectorFuture<'static, HttpResponse, ConnectorError>;
}
pub trait HttpConnector: Send + Sync + fmt::Debug {
fn call(&self, request: HttpRequest) -> HttpConnectorFuture;
}
#[derive(Clone, Debug)]
pub struct SharedHttpConnector(Arc<dyn HttpConnector>);
impl SharedHttpConnector {
pub fn new(connection: impl HttpConnector + 'static) -> Self {
Self(Arc::new(connection))
}
}
impl HttpConnector for SharedHttpConnector {
fn call(&self, request: HttpRequest) -> HttpConnectorFuture {
(*self.0).call(request)
}
}
impl_shared_conversions!(convert SharedHttpConnector from HttpConnector using SharedHttpConnector::new);
pub fn http_client_fn<F>(connector: F) -> SharedHttpClient
where
F: Fn(&HttpConnectorSettings, &RuntimeComponents) -> SharedHttpConnector
+ Send
+ Sync
+ 'static,
{
struct ConnectorFn<T>(T);
impl<T> fmt::Debug for ConnectorFn<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("ConnectorFn")
}
}
impl<T> HttpClient for ConnectorFn<T>
where
T: (Fn(&HttpConnectorSettings, &RuntimeComponents) -> SharedHttpConnector) + Send + Sync,
{
fn http_connector(
&self,
settings: &HttpConnectorSettings,
components: &RuntimeComponents,
) -> SharedHttpConnector {
(self.0)(settings, components)
}
}
SharedHttpClient::new(ConnectorFn(connector))
}
pub trait HttpClient: Send + Sync + fmt::Debug {
fn http_connector(
&self,
settings: &HttpConnectorSettings,
components: &RuntimeComponents,
) -> SharedHttpConnector;
#[doc = include_str!("../../rustdoc/validate_base_client_config.md")]
fn validate_base_client_config(
&self,
runtime_components: &RuntimeComponentsBuilder,
cfg: &ConfigBag,
) -> Result<(), BoxError> {
let _ = (runtime_components, cfg);
Ok(())
}
#[doc = include_str!("../../rustdoc/validate_final_config.md")]
fn validate_final_config(
&self,
runtime_components: &RuntimeComponents,
cfg: &ConfigBag,
) -> Result<(), BoxError> {
let _ = (runtime_components, cfg);
Ok(())
}
fn connector_metadata(&self) -> Option<ConnectorMetadata> {
None
}
}
#[derive(Clone, Debug)]
pub struct SharedHttpClient {
selector: Arc<dyn HttpClient>,
}
impl SharedHttpClient {
pub fn new(selector: impl HttpClient + 'static) -> Self {
Self {
selector: Arc::new(selector),
}
}
}
impl HttpClient for SharedHttpClient {
fn http_connector(
&self,
settings: &HttpConnectorSettings,
components: &RuntimeComponents,
) -> SharedHttpConnector {
self.selector.http_connector(settings, components)
}
fn connector_metadata(&self) -> Option<ConnectorMetadata> {
self.selector.connector_metadata()
}
}
impl ValidateConfig for SharedHttpClient {
fn validate_base_client_config(
&self,
runtime_components: &RuntimeComponentsBuilder,
cfg: &ConfigBag,
) -> Result<(), BoxError> {
self.selector
.validate_base_client_config(runtime_components, cfg)
}
fn validate_final_config(
&self,
runtime_components: &RuntimeComponents,
cfg: &ConfigBag,
) -> Result<(), BoxError> {
self.selector.validate_final_config(runtime_components, cfg)
}
}
impl_shared_conversions!(convert SharedHttpClient from HttpClient using SharedHttpClient::new);
#[non_exhaustive]
#[derive(Default, Debug)]
pub struct HttpConnectorSettingsBuilder {
connect_timeout: Option<Duration>,
read_timeout: Option<Duration>,
}
impl HttpConnectorSettingsBuilder {
pub fn new() -> Self {
Default::default()
}
pub fn connect_timeout(mut self, connect_timeout: Duration) -> Self {
self.connect_timeout = Some(connect_timeout);
self
}
pub fn set_connect_timeout(&mut self, connect_timeout: Option<Duration>) -> &mut Self {
self.connect_timeout = connect_timeout;
self
}
pub fn read_timeout(mut self, read_timeout: Duration) -> Self {
self.read_timeout = Some(read_timeout);
self
}
pub fn set_read_timeout(&mut self, read_timeout: Option<Duration>) -> &mut Self {
self.read_timeout = read_timeout;
self
}
pub fn build(self) -> HttpConnectorSettings {
HttpConnectorSettings {
connect_timeout: self.connect_timeout,
read_timeout: self.read_timeout,
}
}
}
#[non_exhaustive]
#[derive(Clone, Default, Debug)]
pub struct HttpConnectorSettings {
connect_timeout: Option<Duration>,
read_timeout: Option<Duration>,
}
impl HttpConnectorSettings {
pub fn builder() -> HttpConnectorSettingsBuilder {
Default::default()
}
pub fn connect_timeout(&self) -> Option<Duration> {
self.connect_timeout
}
pub fn read_timeout(&self) -> Option<Duration> {
self.read_timeout
}
}