Unverified Commit 71c97a13 authored by Russell Cohen's avatar Russell Cohen Committed by GitHub
Browse files

Ergonomics improvements & a working example (#204)

* Ergonomics improvements & a working example

This diff adds several `pub use` statements to generated service crates to improve ergonomics, namely, this removes the need for customers to depend on internal crates like `aws-auth` when using the SDK. A few other minor bugs were also fixed on the path to getting a working example.

* Fix broken intra doc link

* Fix stale import

* Remove dead code
parent b60b30bb
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -71,7 +71,7 @@ where
    /// access the raw response use `call_raw`.
    pub async fn call<O, T, E, Retry>(&self, input: Operation<O, Retry>) -> Result<T, SdkError<E>>
    where
        O: ParseHttpResponse<hyper::Body, Output = Result<T, E>> + Send + Clone + 'static,
        O: ParseHttpResponse<hyper::Body, Output = Result<T, E>> + Send + 'static,
    {
        self.call_raw(input).await.map(|res| res.parsed)
    }
@@ -85,7 +85,7 @@ where
        input: Operation<O, Retry>,
    ) -> Result<SdkSuccess<R>, SdkError<E>>
    where
        O: ParseHttpResponse<hyper::Body, Output = Result<R, E>> + Send + Clone + 'static,
        O: ParseHttpResponse<hyper::Body, Output = Result<R, E>> + Send + 'static,
    {
        let signer = MapRequestLayer::for_mapper(SigV4SigningStage::new(SigV4Signer::new()));
        let endpoint_resolver = MapRequestLayer::for_mapper(AwsEndpointStage);
+1 −1
Original line number Diff line number Diff line
@@ -18,7 +18,7 @@ pub struct ValidateRequest {
    pub actual: http::Request<SdkBody>,
}

/// TestConnection for use with a [`aws_hyper::Client`](aws_hyper::Client)
/// TestConnection for use with a [`aws_hyper::Client`](crate::Client)
///
/// A basic test connection. It will:
/// - Response to requests with a preloaded series of responses
+0 −1
Original line number Diff line number Diff line
@@ -123,7 +123,6 @@ mod test {
    use aws_auth::CredentialsProvider;
    use aws_endpoint::{set_endpoint_resolver, AwsEndpointStage, DefaultAwsEndpointResolver};
    use aws_types::region::Region;
    use aws_types::Region;
    use http::header::AUTHORIZATION;
    use smithy_http::body::SdkBody;
    use smithy_http::middleware::MapRequest;
+32 −3
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@ 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.customize.RustCodegenDecorator
import software.amazon.smithy.rust.codegen.smithy.generators.LibRsCustomization
import software.amazon.smithy.rust.codegen.smithy.generators.LibRsSection
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
@@ -31,7 +33,10 @@ class AwsEndpointDecorator : RustCodegenDecorator {
        protocolConfig: ProtocolConfig,
        baseCustomizations: List<ConfigCustomization>
    ): List<ConfigCustomization> {
        return baseCustomizations + EndpointConfigCustomization(protocolConfig.runtimeConfig, protocolConfig.serviceShape)
        return baseCustomizations + EndpointConfigCustomization(
            protocolConfig.runtimeConfig,
            protocolConfig.serviceShape
        )
    }

    override fun operationCustomizations(
@@ -41,14 +46,25 @@ class AwsEndpointDecorator : RustCodegenDecorator {
    ): List<OperationCustomization> {
        return baseCustomizations + EndpointResolverFeature(protocolConfig.runtimeConfig, operation)
    }

    override fun libRsCustomizations(
        protocolConfig: ProtocolConfig,
        baseCustomizations: List<LibRsCustomization>
    ): List<LibRsCustomization> {
        return baseCustomizations + PubUseEndpoint(protocolConfig.runtimeConfig)
    }
}

class EndpointConfigCustomization(private val runtimeConfig: RuntimeConfig, serviceShape: ServiceShape) : ConfigCustomization() {
class EndpointConfigCustomization(private val runtimeConfig: RuntimeConfig, serviceShape: ServiceShape) :
    ConfigCustomization() {
    private val endpointPrefix = serviceShape.expectTrait(ServiceTrait::class.java).endpointPrefix
    private val resolveAwsEndpoint = runtimeConfig.awsEndpointDependency().asType().copy(name = "ResolveAwsEndpoint")
    override fun section(section: ServiceConfig): Writable = writable {
        when (section) {
            is ServiceConfig.ConfigStruct -> rust("pub endpoint_resolver: ::std::sync::Arc<dyn #T>,", resolveAwsEndpoint)
            is ServiceConfig.ConfigStruct -> rust(
                "pub endpoint_resolver: ::std::sync::Arc<dyn #T>,",
                resolveAwsEndpoint
            )
            is ServiceConfig.ConfigImpl -> emptySection
            is ServiceConfig.BuilderStruct ->
                rust("endpoint_resolver: Option<::std::sync::Arc<dyn #T>>,", resolveAwsEndpoint)
@@ -93,3 +109,16 @@ class EndpointResolverFeature(private val runtimeConfig: RuntimeConfig, private
        }
    }
}

class PubUseEndpoint(private val runtimeConfig: RuntimeConfig) : LibRsCustomization() {
    override fun section(section: LibRsSection): Writable {
        return when (section) {
            is LibRsSection.Body -> writable {
                rust(
                    "pub use #T::endpoint::Endpoint;",
                    CargoDependency.SmithyHttp(runtimeConfig).asType()
                )
            }
        }
    }
}
+18 −0
Original line number Diff line number Diff line
@@ -9,12 +9,15 @@ 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.asType
import software.amazon.smithy.rust.codegen.rustlang.docs
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.LibRsCustomization
import software.amazon.smithy.rust.codegen.smithy.generators.LibRsSection
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
@@ -39,6 +42,13 @@ class CredentialsProviderDecorator : RustCodegenDecorator {
    ): List<OperationCustomization> {
        return baseCustomizations + CredentialsProviderFeature(protocolConfig.runtimeConfig)
    }

    override fun libRsCustomizations(
        protocolConfig: ProtocolConfig,
        baseCustomizations: List<LibRsCustomization>
    ): List<LibRsCustomization> {
        return baseCustomizations + PubUseCredentials(protocolConfig.runtimeConfig)
    }
}

/**
@@ -93,6 +103,14 @@ class CredentialsProviderFeature(private val runtimeConfig: RuntimeConfig) : Ope
    }
}

class PubUseCredentials(private val runtimeConfig: RuntimeConfig) : LibRsCustomization() {
    override fun section(section: LibRsSection): Writable {
        return when (section) {
            is LibRsSection.Body -> writable { rust("pub use #T::Credentials;", awsAuth(runtimeConfig).asType()) }
        }
    }
}

fun awsAuth(runtimeConfig: RuntimeConfig) = CargoDependency("aws-auth", Local(runtimeConfig.relativePath))
fun credentialsProvider(runtimeConfig: RuntimeConfig) = RuntimeType("ProvideCredentials", awsAuth(runtimeConfig), "aws_auth")
fun defaultProvider(runtimeConfig: RuntimeConfig) = RuntimeType("default_provider", awsAuth(runtimeConfig), "aws_auth")
Loading