#![warn(missing_docs)]
#[allow(dead_code)]
const PKG_VERSION: &str = env!("CARGO_PKG_VERSION");
#[cfg(feature = "default-provider")]
pub mod default_provider;
#[cfg(feature = "environment")]
pub mod environment;
#[cfg(feature = "meta")]
pub mod meta;
#[cfg(feature = "profile")]
pub mod profile;
#[cfg(feature = "sts")]
pub mod sts;
#[cfg(test)]
mod test_case;
#[cfg(feature = "web-identity-token")]
pub mod web_identity_token;
#[cfg(feature = "http-provider")]
pub mod ecs;
pub mod provider_config;
#[cfg(any(feature = "meta", feature = "default-provider"))]
mod cache;
#[cfg(feature = "imds")]
pub mod imds;
#[cfg(any(feature = "http-provider", feature = "imds"))]
mod json_credentials;
#[cfg(feature = "http-provider")]
mod http_provider;
pub use aws_smithy_types::retry::RetryConfig;
pub use aws_smithy_types::timeout::TimeoutConfig;
pub use aws_types::app_name::{AppName, InvalidAppName};
pub use aws_types::config::Config;
#[cfg(feature = "default-provider")]
pub fn from_env() -> ConfigLoader {
ConfigLoader::default()
}
#[cfg(feature = "default-provider")]
pub async fn load_from_env() -> aws_types::config::Config {
from_env().load().await
}
#[cfg(feature = "default-provider")]
pub use loader::ConfigLoader;
#[cfg(feature = "default-provider")]
mod loader {
use std::sync::Arc;
use aws_smithy_async::rt::sleep::{default_async_sleep, AsyncSleep};
use aws_smithy_types::retry::RetryConfig;
use aws_smithy_types::timeout::TimeoutConfig;
use aws_types::app_name::AppName;
use aws_types::config::Config;
use aws_types::credentials::{ProvideCredentials, SharedCredentialsProvider};
use crate::default_provider::{app_name, credentials, region, retry_config, timeout_config};
use crate::meta::region::ProvideRegion;
#[derive(Default, Debug)]
pub struct ConfigLoader {
app_name: Option<AppName>,
credentials_provider: Option<SharedCredentialsProvider>,
region: Option<Box<dyn ProvideRegion>>,
retry_config: Option<RetryConfig>,
sleep: Option<Arc<dyn AsyncSleep>>,
timeout_config: Option<TimeoutConfig>,
}
impl ConfigLoader {
pub fn region(mut self, region: impl ProvideRegion + 'static) -> Self {
self.region = Some(Box::new(region));
self
}
pub fn retry_config(mut self, retry_config: RetryConfig) -> Self {
self.retry_config = Some(retry_config);
self
}
pub fn timeout_config(mut self, timeout_config: TimeoutConfig) -> Self {
self.timeout_config = Some(timeout_config);
self
}
pub fn sleep_impl(mut self, sleep: impl AsyncSleep + 'static) -> Self {
self.sleep = Some(Arc::new(sleep));
self
}
pub fn credentials_provider(
mut self,
credentials_provider: impl ProvideCredentials + 'static,
) -> Self {
self.credentials_provider = Some(SharedCredentialsProvider::new(credentials_provider));
self
}
pub async fn load(self) -> aws_types::config::Config {
let region = if let Some(provider) = self.region {
provider.region().await
} else {
region::default_provider().region().await
};
let retry_config = if let Some(retry_config) = self.retry_config {
retry_config
} else {
retry_config::default_provider().retry_config().await
};
let app_name = if self.app_name.is_some() {
self.app_name
} else {
app_name::default_provider().app_name().await
};
let timeout_config = if let Some(timeout_config) = self.timeout_config {
timeout_config
} else {
timeout_config::default_provider().timeout_config().await
};
let sleep_impl = if self.sleep.is_none() {
if default_async_sleep().is_none() {
tracing::warn!(
"An implementation of AsyncSleep was requested by calling default_async_sleep \
but no default was set.
This happened when ConfigLoader::load was called during Config construction. \
You can fix this by setting a sleep_impl on the ConfigLoader before calling \
load or by enabling the rt-tokio feature"
);
}
default_async_sleep()
} else {
self.sleep
};
let credentials_provider = if let Some(provider) = self.credentials_provider {
provider
} else {
let mut builder = credentials::DefaultCredentialsChain::builder();
builder.set_region(region.clone());
SharedCredentialsProvider::new(builder.build().await)
};
let mut builder = Config::builder()
.region(region)
.retry_config(retry_config)
.timeout_config(timeout_config)
.credentials_provider(credentials_provider);
builder.set_app_name(app_name);
builder.set_sleep_impl(sleep_impl);
builder.build()
}
}
}
mod connector {
use crate::provider_config::HttpSettings;
use aws_smithy_async::rt::sleep::AsyncSleep;
use aws_smithy_client::erase::DynConnector;
use std::sync::Arc;
#[allow(dead_code)]
pub(crate) fn expect_connector(connector: Option<DynConnector>) -> DynConnector {
connector.expect("A connector was not available. Either set a custom connector or enable the `rustls` and `native-tls` crate features.")
}
#[cfg(any(feature = "rustls", feature = "native-tls"))]
fn base(
settings: &HttpSettings,
sleep: Option<Arc<dyn AsyncSleep>>,
) -> aws_smithy_client::hyper_ext::Builder {
let mut hyper =
aws_smithy_client::hyper_ext::Adapter::builder().timeout(&settings.timeout_settings);
if let Some(sleep) = sleep {
hyper = hyper.sleep_impl(sleep);
}
hyper
}
#[cfg(feature = "rustls")]
pub(crate) fn default_connector(
settings: &HttpSettings,
sleep: Option<Arc<dyn AsyncSleep>>,
) -> Option<DynConnector> {
let hyper = base(settings, sleep).build(aws_smithy_client::conns::https());
Some(DynConnector::new(hyper))
}
#[cfg(all(not(feature = "rustls"), feature = "native-tls"))]
pub(crate) fn default_connector(
settings: &HttpSettings,
sleep: Option<Arc<dyn AsyncSleep>>,
) -> Option<DynConnector> {
let hyper = base(settings, sleep).build(aws_smithy_client::conns::native_tls());
Some(DynConnector::new(hyper))
}
#[cfg(not(any(feature = "rustls", feature = "native-tls")))]
pub(crate) fn default_connector(
_settings: &HttpSettings,
_sleep: Option<Arc<dyn AsyncSleep>>,
) -> Option<DynConnector> {
None
}
}