Loading aws/rust-runtime/aws-endpoint/src/lib.rs +16 −9 Original line number Diff line number Diff line use aws_types::{Region, SigningRegion, SigningService}; use http::Uri; use smithy_http::endpoint::{Endpoint, EndpointPrefix}; use smithy_http::middleware::MapRequest; use smithy_http::operation::Request; use smithy_http::property_bag::PropertyBag; use std::error::Error; use std::fmt; use std::fmt::{Debug, Display, Formatter}; use std::str::FromStr; use std::sync::Arc; use http::Uri; use aws_types::region::{Region, SigningRegion}; use aws_types::SigningService; use smithy_http::endpoint::{Endpoint, EndpointPrefix}; use smithy_http::middleware::MapRequest; use smithy_http::operation::Request; use smithy_http::property_bag::PropertyBag; /// Endpoint to connect to an AWS Service /// /// An `AwsEndpoint` captures all necessary information needed to connect to an AWS service, including: Loading Loading @@ -164,13 +167,17 @@ impl MapRequest for AwsEndpointStage { #[cfg(test)] mod test { use crate::{set_endpoint_resolver, AwsEndpointStage, DefaultAwsEndpointResolver}; use aws_types::{Region, SigningRegion, SigningService}; use std::sync::Arc; use http::Uri; use aws_types::region::{Region, SigningRegion}; use aws_types::SigningService; use smithy_http::body::SdkBody; use smithy_http::middleware::MapRequest; use smithy_http::operation; use std::sync::Arc; use crate::{AwsEndpointStage, DefaultAwsEndpointResolver, set_endpoint_resolver}; #[test] fn default_endpoint_updates_request() { Loading aws/rust-runtime/aws-types/src/lib.rs +2 −40 Original line number Diff line number Diff line use std::borrow::Cow; use std::sync::Arc; /// The region to send requests to. /// /// The region MUST be specified on a request. It may be configured globally or on a /// per-client basis unless otherwise noted. A full list of regions is found in the /// "Regions and Endpoints" document. /// /// See http://docs.aws.amazon.com/general/latest/gr/rande.html for /// information on AWS regions. #[derive(Clone, Debug, PartialEq, Eq)] pub struct Region(Arc<String>); impl AsRef<str> for Region { fn as_ref(&self) -> &str { self.0.as_str() } } impl Region { pub fn new(region: impl Into<String>) -> Self { Self(Arc::new(region.into())) } } /// The region to use when signing requests /// /// Generally, user code will not need to interact with `SigningRegion`. See `[Region](crate::Region)`. #[derive(Clone, Debug, PartialEq, Eq)] pub struct SigningRegion(Arc<String>); impl AsRef<str> for SigningRegion { fn as_ref(&self) -> &str { self.0.as_str() } } pub mod region; impl From<Region> for SigningRegion { fn from(inp: Region) -> Self { SigningRegion(inp.0) } } use std::borrow::Cow; /// The name of the service used to sign this request /// Loading aws/rust-runtime/aws-types/src/region.rs 0 → 100644 +80 −0 Original line number Diff line number Diff line /* * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ use std::sync::Arc; /// The region to send requests to. /// /// The region MUST be specified on a request. It may be configured globally or on a /// per-client basis unless otherwise noted. A full list of regions is found in the /// "Regions and Endpoints" document. /// /// See http://docs.aws.amazon.com/general/latest/gr/rande.html for /// information on AWS regions. #[derive(Clone, Debug, PartialEq, Eq)] pub struct Region(Arc<String>); impl AsRef<str> for Region { fn as_ref(&self) -> &str { self.0.as_str() } } impl Region { pub fn new(region: impl Into<String>) -> Self { Self(Arc::new(region.into())) } } /// Provide a [`Region`](Region) to use with AWS requests /// /// For most cases [`default_provider`](default_provider) will be the best option, implementing /// a standard provider chain. pub trait ProvideRegion: Send + Sync { fn region(&self) -> Option<Region>; } impl ProvideRegion for Region { fn region(&self) -> Option<Region> { Some(self.clone()) } } pub fn default_provider() -> impl ProvideRegion { EnvironmentProvider } #[non_exhaustive] pub struct EnvironmentProvider; impl EnvironmentProvider { pub fn new() -> Self { EnvironmentProvider } } impl ProvideRegion for EnvironmentProvider { fn region(&self) -> Option<Region> { std::env::var("AWS_DEFAULT_REGION").map(Region::new).ok() } } /// The region to use when signing requests /// /// Generally, user code will not need to interact with `SigningRegion`. See `[Region](crate::Region)`. #[derive(Clone, Debug, PartialEq, Eq)] pub struct SigningRegion(Arc<String>); impl AsRef<str> for SigningRegion { fn as_ref(&self) -> &str { self.0.as_str() } } impl From<Region> for SigningRegion { fn from(inp: Region) -> Self { SigningRegion(inp.0) } } aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/AwsCodegenDecorator.kt +8 −11 Original line number Diff line number Diff line Loading @@ -5,17 +5,14 @@ package software.amazon.smithy.rustsdk import software.amazon.smithy.rust.codegen.smithy.customize.RustCodegenDecorator import software.amazon.smithy.rust.codegen.smithy.generators.ProtocolConfig import software.amazon.smithy.rust.codegen.smithy.generators.config.ConfigCustomization import software.amazon.smithy.rust.codegen.smithy.customize.CombinedCodegenDecorator class AwsCodegenDecorator : RustCodegenDecorator { override val name: String = "AwsSdkCodgenDecorator" val DECORATORS = listOf( CredentialsProviderDecorator(), RegionDecorator() ) class AwsCodegenDecorator : CombinedCodegenDecorator(DECORATORS) { override val name: String = "AwsSdkCodegenDecorator" override val order: Byte = -1 override fun configCustomizations( protocolConfig: ProtocolConfig, baseCustomizations: List<ConfigCustomization> ): List<ConfigCustomization> { return listOf(BaseAwsConfig()) + baseCustomizations } } aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/RegionDecorator.kt 0 → 100644 +119 −0 Original line number Diff line number Diff line /* * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ package software.amazon.smithy.rustsdk import software.amazon.smithy.model.shapes.OperationShape import software.amazon.smithy.rust.codegen.rustlang.CargoDependency import software.amazon.smithy.rust.codegen.rustlang.Local import software.amazon.smithy.rust.codegen.rustlang.Writable import software.amazon.smithy.rust.codegen.rustlang.rust import software.amazon.smithy.rust.codegen.rustlang.writable import software.amazon.smithy.rust.codegen.smithy.RuntimeConfig import software.amazon.smithy.rust.codegen.smithy.RuntimeType import software.amazon.smithy.rust.codegen.smithy.customize.RustCodegenDecorator import software.amazon.smithy.rust.codegen.smithy.generators.OperationCustomization import software.amazon.smithy.rust.codegen.smithy.generators.OperationSection import software.amazon.smithy.rust.codegen.smithy.generators.ProtocolConfig import software.amazon.smithy.rust.codegen.smithy.generators.config.ConfigCustomization import software.amazon.smithy.rust.codegen.smithy.generators.config.ServiceConfig /* Example Generated Code */ /* pub struct Config { pub region: Option<::aws_types::region::Region>, } #[derive(Default)] pub struct ConfigBuilder { region: Option<::aws_types::region::Region>, } impl ConfigBuilder { pub fn region(mut self, region_provider: impl ::aws_types::region::ProvideRegion) -> Self { self.region = region_provider.region(); self } pub fn build(self) -> Config { Config { region: { use ::aws_types::region::ProvideRegion; self.region .or_else(|| ::aws_types::region::default_provider().region()) }, } } */ class RegionDecorator : RustCodegenDecorator { override val name: String = "Region" override val order: Byte = 0 override fun configCustomizations( protocolConfig: ProtocolConfig, baseCustomizations: List<ConfigCustomization> ): List<ConfigCustomization> { return baseCustomizations + RegionProviderConfig(protocolConfig.runtimeConfig) } override fun operationCustomizations( protocolConfig: ProtocolConfig, operation: OperationShape, baseCustomizations: List<OperationCustomization> ): List<OperationCustomization> { return baseCustomizations + RegionConfigPlugin() } } class RegionProviderConfig(runtimeConfig: RuntimeConfig) : ConfigCustomization() { private val region = region(runtimeConfig) override fun section(section: ServiceConfig) = writable { when (section) { is ServiceConfig.ConfigStruct -> rust("pub(crate) region: Option<#T::Region>,", region) is ServiceConfig.ConfigImpl -> emptySection is ServiceConfig.BuilderStruct -> rust("region: Option<#T::Region>,", region) ServiceConfig.BuilderImpl -> rust( """ pub fn region(mut self, region_provider: impl #1T::ProvideRegion) -> Self { self.region = region_provider.region(); self } """, region ) ServiceConfig.BuilderBuild -> rust( """region: { use #1T::ProvideRegion; self.region.or_else(||#1T::default_provider().region()) },""", region ) } } } class RegionConfigPlugin() : OperationCustomization() { override fun section(section: OperationSection): Writable { return when (section) { OperationSection.ImplBlock -> emptySection is OperationSection.Feature -> writable { // Allow the region to be late-inserted via another method rust( """ if let Some(region) = &${section.config}.region { ${section.request}.config_mut().insert(region.clone()); } """ ) } } } } fun region(runtimeConfig: RuntimeConfig) = RuntimeType("region", awsTypes(runtimeConfig), "aws_types") fun awsTypes(runtimeConfig: RuntimeConfig) = CargoDependency("aws-types", Local(runtimeConfig.relativePath)) Loading
aws/rust-runtime/aws-endpoint/src/lib.rs +16 −9 Original line number Diff line number Diff line use aws_types::{Region, SigningRegion, SigningService}; use http::Uri; use smithy_http::endpoint::{Endpoint, EndpointPrefix}; use smithy_http::middleware::MapRequest; use smithy_http::operation::Request; use smithy_http::property_bag::PropertyBag; use std::error::Error; use std::fmt; use std::fmt::{Debug, Display, Formatter}; use std::str::FromStr; use std::sync::Arc; use http::Uri; use aws_types::region::{Region, SigningRegion}; use aws_types::SigningService; use smithy_http::endpoint::{Endpoint, EndpointPrefix}; use smithy_http::middleware::MapRequest; use smithy_http::operation::Request; use smithy_http::property_bag::PropertyBag; /// Endpoint to connect to an AWS Service /// /// An `AwsEndpoint` captures all necessary information needed to connect to an AWS service, including: Loading Loading @@ -164,13 +167,17 @@ impl MapRequest for AwsEndpointStage { #[cfg(test)] mod test { use crate::{set_endpoint_resolver, AwsEndpointStage, DefaultAwsEndpointResolver}; use aws_types::{Region, SigningRegion, SigningService}; use std::sync::Arc; use http::Uri; use aws_types::region::{Region, SigningRegion}; use aws_types::SigningService; use smithy_http::body::SdkBody; use smithy_http::middleware::MapRequest; use smithy_http::operation; use std::sync::Arc; use crate::{AwsEndpointStage, DefaultAwsEndpointResolver, set_endpoint_resolver}; #[test] fn default_endpoint_updates_request() { Loading
aws/rust-runtime/aws-types/src/lib.rs +2 −40 Original line number Diff line number Diff line use std::borrow::Cow; use std::sync::Arc; /// The region to send requests to. /// /// The region MUST be specified on a request. It may be configured globally or on a /// per-client basis unless otherwise noted. A full list of regions is found in the /// "Regions and Endpoints" document. /// /// See http://docs.aws.amazon.com/general/latest/gr/rande.html for /// information on AWS regions. #[derive(Clone, Debug, PartialEq, Eq)] pub struct Region(Arc<String>); impl AsRef<str> for Region { fn as_ref(&self) -> &str { self.0.as_str() } } impl Region { pub fn new(region: impl Into<String>) -> Self { Self(Arc::new(region.into())) } } /// The region to use when signing requests /// /// Generally, user code will not need to interact with `SigningRegion`. See `[Region](crate::Region)`. #[derive(Clone, Debug, PartialEq, Eq)] pub struct SigningRegion(Arc<String>); impl AsRef<str> for SigningRegion { fn as_ref(&self) -> &str { self.0.as_str() } } pub mod region; impl From<Region> for SigningRegion { fn from(inp: Region) -> Self { SigningRegion(inp.0) } } use std::borrow::Cow; /// The name of the service used to sign this request /// Loading
aws/rust-runtime/aws-types/src/region.rs 0 → 100644 +80 −0 Original line number Diff line number Diff line /* * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ use std::sync::Arc; /// The region to send requests to. /// /// The region MUST be specified on a request. It may be configured globally or on a /// per-client basis unless otherwise noted. A full list of regions is found in the /// "Regions and Endpoints" document. /// /// See http://docs.aws.amazon.com/general/latest/gr/rande.html for /// information on AWS regions. #[derive(Clone, Debug, PartialEq, Eq)] pub struct Region(Arc<String>); impl AsRef<str> for Region { fn as_ref(&self) -> &str { self.0.as_str() } } impl Region { pub fn new(region: impl Into<String>) -> Self { Self(Arc::new(region.into())) } } /// Provide a [`Region`](Region) to use with AWS requests /// /// For most cases [`default_provider`](default_provider) will be the best option, implementing /// a standard provider chain. pub trait ProvideRegion: Send + Sync { fn region(&self) -> Option<Region>; } impl ProvideRegion for Region { fn region(&self) -> Option<Region> { Some(self.clone()) } } pub fn default_provider() -> impl ProvideRegion { EnvironmentProvider } #[non_exhaustive] pub struct EnvironmentProvider; impl EnvironmentProvider { pub fn new() -> Self { EnvironmentProvider } } impl ProvideRegion for EnvironmentProvider { fn region(&self) -> Option<Region> { std::env::var("AWS_DEFAULT_REGION").map(Region::new).ok() } } /// The region to use when signing requests /// /// Generally, user code will not need to interact with `SigningRegion`. See `[Region](crate::Region)`. #[derive(Clone, Debug, PartialEq, Eq)] pub struct SigningRegion(Arc<String>); impl AsRef<str> for SigningRegion { fn as_ref(&self) -> &str { self.0.as_str() } } impl From<Region> for SigningRegion { fn from(inp: Region) -> Self { SigningRegion(inp.0) } }
aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/AwsCodegenDecorator.kt +8 −11 Original line number Diff line number Diff line Loading @@ -5,17 +5,14 @@ package software.amazon.smithy.rustsdk import software.amazon.smithy.rust.codegen.smithy.customize.RustCodegenDecorator import software.amazon.smithy.rust.codegen.smithy.generators.ProtocolConfig import software.amazon.smithy.rust.codegen.smithy.generators.config.ConfigCustomization import software.amazon.smithy.rust.codegen.smithy.customize.CombinedCodegenDecorator class AwsCodegenDecorator : RustCodegenDecorator { override val name: String = "AwsSdkCodgenDecorator" val DECORATORS = listOf( CredentialsProviderDecorator(), RegionDecorator() ) class AwsCodegenDecorator : CombinedCodegenDecorator(DECORATORS) { override val name: String = "AwsSdkCodegenDecorator" override val order: Byte = -1 override fun configCustomizations( protocolConfig: ProtocolConfig, baseCustomizations: List<ConfigCustomization> ): List<ConfigCustomization> { return listOf(BaseAwsConfig()) + baseCustomizations } }
aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/RegionDecorator.kt 0 → 100644 +119 −0 Original line number Diff line number Diff line /* * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ package software.amazon.smithy.rustsdk import software.amazon.smithy.model.shapes.OperationShape import software.amazon.smithy.rust.codegen.rustlang.CargoDependency import software.amazon.smithy.rust.codegen.rustlang.Local import software.amazon.smithy.rust.codegen.rustlang.Writable import software.amazon.smithy.rust.codegen.rustlang.rust import software.amazon.smithy.rust.codegen.rustlang.writable import software.amazon.smithy.rust.codegen.smithy.RuntimeConfig import software.amazon.smithy.rust.codegen.smithy.RuntimeType import software.amazon.smithy.rust.codegen.smithy.customize.RustCodegenDecorator import software.amazon.smithy.rust.codegen.smithy.generators.OperationCustomization import software.amazon.smithy.rust.codegen.smithy.generators.OperationSection import software.amazon.smithy.rust.codegen.smithy.generators.ProtocolConfig import software.amazon.smithy.rust.codegen.smithy.generators.config.ConfigCustomization import software.amazon.smithy.rust.codegen.smithy.generators.config.ServiceConfig /* Example Generated Code */ /* pub struct Config { pub region: Option<::aws_types::region::Region>, } #[derive(Default)] pub struct ConfigBuilder { region: Option<::aws_types::region::Region>, } impl ConfigBuilder { pub fn region(mut self, region_provider: impl ::aws_types::region::ProvideRegion) -> Self { self.region = region_provider.region(); self } pub fn build(self) -> Config { Config { region: { use ::aws_types::region::ProvideRegion; self.region .or_else(|| ::aws_types::region::default_provider().region()) }, } } */ class RegionDecorator : RustCodegenDecorator { override val name: String = "Region" override val order: Byte = 0 override fun configCustomizations( protocolConfig: ProtocolConfig, baseCustomizations: List<ConfigCustomization> ): List<ConfigCustomization> { return baseCustomizations + RegionProviderConfig(protocolConfig.runtimeConfig) } override fun operationCustomizations( protocolConfig: ProtocolConfig, operation: OperationShape, baseCustomizations: List<OperationCustomization> ): List<OperationCustomization> { return baseCustomizations + RegionConfigPlugin() } } class RegionProviderConfig(runtimeConfig: RuntimeConfig) : ConfigCustomization() { private val region = region(runtimeConfig) override fun section(section: ServiceConfig) = writable { when (section) { is ServiceConfig.ConfigStruct -> rust("pub(crate) region: Option<#T::Region>,", region) is ServiceConfig.ConfigImpl -> emptySection is ServiceConfig.BuilderStruct -> rust("region: Option<#T::Region>,", region) ServiceConfig.BuilderImpl -> rust( """ pub fn region(mut self, region_provider: impl #1T::ProvideRegion) -> Self { self.region = region_provider.region(); self } """, region ) ServiceConfig.BuilderBuild -> rust( """region: { use #1T::ProvideRegion; self.region.or_else(||#1T::default_provider().region()) },""", region ) } } } class RegionConfigPlugin() : OperationCustomization() { override fun section(section: OperationSection): Writable { return when (section) { OperationSection.ImplBlock -> emptySection is OperationSection.Feature -> writable { // Allow the region to be late-inserted via another method rust( """ if let Some(region) = &${section.config}.region { ${section.request}.config_mut().insert(region.clone()); } """ ) } } } } fun region(runtimeConfig: RuntimeConfig) = RuntimeType("region", awsTypes(runtimeConfig), "aws_types") fun awsTypes(runtimeConfig: RuntimeConfig) = CargoDependency("aws-types", Local(runtimeConfig.relativePath))