pub mod get;
pub mod put;
use crate::BatchError;
use aws_config::BehaviorVersion;
use aws_config::meta::region::RegionProviderChain;
use aws_sdk_s3::config::Builder as S3ConfigBuilder;
use aws_sdk_s3::config::Credentials;
#[derive(Debug, Clone, Default)]
pub struct S3ClientConfig {
pub region: Option<String>,
pub endpoint_url: Option<String>,
pub access_key_id: Option<String>,
pub secret_access_key: Option<String>,
}
pub(crate) async fn build_s3_client(
config: &S3ClientConfig,
) -> Result<aws_sdk_s3::Client, BatchError> {
let region_provider =
RegionProviderChain::first_try(config.region.clone().map(aws_sdk_s3::config::Region::new))
.or_default_provider();
let sdk_config = aws_config::defaults(BehaviorVersion::latest())
.region(region_provider)
.load()
.await;
let mut builder = S3ConfigBuilder::from(&sdk_config);
if let Some(url) = &config.endpoint_url {
builder = builder.endpoint_url(url).force_path_style(true);
}
if let (Some(key_id), Some(secret)) = (&config.access_key_id, &config.secret_access_key) {
let creds = Credentials::new(key_id, secret, None, None, "static");
builder = builder.credentials_provider(creds);
}
Ok(aws_sdk_s3::Client::from_conf(builder.build()))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn should_default_to_none_fields() {
let config = S3ClientConfig::default();
assert!(config.region.is_none(), "region should default to None");
assert!(
config.endpoint_url.is_none(),
"endpoint_url should default to None"
);
assert!(
config.access_key_id.is_none(),
"access_key_id should default to None"
);
assert!(
config.secret_access_key.is_none(),
"secret_access_key should default to None"
);
}
#[test]
fn should_store_region() {
let config = S3ClientConfig {
region: Some("us-east-1".to_string()),
..Default::default()
};
assert_eq!(config.region.as_deref(), Some("us-east-1"));
}
#[test]
fn should_store_endpoint_url() {
let config = S3ClientConfig {
endpoint_url: Some("http://localhost:9000".to_string()),
..Default::default()
};
assert_eq!(
config.endpoint_url.as_deref(),
Some("http://localhost:9000")
);
}
#[test]
fn should_store_explicit_credentials() {
let config = S3ClientConfig {
access_key_id: Some("AKID".to_string()),
secret_access_key: Some("SECRET".to_string()),
..Default::default()
};
assert_eq!(config.access_key_id.as_deref(), Some("AKID"));
assert_eq!(config.secret_access_key.as_deref(), Some("SECRET"));
}
}