Skip to content

Commit

Permalink
Clean up re-exports and improve 'BuildError' conversions (#3173)
Browse files Browse the repository at this point in the history
## Motivation and Context
- Fixes #3171 
- Fixes #3155 
- Fixes #3172 


## Description
- Add `configReExport` to make it easy and consistent to re-export types
into the config module when they are used!
- Add this for a bunch of types and clean up some (now) dead code
- Re export `BuildError`
- Enable converting from `BuildError` into `SdkError`

There are probably more places this can be used, but I'd like to keep
this change small to facilitate easy backport to 0.57.

## Testing
CI

## Checklist
<!--- If a checkbox below is not applicable, then please DELETE it
rather than leaving it unchecked -->
- [x] I have updated `CHANGELOG.next.toml` if I made changes to the
smithy-rs codegen or runtime crates
- [x] I have updated `CHANGELOG.next.toml` if I made changes to the AWS
SDK, generated SDK code, or SDK runtime crates

----

_By submitting this pull request, I confirm that you can use, modify,
copy, and redistribute this contribution, under the terms of your
choice._
  • Loading branch information
rcoh committed Nov 13, 2023
1 parent 3af97de commit ccab4b6
Show file tree
Hide file tree
Showing 17 changed files with 186 additions and 79 deletions.
49 changes: 49 additions & 0 deletions CHANGELOG.next.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,52 @@ message = "Fix exclusively setting the credentials provider at operation config-
references = ["smithy-rs#3156", "aws-sdk-rust#901"]
meta = { "breaking" = false, "tada" = false, "bug" = true }
author = "ysaito1001"

[[smithy-rs]]
message = """Enable conversion from `BuildError` into `SdkError` & `<service>::Error`. This allows customers to write the following code:
```rust
async fn do_a_thing(client: &Client) -> Result<SdkError<SomeOperationError>> {
client.run_operation().complex_field(ComplexField::builder()
.a("a")
.b("b")
.build()?
).send().await?;
}
```
Previously, `?` could not be used in this position.
"""
references = ["smithy-rs#3173", "smithy-rs#3171"]
meta = { "breaking" = false, "tada" = true, "bug" = false }
author = "rcoh"

[[aws-sdk-rust]]
message = """Enable conversion from `BuildError` into `SdkError` & `<service>::Error`. This allows customers to write the following code:
```rust
async fn create_table(dynamo_client: &Client) -> Result<(), SdkError<CreateTableError>> {
dynamo_client
.create_table()
.table_name("test")
.key_schema(
KeySchemaElement::builder()
.attribute_name("year")
.key_type(KeyType::Hash)
.build()?, // Previously, `?` could not be used here
)
.send()
.await?;
Ok(())
}
```
Previously, `?` could not be used in this position.
"""
references = ["smithy-rs#3173", "smithy-rs#3171"]
meta = { "breaking" = false, "tada" = true, "bug" = false }
author = "rcoh"

[[aws-sdk-rust]]
message = "ProvideCredentials and SharedCredentialsProvider are now re-exported."
references = ["smithy-rs#3173", "smithy-rs#3155"]
meta = { "breaking" = false, "tada" = false, "bug" = false }
author = "rcoh"
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,9 @@ import software.amazon.smithy.rust.codegen.core.smithy.generators.LibRsSection
import software.amazon.smithy.rust.codegen.core.util.serviceNameOrDefault

private class Types(runtimeConfig: RuntimeConfig) {
private val smithyHttp = RuntimeType.smithyHttp(runtimeConfig)
private val smithyTypes = RuntimeType.smithyTypes(runtimeConfig)

val awsTypes = AwsRuntimeType.awsTypes(runtimeConfig)
val connectorError = smithyHttp.resolve("result::ConnectorError")
val retryConfig = smithyTypes.resolve("retry::RetryConfig")
val timeoutConfig = smithyTypes.resolve("timeout::TimeoutConfig")
}
Expand Down Expand Up @@ -102,7 +100,6 @@ class AwsFluentClientDecorator : ClientCodegenDecorator {
private class AwsFluentClientExtensions(private val codegenContext: ClientCodegenContext, private val types: Types) {
private val codegenScope = arrayOf(
"Arc" to RuntimeType.Arc,
"ConnectorError" to types.connectorError,
"RetryConfig" to types.retryConfig,
"TimeoutConfig" to types.timeoutConfig,
"aws_types" to types.awsTypes,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package software.amazon.smithy.rustsdk

import software.amazon.smithy.rust.codegen.client.smithy.ClientCodegenContext
import software.amazon.smithy.rust.codegen.client.smithy.ClientRustModule
import software.amazon.smithy.rust.codegen.client.smithy.configReexport
import software.amazon.smithy.rust.codegen.client.smithy.customize.ClientCodegenDecorator
import software.amazon.smithy.rust.codegen.client.smithy.customize.TestUtilFeature
import software.amazon.smithy.rust.codegen.client.smithy.endpoint.supportedAuthSchemes
Expand Down Expand Up @@ -59,11 +60,15 @@ class CredentialProviderConfig(private val codegenContext: ClientCodegenContext)
private val runtimeConfig = codegenContext.runtimeConfig
private val codegenScope = arrayOf(
*preludeScope,
"Credentials" to AwsRuntimeType.awsCredentialTypes(runtimeConfig).resolve("Credentials"),
"ProvideCredentials" to AwsRuntimeType.awsCredentialTypes(runtimeConfig)
.resolve("provider::ProvideCredentials"),
"SharedCredentialsProvider" to AwsRuntimeType.awsCredentialTypes(runtimeConfig)
.resolve("provider::SharedCredentialsProvider"),
"Credentials" to configReexport(AwsRuntimeType.awsCredentialTypes(runtimeConfig).resolve("Credentials")),
"ProvideCredentials" to configReexport(
AwsRuntimeType.awsCredentialTypes(runtimeConfig)
.resolve("provider::ProvideCredentials"),
),
"SharedCredentialsProvider" to configReexport(
AwsRuntimeType.awsCredentialTypes(runtimeConfig)
.resolve("provider::SharedCredentialsProvider"),
),
"SIGV4A_SCHEME_ID" to AwsRuntimeType.awsRuntime(runtimeConfig)
.resolve("auth::sigv4a::SCHEME_ID"),
"SIGV4_SCHEME_ID" to AwsRuntimeType.awsRuntime(runtimeConfig)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import software.amazon.smithy.model.node.Node
import software.amazon.smithy.rulesengine.aws.language.functions.AwsBuiltIns
import software.amazon.smithy.rulesengine.language.syntax.parameters.Parameter
import software.amazon.smithy.rust.codegen.client.smithy.ClientCodegenContext
import software.amazon.smithy.rust.codegen.client.smithy.ClientRustModule
import software.amazon.smithy.rust.codegen.client.smithy.configReexport
import software.amazon.smithy.rust.codegen.client.smithy.customize.ClientCodegenDecorator
import software.amazon.smithy.rust.codegen.client.smithy.endpoint.EndpointCustomization
import software.amazon.smithy.rust.codegen.client.smithy.generators.config.ConfigCustomization
Expand All @@ -22,7 +22,6 @@ import software.amazon.smithy.rust.codegen.core.rustlang.rustTemplate
import software.amazon.smithy.rust.codegen.core.rustlang.writable
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeConfig
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeType.Companion.preludeScope
import software.amazon.smithy.rust.codegen.core.smithy.RustCrate
import software.amazon.smithy.rust.codegen.core.smithy.customize.AdHocCustomization
import software.amazon.smithy.rust.codegen.core.smithy.customize.adhocCustomization
import software.amazon.smithy.rust.codegen.core.util.dq
Expand Down Expand Up @@ -109,14 +108,6 @@ class RegionDecorator : ClientCodegenDecorator {
}
}

override fun extras(codegenContext: ClientCodegenContext, rustCrate: RustCrate) {
if (usesRegion(codegenContext)) {
rustCrate.withModule(ClientRustModule.config) {
rust("pub use #T::Region;", region(codegenContext.runtimeConfig))
}
}
}

override fun endpointCustomizations(codegenContext: ClientCodegenContext): List<EndpointCustomization> {
if (!usesRegion(codegenContext)) {
return listOf()
Expand Down Expand Up @@ -157,7 +148,7 @@ class RegionProviderConfig(codegenContext: ClientCodegenContext) : ConfigCustomi
private val moduleUseName = codegenContext.moduleUseName()
private val codegenScope = arrayOf(
*preludeScope,
"Region" to region.resolve("Region"),
"Region" to configReexport(region.resolve("Region")),
)

override fun section(section: ServiceConfig) = writable {
Expand Down
41 changes: 41 additions & 0 deletions aws/sdk/integration-tests/dynamodb/tests/build-errors.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/

use aws_sdk_dynamodb::error::SdkError;
use aws_sdk_dynamodb::operation::create_table::CreateTableError;
use aws_sdk_dynamodb::types::{KeySchemaElement, KeyType};
use aws_sdk_dynamodb::Client;

#[allow(dead_code)]
async fn create_table_test(client: &Client) -> Result<(), SdkError<CreateTableError>> {
let _just_checking_compilation = client
.create_table()
.table_name("test")
.key_schema(
KeySchemaElement::builder()
.attribute_name("year")
.key_type(KeyType::Hash)
.build()?,
)
.send()
.await;
Ok(())
}

#[allow(dead_code)]
async fn create_table_test_super_error(client: &Client) -> Result<(), aws_sdk_dynamodb::Error> {
let _just_checking_compilation = client
.create_table()
.table_name("test")
.key_schema(
KeySchemaElement::builder()
.attribute_name("year")
.key_type(KeyType::Hash)
.build()?,
)
.send()
.await;
Ok(())
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/

package software.amazon.smithy.rust.codegen.client.smithy

import software.amazon.smithy.rust.codegen.core.rustlang.rustTemplate
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeType

/** Returns a symbol for a type re-exported into crate::config
* Although it is not always possible to use this, this is the preferred method for using types in config customizations
* and ensures that your type will be re-exported if it is used.
*/
fun configReexport(type: RuntimeType): RuntimeType = RuntimeType.forInlineFun(type.name, module = ClientRustModule.config) {
rustTemplate("pub use #{type};", "type" to type)
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import software.amazon.smithy.model.traits.HttpBasicAuthTrait
import software.amazon.smithy.model.traits.HttpBearerAuthTrait
import software.amazon.smithy.model.traits.HttpDigestAuthTrait
import software.amazon.smithy.rust.codegen.client.smithy.ClientCodegenContext
import software.amazon.smithy.rust.codegen.client.smithy.ClientRustModule
import software.amazon.smithy.rust.codegen.client.smithy.configReexport
import software.amazon.smithy.rust.codegen.client.smithy.customize.AuthSchemeOption
import software.amazon.smithy.rust.codegen.client.smithy.customize.AuthSchemeOption.StaticAuthSchemeOption
import software.amazon.smithy.rust.codegen.client.smithy.customize.ClientCodegenDecorator
Expand All @@ -26,7 +26,6 @@ import software.amazon.smithy.rust.codegen.core.rustlang.Writable
import software.amazon.smithy.rust.codegen.core.rustlang.rustTemplate
import software.amazon.smithy.rust.codegen.core.rustlang.writable
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeConfig
import software.amazon.smithy.rust.codegen.core.smithy.RustCrate
import software.amazon.smithy.rust.codegen.core.util.dq
import software.amazon.smithy.rust.codegen.core.util.getTrait
import software.amazon.smithy.rust.codegen.core.util.letIf
Expand All @@ -38,6 +37,10 @@ private fun codegenScope(runtimeConfig: RuntimeConfig): Array<Pair<String, Any>>
val authHttp = smithyRuntime.resolve("client::auth::http")
val authHttpApi = smithyRuntimeApi.resolve("client::auth::http")
return arrayOf(
"Token" to configReexport(smithyRuntimeApi.resolve("client::identity::http::Token")),
"Login" to configReexport(smithyRuntimeApi.resolve("client::identity::http::Login")),
"ResolveIdentity" to configReexport(smithyRuntimeApi.resolve("client::identity::ResolveIdentity")),

"AuthSchemeId" to smithyRuntimeApi.resolve("client::auth::AuthSchemeId"),
"ApiKeyAuthScheme" to authHttp.resolve("ApiKeyAuthScheme"),
"ApiKeyLocation" to authHttp.resolve("ApiKeyLocation"),
Expand All @@ -48,11 +51,8 @@ private fun codegenScope(runtimeConfig: RuntimeConfig): Array<Pair<String, Any>>
"HTTP_BASIC_AUTH_SCHEME_ID" to authHttpApi.resolve("HTTP_BASIC_AUTH_SCHEME_ID"),
"HTTP_BEARER_AUTH_SCHEME_ID" to authHttpApi.resolve("HTTP_BEARER_AUTH_SCHEME_ID"),
"HTTP_DIGEST_AUTH_SCHEME_ID" to authHttpApi.resolve("HTTP_DIGEST_AUTH_SCHEME_ID"),
"ResolveIdentity" to smithyRuntimeApi.resolve("client::identity::ResolveIdentity"),
"Login" to smithyRuntimeApi.resolve("client::identity::http::Login"),
"SharedAuthScheme" to smithyRuntimeApi.resolve("client::auth::SharedAuthScheme"),
"SharedIdentityResolver" to smithyRuntimeApi.resolve("client::identity::SharedIdentityResolver"),
"Token" to smithyRuntimeApi.resolve("client::identity::http::Token"),
)
}

Expand Down Expand Up @@ -135,25 +135,10 @@ class HttpAuthDecorator : ClientCodegenDecorator {
it + HttpAuthServiceRuntimePluginCustomization(codegenContext, authSchemes)
}
}

override fun extras(codegenContext: ClientCodegenContext, rustCrate: RustCrate) {
val authSchemes = HttpAuthSchemes.from(codegenContext)
if (authSchemes.anyEnabled()) {
rustCrate.withModule(ClientRustModule.config) {
val codegenScope = codegenScope(codegenContext.runtimeConfig)
if (authSchemes.isTokenBased()) {
rustTemplate("pub use #{Token};", *codegenScope)
}
if (authSchemes.isLoginBased()) {
rustTemplate("pub use #{Login};", *codegenScope)
}
}
}
}
}

private class HttpAuthServiceRuntimePluginCustomization(
private val codegenContext: ClientCodegenContext,
codegenContext: ClientCodegenContext,
private val authSchemes: HttpAuthSchemes,
) : ServiceRuntimePluginCustomization() {
private val serviceShape = codegenContext.serviceShape
Expand All @@ -167,6 +152,7 @@ private class HttpAuthServiceRuntimePluginCustomization(
rustTemplate("#{SharedAuthScheme}::new(#{Scheme})", *codegenScope, "Scheme" to scheme)
}
}

fun registerNamedAuthScheme(name: String) {
registerAuthScheme {
rustTemplate("#{$name}::new()", *codegenScope)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
package software.amazon.smithy.rust.codegen.client.smithy.customizations

import software.amazon.smithy.rust.codegen.client.smithy.ClientCodegenContext
import software.amazon.smithy.rust.codegen.client.smithy.configReexport
import software.amazon.smithy.rust.codegen.client.smithy.customize.ClientCodegenDecorator
import software.amazon.smithy.rust.codegen.client.smithy.generators.config.ConfigCustomization
import software.amazon.smithy.rust.codegen.client.smithy.generators.config.ServiceConfig
Expand All @@ -32,13 +33,13 @@ private class HttpConnectorConfigCustomization(
private val moduleUseName = codegenContext.moduleUseName()
private val codegenScope = arrayOf(
*preludeScope,
"Connection" to RuntimeType.smithyRuntimeApi(runtimeConfig).resolve("client::orchestrator::Connection"),
"HttpClient" to RuntimeType.smithyRuntimeApi(runtimeConfig).resolve("client::http::HttpClient"),
"IntoShared" to RuntimeType.smithyRuntimeApi(runtimeConfig).resolve("shared::IntoShared"),
"Resolver" to RuntimeType.smithyRuntime(runtimeConfig).resolve("client::config_override::Resolver"),
"SharedAsyncSleep" to RuntimeType.smithyAsync(runtimeConfig).resolve("rt::sleep::SharedAsyncSleep"),
"SharedHttpClient" to RuntimeType.smithyRuntimeApi(runtimeConfig).resolve("client::http::SharedHttpClient"),
"TimeoutConfig" to RuntimeType.smithyTypes(runtimeConfig).resolve("timeout::TimeoutConfig"),
"HttpClient" to configReexport(
RuntimeType.smithyRuntimeApi(runtimeConfig).resolve("client::http::HttpClient"),
),
"IntoShared" to configReexport(RuntimeType.smithyRuntimeApi(runtimeConfig).resolve("shared::IntoShared")),
"SharedHttpClient" to configReexport(
RuntimeType.smithyRuntimeApi(runtimeConfig).resolve("client::http::SharedHttpClient"),
),
)

override fun section(section: ServiceConfig): Writable {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
package software.amazon.smithy.rust.codegen.client.smithy.customizations

import software.amazon.smithy.rust.codegen.client.smithy.ClientCodegenContext
import software.amazon.smithy.rust.codegen.client.smithy.configReexport
import software.amazon.smithy.rust.codegen.client.smithy.generators.config.ConfigCustomization
import software.amazon.smithy.rust.codegen.client.smithy.generators.config.ServiceConfig
import software.amazon.smithy.rust.codegen.core.rustlang.Writable
Expand All @@ -21,8 +22,8 @@ class IdentityCacheConfigCustomization(codegenContext: ClientCodegenContext) : C
val api = RuntimeType.smithyRuntimeApi(rc)
arrayOf(
*preludeScope,
"ResolveCachedIdentity" to api.resolve("client::identity::ResolveCachedIdentity"),
"SharedIdentityCache" to api.resolve("client::identity::SharedIdentityCache"),
"ResolveCachedIdentity" to configReexport(api.resolve("client::identity::ResolveCachedIdentity")),
"SharedIdentityCache" to configReexport(api.resolve("client::identity::SharedIdentityCache")),
)
}

Expand Down Expand Up @@ -88,6 +89,7 @@ class IdentityCacheConfigCustomization(codegenContext: ClientCodegenContext) : C
*codegenScope,
)
}

is ServiceConfig.ConfigImpl -> {
rustTemplate(
"""
Expand All @@ -99,7 +101,8 @@ class IdentityCacheConfigCustomization(codegenContext: ClientCodegenContext) : C
*codegenScope,
)
}
else -> { }

else -> {}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
package software.amazon.smithy.rust.codegen.client.smithy.customizations

import software.amazon.smithy.rust.codegen.client.smithy.ClientCodegenContext
import software.amazon.smithy.rust.codegen.client.smithy.configReexport
import software.amazon.smithy.rust.codegen.client.smithy.generators.config.ConfigCustomization
import software.amazon.smithy.rust.codegen.client.smithy.generators.config.ServiceConfig
import software.amazon.smithy.rust.codegen.core.rustlang.rustTemplate
Expand All @@ -17,8 +18,8 @@ class InterceptorConfigCustomization(codegenContext: ClientCodegenContext) : Con
private val runtimeConfig = codegenContext.runtimeConfig

private val codegenScope = arrayOf(
"Intercept" to RuntimeType.intercept(runtimeConfig),
"SharedInterceptor" to RuntimeType.sharedInterceptor(runtimeConfig),
"Intercept" to configReexport(RuntimeType.intercept(runtimeConfig)),
"SharedInterceptor" to configReexport(RuntimeType.sharedInterceptor(runtimeConfig)),
)

override fun section(section: ServiceConfig) =
Expand Down
Loading

0 comments on commit ccab4b6

Please sign in to comment.