mirror of https://github.com/smithy-lang/smithy-rs
Make service config just contain a `FrozenLayer` in the orchestrator mode (#2762)
## Motivation and Context Service config structs now only contain a `aws_smithy_types::config_bag::FrozenLayer` in the orchestrator mode (no changes for the middleware mode). ## Description This PR reduces the individual fields of service configs to contain just `FrozenLayer`. This makes service configs work more seamlessly with runtime plugins in the orchestrator mode. Note that service config _builder_ s still contain individual fields. We're planning to make them just contain `aws_smithy_types::config_bag::Layer`. To do that, though, we need to make `Layer` cloneable and that will be handled in a separate PR. For builders, the only change you will in the PR is that their `build` method will put fields into a `Layer`, freeze it, and pass it to service configs. This PR is marked as a breaking change because it's based on [another PR](https://github.com/awslabs/smithy-rs/pull/2728) that's also breaking change. ## Testing - [x] Passed tests in CI ---- _By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice._ --------- Co-authored-by: Yuki Saito <awsaito@amazon.com> Co-authored-by: Zelda Hessler <zhessler@amazon.com>
This commit is contained in:
parent
b2bdcba57a
commit
2e472d068e
|
@ -1,3 +1,6 @@
|
||||||
allowed_external_types = [
|
allowed_external_types = [
|
||||||
"aws_smithy_async::rt::sleep::SharedAsyncSleep",
|
"aws_smithy_async::rt::sleep::SharedAsyncSleep",
|
||||||
|
"aws_smithy_types::config_bag::storable::Storable",
|
||||||
|
"aws_smithy_types::config_bag::storable::StoreReplace",
|
||||||
|
"aws_smithy_types::config_bag::storable::Storer",
|
||||||
]
|
]
|
||||||
|
|
|
@ -14,6 +14,7 @@ pub use lazy_caching::Builder as LazyBuilder;
|
||||||
use no_caching::NoCredentialsCache;
|
use no_caching::NoCredentialsCache;
|
||||||
|
|
||||||
use crate::provider::{future, SharedCredentialsProvider};
|
use crate::provider::{future, SharedCredentialsProvider};
|
||||||
|
use aws_smithy_types::config_bag::{Storable, StoreReplace};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
/// Asynchronous Cached Credentials Provider
|
/// Asynchronous Cached Credentials Provider
|
||||||
|
@ -62,6 +63,10 @@ impl ProvideCachedCredentials for SharedCredentialsCache {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Storable for SharedCredentialsCache {
|
||||||
|
type Storer = StoreReplace<SharedCredentialsCache>;
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub(crate) enum Inner {
|
pub(crate) enum Inner {
|
||||||
Lazy(lazy_caching::Builder),
|
Lazy(lazy_caching::Builder),
|
||||||
|
@ -122,3 +127,7 @@ impl CredentialsCache {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Storable for CredentialsCache {
|
||||||
|
type Storer = StoreReplace<CredentialsCache>;
|
||||||
|
}
|
||||||
|
|
|
@ -72,6 +72,7 @@ construct credentials from hardcoded values.
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
use crate::Credentials;
|
use crate::Credentials;
|
||||||
|
use aws_smithy_types::config_bag::{Storable, StoreReplace};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
/// Credentials provider errors
|
/// Credentials provider errors
|
||||||
|
@ -350,3 +351,7 @@ impl ProvideCredentials for SharedCredentialsProvider {
|
||||||
self.0.provide_credentials()
|
self.0.provide_credentials()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Storable for SharedCredentialsProvider {
|
||||||
|
type Storer = StoreReplace<SharedCredentialsProvider>;
|
||||||
|
}
|
||||||
|
|
|
@ -2,13 +2,16 @@ allowed_external_types = [
|
||||||
"aws_credential_types::cache::CredentialsCache",
|
"aws_credential_types::cache::CredentialsCache",
|
||||||
"aws_credential_types::provider::SharedCredentialsProvider",
|
"aws_credential_types::provider::SharedCredentialsProvider",
|
||||||
"aws_smithy_async::rt::sleep::SharedAsyncSleep",
|
"aws_smithy_async::rt::sleep::SharedAsyncSleep",
|
||||||
"aws_smithy_async::time::TimeSource",
|
|
||||||
"aws_smithy_async::time::SharedTimeSource",
|
"aws_smithy_async::time::SharedTimeSource",
|
||||||
|
"aws_smithy_async::time::TimeSource",
|
||||||
"aws_smithy_client::http_connector",
|
"aws_smithy_client::http_connector",
|
||||||
"aws_smithy_client::http_connector::HttpConnector",
|
"aws_smithy_client::http_connector::HttpConnector",
|
||||||
"aws_smithy_http::endpoint::Endpoint",
|
"aws_smithy_http::endpoint::Endpoint",
|
||||||
"aws_smithy_http::endpoint::EndpointPrefix",
|
"aws_smithy_http::endpoint::EndpointPrefix",
|
||||||
"aws_smithy_http::endpoint::error::InvalidEndpointError",
|
"aws_smithy_http::endpoint::error::InvalidEndpointError",
|
||||||
|
"aws_smithy_types::config_bag::storable::Storable",
|
||||||
|
"aws_smithy_types::config_bag::storable::StoreReplace",
|
||||||
|
"aws_smithy_types::config_bag::storable::Storer",
|
||||||
"aws_smithy_types::retry::RetryConfig",
|
"aws_smithy_types::retry::RetryConfig",
|
||||||
"aws_smithy_types::timeout::TimeoutConfig",
|
"aws_smithy_types::timeout::TimeoutConfig",
|
||||||
"http::uri::Uri",
|
"http::uri::Uri",
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
//! New-type for a configurable app name.
|
//! New-type for a configurable app name.
|
||||||
|
|
||||||
|
use aws_smithy_types::config_bag::{Storable, StoreReplace};
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
@ -38,6 +39,10 @@ impl fmt::Display for AppName {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Storable for AppName {
|
||||||
|
type Storer = StoreReplace<AppName>;
|
||||||
|
}
|
||||||
|
|
||||||
impl AppName {
|
impl AppName {
|
||||||
/// Creates a new app name.
|
/// Creates a new app name.
|
||||||
///
|
///
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
//! Newtypes for endpoint-related parameters
|
||||||
|
//!
|
||||||
|
//! Parameters require newtypes so they have distinct types when stored in layers in config bag.
|
||||||
|
|
||||||
|
use aws_smithy_types::config_bag::{Storable, StoreReplace};
|
||||||
|
|
||||||
|
/// Newtype for `use_fips`
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct UseFips(pub bool);
|
||||||
|
impl Storable for UseFips {
|
||||||
|
type Storer = StoreReplace<UseFips>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Newtype for `use_dual_stack`
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct UseDualStack(pub bool);
|
||||||
|
impl Storable for UseDualStack {
|
||||||
|
type Storer = StoreReplace<UseDualStack>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Newtype for `endpoint_url`
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct EndpointUrl(pub String);
|
||||||
|
impl Storable for EndpointUrl {
|
||||||
|
type Storer = StoreReplace<EndpointUrl>;
|
||||||
|
}
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
pub mod app_name;
|
pub mod app_name;
|
||||||
pub mod build_metadata;
|
pub mod build_metadata;
|
||||||
|
pub mod endpoint_config;
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub mod os_shim_internal;
|
pub mod os_shim_internal;
|
||||||
pub mod region;
|
pub mod region;
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
//! Region type for determining the endpoint to send requests to.
|
//! Region type for determining the endpoint to send requests to.
|
||||||
|
|
||||||
|
use aws_smithy_types::config_bag::{Storable, StoreReplace};
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::fmt::{Display, Formatter};
|
use std::fmt::{Display, Formatter};
|
||||||
|
|
||||||
|
@ -35,6 +36,10 @@ impl Display for Region {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Storable for Region {
|
||||||
|
type Storer = StoreReplace<Region>;
|
||||||
|
}
|
||||||
|
|
||||||
impl Region {
|
impl Region {
|
||||||
/// Creates a new `Region` from the given string.
|
/// Creates a new `Region` from the given string.
|
||||||
pub fn new(region: impl Into<Cow<'static, str>>) -> Self {
|
pub fn new(region: impl Into<Cow<'static, str>>) -> Self {
|
||||||
|
|
|
@ -27,7 +27,7 @@ class CredentialsCacheDecorator : ClientCodegenDecorator {
|
||||||
codegenContext: ClientCodegenContext,
|
codegenContext: ClientCodegenContext,
|
||||||
baseCustomizations: List<ConfigCustomization>,
|
baseCustomizations: List<ConfigCustomization>,
|
||||||
): List<ConfigCustomization> {
|
): List<ConfigCustomization> {
|
||||||
return baseCustomizations + CredentialCacheConfig(codegenContext.runtimeConfig)
|
return baseCustomizations + CredentialCacheConfig(codegenContext)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun operationCustomizations(
|
override fun operationCustomizations(
|
||||||
|
@ -49,44 +49,65 @@ class CredentialsCacheDecorator : ClientCodegenDecorator {
|
||||||
/**
|
/**
|
||||||
* Add a `.credentials_cache` field and builder to the `Config` for a given service
|
* Add a `.credentials_cache` field and builder to the `Config` for a given service
|
||||||
*/
|
*/
|
||||||
class CredentialCacheConfig(runtimeConfig: RuntimeConfig) : ConfigCustomization() {
|
class CredentialCacheConfig(codegenContext: ClientCodegenContext) : ConfigCustomization() {
|
||||||
|
private val runtimeConfig = codegenContext.runtimeConfig
|
||||||
|
private val runtimeMode = codegenContext.smithyRuntimeMode
|
||||||
private val codegenScope = arrayOf(
|
private val codegenScope = arrayOf(
|
||||||
"cache" to AwsRuntimeType.awsCredentialTypes(runtimeConfig).resolve("cache"),
|
"CredentialsCache" to AwsRuntimeType.awsCredentialTypes(runtimeConfig).resolve("cache::CredentialsCache"),
|
||||||
"provider" to AwsRuntimeType.awsCredentialTypes(runtimeConfig).resolve("provider"),
|
|
||||||
"DefaultProvider" to defaultProvider(),
|
"DefaultProvider" to defaultProvider(),
|
||||||
|
"SharedCredentialsCache" to AwsRuntimeType.awsCredentialTypes(runtimeConfig).resolve("cache::SharedCredentialsCache"),
|
||||||
|
"SharedCredentialsProvider" to AwsRuntimeType.awsCredentialTypes(runtimeConfig).resolve("provider::SharedCredentialsProvider"),
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun section(section: ServiceConfig) = writable {
|
override fun section(section: ServiceConfig) = writable {
|
||||||
when (section) {
|
when (section) {
|
||||||
ServiceConfig.ConfigStruct -> rustTemplate(
|
ServiceConfig.ConfigStruct -> {
|
||||||
"""pub(crate) credentials_cache: #{cache}::SharedCredentialsCache,""",
|
if (runtimeMode.defaultToMiddleware) {
|
||||||
*codegenScope,
|
rustTemplate(
|
||||||
)
|
"""pub(crate) credentials_cache: #{SharedCredentialsCache},""",
|
||||||
|
*codegenScope,
|
||||||
ServiceConfig.ConfigImpl -> rustTemplate(
|
)
|
||||||
"""
|
|
||||||
/// Returns the credentials cache.
|
|
||||||
pub fn credentials_cache(&self) -> #{cache}::SharedCredentialsCache {
|
|
||||||
self.credentials_cache.clone()
|
|
||||||
}
|
}
|
||||||
""",
|
}
|
||||||
*codegenScope,
|
|
||||||
)
|
ServiceConfig.ConfigImpl -> {
|
||||||
|
if (runtimeMode.defaultToOrchestrator) {
|
||||||
|
rustTemplate(
|
||||||
|
"""
|
||||||
|
/// Returns the credentials cache.
|
||||||
|
pub fn credentials_cache(&self) -> #{SharedCredentialsCache} {
|
||||||
|
self.inner.load::<#{SharedCredentialsCache}>().expect("credentials cache should be set").clone()
|
||||||
|
}
|
||||||
|
""",
|
||||||
|
*codegenScope,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
rustTemplate(
|
||||||
|
"""
|
||||||
|
/// Returns the credentials cache.
|
||||||
|
pub fn credentials_cache(&self) -> #{SharedCredentialsCache} {
|
||||||
|
self.credentials_cache.clone()
|
||||||
|
}
|
||||||
|
""",
|
||||||
|
*codegenScope,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ServiceConfig.BuilderStruct ->
|
ServiceConfig.BuilderStruct ->
|
||||||
rustTemplate("credentials_cache: Option<#{cache}::CredentialsCache>,", *codegenScope)
|
rustTemplate("credentials_cache: Option<#{CredentialsCache}>,", *codegenScope)
|
||||||
|
|
||||||
ServiceConfig.BuilderImpl -> {
|
ServiceConfig.BuilderImpl -> {
|
||||||
rustTemplate(
|
rustTemplate(
|
||||||
"""
|
"""
|
||||||
/// Sets the credentials cache for this service
|
/// Sets the credentials cache for this service
|
||||||
pub fn credentials_cache(mut self, credentials_cache: #{cache}::CredentialsCache) -> Self {
|
pub fn credentials_cache(mut self, credentials_cache: #{CredentialsCache}) -> Self {
|
||||||
self.set_credentials_cache(Some(credentials_cache));
|
self.set_credentials_cache(Some(credentials_cache));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the credentials cache for this service
|
/// Sets the credentials cache for this service
|
||||||
pub fn set_credentials_cache(&mut self, credentials_cache: Option<#{cache}::CredentialsCache>) -> &mut Self {
|
pub fn set_credentials_cache(&mut self, credentials_cache: Option<#{CredentialsCache}>) -> &mut Self {
|
||||||
self.credentials_cache = credentials_cache;
|
self.credentials_cache = credentials_cache;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
@ -95,29 +116,56 @@ class CredentialCacheConfig(runtimeConfig: RuntimeConfig) : ConfigCustomization(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
ServiceConfig.BuilderBuild -> rustTemplate(
|
ServiceConfig.BuilderBuild -> {
|
||||||
"""
|
if (runtimeMode.defaultToOrchestrator) {
|
||||||
credentials_cache: self
|
rustTemplate(
|
||||||
.credentials_cache
|
"""
|
||||||
.unwrap_or_else({
|
layer.store_put(
|
||||||
let sleep = self.sleep_impl.clone();
|
self.credentials_cache
|
||||||
|| match sleep {
|
.unwrap_or_else({
|
||||||
Some(sleep) => {
|
let sleep = self.sleep_impl.clone();
|
||||||
#{cache}::CredentialsCache::lazy_builder()
|
|| match sleep {
|
||||||
.sleep(sleep)
|
Some(sleep) => {
|
||||||
.into_credentials_cache()
|
#{CredentialsCache}::lazy_builder()
|
||||||
}
|
.sleep(sleep)
|
||||||
None => #{cache}::CredentialsCache::lazy(),
|
.into_credentials_cache()
|
||||||
}
|
}
|
||||||
})
|
None => #{CredentialsCache}::lazy(),
|
||||||
.create_cache(
|
}
|
||||||
self.credentials_provider.unwrap_or_else(|| {
|
})
|
||||||
#{provider}::SharedCredentialsProvider::new(#{DefaultProvider})
|
.create_cache(self.credentials_provider.unwrap_or_else(|| {
|
||||||
})
|
#{SharedCredentialsProvider}::new(#{DefaultProvider})
|
||||||
),
|
})),
|
||||||
""",
|
);
|
||||||
*codegenScope,
|
""",
|
||||||
)
|
*codegenScope,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
rustTemplate(
|
||||||
|
"""
|
||||||
|
credentials_cache: self
|
||||||
|
.credentials_cache
|
||||||
|
.unwrap_or_else({
|
||||||
|
let sleep = self.sleep_impl.clone();
|
||||||
|
|| match sleep {
|
||||||
|
Some(sleep) => {
|
||||||
|
#{CredentialsCache}::lazy_builder()
|
||||||
|
.sleep(sleep)
|
||||||
|
.into_credentials_cache()
|
||||||
|
}
|
||||||
|
None => #{CredentialsCache}::lazy(),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.create_cache(
|
||||||
|
self.credentials_provider.unwrap_or_else(|| {
|
||||||
|
#{SharedCredentialsProvider}::new(#{DefaultProvider})
|
||||||
|
})
|
||||||
|
),
|
||||||
|
""",
|
||||||
|
*codegenScope,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
else -> emptySection
|
else -> emptySection
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,18 +22,21 @@ import software.amazon.smithy.rust.codegen.client.smithy.endpoint.EndpointRulese
|
||||||
import software.amazon.smithy.rust.codegen.client.smithy.endpoint.rustName
|
import software.amazon.smithy.rust.codegen.client.smithy.endpoint.rustName
|
||||||
import software.amazon.smithy.rust.codegen.client.smithy.generators.config.ConfigCustomization
|
import software.amazon.smithy.rust.codegen.client.smithy.generators.config.ConfigCustomization
|
||||||
import software.amazon.smithy.rust.codegen.client.smithy.generators.config.ConfigParam
|
import software.amazon.smithy.rust.codegen.client.smithy.generators.config.ConfigParam
|
||||||
|
import software.amazon.smithy.rust.codegen.client.smithy.generators.config.configParamNewtype
|
||||||
import software.amazon.smithy.rust.codegen.client.smithy.generators.config.standardConfigParam
|
import software.amazon.smithy.rust.codegen.client.smithy.generators.config.standardConfigParam
|
||||||
import software.amazon.smithy.rust.codegen.core.rustlang.Writable
|
import software.amazon.smithy.rust.codegen.core.rustlang.Writable
|
||||||
import software.amazon.smithy.rust.codegen.core.rustlang.docs
|
import software.amazon.smithy.rust.codegen.core.rustlang.docs
|
||||||
import software.amazon.smithy.rust.codegen.core.rustlang.rust
|
import software.amazon.smithy.rust.codegen.core.rustlang.rust
|
||||||
import software.amazon.smithy.rust.codegen.core.rustlang.rustTemplate
|
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.rustlang.writable
|
||||||
|
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeConfig
|
||||||
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeType
|
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeType
|
||||||
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.PANIC
|
import software.amazon.smithy.rust.codegen.core.util.PANIC
|
||||||
import software.amazon.smithy.rust.codegen.core.util.dq
|
import software.amazon.smithy.rust.codegen.core.util.dq
|
||||||
import software.amazon.smithy.rust.codegen.core.util.extendIf
|
import software.amazon.smithy.rust.codegen.core.util.extendIf
|
||||||
import software.amazon.smithy.rust.codegen.core.util.orNull
|
import software.amazon.smithy.rust.codegen.core.util.orNull
|
||||||
|
import software.amazon.smithy.rust.codegen.core.util.toPascalCase
|
||||||
import java.util.Optional
|
import java.util.Optional
|
||||||
|
|
||||||
/** load a builtIn parameter from a ruleset by name */
|
/** load a builtIn parameter from a ruleset by name */
|
||||||
|
@ -48,14 +51,27 @@ fun ClientCodegenContext.getBuiltIn(builtIn: String): Parameter? {
|
||||||
return rules.getBuiltIn(builtIn)
|
return rules.getBuiltIn(builtIn)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun toConfigParam(parameter: Parameter): ConfigParam = ConfigParam(
|
private fun promotedBuiltins(parameter: Parameter) =
|
||||||
parameter.name.rustName(),
|
parameter == Builtins.FIPS || parameter == Builtins.DUALSTACK || parameter == Builtins.SDK_ENDPOINT
|
||||||
when (parameter.type!!) {
|
|
||||||
ParameterType.STRING -> RuntimeType.String.toSymbol()
|
private fun ConfigParam.Builder.toConfigParam(parameter: Parameter, runtimeConfig: RuntimeConfig): ConfigParam =
|
||||||
ParameterType.BOOLEAN -> RuntimeType.Bool.toSymbol()
|
this.name(this.name ?: parameter.name.rustName())
|
||||||
},
|
.type(
|
||||||
parameter.documentation.orNull()?.let { writable { docs(it) } },
|
when (parameter.type!!) {
|
||||||
)
|
ParameterType.STRING -> RuntimeType.String.toSymbol()
|
||||||
|
ParameterType.BOOLEAN -> RuntimeType.Bool.toSymbol()
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.newtype(
|
||||||
|
when (promotedBuiltins(parameter)) {
|
||||||
|
true -> AwsRuntimeType.awsTypes(runtimeConfig)
|
||||||
|
.resolve("endpoint_config::${this.name!!.toPascalCase()}")
|
||||||
|
|
||||||
|
false -> configParamNewtype(this.name!!.toPascalCase(), this.type!!, runtimeConfig)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.setterDocs(this.setterDocs ?: parameter.documentation.orNull()?.let { writable { docs(it) } })
|
||||||
|
.build()
|
||||||
|
|
||||||
fun Model.loadBuiltIn(serviceId: ShapeId, builtInSrc: Parameter): Parameter? {
|
fun Model.loadBuiltIn(serviceId: ShapeId, builtInSrc: Parameter): Parameter? {
|
||||||
val model = this
|
val model = this
|
||||||
|
@ -82,14 +98,14 @@ fun Model.sdkConfigSetter(
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a client codegen decorator that creates bindings for a builtIn parameter. Optionally, you can provide [clientParam]
|
* Create a client codegen decorator that creates bindings for a builtIn parameter. Optionally, you can provide
|
||||||
* which allows control over the config parameter that will be generated.
|
* [clientParam.Builder] which allows control over the config parameter that will be generated.
|
||||||
*/
|
*/
|
||||||
fun decoratorForBuiltIn(
|
fun decoratorForBuiltIn(
|
||||||
builtIn: Parameter,
|
builtIn: Parameter,
|
||||||
clientParam: ConfigParam? = null,
|
clientParamBuilder: ConfigParam.Builder? = null,
|
||||||
): ClientCodegenDecorator {
|
): ClientCodegenDecorator {
|
||||||
val nameOverride = clientParam?.name
|
val nameOverride = clientParamBuilder?.name
|
||||||
val name = nameOverride ?: builtIn.name.rustName()
|
val name = nameOverride ?: builtIn.name.rustName()
|
||||||
return object : ClientCodegenDecorator {
|
return object : ClientCodegenDecorator {
|
||||||
override val name: String = "Auto${builtIn.builtIn.get()}"
|
override val name: String = "Auto${builtIn.builtIn.get()}"
|
||||||
|
@ -100,7 +116,7 @@ fun decoratorForBuiltIn(
|
||||||
|
|
||||||
override fun extraSections(codegenContext: ClientCodegenContext): List<AdHocCustomization> {
|
override fun extraSections(codegenContext: ClientCodegenContext): List<AdHocCustomization> {
|
||||||
return listOfNotNull(
|
return listOfNotNull(
|
||||||
codegenContext.model.sdkConfigSetter(codegenContext.serviceShape.id, builtIn, clientParam?.name),
|
codegenContext.model.sdkConfigSetter(codegenContext.serviceShape.id, builtIn, clientParamBuilder?.name),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,7 +126,9 @@ fun decoratorForBuiltIn(
|
||||||
): List<ConfigCustomization> {
|
): List<ConfigCustomization> {
|
||||||
return baseCustomizations.extendIf(rulesetContainsBuiltIn(codegenContext)) {
|
return baseCustomizations.extendIf(rulesetContainsBuiltIn(codegenContext)) {
|
||||||
standardConfigParam(
|
standardConfigParam(
|
||||||
clientParam ?: toConfigParam(builtIn),
|
clientParamBuilder?.toConfigParam(builtIn, codegenContext.runtimeConfig) ?: ConfigParam.Builder()
|
||||||
|
.toConfigParam(builtIn, codegenContext.runtimeConfig),
|
||||||
|
codegenContext,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -120,11 +138,16 @@ fun decoratorForBuiltIn(
|
||||||
override fun loadBuiltInFromServiceConfig(parameter: Parameter, configRef: String): Writable? =
|
override fun loadBuiltInFromServiceConfig(parameter: Parameter, configRef: String): Writable? =
|
||||||
when (parameter.builtIn) {
|
when (parameter.builtIn) {
|
||||||
builtIn.builtIn -> writable {
|
builtIn.builtIn -> writable {
|
||||||
rust("$configRef.$name")
|
if (codegenContext.smithyRuntimeMode.defaultToOrchestrator) {
|
||||||
|
rust("$configRef.$name()")
|
||||||
|
} else {
|
||||||
|
rust("$configRef.$name")
|
||||||
|
}
|
||||||
if (parameter.type == ParameterType.STRING) {
|
if (parameter.type == ParameterType.STRING) {
|
||||||
rust(".clone()")
|
rust(".clone()")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,6 +196,6 @@ val PromotedBuiltInsDecorators =
|
||||||
decoratorForBuiltIn(Builtins.DUALSTACK),
|
decoratorForBuiltIn(Builtins.DUALSTACK),
|
||||||
decoratorForBuiltIn(
|
decoratorForBuiltIn(
|
||||||
Builtins.SDK_ENDPOINT,
|
Builtins.SDK_ENDPOINT,
|
||||||
ConfigParam("endpoint_url", RuntimeType.String.toSymbol(), endpointUrlDocs),
|
ConfigParam.Builder().name("endpoint_url").type(RuntimeType.String.toSymbol()).setterDocs(endpointUrlDocs),
|
||||||
),
|
),
|
||||||
).toTypedArray()
|
).toTypedArray()
|
||||||
|
|
|
@ -13,7 +13,6 @@ import software.amazon.smithy.rust.codegen.core.rustlang.Writable
|
||||||
import software.amazon.smithy.rust.codegen.core.rustlang.rust
|
import software.amazon.smithy.rust.codegen.core.rustlang.rust
|
||||||
import software.amazon.smithy.rust.codegen.core.rustlang.rustTemplate
|
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.rustlang.writable
|
||||||
import software.amazon.smithy.rust.codegen.core.smithy.CodegenContext
|
|
||||||
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeType
|
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeType
|
||||||
import software.amazon.smithy.rust.codegen.core.util.letIf
|
import software.amazon.smithy.rust.codegen.core.util.letIf
|
||||||
|
|
||||||
|
@ -32,9 +31,10 @@ class HttpConnectorDecorator : ClientCodegenDecorator {
|
||||||
}
|
}
|
||||||
|
|
||||||
class HttpConnectorConfigCustomization(
|
class HttpConnectorConfigCustomization(
|
||||||
codegenContext: CodegenContext,
|
codegenContext: ClientCodegenContext,
|
||||||
) : ConfigCustomization() {
|
) : ConfigCustomization() {
|
||||||
private val runtimeConfig = codegenContext.runtimeConfig
|
private val runtimeConfig = codegenContext.runtimeConfig
|
||||||
|
private val runtimeMode = codegenContext.smithyRuntimeMode
|
||||||
private val moduleUseName = codegenContext.moduleUseName()
|
private val moduleUseName = codegenContext.moduleUseName()
|
||||||
private val codegenScope = arrayOf(
|
private val codegenScope = arrayOf(
|
||||||
"HttpConnector" to RuntimeType.smithyClient(runtimeConfig).resolve("http_connector::HttpConnector"),
|
"HttpConnector" to RuntimeType.smithyClient(runtimeConfig).resolve("http_connector::HttpConnector"),
|
||||||
|
@ -43,18 +43,32 @@ class HttpConnectorConfigCustomization(
|
||||||
override fun section(section: ServiceConfig): Writable {
|
override fun section(section: ServiceConfig): Writable {
|
||||||
return when (section) {
|
return when (section) {
|
||||||
is ServiceConfig.ConfigStruct -> writable {
|
is ServiceConfig.ConfigStruct -> writable {
|
||||||
rustTemplate("http_connector: Option<#{HttpConnector}>,", *codegenScope)
|
if (runtimeMode.defaultToMiddleware) {
|
||||||
|
rustTemplate("http_connector: Option<#{HttpConnector}>,", *codegenScope)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
is ServiceConfig.ConfigImpl -> writable {
|
is ServiceConfig.ConfigImpl -> writable {
|
||||||
rustTemplate(
|
if (runtimeMode.defaultToOrchestrator) {
|
||||||
"""
|
rustTemplate(
|
||||||
/// Return an [`HttpConnector`](#{HttpConnector}) to use when making requests, if any.
|
"""
|
||||||
pub fn http_connector(&self) -> Option<&#{HttpConnector}> {
|
/// Return an [`HttpConnector`](#{HttpConnector}) to use when making requests, if any.
|
||||||
self.http_connector.as_ref()
|
pub fn http_connector(&self) -> Option<&#{HttpConnector}> {
|
||||||
}
|
self.inner.load::<#{HttpConnector}>()
|
||||||
""",
|
}
|
||||||
*codegenScope,
|
""",
|
||||||
)
|
*codegenScope,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
rustTemplate(
|
||||||
|
"""
|
||||||
|
/// Return an [`HttpConnector`](#{HttpConnector}) to use when making requests, if any.
|
||||||
|
pub fn http_connector(&self) -> Option<&#{HttpConnector}> {
|
||||||
|
self.http_connector.as_ref()
|
||||||
|
}
|
||||||
|
""",
|
||||||
|
*codegenScope,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
is ServiceConfig.BuilderStruct -> writable {
|
is ServiceConfig.BuilderStruct -> writable {
|
||||||
rustTemplate("http_connector: Option<#{HttpConnector}>,", *codegenScope)
|
rustTemplate("http_connector: Option<#{HttpConnector}>,", *codegenScope)
|
||||||
|
@ -145,7 +159,11 @@ class HttpConnectorConfigCustomization(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
is ServiceConfig.BuilderBuild -> writable {
|
is ServiceConfig.BuilderBuild -> writable {
|
||||||
rust("http_connector: self.http_connector,")
|
if (runtimeMode.defaultToOrchestrator) {
|
||||||
|
rust("layer.store_or_unset(self.http_connector);")
|
||||||
|
} else {
|
||||||
|
rust("http_connector: self.http_connector,")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else -> emptySection
|
else -> emptySection
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,6 @@ import software.amazon.smithy.rust.codegen.core.rustlang.Writable
|
||||||
import software.amazon.smithy.rust.codegen.core.rustlang.rust
|
import software.amazon.smithy.rust.codegen.core.rustlang.rust
|
||||||
import software.amazon.smithy.rust.codegen.core.rustlang.rustTemplate
|
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.rustlang.writable
|
||||||
import software.amazon.smithy.rust.codegen.core.smithy.CodegenContext
|
|
||||||
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeConfig
|
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.smithy.RustCrate
|
||||||
import software.amazon.smithy.rust.codegen.core.smithy.customize.AdHocCustomization
|
import software.amazon.smithy.rust.codegen.core.smithy.customize.AdHocCustomization
|
||||||
|
@ -131,7 +130,11 @@ class RegionDecorator : ClientCodegenDecorator {
|
||||||
override fun loadBuiltInFromServiceConfig(parameter: Parameter, configRef: String): Writable? {
|
override fun loadBuiltInFromServiceConfig(parameter: Parameter, configRef: String): Writable? {
|
||||||
return when (parameter.builtIn) {
|
return when (parameter.builtIn) {
|
||||||
Builtins.REGION.builtIn -> writable {
|
Builtins.REGION.builtIn -> writable {
|
||||||
rust("$configRef.region.as_ref().map(|r|r.as_ref().to_owned())")
|
if (codegenContext.smithyRuntimeMode.defaultToOrchestrator) {
|
||||||
|
rust("$configRef.region().as_ref().map(|r|r.as_ref().to_owned())")
|
||||||
|
} else {
|
||||||
|
rust("$configRef.region.as_ref().map(|r|r.as_ref().to_owned())")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
|
@ -153,22 +156,41 @@ class RegionDecorator : ClientCodegenDecorator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class RegionProviderConfig(codegenContext: CodegenContext) : ConfigCustomization() {
|
class RegionProviderConfig(codegenContext: ClientCodegenContext) : ConfigCustomization() {
|
||||||
private val region = region(codegenContext.runtimeConfig)
|
private val region = region(codegenContext.runtimeConfig)
|
||||||
private val moduleUseName = codegenContext.moduleUseName()
|
private val moduleUseName = codegenContext.moduleUseName()
|
||||||
|
private val runtimeMode = codegenContext.smithyRuntimeMode
|
||||||
private val codegenScope = arrayOf("Region" to region.resolve("Region"))
|
private val codegenScope = arrayOf("Region" to region.resolve("Region"))
|
||||||
override fun section(section: ServiceConfig) = writable {
|
override fun section(section: ServiceConfig) = writable {
|
||||||
when (section) {
|
when (section) {
|
||||||
ServiceConfig.ConfigStruct -> rustTemplate("pub(crate) region: Option<#{Region}>,", *codegenScope)
|
ServiceConfig.ConfigStruct -> {
|
||||||
ServiceConfig.ConfigImpl -> rustTemplate(
|
if (runtimeMode.defaultToMiddleware) {
|
||||||
"""
|
rustTemplate("pub(crate) region: Option<#{Region}>,", *codegenScope)
|
||||||
/// Returns the AWS region, if it was provided.
|
|
||||||
pub fn region(&self) -> Option<&#{Region}> {
|
|
||||||
self.region.as_ref()
|
|
||||||
}
|
}
|
||||||
""",
|
}
|
||||||
*codegenScope,
|
ServiceConfig.ConfigImpl -> {
|
||||||
)
|
if (runtimeMode.defaultToOrchestrator) {
|
||||||
|
rustTemplate(
|
||||||
|
"""
|
||||||
|
/// Returns the AWS region, if it was provided.
|
||||||
|
pub fn region(&self) -> Option<&#{Region}> {
|
||||||
|
self.inner.load::<#{Region}>()
|
||||||
|
}
|
||||||
|
""",
|
||||||
|
*codegenScope,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
rustTemplate(
|
||||||
|
"""
|
||||||
|
/// Returns the AWS region, if it was provided.
|
||||||
|
pub fn region(&self) -> Option<&#{Region}> {
|
||||||
|
self.region.as_ref()
|
||||||
|
}
|
||||||
|
""",
|
||||||
|
*codegenScope,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ServiceConfig.BuilderStruct ->
|
ServiceConfig.BuilderStruct ->
|
||||||
rustTemplate("pub(crate) region: Option<#{Region}>,", *codegenScope)
|
rustTemplate("pub(crate) region: Option<#{Region}>,", *codegenScope)
|
||||||
|
@ -201,10 +223,13 @@ class RegionProviderConfig(codegenContext: CodegenContext) : ConfigCustomization
|
||||||
*codegenScope,
|
*codegenScope,
|
||||||
)
|
)
|
||||||
|
|
||||||
ServiceConfig.BuilderBuild -> rustTemplate(
|
ServiceConfig.BuilderBuild -> {
|
||||||
"""region: self.region,""",
|
if (runtimeMode.defaultToOrchestrator) {
|
||||||
*codegenScope,
|
rust("layer.store_or_unset(self.region);")
|
||||||
)
|
} else {
|
||||||
|
rust("region: self.region,")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
else -> emptySection
|
else -> emptySection
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ import software.amazon.smithy.rust.codegen.core.rustlang.Writable
|
||||||
import software.amazon.smithy.rust.codegen.core.rustlang.rust
|
import software.amazon.smithy.rust.codegen.core.rustlang.rust
|
||||||
import software.amazon.smithy.rust.codegen.core.rustlang.rustTemplate
|
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.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.RustCrate
|
||||||
import software.amazon.smithy.rust.codegen.core.smithy.customizations.CrateVersionCustomization
|
import software.amazon.smithy.rust.codegen.core.smithy.customizations.CrateVersionCustomization
|
||||||
import software.amazon.smithy.rust.codegen.core.smithy.customize.AdHocCustomization
|
import software.amazon.smithy.rust.codegen.core.smithy.customize.AdHocCustomization
|
||||||
|
@ -40,7 +40,7 @@ class UserAgentDecorator : ClientCodegenDecorator {
|
||||||
codegenContext: ClientCodegenContext,
|
codegenContext: ClientCodegenContext,
|
||||||
baseCustomizations: List<ConfigCustomization>,
|
baseCustomizations: List<ConfigCustomization>,
|
||||||
): List<ConfigCustomization> {
|
): List<ConfigCustomization> {
|
||||||
return baseCustomizations + AppNameCustomization(codegenContext.runtimeConfig)
|
return baseCustomizations + AppNameCustomization(codegenContext)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun operationCustomizations(
|
override fun operationCustomizations(
|
||||||
|
@ -149,15 +149,18 @@ class UserAgentDecorator : ClientCodegenDecorator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class AppNameCustomization(runtimeConfig: RuntimeConfig) : ConfigCustomization() {
|
private class AppNameCustomization(codegenContext: ClientCodegenContext) : ConfigCustomization() {
|
||||||
|
private val runtimeConfig = codegenContext.runtimeConfig
|
||||||
|
private val runtimeMode = codegenContext.smithyRuntimeMode
|
||||||
private val codegenScope = arrayOf(
|
private val codegenScope = arrayOf(
|
||||||
|
*preludeScope,
|
||||||
"AppName" to AwsRuntimeType.awsTypes(runtimeConfig).resolve("app_name::AppName"),
|
"AppName" to AwsRuntimeType.awsTypes(runtimeConfig).resolve("app_name::AppName"),
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun section(section: ServiceConfig): Writable =
|
override fun section(section: ServiceConfig): Writable =
|
||||||
when (section) {
|
when (section) {
|
||||||
is ServiceConfig.BuilderStruct -> writable {
|
is ServiceConfig.BuilderStruct -> writable {
|
||||||
rustTemplate("app_name: Option<#{AppName}>,", *codegenScope)
|
rustTemplate("app_name: #{Option}<#{AppName}>,", *codegenScope)
|
||||||
}
|
}
|
||||||
|
|
||||||
is ServiceConfig.BuilderImpl -> writable {
|
is ServiceConfig.BuilderImpl -> writable {
|
||||||
|
@ -176,7 +179,7 @@ class UserAgentDecorator : ClientCodegenDecorator {
|
||||||
///
|
///
|
||||||
/// This _optional_ name is used to identify the application in the user agent that
|
/// This _optional_ name is used to identify the application in the user agent that
|
||||||
/// gets sent along with requests.
|
/// gets sent along with requests.
|
||||||
pub fn set_app_name(&mut self, app_name: Option<#{AppName}>) -> &mut Self {
|
pub fn set_app_name(&mut self, app_name: #{Option}<#{AppName}>) -> &mut Self {
|
||||||
self.app_name = app_name;
|
self.app_name = app_name;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
@ -186,26 +189,47 @@ class UserAgentDecorator : ClientCodegenDecorator {
|
||||||
}
|
}
|
||||||
|
|
||||||
is ServiceConfig.BuilderBuild -> writable {
|
is ServiceConfig.BuilderBuild -> writable {
|
||||||
rust("app_name: self.app_name,")
|
if (runtimeMode.defaultToOrchestrator) {
|
||||||
|
rust("layer.store_or_unset(self.app_name);")
|
||||||
|
} else {
|
||||||
|
rust("app_name: self.app_name,")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
is ServiceConfig.ConfigStruct -> writable {
|
is ServiceConfig.ConfigStruct -> writable {
|
||||||
rustTemplate("app_name: Option<#{AppName}>,", *codegenScope)
|
if (runtimeMode.defaultToMiddleware) {
|
||||||
|
rustTemplate("app_name: #{Option}<#{AppName}>,", *codegenScope)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
is ServiceConfig.ConfigImpl -> writable {
|
is ServiceConfig.ConfigImpl -> writable {
|
||||||
rustTemplate(
|
if (runtimeMode.defaultToOrchestrator) {
|
||||||
"""
|
rustTemplate(
|
||||||
/// Returns the name of the app that is using the client, if it was provided.
|
"""
|
||||||
///
|
/// Returns the name of the app that is using the client, if it was provided.
|
||||||
/// This _optional_ name is used to identify the application in the user agent that
|
///
|
||||||
/// gets sent along with requests.
|
/// This _optional_ name is used to identify the application in the user agent that
|
||||||
pub fn app_name(&self) -> Option<&#{AppName}> {
|
/// gets sent along with requests.
|
||||||
self.app_name.as_ref()
|
pub fn app_name(&self) -> #{Option}<&#{AppName}> {
|
||||||
}
|
self.inner.load::<#{AppName}>()
|
||||||
""",
|
}
|
||||||
*codegenScope,
|
""",
|
||||||
)
|
*codegenScope,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
rustTemplate(
|
||||||
|
"""
|
||||||
|
/// Returns the name of the app that is using the client, if it was provided.
|
||||||
|
///
|
||||||
|
/// This _optional_ name is used to identify the application in the user agent that
|
||||||
|
/// gets sent along with requests.
|
||||||
|
pub fn app_name(&self) -> #{Option}<&#{AppName}> {
|
||||||
|
self.app_name.as_ref()
|
||||||
|
}
|
||||||
|
""",
|
||||||
|
*codegenScope,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> emptySection
|
else -> emptySection
|
||||||
|
|
|
@ -52,6 +52,7 @@ class TimestreamDecorator : ClientCodegenDecorator {
|
||||||
Visibility.PUBLIC,
|
Visibility.PUBLIC,
|
||||||
CargoDependency.Tokio.copy(scope = DependencyScope.Compile, features = setOf("sync")),
|
CargoDependency.Tokio.copy(scope = DependencyScope.Compile, features = setOf("sync")),
|
||||||
)
|
)
|
||||||
|
val runtimeMode = codegenContext.smithyRuntimeMode
|
||||||
rustCrate.lib {
|
rustCrate.lib {
|
||||||
// helper function to resolve an endpoint given a base client
|
// helper function to resolve an endpoint given a base client
|
||||||
rustTemplate(
|
rustTemplate(
|
||||||
|
@ -62,7 +63,7 @@ class TimestreamDecorator : ClientCodegenDecorator {
|
||||||
#{ResolveEndpointError}::from_source("failed to call describe_endpoints", e)
|
#{ResolveEndpointError}::from_source("failed to call describe_endpoints", e)
|
||||||
})?;
|
})?;
|
||||||
let endpoint = describe_endpoints.endpoints().unwrap().get(0).unwrap();
|
let endpoint = describe_endpoints.endpoints().unwrap().get(0).unwrap();
|
||||||
let expiry = client.conf().time_source.now() + #{Duration}::from_secs(endpoint.cache_period_in_minutes() as u64 * 60);
|
let expiry = client.conf().time_source().now() + #{Duration}::from_secs(endpoint.cache_period_in_minutes() as u64 * 60);
|
||||||
Ok((
|
Ok((
|
||||||
#{Endpoint}::builder()
|
#{Endpoint}::builder()
|
||||||
.url(format!("https://{}", endpoint.address().unwrap()))
|
.url(format!("https://{}", endpoint.address().unwrap()))
|
||||||
|
@ -78,7 +79,7 @@ class TimestreamDecorator : ClientCodegenDecorator {
|
||||||
pub async fn enable_endpoint_discovery(self) -> #{Result}<(Self, #{endpoint_discovery}::ReloadEndpoint), #{ResolveEndpointError}> {
|
pub async fn enable_endpoint_discovery(self) -> #{Result}<(Self, #{endpoint_discovery}::ReloadEndpoint), #{ResolveEndpointError}> {
|
||||||
let mut new_conf = self.conf().clone();
|
let mut new_conf = self.conf().clone();
|
||||||
let sleep = self.conf().sleep_impl().expect("sleep impl must be provided");
|
let sleep = self.conf().sleep_impl().expect("sleep impl must be provided");
|
||||||
let time = self.conf().time_source.clone();
|
let time = self.conf().time_source();
|
||||||
let (resolver, reloader) = #{endpoint_discovery}::create_cache(
|
let (resolver, reloader) = #{endpoint_discovery}::create_cache(
|
||||||
move || {
|
move || {
|
||||||
let client = self.clone();
|
let client = self.clone();
|
||||||
|
@ -92,7 +93,6 @@ class TimestreamDecorator : ClientCodegenDecorator {
|
||||||
Ok((Self::from_conf(new_conf), reloader))
|
Ok((Self::from_conf(new_conf), reloader))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
""",
|
""",
|
||||||
"endpoint_discovery" to endpointDiscovery.toType(),
|
"endpoint_discovery" to endpointDiscovery.toType(),
|
||||||
"SystemTime" to RuntimeType.std.resolve("time::SystemTime"),
|
"SystemTime" to RuntimeType.std.resolve("time::SystemTime"),
|
||||||
|
|
|
@ -5,12 +5,18 @@
|
||||||
|
|
||||||
package software.amazon.smithy.rustsdk
|
package software.amazon.smithy.rustsdk
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.params.ParameterizedTest
|
||||||
|
import org.junit.jupiter.params.provider.ValueSource
|
||||||
|
import software.amazon.smithy.rust.codegen.client.smithy.SmithyRuntimeMode
|
||||||
import software.amazon.smithy.rust.codegen.client.testutil.validateConfigCustomizations
|
import software.amazon.smithy.rust.codegen.client.testutil.validateConfigCustomizations
|
||||||
|
import software.amazon.smithy.rust.codegen.client.testutil.withSmithyRuntimeMode
|
||||||
|
|
||||||
internal class CredentialProviderConfigTest {
|
internal class CredentialProviderConfigTest {
|
||||||
@Test
|
@ParameterizedTest
|
||||||
fun `generates a valid config`() {
|
@ValueSource(strings = ["middleware", "orchestrator"])
|
||||||
validateConfigCustomizations(CredentialProviderConfig(AwsTestRuntimeConfig))
|
fun `generates a valid config`(smithyRuntimeModeStr: String) {
|
||||||
|
val smithyRuntimeMode = SmithyRuntimeMode.fromString(smithyRuntimeModeStr)
|
||||||
|
val codegenContext = awsTestCodegenContext().withSmithyRuntimeMode(smithyRuntimeMode)
|
||||||
|
validateConfigCustomizations(codegenContext, CredentialProviderConfig(codegenContext.runtimeConfig))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,15 +5,20 @@
|
||||||
|
|
||||||
package software.amazon.smithy.rustsdk
|
package software.amazon.smithy.rustsdk
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.params.ParameterizedTest
|
||||||
|
import org.junit.jupiter.params.provider.ValueSource
|
||||||
|
import software.amazon.smithy.rust.codegen.client.smithy.SmithyRuntimeMode
|
||||||
import software.amazon.smithy.rust.codegen.client.testutil.validateConfigCustomizations
|
import software.amazon.smithy.rust.codegen.client.testutil.validateConfigCustomizations
|
||||||
|
import software.amazon.smithy.rust.codegen.client.testutil.withSmithyRuntimeMode
|
||||||
import software.amazon.smithy.rust.codegen.core.testutil.TestWorkspace
|
import software.amazon.smithy.rust.codegen.core.testutil.TestWorkspace
|
||||||
|
|
||||||
class HttpConnectorConfigCustomizationTest {
|
class HttpConnectorConfigCustomizationTest {
|
||||||
@Test
|
@ParameterizedTest
|
||||||
fun `generates a valid config`() {
|
@ValueSource(strings = ["middleware", "orchestrator"])
|
||||||
|
fun `generates a valid config`(smithyRuntimeModeStr: String) {
|
||||||
val project = TestWorkspace.testProject()
|
val project = TestWorkspace.testProject()
|
||||||
val codegenContext = awsTestCodegenContext()
|
val smithyRuntimeMode = SmithyRuntimeMode.fromString(smithyRuntimeModeStr)
|
||||||
validateConfigCustomizations(HttpConnectorConfigCustomization(codegenContext), project)
|
val codegenContext = awsTestCodegenContext().withSmithyRuntimeMode(smithyRuntimeMode)
|
||||||
|
validateConfigCustomizations(codegenContext, HttpConnectorConfigCustomization(codegenContext), project)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,22 +5,27 @@
|
||||||
|
|
||||||
package software.amazon.smithy.rustsdk
|
package software.amazon.smithy.rustsdk
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.params.ParameterizedTest
|
||||||
|
import org.junit.jupiter.params.provider.ValueSource
|
||||||
|
import software.amazon.smithy.rust.codegen.client.smithy.SmithyRuntimeMode
|
||||||
import software.amazon.smithy.rust.codegen.client.testutil.testClientRustSettings
|
import software.amazon.smithy.rust.codegen.client.testutil.testClientRustSettings
|
||||||
import software.amazon.smithy.rust.codegen.client.testutil.validateConfigCustomizations
|
import software.amazon.smithy.rust.codegen.client.testutil.validateConfigCustomizations
|
||||||
|
import software.amazon.smithy.rust.codegen.client.testutil.withSmithyRuntimeMode
|
||||||
import software.amazon.smithy.rust.codegen.core.testutil.TestWorkspace
|
import software.amazon.smithy.rust.codegen.core.testutil.TestWorkspace
|
||||||
import software.amazon.smithy.rust.codegen.core.testutil.rustSettings
|
import software.amazon.smithy.rust.codegen.core.testutil.rustSettings
|
||||||
|
|
||||||
internal class RegionProviderConfigTest {
|
internal class RegionProviderConfigTest {
|
||||||
@Test
|
@ParameterizedTest
|
||||||
fun `generates a valid config`() {
|
@ValueSource(strings = ["middleware", "orchestrator"])
|
||||||
|
fun `generates a valid config`(smithyRuntimeModeStr: String) {
|
||||||
val project = TestWorkspace.testProject()
|
val project = TestWorkspace.testProject()
|
||||||
|
val smithyRuntimeMode = SmithyRuntimeMode.fromString(smithyRuntimeModeStr)
|
||||||
val codegenContext = awsTestCodegenContext(
|
val codegenContext = awsTestCodegenContext(
|
||||||
settings = testClientRustSettings(
|
settings = testClientRustSettings(
|
||||||
moduleName = project.rustSettings().moduleName,
|
moduleName = project.rustSettings().moduleName,
|
||||||
runtimeConfig = AwsTestRuntimeConfig,
|
runtimeConfig = AwsTestRuntimeConfig,
|
||||||
),
|
),
|
||||||
)
|
).withSmithyRuntimeMode(smithyRuntimeMode)
|
||||||
validateConfigCustomizations(RegionProviderConfig(codegenContext), project)
|
validateConfigCustomizations(codegenContext, RegionProviderConfig(codegenContext), project)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,19 +5,31 @@
|
||||||
|
|
||||||
package software.amazon.smithy.rustsdk
|
package software.amazon.smithy.rustsdk
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.params.ParameterizedTest
|
||||||
|
import org.junit.jupiter.params.provider.ValueSource
|
||||||
import software.amazon.smithy.aws.traits.auth.SigV4Trait
|
import software.amazon.smithy.aws.traits.auth.SigV4Trait
|
||||||
|
import software.amazon.smithy.rust.codegen.client.smithy.SmithyRuntimeMode
|
||||||
import software.amazon.smithy.rust.codegen.client.testutil.stubConfigProject
|
import software.amazon.smithy.rust.codegen.client.testutil.stubConfigProject
|
||||||
|
import software.amazon.smithy.rust.codegen.client.testutil.testClientRustSettings
|
||||||
|
import software.amazon.smithy.rust.codegen.client.testutil.withSmithyRuntimeMode
|
||||||
import software.amazon.smithy.rust.codegen.core.testutil.TestWorkspace
|
import software.amazon.smithy.rust.codegen.core.testutil.TestWorkspace
|
||||||
import software.amazon.smithy.rust.codegen.core.testutil.compileAndTest
|
import software.amazon.smithy.rust.codegen.core.testutil.compileAndTest
|
||||||
import software.amazon.smithy.rust.codegen.core.testutil.unitTest
|
import software.amazon.smithy.rust.codegen.core.testutil.unitTest
|
||||||
|
|
||||||
internal class SigV4SigningDecoratorTest {
|
internal class SigV4SigningDecoratorTest {
|
||||||
@Test
|
@ParameterizedTest
|
||||||
fun `generates a valid config`() {
|
@ValueSource(strings = ["middleware", "orchestrator"])
|
||||||
|
fun `generates a valid config`(smithyRuntimeModeStr: String) {
|
||||||
|
val smithyRuntimeMode = SmithyRuntimeMode.fromString(smithyRuntimeModeStr)
|
||||||
|
val codegenContext = awsTestCodegenContext(
|
||||||
|
settings = testClientRustSettings(
|
||||||
|
runtimeConfig = AwsTestRuntimeConfig,
|
||||||
|
),
|
||||||
|
).withSmithyRuntimeMode(smithyRuntimeMode)
|
||||||
val project = stubConfigProject(
|
val project = stubConfigProject(
|
||||||
|
codegenContext,
|
||||||
SigV4SigningConfig(
|
SigV4SigningConfig(
|
||||||
AwsTestRuntimeConfig,
|
codegenContext.runtimeConfig,
|
||||||
true,
|
true,
|
||||||
SigV4Trait.builder().name("test-service").build(),
|
SigV4Trait.builder().name("test-service").build(),
|
||||||
),
|
),
|
||||||
|
|
|
@ -25,6 +25,7 @@ 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.rustlang.writable
|
||||||
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeConfig
|
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeConfig
|
||||||
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeType
|
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeType
|
||||||
|
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.RustCrate
|
||||||
import software.amazon.smithy.rust.codegen.core.util.letIf
|
import software.amazon.smithy.rust.codegen.core.util.letIf
|
||||||
|
|
||||||
|
@ -46,7 +47,7 @@ class ApiKeyAuthDecorator : ClientCodegenDecorator {
|
||||||
baseCustomizations: List<ConfigCustomization>,
|
baseCustomizations: List<ConfigCustomization>,
|
||||||
): List<ConfigCustomization> {
|
): List<ConfigCustomization> {
|
||||||
return baseCustomizations.letIf(applies(codegenContext)) { customizations ->
|
return baseCustomizations.letIf(applies(codegenContext)) { customizations ->
|
||||||
customizations + ApiKeyConfigCustomization(codegenContext.runtimeConfig)
|
customizations + ApiKeyConfigCustomization(codegenContext)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,15 +157,18 @@ private class ApiKeyOperationCustomization(private val runtimeConfig: RuntimeCon
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ApiKeyConfigCustomization(runtimeConfig: RuntimeConfig) : ConfigCustomization() {
|
private class ApiKeyConfigCustomization(codegenContext: ClientCodegenContext) : ConfigCustomization() {
|
||||||
|
val runtimeMode = codegenContext.smithyRuntimeMode
|
||||||
|
val runtimeConfig = codegenContext.runtimeConfig
|
||||||
private val codegenScope = arrayOf(
|
private val codegenScope = arrayOf(
|
||||||
|
*preludeScope,
|
||||||
"ApiKey" to apiKey(runtimeConfig),
|
"ApiKey" to apiKey(runtimeConfig),
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun section(section: ServiceConfig): Writable =
|
override fun section(section: ServiceConfig): Writable =
|
||||||
when (section) {
|
when (section) {
|
||||||
is ServiceConfig.BuilderStruct -> writable {
|
is ServiceConfig.BuilderStruct -> writable {
|
||||||
rustTemplate("api_key: Option<#{ApiKey}>,", *codegenScope)
|
rustTemplate("api_key: #{Option}<#{ApiKey}>,", *codegenScope)
|
||||||
}
|
}
|
||||||
is ServiceConfig.BuilderImpl -> writable {
|
is ServiceConfig.BuilderImpl -> writable {
|
||||||
rustTemplate(
|
rustTemplate(
|
||||||
|
@ -176,7 +180,7 @@ private class ApiKeyConfigCustomization(runtimeConfig: RuntimeConfig) : ConfigCu
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the API key that will be used by the client.
|
/// Sets the API key that will be used by the client.
|
||||||
pub fn set_api_key(&mut self, api_key: Option<#{ApiKey}>) -> &mut Self {
|
pub fn set_api_key(&mut self, api_key: #{Option}<#{ApiKey}>) -> &mut Self {
|
||||||
self.api_key = api_key;
|
self.api_key = api_key;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
@ -185,21 +189,39 @@ private class ApiKeyConfigCustomization(runtimeConfig: RuntimeConfig) : ConfigCu
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
is ServiceConfig.BuilderBuild -> writable {
|
is ServiceConfig.BuilderBuild -> writable {
|
||||||
rust("api_key: self.api_key,")
|
if (runtimeMode.defaultToOrchestrator) {
|
||||||
|
rust("layer.store_or_unset(self.api_key);")
|
||||||
|
} else {
|
||||||
|
rust("api_key: self.api_key,")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
is ServiceConfig.ConfigStruct -> writable {
|
is ServiceConfig.ConfigStruct -> writable {
|
||||||
rustTemplate("api_key: Option<#{ApiKey}>,", *codegenScope)
|
if (runtimeMode.defaultToMiddleware) {
|
||||||
|
rustTemplate("api_key: #{Option}<#{ApiKey}>,", *codegenScope)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
is ServiceConfig.ConfigImpl -> writable {
|
is ServiceConfig.ConfigImpl -> writable {
|
||||||
rustTemplate(
|
if (runtimeMode.defaultToOrchestrator) {
|
||||||
"""
|
rustTemplate(
|
||||||
/// Returns API key used by the client, if it was provided.
|
"""
|
||||||
pub fn api_key(&self) -> Option<&#{ApiKey}> {
|
/// Returns API key used by the client, if it was provided.
|
||||||
self.api_key.as_ref()
|
pub fn api_key(&self) -> #{Option}<&#{ApiKey}> {
|
||||||
}
|
self.inner.load::<#{ApiKey}>()
|
||||||
""",
|
}
|
||||||
*codegenScope,
|
""",
|
||||||
)
|
*codegenScope,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
rustTemplate(
|
||||||
|
"""
|
||||||
|
/// Returns API key used by the client, if it was provided.
|
||||||
|
pub fn api_key(&self) -> #{Option}<&#{ApiKey}> {
|
||||||
|
self.api_key.as_ref()
|
||||||
|
}
|
||||||
|
""",
|
||||||
|
*codegenScope,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else -> emptySection
|
else -> emptySection
|
||||||
}
|
}
|
||||||
|
|
|
@ -237,6 +237,7 @@ private class HttpAuthConfigCustomization(
|
||||||
private val authSchemes: HttpAuthSchemes,
|
private val authSchemes: HttpAuthSchemes,
|
||||||
) : ConfigCustomization() {
|
) : ConfigCustomization() {
|
||||||
private val codegenScope = codegenScope(codegenContext.runtimeConfig)
|
private val codegenScope = codegenScope(codegenContext.runtimeConfig)
|
||||||
|
private val runtimeMode = codegenContext.smithyRuntimeMode
|
||||||
|
|
||||||
override fun section(section: ServiceConfig): Writable = writable {
|
override fun section(section: ServiceConfig): Writable = writable {
|
||||||
when (section) {
|
when (section) {
|
||||||
|
@ -324,7 +325,9 @@ private class HttpAuthConfigCustomization(
|
||||||
}
|
}
|
||||||
|
|
||||||
is ServiceConfig.BuilderBuild -> {
|
is ServiceConfig.BuilderBuild -> {
|
||||||
rust("identity_resolvers: self.identity_resolvers,")
|
if (runtimeMode.defaultToMiddleware) {
|
||||||
|
rust("identity_resolvers: self.identity_resolvers,")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
is ServiceConfig.ConfigStruct -> {
|
is ServiceConfig.ConfigStruct -> {
|
||||||
|
@ -343,6 +346,10 @@ private class HttpAuthConfigCustomization(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
is ServiceConfig.BuilderBuildExtras -> {
|
||||||
|
rust("identity_resolvers: self.identity_resolvers,")
|
||||||
|
}
|
||||||
|
|
||||||
else -> {}
|
else -> {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,6 @@ import software.amazon.smithy.rust.codegen.core.rustlang.Writable
|
||||||
import software.amazon.smithy.rust.codegen.core.rustlang.rust
|
import software.amazon.smithy.rust.codegen.core.rustlang.rust
|
||||||
import software.amazon.smithy.rust.codegen.core.rustlang.rustTemplate
|
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.rustlang.writable
|
||||||
import software.amazon.smithy.rust.codegen.core.smithy.CodegenContext
|
|
||||||
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeType
|
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeType
|
||||||
import software.amazon.smithy.rust.codegen.core.util.letIf
|
import software.amazon.smithy.rust.codegen.core.util.letIf
|
||||||
|
|
||||||
|
@ -31,9 +30,10 @@ class HttpConnectorConfigDecorator : ClientCodegenDecorator {
|
||||||
}
|
}
|
||||||
|
|
||||||
private class HttpConnectorConfigCustomization(
|
private class HttpConnectorConfigCustomization(
|
||||||
codegenContext: CodegenContext,
|
codegenContext: ClientCodegenContext,
|
||||||
) : ConfigCustomization() {
|
) : ConfigCustomization() {
|
||||||
private val runtimeConfig = codegenContext.runtimeConfig
|
private val runtimeConfig = codegenContext.runtimeConfig
|
||||||
|
private val runtimeMode = codegenContext.smithyRuntimeMode
|
||||||
private val moduleUseName = codegenContext.moduleUseName()
|
private val moduleUseName = codegenContext.moduleUseName()
|
||||||
private val codegenScope = arrayOf(
|
private val codegenScope = arrayOf(
|
||||||
"HttpConnector" to RuntimeType.smithyClient(runtimeConfig).resolve("http_connector::HttpConnector"),
|
"HttpConnector" to RuntimeType.smithyClient(runtimeConfig).resolve("http_connector::HttpConnector"),
|
||||||
|
@ -42,19 +42,33 @@ private class HttpConnectorConfigCustomization(
|
||||||
override fun section(section: ServiceConfig): Writable {
|
override fun section(section: ServiceConfig): Writable {
|
||||||
return when (section) {
|
return when (section) {
|
||||||
is ServiceConfig.ConfigStruct -> writable {
|
is ServiceConfig.ConfigStruct -> writable {
|
||||||
rustTemplate("http_connector: Option<#{HttpConnector}>,", *codegenScope)
|
if (runtimeMode.defaultToMiddleware) {
|
||||||
|
rustTemplate("http_connector: Option<#{HttpConnector}>,", *codegenScope)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
is ServiceConfig.ConfigImpl -> writable {
|
is ServiceConfig.ConfigImpl -> writable {
|
||||||
rustTemplate(
|
if (runtimeMode.defaultToOrchestrator) {
|
||||||
"""
|
rustTemplate(
|
||||||
/// Return an [`HttpConnector`](#{HttpConnector}) to use when making requests, if any.
|
"""
|
||||||
pub fn http_connector(&self) -> Option<&#{HttpConnector}> {
|
/// Return an [`HttpConnector`](#{HttpConnector}) to use when making requests, if any.
|
||||||
self.http_connector.as_ref()
|
pub fn http_connector(&self) -> Option<&#{HttpConnector}> {
|
||||||
}
|
self.inner.load::<#{HttpConnector}>()
|
||||||
""",
|
}
|
||||||
*codegenScope,
|
""",
|
||||||
)
|
*codegenScope,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
rustTemplate(
|
||||||
|
"""
|
||||||
|
/// Return an [`HttpConnector`](#{HttpConnector}) to use when making requests, if any.
|
||||||
|
pub fn http_connector(&self) -> Option<&#{HttpConnector}> {
|
||||||
|
self.http_connector.as_ref()
|
||||||
|
}
|
||||||
|
""",
|
||||||
|
*codegenScope,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
is ServiceConfig.BuilderStruct -> writable {
|
is ServiceConfig.BuilderStruct -> writable {
|
||||||
|
@ -147,7 +161,11 @@ private class HttpConnectorConfigCustomization(
|
||||||
}
|
}
|
||||||
|
|
||||||
is ServiceConfig.BuilderBuild -> writable {
|
is ServiceConfig.BuilderBuild -> writable {
|
||||||
rust("http_connector: self.http_connector,")
|
if (runtimeMode.defaultToOrchestrator) {
|
||||||
|
rust("self.http_connector.map(|c| layer.store_put(c));")
|
||||||
|
} else {
|
||||||
|
rust("http_connector: self.http_connector,")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> emptySection
|
else -> emptySection
|
||||||
|
|
|
@ -26,17 +26,13 @@ class InterceptorConfigCustomization(codegenContext: CodegenContext) : ConfigCus
|
||||||
writable {
|
writable {
|
||||||
when (section) {
|
when (section) {
|
||||||
ServiceConfig.ConfigStruct -> rustTemplate(
|
ServiceConfig.ConfigStruct -> rustTemplate(
|
||||||
"""
|
"pub(crate) interceptors: Vec<#{SharedInterceptor}>,",
|
||||||
pub(crate) interceptors: Vec<#{SharedInterceptor}>,
|
|
||||||
""",
|
|
||||||
*codegenScope,
|
*codegenScope,
|
||||||
)
|
)
|
||||||
|
|
||||||
ServiceConfig.BuilderStruct ->
|
ServiceConfig.BuilderStruct ->
|
||||||
rustTemplate(
|
rustTemplate(
|
||||||
"""
|
"interceptors: Vec<#{SharedInterceptor}>,",
|
||||||
interceptors: Vec<#{SharedInterceptor}>,
|
|
||||||
""",
|
|
||||||
*codegenScope,
|
*codegenScope,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -171,18 +167,14 @@ class InterceptorConfigCustomization(codegenContext: CodegenContext) : ConfigCus
|
||||||
*codegenScope,
|
*codegenScope,
|
||||||
)
|
)
|
||||||
|
|
||||||
ServiceConfig.BuilderBuild -> rust(
|
|
||||||
"""
|
|
||||||
interceptors: self.interceptors,
|
|
||||||
""",
|
|
||||||
)
|
|
||||||
|
|
||||||
is ServiceConfig.RuntimePluginInterceptors -> rust(
|
is ServiceConfig.RuntimePluginInterceptors -> rust(
|
||||||
"""
|
"""
|
||||||
${section.interceptors}.extend(self.interceptors.iter().cloned());
|
${section.interceptors}.extend(self.interceptors.iter().cloned());
|
||||||
""",
|
""",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
is ServiceConfig.BuilderBuildExtras -> rust("interceptors: self.interceptors,")
|
||||||
|
|
||||||
else -> emptySection
|
else -> emptySection
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
package software.amazon.smithy.rust.codegen.client.smithy.customizations
|
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.ClientRustModule
|
import software.amazon.smithy.rust.codegen.client.smithy.ClientRustModule
|
||||||
import software.amazon.smithy.rust.codegen.client.smithy.generators.ServiceRuntimePluginCustomization
|
import software.amazon.smithy.rust.codegen.client.smithy.generators.ServiceRuntimePluginCustomization
|
||||||
import software.amazon.smithy.rust.codegen.client.smithy.generators.ServiceRuntimePluginSection
|
import software.amazon.smithy.rust.codegen.client.smithy.generators.ServiceRuntimePluginSection
|
||||||
|
@ -14,13 +15,13 @@ import software.amazon.smithy.rust.codegen.core.rustlang.Writable
|
||||||
import software.amazon.smithy.rust.codegen.core.rustlang.rust
|
import software.amazon.smithy.rust.codegen.core.rustlang.rust
|
||||||
import software.amazon.smithy.rust.codegen.core.rustlang.rustTemplate
|
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.rustlang.writable
|
||||||
import software.amazon.smithy.rust.codegen.core.smithy.CodegenContext
|
|
||||||
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeConfig
|
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeConfig
|
||||||
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeType
|
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeType
|
||||||
import software.amazon.smithy.rust.codegen.core.smithy.RustCrate
|
import software.amazon.smithy.rust.codegen.core.smithy.RustCrate
|
||||||
|
|
||||||
class ResiliencyConfigCustomization(codegenContext: CodegenContext) : ConfigCustomization() {
|
class ResiliencyConfigCustomization(codegenContext: ClientCodegenContext) : ConfigCustomization() {
|
||||||
private val runtimeConfig = codegenContext.runtimeConfig
|
private val runtimeConfig = codegenContext.runtimeConfig
|
||||||
|
private val runtimeMode = codegenContext.smithyRuntimeMode
|
||||||
private val retryConfig = RuntimeType.smithyTypes(runtimeConfig).resolve("retry")
|
private val retryConfig = RuntimeType.smithyTypes(runtimeConfig).resolve("retry")
|
||||||
private val sleepModule = RuntimeType.smithyAsync(runtimeConfig).resolve("rt::sleep")
|
private val sleepModule = RuntimeType.smithyAsync(runtimeConfig).resolve("rt::sleep")
|
||||||
private val timeoutModule = RuntimeType.smithyTypes(runtimeConfig).resolve("timeout")
|
private val timeoutModule = RuntimeType.smithyTypes(runtimeConfig).resolve("timeout")
|
||||||
|
@ -35,38 +36,64 @@ class ResiliencyConfigCustomization(codegenContext: CodegenContext) : ConfigCust
|
||||||
override fun section(section: ServiceConfig) =
|
override fun section(section: ServiceConfig) =
|
||||||
writable {
|
writable {
|
||||||
when (section) {
|
when (section) {
|
||||||
is ServiceConfig.ConfigStruct -> rustTemplate(
|
is ServiceConfig.ConfigStruct -> {
|
||||||
"""
|
if (runtimeMode.defaultToMiddleware) {
|
||||||
retry_config: Option<#{RetryConfig}>,
|
rustTemplate(
|
||||||
sleep_impl: Option<#{SharedAsyncSleep}>,
|
"""
|
||||||
timeout_config: Option<#{TimeoutConfig}>,
|
retry_config: Option<#{RetryConfig}>,
|
||||||
""",
|
sleep_impl: Option<#{SharedAsyncSleep}>,
|
||||||
*codegenScope,
|
timeout_config: Option<#{TimeoutConfig}>,
|
||||||
)
|
""",
|
||||||
|
*codegenScope,
|
||||||
is ServiceConfig.ConfigImpl -> {
|
)
|
||||||
rustTemplate(
|
}
|
||||||
"""
|
|
||||||
/// Return a reference to the retry configuration contained in this config, if any.
|
|
||||||
pub fn retry_config(&self) -> Option<&#{RetryConfig}> {
|
|
||||||
self.retry_config.as_ref()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return a cloned shared async sleep implementation from this config, if any.
|
|
||||||
pub fn sleep_impl(&self) -> Option<#{SharedAsyncSleep}> {
|
|
||||||
self.sleep_impl.clone()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return a reference to the timeout configuration contained in this config, if any.
|
|
||||||
pub fn timeout_config(&self) -> Option<&#{TimeoutConfig}> {
|
|
||||||
self.timeout_config.as_ref()
|
|
||||||
}
|
|
||||||
""",
|
|
||||||
*codegenScope,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
is ServiceConfig.BuilderStruct ->
|
is ServiceConfig.ConfigImpl -> {
|
||||||
|
if (runtimeMode.defaultToOrchestrator) {
|
||||||
|
rustTemplate(
|
||||||
|
"""
|
||||||
|
/// Return a reference to the retry configuration contained in this config, if any.
|
||||||
|
pub fn retry_config(&self) -> Option<&#{RetryConfig}> {
|
||||||
|
self.inner.load::<#{RetryConfig}>()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return a cloned shared async sleep implementation from this config, if any.
|
||||||
|
pub fn sleep_impl(&self) -> Option<#{SharedAsyncSleep}> {
|
||||||
|
self.inner.load::<#{SharedAsyncSleep}>().cloned()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return a reference to the timeout configuration contained in this config, if any.
|
||||||
|
pub fn timeout_config(&self) -> Option<&#{TimeoutConfig}> {
|
||||||
|
self.inner.load::<#{TimeoutConfig}>()
|
||||||
|
}
|
||||||
|
""",
|
||||||
|
*codegenScope,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
rustTemplate(
|
||||||
|
"""
|
||||||
|
/// Return a reference to the retry configuration contained in this config, if any.
|
||||||
|
pub fn retry_config(&self) -> Option<&#{RetryConfig}> {
|
||||||
|
self.retry_config.as_ref()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return a cloned shared async sleep implementation from this config, if any.
|
||||||
|
pub fn sleep_impl(&self) -> Option<#{SharedAsyncSleep}> {
|
||||||
|
self.sleep_impl.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return a reference to the timeout configuration contained in this config, if any.
|
||||||
|
pub fn timeout_config(&self) -> Option<&#{TimeoutConfig}> {
|
||||||
|
self.timeout_config.as_ref()
|
||||||
|
}
|
||||||
|
""",
|
||||||
|
*codegenScope,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
is ServiceConfig.BuilderStruct -> {
|
||||||
rustTemplate(
|
rustTemplate(
|
||||||
"""
|
"""
|
||||||
retry_config: Option<#{RetryConfig}>,
|
retry_config: Option<#{RetryConfig}>,
|
||||||
|
@ -75,6 +102,7 @@ class ResiliencyConfigCustomization(codegenContext: CodegenContext) : ConfigCust
|
||||||
""",
|
""",
|
||||||
*codegenScope,
|
*codegenScope,
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
ServiceConfig.BuilderImpl ->
|
ServiceConfig.BuilderImpl ->
|
||||||
rustTemplate(
|
rustTemplate(
|
||||||
|
@ -216,21 +244,30 @@ class ResiliencyConfigCustomization(codegenContext: CodegenContext) : ConfigCust
|
||||||
*codegenScope,
|
*codegenScope,
|
||||||
)
|
)
|
||||||
|
|
||||||
ServiceConfig.BuilderBuild -> rustTemplate(
|
ServiceConfig.BuilderBuild -> {
|
||||||
// We call clone on sleep_impl because the field is used by
|
if (runtimeMode.defaultToOrchestrator) {
|
||||||
// initializing the credentials_cache field later in the build
|
rustTemplate(
|
||||||
// method of a Config builder.
|
"""
|
||||||
// We could rearrange the order of decorators so that AwsCodegenDecorator
|
self.retry_config.map(|r| layer.store_put(r));
|
||||||
// runs before RequiredCustomizations, which in turns renders
|
self.sleep_impl.clone().map(|s| layer.store_put(s));
|
||||||
// CredentialsCacheDecorator before this class, but that is a bigger
|
self.timeout_config.map(|t| layer.store_put(t));
|
||||||
// change than adding a call to the clone method on sleep_impl.
|
""",
|
||||||
"""
|
*codegenScope,
|
||||||
retry_config: self.retry_config,
|
)
|
||||||
sleep_impl: self.sleep_impl.clone(),
|
} else {
|
||||||
timeout_config: self.timeout_config,
|
rustTemplate(
|
||||||
""",
|
// We call clone on sleep_impl because the field is used by
|
||||||
*codegenScope,
|
// initializing the credentials_cache field later in the build
|
||||||
)
|
// method of a Config builder.
|
||||||
|
"""
|
||||||
|
retry_config: self.retry_config,
|
||||||
|
sleep_impl: self.sleep_impl.clone(),
|
||||||
|
timeout_config: self.timeout_config,
|
||||||
|
""",
|
||||||
|
*codegenScope,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
else -> emptySection
|
else -> emptySection
|
||||||
}
|
}
|
||||||
|
@ -276,7 +313,7 @@ class ResiliencyServiceRuntimePluginCustomization : ServiceRuntimePluginCustomiz
|
||||||
if let Some(timeout_config) = self.handle.conf.timeout_config() {
|
if let Some(timeout_config) = self.handle.conf.timeout_config() {
|
||||||
${section.newLayerName}.put(timeout_config.clone());
|
${section.newLayerName}.put(timeout_config.clone());
|
||||||
}
|
}
|
||||||
${section.newLayerName}.put(self.handle.conf.time_source.clone());
|
${section.newLayerName}.put(self.handle.conf.time_source().clone());
|
||||||
""",
|
""",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,127 @@
|
||||||
|
/*
|
||||||
|
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
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.generators.OperationCustomization
|
||||||
|
import software.amazon.smithy.rust.codegen.client.smithy.generators.OperationSection
|
||||||
|
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
|
||||||
|
import software.amazon.smithy.rust.codegen.core.rustlang.rust
|
||||||
|
import software.amazon.smithy.rust.codegen.core.rustlang.rustBlockTemplate
|
||||||
|
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.RuntimeType
|
||||||
|
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeType.Companion.preludeScope
|
||||||
|
|
||||||
|
class TimeSourceCustomization(codegenContext: ClientCodegenContext) : ConfigCustomization() {
|
||||||
|
private val runtimeMode = codegenContext.smithyRuntimeMode
|
||||||
|
private val codegenScope = arrayOf(
|
||||||
|
*preludeScope,
|
||||||
|
"SharedTimeSource" to RuntimeType.smithyAsync(codegenContext.runtimeConfig).resolve("time::SharedTimeSource"),
|
||||||
|
)
|
||||||
|
|
||||||
|
override fun section(section: ServiceConfig) =
|
||||||
|
writable {
|
||||||
|
when (section) {
|
||||||
|
is ServiceConfig.ConfigStruct -> {
|
||||||
|
if (runtimeMode.defaultToMiddleware) {
|
||||||
|
rustTemplate(
|
||||||
|
"""
|
||||||
|
pub(crate) time_source: #{SharedTimeSource},
|
||||||
|
""",
|
||||||
|
*codegenScope,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
is ServiceConfig.ConfigImpl -> {
|
||||||
|
rust("/// Return time source used for this service.")
|
||||||
|
rustBlockTemplate(
|
||||||
|
"pub fn time_source(&self) -> #{SharedTimeSource}",
|
||||||
|
*codegenScope,
|
||||||
|
) {
|
||||||
|
if (runtimeMode.defaultToOrchestrator) {
|
||||||
|
rustTemplate(
|
||||||
|
"""self.inner.load::<#{SharedTimeSource}>().expect("time source should be set").clone()""",
|
||||||
|
*codegenScope,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
rust("self.time_source.clone()")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
is ServiceConfig.BuilderStruct ->
|
||||||
|
rustTemplate(
|
||||||
|
"""
|
||||||
|
time_source: #{Option}<#{SharedTimeSource}>,
|
||||||
|
""",
|
||||||
|
*codegenScope,
|
||||||
|
)
|
||||||
|
|
||||||
|
ServiceConfig.BuilderImpl ->
|
||||||
|
rustTemplate(
|
||||||
|
"""
|
||||||
|
/// Sets the time source used for this service
|
||||||
|
pub fn time_source(
|
||||||
|
mut self,
|
||||||
|
time_source: impl #{Into}<#{SharedTimeSource}>,
|
||||||
|
) -> Self {
|
||||||
|
self.time_source = Some(time_source.into());
|
||||||
|
self
|
||||||
|
}
|
||||||
|
/// Sets the time source used for this service
|
||||||
|
pub fn set_time_source(
|
||||||
|
&mut self,
|
||||||
|
time_source: #{Option}<#{SharedTimeSource}>,
|
||||||
|
) -> &mut Self {
|
||||||
|
self.time_source = time_source;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
""",
|
||||||
|
*codegenScope,
|
||||||
|
)
|
||||||
|
|
||||||
|
ServiceConfig.BuilderBuild -> {
|
||||||
|
if (runtimeMode.defaultToOrchestrator) {
|
||||||
|
rustTemplate(
|
||||||
|
"""
|
||||||
|
layer.store_put(self.time_source.unwrap_or_default());
|
||||||
|
""",
|
||||||
|
*codegenScope,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
rustTemplate(
|
||||||
|
"""
|
||||||
|
time_source: self.time_source.unwrap_or_default(),
|
||||||
|
""",
|
||||||
|
*codegenScope,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> emptySection
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TimeSourceOperationCustomization : OperationCustomization() {
|
||||||
|
override fun section(section: OperationSection): Writable {
|
||||||
|
return when (section) {
|
||||||
|
is OperationSection.MutateRequest -> writable {
|
||||||
|
rust(
|
||||||
|
"""
|
||||||
|
${section.request}.properties_mut().insert(${section.config}.time_source.clone());
|
||||||
|
""",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> emptySection
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,11 +16,11 @@ import software.amazon.smithy.rust.codegen.client.smithy.customizations.Intercep
|
||||||
import software.amazon.smithy.rust.codegen.client.smithy.customizations.ResiliencyConfigCustomization
|
import software.amazon.smithy.rust.codegen.client.smithy.customizations.ResiliencyConfigCustomization
|
||||||
import software.amazon.smithy.rust.codegen.client.smithy.customizations.ResiliencyReExportCustomization
|
import software.amazon.smithy.rust.codegen.client.smithy.customizations.ResiliencyReExportCustomization
|
||||||
import software.amazon.smithy.rust.codegen.client.smithy.customizations.ResiliencyServiceRuntimePluginCustomization
|
import software.amazon.smithy.rust.codegen.client.smithy.customizations.ResiliencyServiceRuntimePluginCustomization
|
||||||
|
import software.amazon.smithy.rust.codegen.client.smithy.customizations.TimeSourceCustomization
|
||||||
|
import software.amazon.smithy.rust.codegen.client.smithy.customizations.TimeSourceOperationCustomization
|
||||||
import software.amazon.smithy.rust.codegen.client.smithy.generators.OperationCustomization
|
import software.amazon.smithy.rust.codegen.client.smithy.generators.OperationCustomization
|
||||||
import software.amazon.smithy.rust.codegen.client.smithy.generators.ServiceRuntimePluginCustomization
|
import software.amazon.smithy.rust.codegen.client.smithy.generators.ServiceRuntimePluginCustomization
|
||||||
import software.amazon.smithy.rust.codegen.client.smithy.generators.config.ConfigCustomization
|
import software.amazon.smithy.rust.codegen.client.smithy.generators.config.ConfigCustomization
|
||||||
import software.amazon.smithy.rust.codegen.client.smithy.generators.config.TimeSourceOperationCustomization
|
|
||||||
import software.amazon.smithy.rust.codegen.client.smithy.generators.config.timeSourceCustomization
|
|
||||||
import software.amazon.smithy.rust.codegen.core.rustlang.Feature
|
import software.amazon.smithy.rust.codegen.core.rustlang.Feature
|
||||||
import software.amazon.smithy.rust.codegen.core.smithy.RustCrate
|
import software.amazon.smithy.rust.codegen.core.smithy.RustCrate
|
||||||
import software.amazon.smithy.rust.codegen.core.smithy.customizations.AllowLintsCustomization
|
import software.amazon.smithy.rust.codegen.core.smithy.customizations.AllowLintsCustomization
|
||||||
|
@ -59,9 +59,9 @@ class RequiredCustomizations : ClientCodegenDecorator {
|
||||||
if (codegenContext.smithyRuntimeMode.generateOrchestrator) {
|
if (codegenContext.smithyRuntimeMode.generateOrchestrator) {
|
||||||
baseCustomizations + ResiliencyConfigCustomization(codegenContext) + InterceptorConfigCustomization(
|
baseCustomizations + ResiliencyConfigCustomization(codegenContext) + InterceptorConfigCustomization(
|
||||||
codegenContext,
|
codegenContext,
|
||||||
) + timeSourceCustomization(codegenContext)
|
) + TimeSourceCustomization(codegenContext)
|
||||||
} else {
|
} else {
|
||||||
baseCustomizations + ResiliencyConfigCustomization(codegenContext) + timeSourceCustomization(codegenContext)
|
baseCustomizations + ResiliencyConfigCustomization(codegenContext) + TimeSourceCustomization(codegenContext)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun libRsCustomizations(
|
override fun libRsCustomizations(
|
||||||
|
|
|
@ -11,19 +11,22 @@ import software.amazon.smithy.model.shapes.ShapeType
|
||||||
import software.amazon.smithy.model.shapes.StringShape
|
import software.amazon.smithy.model.shapes.StringShape
|
||||||
import software.amazon.smithy.rulesengine.traits.ClientContextParamDefinition
|
import software.amazon.smithy.rulesengine.traits.ClientContextParamDefinition
|
||||||
import software.amazon.smithy.rulesengine.traits.ClientContextParamsTrait
|
import software.amazon.smithy.rulesengine.traits.ClientContextParamsTrait
|
||||||
|
import software.amazon.smithy.rust.codegen.client.smithy.ClientCodegenContext
|
||||||
import software.amazon.smithy.rust.codegen.client.smithy.generators.config.ConfigCustomization
|
import software.amazon.smithy.rust.codegen.client.smithy.generators.config.ConfigCustomization
|
||||||
import software.amazon.smithy.rust.codegen.client.smithy.generators.config.ConfigParam
|
import software.amazon.smithy.rust.codegen.client.smithy.generators.config.ConfigParam
|
||||||
import software.amazon.smithy.rust.codegen.client.smithy.generators.config.ServiceConfig
|
import software.amazon.smithy.rust.codegen.client.smithy.generators.config.ServiceConfig
|
||||||
|
import software.amazon.smithy.rust.codegen.client.smithy.generators.config.configParamNewtype
|
||||||
import software.amazon.smithy.rust.codegen.client.smithy.generators.config.standardConfigParam
|
import software.amazon.smithy.rust.codegen.client.smithy.generators.config.standardConfigParam
|
||||||
import software.amazon.smithy.rust.codegen.core.rustlang.RustReservedWords
|
import software.amazon.smithy.rust.codegen.core.rustlang.RustReservedWords
|
||||||
import software.amazon.smithy.rust.codegen.core.rustlang.Writable
|
import software.amazon.smithy.rust.codegen.core.rustlang.Writable
|
||||||
import software.amazon.smithy.rust.codegen.core.rustlang.docs
|
import software.amazon.smithy.rust.codegen.core.rustlang.docs
|
||||||
import software.amazon.smithy.rust.codegen.core.rustlang.join
|
import software.amazon.smithy.rust.codegen.core.rustlang.join
|
||||||
import software.amazon.smithy.rust.codegen.core.rustlang.writable
|
import software.amazon.smithy.rust.codegen.core.rustlang.writable
|
||||||
import software.amazon.smithy.rust.codegen.core.smithy.CodegenContext
|
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeConfig
|
||||||
import software.amazon.smithy.rust.codegen.core.smithy.RustSymbolProvider
|
import software.amazon.smithy.rust.codegen.core.smithy.RustSymbolProvider
|
||||||
import software.amazon.smithy.rust.codegen.core.util.getTrait
|
import software.amazon.smithy.rust.codegen.core.util.getTrait
|
||||||
import software.amazon.smithy.rust.codegen.core.util.orNull
|
import software.amazon.smithy.rust.codegen.core.util.orNull
|
||||||
|
import software.amazon.smithy.rust.codegen.core.util.toPascalCase
|
||||||
import software.amazon.smithy.rust.codegen.core.util.toSnakeCase
|
import software.amazon.smithy.rust.codegen.core.util.toSnakeCase
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -32,10 +35,11 @@ import software.amazon.smithy.rust.codegen.core.util.toSnakeCase
|
||||||
* This handles injecting parameters like `s3::Accelerate` or `s3::ForcePathStyle`. The resulting parameters become
|
* This handles injecting parameters like `s3::Accelerate` or `s3::ForcePathStyle`. The resulting parameters become
|
||||||
* setters on the config builder object.
|
* setters on the config builder object.
|
||||||
*/
|
*/
|
||||||
class ClientContextConfigCustomization(ctx: CodegenContext) : ConfigCustomization() {
|
class ClientContextConfigCustomization(ctx: ClientCodegenContext) : ConfigCustomization() {
|
||||||
|
private val runtimeConfig = ctx.runtimeConfig
|
||||||
private val configParams = ctx.serviceShape.getTrait<ClientContextParamsTrait>()?.parameters.orEmpty().toList()
|
private val configParams = ctx.serviceShape.getTrait<ClientContextParamsTrait>()?.parameters.orEmpty().toList()
|
||||||
.map { (key, value) -> fromClientParam(key, value, ctx.symbolProvider) }
|
.map { (key, value) -> fromClientParam(key, value, ctx.symbolProvider, runtimeConfig) }
|
||||||
private val decorators = configParams.map { standardConfigParam(it) }
|
private val decorators = configParams.map { standardConfigParam(it, ctx) }
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun toSymbol(shapeType: ShapeType, symbolProvider: RustSymbolProvider): Symbol =
|
fun toSymbol(shapeType: ShapeType, symbolProvider: RustSymbolProvider): Symbol =
|
||||||
|
@ -51,10 +55,13 @@ class ClientContextConfigCustomization(ctx: CodegenContext) : ConfigCustomizatio
|
||||||
name: String,
|
name: String,
|
||||||
definition: ClientContextParamDefinition,
|
definition: ClientContextParamDefinition,
|
||||||
symbolProvider: RustSymbolProvider,
|
symbolProvider: RustSymbolProvider,
|
||||||
|
runtimeConfig: RuntimeConfig,
|
||||||
): ConfigParam {
|
): ConfigParam {
|
||||||
|
val inner = toSymbol(definition.type, symbolProvider)
|
||||||
return ConfigParam(
|
return ConfigParam(
|
||||||
RustReservedWords.escapeIfNeeded(name.toSnakeCase()),
|
RustReservedWords.escapeIfNeeded(name.toSnakeCase()),
|
||||||
toSymbol(definition.type, symbolProvider),
|
inner,
|
||||||
|
configParamNewtype(RustReservedWords.escapeIfNeeded(name.toPascalCase()), inner, runtimeConfig),
|
||||||
definition.documentation.orNull()?.let { writable { docs(it) } },
|
definition.documentation.orNull()?.let { writable { docs(it) } },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ internal class EndpointConfigCustomization(
|
||||||
ConfigCustomization() {
|
ConfigCustomization() {
|
||||||
private val runtimeConfig = codegenContext.runtimeConfig
|
private val runtimeConfig = codegenContext.runtimeConfig
|
||||||
private val moduleUseName = codegenContext.moduleUseName()
|
private val moduleUseName = codegenContext.moduleUseName()
|
||||||
|
private val runtimeMode = codegenContext.smithyRuntimeMode
|
||||||
private val types = Types(runtimeConfig)
|
private val types = Types(runtimeConfig)
|
||||||
|
|
||||||
override fun section(section: ServiceConfig): Writable {
|
override fun section(section: ServiceConfig): Writable {
|
||||||
|
@ -38,21 +39,38 @@ internal class EndpointConfigCustomization(
|
||||||
"Params" to typesGenerator.paramsStruct(),
|
"Params" to typesGenerator.paramsStruct(),
|
||||||
)
|
)
|
||||||
when (section) {
|
when (section) {
|
||||||
is ServiceConfig.ConfigStruct -> rustTemplate(
|
is ServiceConfig.ConfigStruct -> {
|
||||||
"pub (crate) endpoint_resolver: $sharedEndpointResolver,",
|
if (runtimeMode.defaultToMiddleware) {
|
||||||
*codegenScope,
|
rustTemplate(
|
||||||
)
|
"pub (crate) endpoint_resolver: $sharedEndpointResolver,",
|
||||||
|
*codegenScope,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
is ServiceConfig.ConfigImpl ->
|
is ServiceConfig.ConfigImpl -> {
|
||||||
rustTemplate(
|
if (runtimeMode.defaultToOrchestrator) {
|
||||||
"""
|
rustTemplate(
|
||||||
/// Returns the endpoint resolver.
|
"""
|
||||||
pub fn endpoint_resolver(&self) -> $sharedEndpointResolver {
|
/// Returns the endpoint resolver.
|
||||||
self.endpoint_resolver.clone()
|
pub fn endpoint_resolver(&self) -> $sharedEndpointResolver {
|
||||||
}
|
self.inner.load::<$sharedEndpointResolver>().expect("endpoint resolver should be set").clone()
|
||||||
""",
|
}
|
||||||
*codegenScope,
|
""",
|
||||||
)
|
*codegenScope,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
rustTemplate(
|
||||||
|
"""
|
||||||
|
/// Returns the endpoint resolver.
|
||||||
|
pub fn endpoint_resolver(&self) -> $sharedEndpointResolver {
|
||||||
|
self.endpoint_resolver.clone()
|
||||||
|
}
|
||||||
|
""",
|
||||||
|
*codegenScope,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
is ServiceConfig.BuilderStruct ->
|
is ServiceConfig.BuilderStruct ->
|
||||||
rustTemplate(
|
rustTemplate(
|
||||||
|
@ -123,15 +141,27 @@ internal class EndpointConfigCustomization(
|
||||||
ServiceConfig.BuilderBuild -> {
|
ServiceConfig.BuilderBuild -> {
|
||||||
val defaultResolver = typesGenerator.defaultResolver()
|
val defaultResolver = typesGenerator.defaultResolver()
|
||||||
if (defaultResolver != null) {
|
if (defaultResolver != null) {
|
||||||
rustTemplate(
|
if (runtimeMode.defaultToOrchestrator) {
|
||||||
"""
|
rustTemplate(
|
||||||
endpoint_resolver: self.endpoint_resolver.unwrap_or_else(||
|
"""
|
||||||
#{SharedEndpointResolver}::new(#{DefaultResolver}::new())
|
layer.store_put(self.endpoint_resolver.unwrap_or_else(||
|
||||||
),
|
#{SharedEndpointResolver}::new(#{DefaultResolver}::new())
|
||||||
""",
|
));
|
||||||
*codegenScope,
|
""",
|
||||||
"DefaultResolver" to defaultResolver,
|
*codegenScope,
|
||||||
)
|
"DefaultResolver" to defaultResolver,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
rustTemplate(
|
||||||
|
"""
|
||||||
|
endpoint_resolver: self.endpoint_resolver.unwrap_or_else(||
|
||||||
|
#{SharedEndpointResolver}::new(#{DefaultResolver}::new())
|
||||||
|
),
|
||||||
|
""",
|
||||||
|
*codegenScope,
|
||||||
|
"DefaultResolver" to defaultResolver,
|
||||||
|
)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
val alwaysFailsResolver =
|
val alwaysFailsResolver =
|
||||||
RuntimeType.forInlineFun("MissingResolver", ClientRustModule.Endpoint) {
|
RuntimeType.forInlineFun("MissingResolver", ClientRustModule.Endpoint) {
|
||||||
|
@ -152,13 +182,23 @@ internal class EndpointConfigCustomization(
|
||||||
}
|
}
|
||||||
// To keep this diff under control, rather than `.expect` here, insert a resolver that will
|
// To keep this diff under control, rather than `.expect` here, insert a resolver that will
|
||||||
// always fail. In the future, this will be changed to an `expect()`
|
// always fail. In the future, this will be changed to an `expect()`
|
||||||
rustTemplate(
|
if (runtimeMode.defaultToOrchestrator) {
|
||||||
"""
|
rustTemplate(
|
||||||
endpoint_resolver: self.endpoint_resolver.unwrap_or_else(||#{SharedEndpointResolver}::new(#{FailingResolver})),
|
"""
|
||||||
""",
|
layer.store_put(self.endpoint_resolver.unwrap_or_else(||#{SharedEndpointResolver}::new(#{FailingResolver})));
|
||||||
*codegenScope,
|
""",
|
||||||
"FailingResolver" to alwaysFailsResolver,
|
*codegenScope,
|
||||||
)
|
"FailingResolver" to alwaysFailsResolver,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
rustTemplate(
|
||||||
|
"""
|
||||||
|
endpoint_resolver: self.endpoint_resolver.unwrap_or_else(||#{SharedEndpointResolver}::new(#{FailingResolver})),
|
||||||
|
""",
|
||||||
|
*codegenScope,
|
||||||
|
"FailingResolver" to alwaysFailsResolver,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -119,9 +119,9 @@ class EndpointParamsInterceptorGenerator(
|
||||||
val paramName = EndpointParamsGenerator.memberName(name)
|
val paramName = EndpointParamsGenerator.memberName(name)
|
||||||
val setterName = EndpointParamsGenerator.setterName(name)
|
val setterName = EndpointParamsGenerator.setterName(name)
|
||||||
if (param.type == ShapeType.BOOLEAN) {
|
if (param.type == ShapeType.BOOLEAN) {
|
||||||
rust(".$setterName(_config.$paramName)")
|
rust(".$setterName(_config.$paramName())")
|
||||||
} else {
|
} else {
|
||||||
rust(".$setterName(_config.$paramName.clone())")
|
rust(".$setterName(_config.$paramName().clone())")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -170,7 +170,7 @@ class ServiceRuntimePluginGenerator(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn interceptors(&self, interceptors: &mut #{InterceptorRegistrar}) {
|
fn interceptors(&self, interceptors: &mut #{InterceptorRegistrar}) {
|
||||||
interceptors.extend(self.handle.conf.interceptors.iter().cloned());
|
interceptors.extend(self.handle.conf.interceptors().cloned());
|
||||||
#{additional_interceptors}
|
#{additional_interceptors}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,62 +5,98 @@
|
||||||
|
|
||||||
package software.amazon.smithy.rust.codegen.client.smithy.generators.config
|
package software.amazon.smithy.rust.codegen.client.smithy.generators.config
|
||||||
|
|
||||||
|
import software.amazon.smithy.rust.codegen.client.smithy.ClientCodegenContext
|
||||||
import software.amazon.smithy.rust.codegen.core.rustlang.Writable
|
import software.amazon.smithy.rust.codegen.core.rustlang.Writable
|
||||||
import software.amazon.smithy.rust.codegen.core.rustlang.rust
|
import software.amazon.smithy.rust.codegen.core.rustlang.rust
|
||||||
import software.amazon.smithy.rust.codegen.core.rustlang.rustTemplate
|
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.rustlang.writable
|
||||||
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeType
|
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeType
|
||||||
|
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeType.Companion.preludeScope
|
||||||
import software.amazon.smithy.rust.codegen.core.smithy.customize.NamedCustomization
|
import software.amazon.smithy.rust.codegen.core.smithy.customize.NamedCustomization
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a `make_token` field to Service config. See below for the resulting generated code.
|
* Add a `make_token` field to Service config. See below for the resulting generated code.
|
||||||
*/
|
*/
|
||||||
class IdempotencyTokenProviderCustomization : NamedCustomization<ServiceConfig>() {
|
class IdempotencyTokenProviderCustomization(codegenContext: ClientCodegenContext) : NamedCustomization<ServiceConfig>() {
|
||||||
|
private val runtimeConfig = codegenContext.runtimeConfig
|
||||||
|
private val runtimeMode = codegenContext.smithyRuntimeMode
|
||||||
|
private val codegenScope = arrayOf(
|
||||||
|
*preludeScope,
|
||||||
|
"default_provider" to RuntimeType.idempotencyToken(runtimeConfig).resolve("default_provider"),
|
||||||
|
"IdempotencyTokenProvider" to RuntimeType.idempotencyToken(runtimeConfig).resolve("IdempotencyTokenProvider"),
|
||||||
|
)
|
||||||
|
|
||||||
override fun section(section: ServiceConfig): Writable {
|
override fun section(section: ServiceConfig): Writable {
|
||||||
return when (section) {
|
return when (section) {
|
||||||
is ServiceConfig.ConfigStruct -> writable {
|
is ServiceConfig.ConfigStruct -> writable {
|
||||||
rust("pub (crate) make_token: #T::IdempotencyTokenProvider,", RuntimeType.IdempotencyToken)
|
if (runtimeMode.defaultToMiddleware) {
|
||||||
|
rustTemplate("pub (crate) make_token: #{IdempotencyTokenProvider},", *codegenScope)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ServiceConfig.ConfigImpl -> writable {
|
ServiceConfig.ConfigImpl -> writable {
|
||||||
rust(
|
if (runtimeMode.defaultToOrchestrator) {
|
||||||
"""
|
rustTemplate(
|
||||||
/// Returns a copy of the idempotency token provider.
|
"""
|
||||||
/// If a random token provider was configured,
|
/// Returns a copy of the idempotency token provider.
|
||||||
/// a newly-randomized token provider will be returned.
|
/// If a random token provider was configured,
|
||||||
pub fn make_token(&self) -> #T::IdempotencyTokenProvider {
|
/// a newly-randomized token provider will be returned.
|
||||||
self.make_token.clone()
|
pub fn make_token(&self) -> #{IdempotencyTokenProvider} {
|
||||||
}
|
self.inner.load::<#{IdempotencyTokenProvider}>().expect("the idempotency provider should be set").clone()
|
||||||
""",
|
}
|
||||||
RuntimeType.IdempotencyToken,
|
""",
|
||||||
)
|
*codegenScope,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
rustTemplate(
|
||||||
|
"""
|
||||||
|
/// Returns a copy of the idempotency token provider.
|
||||||
|
/// If a random token provider was configured,
|
||||||
|
/// a newly-randomized token provider will be returned.
|
||||||
|
pub fn make_token(&self) -> #{IdempotencyTokenProvider} {
|
||||||
|
self.make_token.clone()
|
||||||
|
}
|
||||||
|
""",
|
||||||
|
*codegenScope,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ServiceConfig.BuilderStruct -> writable {
|
ServiceConfig.BuilderStruct -> writable {
|
||||||
rust("make_token: Option<#T::IdempotencyTokenProvider>,", RuntimeType.IdempotencyToken)
|
rustTemplate("make_token: #{Option}<#{IdempotencyTokenProvider}>,", *codegenScope)
|
||||||
}
|
}
|
||||||
|
|
||||||
ServiceConfig.BuilderImpl -> writable {
|
ServiceConfig.BuilderImpl -> writable {
|
||||||
rustTemplate(
|
rustTemplate(
|
||||||
"""
|
"""
|
||||||
/// Sets the idempotency token provider to use for service calls that require tokens.
|
/// Sets the idempotency token provider to use for service calls that require tokens.
|
||||||
pub fn make_token(mut self, make_token: impl Into<#{TokenProvider}>) -> Self {
|
pub fn make_token(mut self, make_token: impl #{Into}<#{IdempotencyTokenProvider}>) -> Self {
|
||||||
self.set_make_token(Some(make_token.into()));
|
self.set_make_token(#{Some}(make_token.into()));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the idempotency token provider to use for service calls that require tokens.
|
/// Sets the idempotency token provider to use for service calls that require tokens.
|
||||||
pub fn set_make_token(&mut self, make_token: Option<#{TokenProvider}>) -> &mut Self {
|
pub fn set_make_token(&mut self, make_token: #{Option}<#{IdempotencyTokenProvider}>) -> &mut Self {
|
||||||
self.make_token = make_token;
|
self.make_token = make_token;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
""",
|
""",
|
||||||
"TokenProvider" to RuntimeType.IdempotencyToken.resolve("IdempotencyTokenProvider"),
|
*codegenScope,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
ServiceConfig.BuilderBuild -> writable {
|
ServiceConfig.BuilderBuild -> writable {
|
||||||
rust("make_token: self.make_token.unwrap_or_else(#T::default_provider),", RuntimeType.IdempotencyToken)
|
if (runtimeMode.defaultToOrchestrator) {
|
||||||
|
rustTemplate(
|
||||||
|
"layer.store_put(self.make_token.unwrap_or_else(#{default_provider}));",
|
||||||
|
*codegenScope,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
rustTemplate(
|
||||||
|
"make_token: self.make_token.unwrap_or_else(#{default_provider}),",
|
||||||
|
*codegenScope,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
is ServiceConfig.DefaultForTests -> writable {
|
is ServiceConfig.DefaultForTests -> writable {
|
||||||
|
@ -71,41 +107,3 @@ class IdempotencyTokenProviderCustomization : NamedCustomization<ServiceConfig>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Generated Code
|
|
||||||
pub struct Config {
|
|
||||||
pub(crate) make_token: Box<dyn crate::idempotency_token::MakeIdempotencyToken>,
|
|
||||||
}
|
|
||||||
impl Config {
|
|
||||||
pub fn builder() -> Builder {
|
|
||||||
Builder::default()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[derive(Default)]
|
|
||||||
pub struct Builder {
|
|
||||||
#[allow(dead_code)]
|
|
||||||
make_token: Option<Box<dyn crate::idempotency_token::MakeIdempotencyToken>>,
|
|
||||||
}
|
|
||||||
impl Builder {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self::default()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Sets the idempotency token provider to use for service calls that require tokens.
|
|
||||||
pub fn make_token(
|
|
||||||
mut self,
|
|
||||||
make_token: impl crate::idempotency_token::MakeIdempotencyToken + 'static,
|
|
||||||
) -> Self {
|
|
||||||
self.make_token = Some(Box::new(make_token));
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn build(self) -> Config {
|
|
||||||
Config {
|
|
||||||
make_token: self
|
|
||||||
.make_token
|
|
||||||
.unwrap_or_else(|| Box::new(crate::idempotency_token::default_provider())),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
|
@ -11,6 +11,9 @@ import software.amazon.smithy.model.knowledge.OperationIndex
|
||||||
import software.amazon.smithy.model.knowledge.TopDownIndex
|
import software.amazon.smithy.model.knowledge.TopDownIndex
|
||||||
import software.amazon.smithy.model.shapes.ServiceShape
|
import software.amazon.smithy.model.shapes.ServiceShape
|
||||||
import software.amazon.smithy.model.traits.IdempotencyTokenTrait
|
import software.amazon.smithy.model.traits.IdempotencyTokenTrait
|
||||||
|
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.customizations.codegenScope
|
||||||
import software.amazon.smithy.rust.codegen.client.smithy.customize.TestUtilFeature
|
import software.amazon.smithy.rust.codegen.client.smithy.customize.TestUtilFeature
|
||||||
import software.amazon.smithy.rust.codegen.core.rustlang.Attribute
|
import software.amazon.smithy.rust.codegen.core.rustlang.Attribute
|
||||||
import software.amazon.smithy.rust.codegen.core.rustlang.RustWriter
|
import software.amazon.smithy.rust.codegen.core.rustlang.RustWriter
|
||||||
|
@ -22,7 +25,7 @@ import software.amazon.smithy.rust.codegen.core.rustlang.rust
|
||||||
import software.amazon.smithy.rust.codegen.core.rustlang.rustBlock
|
import software.amazon.smithy.rust.codegen.core.rustlang.rustBlock
|
||||||
import software.amazon.smithy.rust.codegen.core.rustlang.rustTemplate
|
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.rustlang.writable
|
||||||
import software.amazon.smithy.rust.codegen.core.smithy.CodegenContext
|
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeConfig
|
||||||
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeType
|
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeType
|
||||||
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeType.Companion.preludeScope
|
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeType.Companion.preludeScope
|
||||||
import software.amazon.smithy.rust.codegen.core.smithy.customize.NamedCustomization
|
import software.amazon.smithy.rust.codegen.core.smithy.customize.NamedCustomization
|
||||||
|
@ -89,6 +92,14 @@ sealed class ServiceConfig(name: String) : Section(name) {
|
||||||
*/
|
*/
|
||||||
object BuilderBuild : ServiceConfig("BuilderBuild")
|
object BuilderBuild : ServiceConfig("BuilderBuild")
|
||||||
|
|
||||||
|
// TODO(enableNewSmithyRuntime): This is temporary until config builder is backed by a CloneableLayer.
|
||||||
|
// It is needed because certain config fields appear explicitly regardless of the smithy runtime mode, e.g.
|
||||||
|
// interceptors. The [BuilderBuild] section is bifurcated depending on the runtime mode (in the orchestrator mode,
|
||||||
|
// storing a field into a frozen layer and in the middleware moving it into a corresponding service config field)
|
||||||
|
// so we need a different temporary section to always move a field from a builder to service config within the
|
||||||
|
// build method.
|
||||||
|
object BuilderBuildExtras : ServiceConfig("BuilderBuildExtras")
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A section for setting up a field to be used by RuntimePlugin
|
* A section for setting up a field to be used by RuntimePlugin
|
||||||
*/
|
*/
|
||||||
|
@ -110,10 +121,53 @@ sealed class ServiceConfig(name: String) : Section(name) {
|
||||||
data class ConfigParam(
|
data class ConfigParam(
|
||||||
val name: String,
|
val name: String,
|
||||||
val type: Symbol,
|
val type: Symbol,
|
||||||
|
val newtype: RuntimeType?,
|
||||||
val setterDocs: Writable?,
|
val setterDocs: Writable?,
|
||||||
val getterDocs: Writable? = null,
|
val getterDocs: Writable? = null,
|
||||||
val optional: Boolean = true,
|
val optional: Boolean = true,
|
||||||
)
|
) {
|
||||||
|
|
||||||
|
data class Builder(
|
||||||
|
var name: String? = null,
|
||||||
|
var type: Symbol? = null,
|
||||||
|
var newtype: RuntimeType? = null,
|
||||||
|
var setterDocs: Writable? = null,
|
||||||
|
var getterDocs: Writable? = null,
|
||||||
|
var optional: Boolean = true,
|
||||||
|
) {
|
||||||
|
fun name(name: String) = apply { this.name = name }
|
||||||
|
fun type(type: Symbol) = apply { this.type = type }
|
||||||
|
fun newtype(newtype: RuntimeType) = apply { this.newtype = newtype }
|
||||||
|
fun setterDocs(setterDocs: Writable?) = apply { this.setterDocs = setterDocs }
|
||||||
|
fun getterDocs(getterDocs: Writable?) = apply { this.getterDocs = getterDocs }
|
||||||
|
fun optional(optional: Boolean) = apply { this.optional = optional }
|
||||||
|
fun build() = ConfigParam(name!!, type!!, newtype, setterDocs, getterDocs, optional)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a [RuntimeType] for a newtype whose name is [newtypeName] that wraps [inner].
|
||||||
|
*
|
||||||
|
* When config parameters are stored in a config map in Rust, stored parameters are keyed by type.
|
||||||
|
* Therefore, primitive types, such as bool and String, need to be wrapped in newtypes to make them distinct.
|
||||||
|
*/
|
||||||
|
fun configParamNewtype(newtypeName: String, inner: Symbol, runtimeConfig: RuntimeConfig) =
|
||||||
|
RuntimeType.forInlineFun(newtypeName, ClientRustModule.Config) {
|
||||||
|
val codegenScope = arrayOf(
|
||||||
|
"Storable" to RuntimeType.smithyTypes(runtimeConfig).resolve("config_bag::Storable"),
|
||||||
|
"StoreReplace" to RuntimeType.smithyTypes(runtimeConfig).resolve("config_bag::StoreReplace"),
|
||||||
|
)
|
||||||
|
rustTemplate(
|
||||||
|
"""
|
||||||
|
##[derive(Debug, Clone)]
|
||||||
|
pub(crate) struct $newtypeName($inner);
|
||||||
|
impl #{Storable} for $newtypeName {
|
||||||
|
type Storer = #{StoreReplace}<$newtypeName>;
|
||||||
|
}
|
||||||
|
""",
|
||||||
|
*codegenScope,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Config customization for a config param with no special behavior:
|
* Config customization for a config param with no special behavior:
|
||||||
|
@ -121,19 +175,47 @@ data class ConfigParam(
|
||||||
* 2. convenience setter (non-optional)
|
* 2. convenience setter (non-optional)
|
||||||
* 3. standard setter (&mut self)
|
* 3. standard setter (&mut self)
|
||||||
*/
|
*/
|
||||||
fun standardConfigParam(param: ConfigParam): ConfigCustomization = object : ConfigCustomization() {
|
fun standardConfigParam(param: ConfigParam, codegenContext: ClientCodegenContext): ConfigCustomization = object : ConfigCustomization() {
|
||||||
|
private val runtimeMode = codegenContext.smithyRuntimeMode
|
||||||
|
|
||||||
override fun section(section: ServiceConfig): Writable {
|
override fun section(section: ServiceConfig): Writable {
|
||||||
return when (section) {
|
return when (section) {
|
||||||
is ServiceConfig.ConfigStruct -> writable {
|
ServiceConfig.ConfigStruct -> writable {
|
||||||
docsOrFallback(param.getterDocs)
|
if (runtimeMode.defaultToMiddleware) {
|
||||||
val t = when (param.optional) {
|
docsOrFallback(param.getterDocs)
|
||||||
true -> param.type.makeOptional()
|
val t = when (param.optional) {
|
||||||
false -> param.type
|
true -> param.type.makeOptional()
|
||||||
|
false -> param.type
|
||||||
|
}
|
||||||
|
rust("pub (crate) ${param.name}: #T,", t)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ServiceConfig.ConfigImpl -> writable {
|
||||||
|
if (runtimeMode.defaultToOrchestrator) {
|
||||||
|
rustTemplate(
|
||||||
|
"""
|
||||||
|
pub(crate) fn ${param.name}(&self) -> #{output} {
|
||||||
|
self.inner.load::<#{newtype}>().map(#{f})
|
||||||
|
}
|
||||||
|
""",
|
||||||
|
"f" to writable {
|
||||||
|
if (param.type.name == "bool") {
|
||||||
|
rust("|ty| ty.0")
|
||||||
|
} else {
|
||||||
|
rust("|ty| ty.0.clone()")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"newtype" to param.newtype!!,
|
||||||
|
"output" to if (param.optional) {
|
||||||
|
param.type.makeOptional()
|
||||||
|
} else {
|
||||||
|
param.type
|
||||||
|
},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
rust("pub (crate) ${param.name}: #T,", t)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ServiceConfig.ConfigImpl -> emptySection
|
|
||||||
ServiceConfig.BuilderStruct -> writable {
|
ServiceConfig.BuilderStruct -> writable {
|
||||||
rust("${param.name}: #T,", param.type.makeOptional())
|
rust("${param.name}: #T,", param.type.makeOptional())
|
||||||
}
|
}
|
||||||
|
@ -162,8 +244,15 @@ fun standardConfigParam(param: ConfigParam): ConfigCustomization = object : Conf
|
||||||
}
|
}
|
||||||
|
|
||||||
ServiceConfig.BuilderBuild -> writable {
|
ServiceConfig.BuilderBuild -> writable {
|
||||||
val default = "".letIf(!param.optional) { ".unwrap_or_default() " }
|
if (runtimeMode.defaultToOrchestrator) {
|
||||||
rust("${param.name}: self.${param.name}$default,")
|
rustTemplate(
|
||||||
|
"layer.store_or_unset(self.${param.name}.map(#{newtype}));",
|
||||||
|
"newtype" to param.newtype!!,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
val default = "".letIf(!param.optional) { ".unwrap_or_default() " }
|
||||||
|
rust("${param.name}: self.${param.name}$default,")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
is ServiceConfig.RuntimePluginConfig -> emptySection
|
is ServiceConfig.RuntimePluginConfig -> emptySection
|
||||||
|
@ -199,19 +288,19 @@ typealias ConfigCustomization = NamedCustomization<ServiceConfig>
|
||||||
* // builder implementation
|
* // builder implementation
|
||||||
* }
|
* }
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class ServiceConfigGenerator(
|
class ServiceConfigGenerator(
|
||||||
private val codegenContext: CodegenContext,
|
private val codegenContext: ClientCodegenContext,
|
||||||
private val customizations: List<ConfigCustomization> = listOf(),
|
private val customizations: List<ConfigCustomization> = listOf(),
|
||||||
) {
|
) {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun withBaseBehavior(
|
fun withBaseBehavior(
|
||||||
codegenContext: CodegenContext,
|
codegenContext: ClientCodegenContext,
|
||||||
extraCustomizations: List<ConfigCustomization>,
|
extraCustomizations: List<ConfigCustomization>,
|
||||||
): ServiceConfigGenerator {
|
): ServiceConfigGenerator {
|
||||||
val baseFeatures = mutableListOf<ConfigCustomization>()
|
val baseFeatures = mutableListOf<ConfigCustomization>()
|
||||||
if (codegenContext.serviceShape.needsIdempotencyToken(codegenContext.model)) {
|
if (codegenContext.serviceShape.needsIdempotencyToken(codegenContext.model)) {
|
||||||
baseFeatures.add(IdempotencyTokenProviderCustomization())
|
baseFeatures.add(IdempotencyTokenProviderCustomization(codegenContext))
|
||||||
}
|
}
|
||||||
return ServiceConfigGenerator(codegenContext, baseFeatures + extraCustomizations)
|
return ServiceConfigGenerator(codegenContext, baseFeatures + extraCustomizations)
|
||||||
}
|
}
|
||||||
|
@ -228,6 +317,8 @@ class ServiceConfigGenerator(
|
||||||
"RuntimePlugin" to runtimeApi.resolve("client::runtime_plugin::RuntimePlugin"),
|
"RuntimePlugin" to runtimeApi.resolve("client::runtime_plugin::RuntimePlugin"),
|
||||||
*preludeScope,
|
*preludeScope,
|
||||||
)
|
)
|
||||||
|
private val moduleUseName = codegenContext.moduleUseName()
|
||||||
|
private val runtimeMode = codegenContext.smithyRuntimeMode
|
||||||
|
|
||||||
fun render(writer: RustWriter) {
|
fun render(writer: RustWriter) {
|
||||||
writer.docs("Service config.\n")
|
writer.docs("Service config.\n")
|
||||||
|
@ -236,6 +327,12 @@ class ServiceConfigGenerator(
|
||||||
}
|
}
|
||||||
Attribute(Attribute.derive(RuntimeType.Clone)).render(writer)
|
Attribute(Attribute.derive(RuntimeType.Clone)).render(writer)
|
||||||
writer.rustBlock("pub struct Config") {
|
writer.rustBlock("pub struct Config") {
|
||||||
|
if (runtimeMode.defaultToOrchestrator) {
|
||||||
|
rustTemplate(
|
||||||
|
"inner: #{FrozenLayer},",
|
||||||
|
*codegenScope,
|
||||||
|
)
|
||||||
|
}
|
||||||
customizations.forEach {
|
customizations.forEach {
|
||||||
it.section(ServiceConfig.ConfigStruct)(this)
|
it.section(ServiceConfig.ConfigStruct)(this)
|
||||||
}
|
}
|
||||||
|
@ -287,7 +384,7 @@ class ServiceConfigGenerator(
|
||||||
|
|
||||||
writer.rustBlock("impl Builder") {
|
writer.rustBlock("impl Builder") {
|
||||||
writer.docs("Constructs a config builder.")
|
writer.docs("Constructs a config builder.")
|
||||||
writer.rustTemplate("pub fn new() -> Self { Self::default() }")
|
writer.rust("pub fn new() -> Self { Self::default() }")
|
||||||
customizations.forEach {
|
customizations.forEach {
|
||||||
it.section(ServiceConfig.BuilderImpl)(this)
|
it.section(ServiceConfig.BuilderImpl)(this)
|
||||||
}
|
}
|
||||||
|
@ -312,15 +409,31 @@ class ServiceConfigGenerator(
|
||||||
|
|
||||||
docs("Builds a [`Config`].")
|
docs("Builds a [`Config`].")
|
||||||
rustBlock("pub fn build(self) -> Config") {
|
rustBlock("pub fn build(self) -> Config") {
|
||||||
rustBlock("Config") {
|
if (runtimeMode.defaultToOrchestrator) {
|
||||||
|
rustTemplate(
|
||||||
|
"""let mut layer = #{Layer}::new("$moduleUseName::Config");""",
|
||||||
|
*codegenScope,
|
||||||
|
)
|
||||||
customizations.forEach {
|
customizations.forEach {
|
||||||
it.section(ServiceConfig.BuilderBuild)(this)
|
it.section(ServiceConfig.BuilderBuild)(this)
|
||||||
}
|
}
|
||||||
|
rustBlock("Config") {
|
||||||
|
customizations.forEach {
|
||||||
|
it.section(ServiceConfig.BuilderBuildExtras)(this)
|
||||||
|
}
|
||||||
|
rust("inner: layer.freeze(),")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
rustBlock("Config") {
|
||||||
|
customizations.forEach {
|
||||||
|
it.section(ServiceConfig.BuilderBuild)(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
customizations.forEach {
|
||||||
customizations.forEach {
|
it.section(ServiceConfig.Extras)(writer)
|
||||||
it.section(ServiceConfig.Extras)(writer)
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,40 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
package software.amazon.smithy.rust.codegen.client.smithy.generators.config
|
|
||||||
|
|
||||||
import software.amazon.smithy.rust.codegen.client.smithy.ClientCodegenContext
|
|
||||||
import software.amazon.smithy.rust.codegen.client.smithy.generators.OperationCustomization
|
|
||||||
import software.amazon.smithy.rust.codegen.client.smithy.generators.OperationSection
|
|
||||||
import software.amazon.smithy.rust.codegen.core.rustlang.Writable
|
|
||||||
import software.amazon.smithy.rust.codegen.core.rustlang.docs
|
|
||||||
import software.amazon.smithy.rust.codegen.core.rustlang.rust
|
|
||||||
import software.amazon.smithy.rust.codegen.core.rustlang.writable
|
|
||||||
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeType
|
|
||||||
|
|
||||||
fun timeSourceCustomization(codegenContext: ClientCodegenContext) = standardConfigParam(
|
|
||||||
ConfigParam(
|
|
||||||
"time_source",
|
|
||||||
RuntimeType.smithyAsync(codegenContext.runtimeConfig).resolve("time::SharedTimeSource").toSymbol(),
|
|
||||||
setterDocs = writable { docs("""Sets the time source used for this service""") },
|
|
||||||
optional = false,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
class TimeSourceOperationCustomization : OperationCustomization() {
|
|
||||||
override fun section(section: OperationSection): Writable {
|
|
||||||
return when (section) {
|
|
||||||
is OperationSection.MutateRequest -> writable {
|
|
||||||
rust(
|
|
||||||
"""
|
|
||||||
${section.request}.properties_mut().insert(${section.config}.time_source.clone());
|
|
||||||
""",
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
else -> emptySection
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -5,36 +5,61 @@
|
||||||
|
|
||||||
package software.amazon.smithy.rust.codegen.client.testutil
|
package software.amazon.smithy.rust.codegen.client.testutil
|
||||||
|
|
||||||
|
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.ClientRustModule
|
||||||
import software.amazon.smithy.rust.codegen.client.smithy.generators.config.ConfigCustomization
|
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.client.smithy.generators.config.ServiceConfig
|
||||||
import software.amazon.smithy.rust.codegen.client.smithy.generators.config.ServiceConfigGenerator
|
import software.amazon.smithy.rust.codegen.client.smithy.generators.config.ServiceConfigGenerator
|
||||||
|
import software.amazon.smithy.rust.codegen.client.smithy.generators.config.configParamNewtype
|
||||||
import software.amazon.smithy.rust.codegen.core.rustlang.Writable
|
import software.amazon.smithy.rust.codegen.core.rustlang.Writable
|
||||||
import software.amazon.smithy.rust.codegen.core.rustlang.rust
|
import software.amazon.smithy.rust.codegen.core.rustlang.rust
|
||||||
|
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.rustlang.writable
|
||||||
|
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeType
|
||||||
import software.amazon.smithy.rust.codegen.core.testutil.TestWorkspace
|
import software.amazon.smithy.rust.codegen.core.testutil.TestWorkspace
|
||||||
import software.amazon.smithy.rust.codegen.core.testutil.TestWriterDelegator
|
import software.amazon.smithy.rust.codegen.core.testutil.TestWriterDelegator
|
||||||
import software.amazon.smithy.rust.codegen.core.testutil.asSmithyModel
|
|
||||||
import software.amazon.smithy.rust.codegen.core.testutil.compileAndTest
|
import software.amazon.smithy.rust.codegen.core.testutil.compileAndTest
|
||||||
import software.amazon.smithy.rust.codegen.core.testutil.unitTest
|
import software.amazon.smithy.rust.codegen.core.testutil.unitTest
|
||||||
|
import software.amazon.smithy.rust.codegen.core.util.toPascalCase
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test helper to produce a valid config customization to test that a [ConfigCustomization] can be used in conjunction
|
* Test helper to produce a valid config customization to test that a [ConfigCustomization] can be used in conjunction
|
||||||
* with other [ConfigCustomization]s.
|
* with other [ConfigCustomization]s.
|
||||||
*/
|
*/
|
||||||
fun stubConfigCustomization(name: String): ConfigCustomization {
|
fun stubConfigCustomization(name: String, codegenContext: ClientCodegenContext): ConfigCustomization {
|
||||||
return object : ConfigCustomization() {
|
return object : ConfigCustomization() {
|
||||||
override fun section(section: ServiceConfig): Writable = writable {
|
override fun section(section: ServiceConfig): Writable = writable {
|
||||||
when (section) {
|
when (section) {
|
||||||
ServiceConfig.ConfigStruct -> rust("_$name: u64,")
|
ServiceConfig.ConfigStruct -> {
|
||||||
ServiceConfig.ConfigImpl -> rust(
|
if (codegenContext.smithyRuntimeMode.defaultToMiddleware) {
|
||||||
"""
|
rust("_$name: u64,")
|
||||||
##[allow(missing_docs)]
|
|
||||||
pub fn $name(&self) -> u64 {
|
|
||||||
self._$name
|
|
||||||
}
|
}
|
||||||
""",
|
}
|
||||||
)
|
ServiceConfig.ConfigImpl -> {
|
||||||
|
if (codegenContext.smithyRuntimeMode.defaultToOrchestrator) {
|
||||||
|
rustTemplate(
|
||||||
|
"""
|
||||||
|
##[allow(missing_docs)]
|
||||||
|
pub fn $name(&self) -> u64 {
|
||||||
|
self.inner.load::<#{T}>().map(|u| u.0).unwrap()
|
||||||
|
}
|
||||||
|
""",
|
||||||
|
"T" to configParamNewtype(
|
||||||
|
"_$name".toPascalCase(), RuntimeType.U64.toSymbol(),
|
||||||
|
codegenContext.runtimeConfig,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
rust(
|
||||||
|
"""
|
||||||
|
##[allow(missing_docs)]
|
||||||
|
pub fn $name(&self) -> u64 {
|
||||||
|
self._$name
|
||||||
|
}
|
||||||
|
""",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
ServiceConfig.BuilderStruct -> rust("_$name: Option<u64>,")
|
ServiceConfig.BuilderStruct -> rust("_$name: Option<u64>,")
|
||||||
ServiceConfig.BuilderImpl -> rust(
|
ServiceConfig.BuilderImpl -> rust(
|
||||||
"""
|
"""
|
||||||
|
@ -45,11 +70,25 @@ fun stubConfigCustomization(name: String): ConfigCustomization {
|
||||||
}
|
}
|
||||||
""",
|
""",
|
||||||
)
|
)
|
||||||
ServiceConfig.BuilderBuild -> rust(
|
ServiceConfig.BuilderBuild -> {
|
||||||
"""
|
if (codegenContext.smithyRuntimeMode.defaultToOrchestrator) {
|
||||||
_$name: self._$name.unwrap_or(123),
|
rustTemplate(
|
||||||
""",
|
"""
|
||||||
)
|
layer.store_or_unset(self._$name.map(#{T}));
|
||||||
|
""",
|
||||||
|
"T" to configParamNewtype(
|
||||||
|
"_$name".toPascalCase(), RuntimeType.U64.toSymbol(),
|
||||||
|
codegenContext.runtimeConfig,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
rust(
|
||||||
|
"""
|
||||||
|
_$name: self._$name.unwrap_or(123),
|
||||||
|
""",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
else -> emptySection
|
else -> emptySection
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -63,18 +102,19 @@ fun stubConfigCustomization(name: String): ConfigCustomization {
|
||||||
* */
|
* */
|
||||||
@Suppress("NAME_SHADOWING")
|
@Suppress("NAME_SHADOWING")
|
||||||
fun validateConfigCustomizations(
|
fun validateConfigCustomizations(
|
||||||
|
codegenContext: ClientCodegenContext,
|
||||||
customization: ConfigCustomization,
|
customization: ConfigCustomization,
|
||||||
project: TestWriterDelegator? = null,
|
project: TestWriterDelegator? = null,
|
||||||
): TestWriterDelegator {
|
): TestWriterDelegator {
|
||||||
val project = project ?: TestWorkspace.testProject()
|
val project = project ?: TestWorkspace.testProject()
|
||||||
stubConfigProject(customization, project)
|
stubConfigProject(codegenContext, customization, project)
|
||||||
project.compileAndTest()
|
project.compileAndTest()
|
||||||
return project
|
return project
|
||||||
}
|
}
|
||||||
|
|
||||||
fun stubConfigProject(customization: ConfigCustomization, project: TestWriterDelegator): TestWriterDelegator {
|
fun stubConfigProject(codegenContext: ClientCodegenContext, customization: ConfigCustomization, project: TestWriterDelegator): TestWriterDelegator {
|
||||||
val customizations = listOf(stubConfigCustomization("a")) + customization + stubConfigCustomization("b")
|
val customizations = listOf(stubConfigCustomization("a", codegenContext)) + customization + stubConfigCustomization("b", codegenContext)
|
||||||
val generator = ServiceConfigGenerator(testClientCodegenContext("namespace test".asSmithyModel()), customizations = customizations.toList())
|
val generator = ServiceConfigGenerator(codegenContext, customizations = customizations.toList())
|
||||||
project.withModule(ClientRustModule.Config) {
|
project.withModule(ClientRustModule.Config) {
|
||||||
generator.render(this)
|
generator.render(this)
|
||||||
unitTest(
|
unitTest(
|
||||||
|
|
|
@ -15,6 +15,7 @@ import software.amazon.smithy.rust.codegen.client.smithy.ClientCodegenContext
|
||||||
import software.amazon.smithy.rust.codegen.client.smithy.ClientModuleProvider
|
import software.amazon.smithy.rust.codegen.client.smithy.ClientModuleProvider
|
||||||
import software.amazon.smithy.rust.codegen.client.smithy.ClientRustSettings
|
import software.amazon.smithy.rust.codegen.client.smithy.ClientRustSettings
|
||||||
import software.amazon.smithy.rust.codegen.client.smithy.RustClientCodegenPlugin
|
import software.amazon.smithy.rust.codegen.client.smithy.RustClientCodegenPlugin
|
||||||
|
import software.amazon.smithy.rust.codegen.client.smithy.SmithyRuntimeMode
|
||||||
import software.amazon.smithy.rust.codegen.client.smithy.customize.ClientCodegenDecorator
|
import software.amazon.smithy.rust.codegen.client.smithy.customize.ClientCodegenDecorator
|
||||||
import software.amazon.smithy.rust.codegen.client.smithy.customize.CombinedClientCodegenDecorator
|
import software.amazon.smithy.rust.codegen.client.smithy.customize.CombinedClientCodegenDecorator
|
||||||
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeConfig
|
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeConfig
|
||||||
|
@ -90,6 +91,9 @@ fun testClientCodegenContext(
|
||||||
rootDecorator ?: CombinedClientCodegenDecorator(emptyList()),
|
rootDecorator ?: CombinedClientCodegenDecorator(emptyList()),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
fun ClientCodegenContext.withSmithyRuntimeMode(smithyRuntimeMode: SmithyRuntimeMode): ClientCodegenContext =
|
||||||
|
copy(settings = settings.copy(codegenConfig = settings.codegenConfig.copy(enableNewSmithyRuntime = smithyRuntimeMode)))
|
||||||
|
|
||||||
fun TestWriterDelegator.clientRustSettings() =
|
fun TestWriterDelegator.clientRustSettings() =
|
||||||
testClientRustSettings(
|
testClientRustSettings(
|
||||||
service = ShapeId.from("fake#Fake"),
|
service = ShapeId.from("fake#Fake"),
|
||||||
|
|
|
@ -39,7 +39,7 @@ internal class ResiliencyConfigCustomizationTest {
|
||||||
val project = TestWorkspace.testProject(model, ClientCodegenConfig())
|
val project = TestWorkspace.testProject(model, ClientCodegenConfig())
|
||||||
val codegenContext = testClientCodegenContext(model, settings = project.clientRustSettings())
|
val codegenContext = testClientCodegenContext(model, settings = project.clientRustSettings())
|
||||||
|
|
||||||
stubConfigProject(ResiliencyConfigCustomization(codegenContext), project)
|
stubConfigProject(codegenContext, ResiliencyConfigCustomization(codegenContext), project)
|
||||||
ResiliencyReExportCustomization(codegenContext.runtimeConfig).extras(project)
|
ResiliencyReExportCustomization(codegenContext.runtimeConfig).extras(project)
|
||||||
project.compileAndTest()
|
project.compileAndTest()
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,9 +5,12 @@
|
||||||
|
|
||||||
package software.amazon.smithy.rust.codegen.client.smithy.endpoint
|
package software.amazon.smithy.rust.codegen.client.smithy.endpoint
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.params.ParameterizedTest
|
||||||
|
import org.junit.jupiter.params.provider.ValueSource
|
||||||
|
import software.amazon.smithy.rust.codegen.client.smithy.SmithyRuntimeMode
|
||||||
import software.amazon.smithy.rust.codegen.client.testutil.testClientCodegenContext
|
import software.amazon.smithy.rust.codegen.client.testutil.testClientCodegenContext
|
||||||
import software.amazon.smithy.rust.codegen.client.testutil.validateConfigCustomizations
|
import software.amazon.smithy.rust.codegen.client.testutil.validateConfigCustomizations
|
||||||
|
import software.amazon.smithy.rust.codegen.client.testutil.withSmithyRuntimeMode
|
||||||
import software.amazon.smithy.rust.codegen.core.rustlang.rust
|
import software.amazon.smithy.rust.codegen.core.rustlang.rust
|
||||||
import software.amazon.smithy.rust.codegen.core.testutil.TestWorkspace
|
import software.amazon.smithy.rust.codegen.core.testutil.TestWorkspace
|
||||||
import software.amazon.smithy.rust.codegen.core.testutil.asSmithyModel
|
import software.amazon.smithy.rust.codegen.core.testutil.asSmithyModel
|
||||||
|
@ -29,28 +32,51 @@ class ClientContextConfigCustomizationTest {
|
||||||
service TestService { operations: [] }
|
service TestService { operations: [] }
|
||||||
""".asSmithyModel()
|
""".asSmithyModel()
|
||||||
|
|
||||||
@Test
|
@ParameterizedTest
|
||||||
fun `client params generate a valid customization`() {
|
@ValueSource(strings = ["middleware", "orchestrator"])
|
||||||
|
fun `client params generate a valid customization`(smithyRuntimeModeStr: String) {
|
||||||
val project = TestWorkspace.testProject()
|
val project = TestWorkspace.testProject()
|
||||||
|
val smithyRuntimeMode = SmithyRuntimeMode.fromString(smithyRuntimeModeStr)
|
||||||
project.unitTest {
|
project.unitTest {
|
||||||
rust(
|
if (smithyRuntimeMode.defaultToOrchestrator) {
|
||||||
"""
|
rust(
|
||||||
let conf = crate::Config::builder().a_string_param("hello!").a_bool_param(true).build();
|
"""
|
||||||
assert_eq!(conf.a_string_param.unwrap(), "hello!");
|
let conf = crate::Config::builder().a_string_param("hello!").a_bool_param(true).build();
|
||||||
assert_eq!(conf.a_bool_param, Some(true));
|
assert_eq!(conf.a_string_param().unwrap(), "hello!");
|
||||||
""",
|
assert_eq!(conf.a_bool_param(), Some(true));
|
||||||
)
|
""",
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
rust(
|
||||||
|
"""
|
||||||
|
let conf = crate::Config::builder().a_string_param("hello!").a_bool_param(true).build();
|
||||||
|
assert_eq!(conf.a_string_param.unwrap(), "hello!");
|
||||||
|
assert_eq!(conf.a_bool_param, Some(true));
|
||||||
|
""",
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// unset fields
|
// unset fields
|
||||||
project.unitTest {
|
project.unitTest {
|
||||||
rust(
|
if (smithyRuntimeMode.defaultToOrchestrator) {
|
||||||
"""
|
rust(
|
||||||
let conf = crate::Config::builder().a_string_param("hello!").build();
|
"""
|
||||||
assert_eq!(conf.a_string_param.unwrap(), "hello!");
|
let conf = crate::Config::builder().a_string_param("hello!").build();
|
||||||
assert_eq!(conf.a_bool_param, None);
|
assert_eq!(conf.a_string_param().unwrap(), "hello!");
|
||||||
""",
|
assert_eq!(conf.a_bool_param(), None);
|
||||||
)
|
""",
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
rust(
|
||||||
|
"""
|
||||||
|
let conf = crate::Config::builder().a_string_param("hello!").build();
|
||||||
|
assert_eq!(conf.a_string_param.unwrap(), "hello!");
|
||||||
|
assert_eq!(conf.a_bool_param, None);
|
||||||
|
""",
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
validateConfigCustomizations(ClientContextConfigCustomization(testClientCodegenContext(model)), project)
|
val context = testClientCodegenContext(model).withSmithyRuntimeMode(smithyRuntimeMode)
|
||||||
|
validateConfigCustomizations(context, ClientContextConfigCustomization(context), project)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,12 +5,24 @@
|
||||||
|
|
||||||
package software.amazon.smithy.rust.codegen.client.smithy.generators.config
|
package software.amazon.smithy.rust.codegen.client.smithy.generators.config
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.params.ParameterizedTest
|
||||||
|
import org.junit.jupiter.params.provider.ValueSource
|
||||||
|
import software.amazon.smithy.rust.codegen.client.smithy.SmithyRuntimeMode
|
||||||
|
import software.amazon.smithy.rust.codegen.client.testutil.testClientCodegenContext
|
||||||
import software.amazon.smithy.rust.codegen.client.testutil.validateConfigCustomizations
|
import software.amazon.smithy.rust.codegen.client.testutil.validateConfigCustomizations
|
||||||
|
import software.amazon.smithy.rust.codegen.client.testutil.withSmithyRuntimeMode
|
||||||
|
import software.amazon.smithy.rust.codegen.core.testutil.asSmithyModel
|
||||||
|
|
||||||
class IdempotencyTokenProviderCustomizationTest {
|
class IdempotencyTokenProviderCustomizationTest {
|
||||||
@Test
|
@ParameterizedTest
|
||||||
fun `generates a valid config`() {
|
@ValueSource(strings = ["middleware", "orchestrator"])
|
||||||
validateConfigCustomizations(IdempotencyTokenProviderCustomization())
|
fun `generates a valid config`(smithyRuntimeModeStr: String) {
|
||||||
|
val smithyRuntimeMode = SmithyRuntimeMode.fromString(smithyRuntimeModeStr)
|
||||||
|
val model = "namespace test".asSmithyModel()
|
||||||
|
val codegenContext = testClientCodegenContext(model).withSmithyRuntimeMode(smithyRuntimeMode)
|
||||||
|
validateConfigCustomizations(
|
||||||
|
codegenContext,
|
||||||
|
IdempotencyTokenProviderCustomization(codegenContext),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,18 +7,26 @@ package software.amazon.smithy.rust.codegen.client.smithy.generators.config
|
||||||
|
|
||||||
import io.kotest.matchers.shouldBe
|
import io.kotest.matchers.shouldBe
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
|
import org.junit.jupiter.params.ParameterizedTest
|
||||||
|
import org.junit.jupiter.params.provider.ValueSource
|
||||||
import software.amazon.smithy.model.shapes.ServiceShape
|
import software.amazon.smithy.model.shapes.ServiceShape
|
||||||
|
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.ClientRustModule
|
||||||
|
import software.amazon.smithy.rust.codegen.client.smithy.SmithyRuntimeMode
|
||||||
import software.amazon.smithy.rust.codegen.client.testutil.testClientCodegenContext
|
import software.amazon.smithy.rust.codegen.client.testutil.testClientCodegenContext
|
||||||
|
import software.amazon.smithy.rust.codegen.client.testutil.withSmithyRuntimeMode
|
||||||
import software.amazon.smithy.rust.codegen.core.rustlang.Writable
|
import software.amazon.smithy.rust.codegen.core.rustlang.Writable
|
||||||
import software.amazon.smithy.rust.codegen.core.rustlang.rust
|
import software.amazon.smithy.rust.codegen.core.rustlang.rust
|
||||||
|
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.rustlang.writable
|
||||||
|
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeType
|
||||||
import software.amazon.smithy.rust.codegen.core.smithy.customize.NamedCustomization
|
import software.amazon.smithy.rust.codegen.core.smithy.customize.NamedCustomization
|
||||||
import software.amazon.smithy.rust.codegen.core.testutil.TestWorkspace
|
import software.amazon.smithy.rust.codegen.core.testutil.TestWorkspace
|
||||||
import software.amazon.smithy.rust.codegen.core.testutil.asSmithyModel
|
import software.amazon.smithy.rust.codegen.core.testutil.asSmithyModel
|
||||||
import software.amazon.smithy.rust.codegen.core.testutil.compileAndTest
|
import software.amazon.smithy.rust.codegen.core.testutil.compileAndTest
|
||||||
import software.amazon.smithy.rust.codegen.core.testutil.unitTest
|
import software.amazon.smithy.rust.codegen.core.testutil.unitTest
|
||||||
import software.amazon.smithy.rust.codegen.core.util.lookup
|
import software.amazon.smithy.rust.codegen.core.util.lookup
|
||||||
|
import software.amazon.smithy.rust.codegen.core.util.toPascalCase
|
||||||
|
|
||||||
internal class ServiceConfigGeneratorTest {
|
internal class ServiceConfigGeneratorTest {
|
||||||
@Test
|
@Test
|
||||||
|
@ -76,46 +84,98 @@ internal class ServiceConfigGeneratorTest {
|
||||||
model.lookup<ServiceShape>("com.example#ResourceService").needsIdempotencyToken(model) shouldBe true
|
model.lookup<ServiceShape>("com.example#ResourceService").needsIdempotencyToken(model) shouldBe true
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@ParameterizedTest
|
||||||
fun `generate customizations as specified`() {
|
@ValueSource(strings = ["middleware", "orchestrator"])
|
||||||
class ServiceCustomizer : NamedCustomization<ServiceConfig>() {
|
fun `generate customizations as specified`(smithyRuntimeModeStr: String) {
|
||||||
|
class ServiceCustomizer(private val codegenContext: ClientCodegenContext) :
|
||||||
|
NamedCustomization<ServiceConfig>() {
|
||||||
|
private val runtimeMode = codegenContext.smithyRuntimeMode
|
||||||
|
|
||||||
override fun section(section: ServiceConfig): Writable {
|
override fun section(section: ServiceConfig): Writable {
|
||||||
return when (section) {
|
return when (section) {
|
||||||
ServiceConfig.ConfigStructAdditionalDocs -> emptySection
|
ServiceConfig.ConfigStructAdditionalDocs -> emptySection
|
||||||
ServiceConfig.ConfigStruct -> writable { rust("config_field: u64,") }
|
ServiceConfig.ConfigStruct -> writable {
|
||||||
ServiceConfig.ConfigImpl -> writable {
|
if (runtimeMode.defaultToMiddleware) {
|
||||||
rust(
|
rust("config_field: u64,")
|
||||||
"""
|
}
|
||||||
pub fn config_field(&self) -> u64 {
|
|
||||||
self.config_field
|
|
||||||
}
|
|
||||||
""",
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ServiceConfig.ConfigImpl -> writable {
|
||||||
|
if (runtimeMode.defaultToOrchestrator) {
|
||||||
|
rustTemplate(
|
||||||
|
"""
|
||||||
|
##[allow(missing_docs)]
|
||||||
|
pub fn config_field(&self) -> u64 {
|
||||||
|
self.inner.load::<#{T}>().map(|u| u.0).unwrap()
|
||||||
|
}
|
||||||
|
""",
|
||||||
|
"T" to configParamNewtype(
|
||||||
|
"config_field".toPascalCase(), RuntimeType.U64.toSymbol(),
|
||||||
|
codegenContext.runtimeConfig,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
rust(
|
||||||
|
"""
|
||||||
|
##[allow(missing_docs)]
|
||||||
|
pub fn config_field(&self) -> u64 {
|
||||||
|
self.config_field
|
||||||
|
}
|
||||||
|
""",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ServiceConfig.BuilderStruct -> writable { rust("config_field: Option<u64>") }
|
ServiceConfig.BuilderStruct -> writable { rust("config_field: Option<u64>") }
|
||||||
ServiceConfig.BuilderImpl -> emptySection
|
ServiceConfig.BuilderImpl -> emptySection
|
||||||
ServiceConfig.BuilderBuild -> writable {
|
ServiceConfig.BuilderBuild -> writable {
|
||||||
rust("config_field: self.config_field.unwrap_or_default(),")
|
if (runtimeMode.defaultToOrchestrator) {
|
||||||
|
rustTemplate(
|
||||||
|
"layer.store_or_unset(self.config_field.map(#{T}));",
|
||||||
|
"T" to configParamNewtype(
|
||||||
|
"config_field".toPascalCase(), RuntimeType.U64.toSymbol(),
|
||||||
|
codegenContext.runtimeConfig,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
rust("config_field: self.config_field.unwrap_or_default(),")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> emptySection
|
else -> emptySection
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val ctx = testClientCodegenContext()
|
|
||||||
val sut = ServiceConfigGenerator(ctx, listOf(ServiceCustomizer()))
|
val model = "namespace empty".asSmithyModel()
|
||||||
val symbolProvider = ctx.symbolProvider
|
val smithyRuntimeMode = SmithyRuntimeMode.fromString(smithyRuntimeModeStr)
|
||||||
|
val codegenContext = testClientCodegenContext(model).withSmithyRuntimeMode(smithyRuntimeMode)
|
||||||
|
val sut = ServiceConfigGenerator(codegenContext, listOf(ServiceCustomizer(codegenContext)))
|
||||||
|
val symbolProvider = codegenContext.symbolProvider
|
||||||
val project = TestWorkspace.testProject(symbolProvider)
|
val project = TestWorkspace.testProject(symbolProvider)
|
||||||
project.withModule(ClientRustModule.Config) {
|
project.withModule(ClientRustModule.Config) {
|
||||||
sut.render(this)
|
sut.render(this)
|
||||||
unitTest(
|
if (smithyRuntimeMode.defaultToOrchestrator) {
|
||||||
"set_config_fields",
|
unitTest(
|
||||||
"""
|
"set_config_fields",
|
||||||
let mut builder = Config::builder();
|
"""
|
||||||
builder.config_field = Some(99);
|
let mut builder = Config::builder();
|
||||||
let config = builder.build();
|
builder.config_field = Some(99);
|
||||||
assert_eq!(config.config_field, 99);
|
let config = builder.build();
|
||||||
""",
|
assert_eq!(config.config_field(), 99);
|
||||||
)
|
""",
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
unitTest(
|
||||||
|
"set_config_fields",
|
||||||
|
"""
|
||||||
|
let mut builder = Config::builder();
|
||||||
|
builder.config_field = Some(99);
|
||||||
|
let config = builder.build();
|
||||||
|
assert_eq!(config.config_field, 99);
|
||||||
|
""",
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
project.compileAndTest()
|
project.compileAndTest()
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,8 +104,12 @@ class InlineDependency(
|
||||||
CargoDependency.Http,
|
CargoDependency.Http,
|
||||||
)
|
)
|
||||||
|
|
||||||
fun idempotencyToken() =
|
fun idempotencyToken(runtimeConfig: RuntimeConfig) =
|
||||||
forInlineableRustFile("idempotency_token", CargoDependency.FastRand)
|
forInlineableRustFile(
|
||||||
|
"idempotency_token",
|
||||||
|
CargoDependency.FastRand,
|
||||||
|
CargoDependency.smithyTypes(runtimeConfig),
|
||||||
|
)
|
||||||
|
|
||||||
fun ec2QueryErrors(runtimeConfig: RuntimeConfig): InlineDependency =
|
fun ec2QueryErrors(runtimeConfig: RuntimeConfig): InlineDependency =
|
||||||
forInlineableRustFile("ec2_query_errors", CargoDependency.smithyXml(runtimeConfig))
|
forInlineableRustFile("ec2_query_errors", CargoDependency.smithyXml(runtimeConfig))
|
||||||
|
@ -232,7 +236,8 @@ data class CargoDependency(
|
||||||
val AsyncStream: CargoDependency = CargoDependency("async-stream", CratesIo("0.3.0"), DependencyScope.Dev)
|
val AsyncStream: CargoDependency = CargoDependency("async-stream", CratesIo("0.3.0"), DependencyScope.Dev)
|
||||||
val Criterion: CargoDependency = CargoDependency("criterion", CratesIo("0.4.0"), DependencyScope.Dev)
|
val Criterion: CargoDependency = CargoDependency("criterion", CratesIo("0.4.0"), DependencyScope.Dev)
|
||||||
val FuturesCore: CargoDependency = CargoDependency("futures-core", CratesIo("0.3.25"), DependencyScope.Dev)
|
val FuturesCore: CargoDependency = CargoDependency("futures-core", CratesIo("0.3.25"), DependencyScope.Dev)
|
||||||
val FuturesUtil: CargoDependency = CargoDependency("futures-util", CratesIo("0.3.25"), DependencyScope.Dev, defaultFeatures = false)
|
val FuturesUtil: CargoDependency =
|
||||||
|
CargoDependency("futures-util", CratesIo("0.3.25"), DependencyScope.Dev, defaultFeatures = false)
|
||||||
val HdrHistogram: CargoDependency = CargoDependency("hdrhistogram", CratesIo("7.5.2"), DependencyScope.Dev)
|
val HdrHistogram: CargoDependency = CargoDependency("hdrhistogram", CratesIo("7.5.2"), DependencyScope.Dev)
|
||||||
val Hound: CargoDependency = CargoDependency("hound", CratesIo("3.4.0"), DependencyScope.Dev)
|
val Hound: CargoDependency = CargoDependency("hound", CratesIo("3.4.0"), DependencyScope.Dev)
|
||||||
val PrettyAssertions: CargoDependency =
|
val PrettyAssertions: CargoDependency =
|
||||||
|
|
|
@ -274,6 +274,7 @@ data class RuntimeType(val path: String, val dependency: RustDependency? = null)
|
||||||
val String = std.resolve("string::String")
|
val String = std.resolve("string::String")
|
||||||
val Sync = std.resolve("marker::Sync")
|
val Sync = std.resolve("marker::Sync")
|
||||||
val TryFrom = stdConvert.resolve("TryFrom")
|
val TryFrom = stdConvert.resolve("TryFrom")
|
||||||
|
val U64 = std.resolve("primitive::u64")
|
||||||
val Vec = std.resolve("vec::Vec")
|
val Vec = std.resolve("vec::Vec")
|
||||||
|
|
||||||
// external cargo dependency types
|
// external cargo dependency types
|
||||||
|
@ -431,7 +432,8 @@ data class RuntimeType(val path: String, val dependency: RustDependency? = null)
|
||||||
fun unwrappedXmlErrors(runtimeConfig: RuntimeConfig) =
|
fun unwrappedXmlErrors(runtimeConfig: RuntimeConfig) =
|
||||||
forInlineDependency(InlineDependency.unwrappedXmlErrors(runtimeConfig))
|
forInlineDependency(InlineDependency.unwrappedXmlErrors(runtimeConfig))
|
||||||
|
|
||||||
val IdempotencyToken by lazy { forInlineDependency(InlineDependency.idempotencyToken()) }
|
fun idempotencyToken(runtimeConfig: RuntimeConfig) =
|
||||||
|
forInlineDependency(InlineDependency.idempotencyToken(runtimeConfig))
|
||||||
|
|
||||||
fun runtimePlugin(runtimeConfig: RuntimeConfig) =
|
fun runtimePlugin(runtimeConfig: RuntimeConfig) =
|
||||||
RuntimeType.smithyRuntimeApi(runtimeConfig).resolve("client::runtime_plugin::RuntimePlugin")
|
RuntimeType.smithyRuntimeApi(runtimeConfig).resolve("client::runtime_plugin::RuntimePlugin")
|
||||||
|
|
|
@ -10,6 +10,7 @@ import io.kotest.matchers.shouldBe
|
||||||
import io.kotest.matchers.shouldNotBe
|
import io.kotest.matchers.shouldNotBe
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeType
|
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeType
|
||||||
|
import software.amazon.smithy.rust.codegen.core.testutil.TestRuntimeConfig
|
||||||
import software.amazon.smithy.rust.codegen.core.testutil.TestWorkspace
|
import software.amazon.smithy.rust.codegen.core.testutil.TestWorkspace
|
||||||
import software.amazon.smithy.rust.codegen.core.testutil.compileAndTest
|
import software.amazon.smithy.rust.codegen.core.testutil.compileAndTest
|
||||||
import software.amazon.smithy.rust.codegen.core.testutil.unitTest
|
import software.amazon.smithy.rust.codegen.core.testutil.unitTest
|
||||||
|
@ -32,20 +33,23 @@ internal class InlineDependencyTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `locate dependencies from the inlineable module`() {
|
fun `locate dependencies from the inlineable module`() {
|
||||||
val dep = InlineDependency.idempotencyToken()
|
val runtimeConfig = TestRuntimeConfig
|
||||||
|
val dep = InlineDependency.serializationSettings(runtimeConfig)
|
||||||
val testProject = TestWorkspace.testProject()
|
val testProject = TestWorkspace.testProject()
|
||||||
testProject.lib {
|
testProject.lib {
|
||||||
rustTemplate(
|
rustTemplate(
|
||||||
"""
|
"""
|
||||||
|
|
||||||
##[test]
|
##[test]
|
||||||
fn idempotency_works() {
|
fn header_serialization_settings_can_be_constructed() {
|
||||||
use #{idempotency}::uuid_v4;
|
use #{serialization_settings}::HeaderSerializationSettings;
|
||||||
let res = uuid_v4(0);
|
use #{aws_smithy_http}::header::set_request_header_if_absent;
|
||||||
assert_eq!(res, "00000000-0000-4000-8000-000000000000");
|
let _settings = HeaderSerializationSettings::default();
|
||||||
}
|
}
|
||||||
|
|
||||||
""",
|
""",
|
||||||
"idempotency" to dep.toType(),
|
"serialization_settings" to dep.toType(),
|
||||||
|
"aws_smithy_http" to RuntimeType.smithyHttp(runtimeConfig),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
testProject.compileAndTest()
|
testProject.compileAndTest()
|
||||||
|
|
|
@ -12,6 +12,7 @@ rt-tokio = ["tokio/time"]
|
||||||
test-util = []
|
test-util = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
aws-smithy-types = { path = "../aws-smithy-types" }
|
||||||
pin-project-lite = "0.2"
|
pin-project-lite = "0.2"
|
||||||
tokio = { version = "1.23.1", features = ["sync"] }
|
tokio = { version = "1.23.1", features = ["sync"] }
|
||||||
tokio-stream = { version = "0.1.5", default-features = false }
|
tokio-stream = { version = "0.1.5", default-features = false }
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
allowed_external_types = [
|
allowed_external_types = [
|
||||||
|
"aws_smithy_types::config_bag::storable::Storable",
|
||||||
|
"aws_smithy_types::config_bag::storable::StoreReplace",
|
||||||
|
"aws_smithy_types::config_bag::storable::Storer",
|
||||||
|
|
||||||
# TODO(https://github.com/awslabs/smithy-rs/issues/1193): Switch to AsyncIterator once standardized
|
# TODO(https://github.com/awslabs/smithy-rs/issues/1193): Switch to AsyncIterator once standardized
|
||||||
"futures_core::stream::Stream",
|
"futures_core::stream::Stream",
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
//! Provides an [`AsyncSleep`] trait that returns a future that sleeps for a given duration,
|
//! Provides an [`AsyncSleep`] trait that returns a future that sleeps for a given duration,
|
||||||
//! and implementations of `AsyncSleep` for different async runtimes.
|
//! and implementations of `AsyncSleep` for different async runtimes.
|
||||||
|
|
||||||
|
use aws_smithy_types::config_bag::{Storable, StoreReplace};
|
||||||
use std::fmt::{Debug, Formatter};
|
use std::fmt::{Debug, Formatter};
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
|
@ -68,6 +69,10 @@ impl AsyncSleep for SharedAsyncSleep {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Storable for SharedAsyncSleep {
|
||||||
|
type Storer = StoreReplace<SharedAsyncSleep>;
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "rt-tokio")]
|
#[cfg(feature = "rt-tokio")]
|
||||||
/// Returns a default sleep implementation based on the features enabled
|
/// Returns a default sleep implementation based on the features enabled
|
||||||
pub fn default_async_sleep() -> Option<SharedAsyncSleep> {
|
pub fn default_async_sleep() -> Option<SharedAsyncSleep> {
|
||||||
|
|
|
@ -24,7 +24,7 @@ pub struct ManualTimeSource {
|
||||||
|
|
||||||
impl TimeSource for ManualTimeSource {
|
impl TimeSource for ManualTimeSource {
|
||||||
fn now(&self) -> SystemTime {
|
fn now(&self) -> SystemTime {
|
||||||
self.start_time + self.log.lock().unwrap().iter().sum()
|
self.start_time + self.log.lock().unwrap().iter().sum::<Duration>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//! Time source abstraction to support WASM and testing
|
//! Time source abstraction to support WASM and testing
|
||||||
|
use aws_smithy_types::config_bag::{Storable, StoreReplace};
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::SystemTime;
|
use std::time::SystemTime;
|
||||||
|
@ -86,3 +87,7 @@ impl TimeSource for SharedTimeSource {
|
||||||
self.0.now()
|
self.0.now()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Storable for SharedTimeSource {
|
||||||
|
type Storer = StoreReplace<SharedTimeSource>;
|
||||||
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
use crate::erase::DynConnector;
|
use crate::erase::DynConnector;
|
||||||
use aws_smithy_async::rt::sleep::SharedAsyncSleep;
|
use aws_smithy_async::rt::sleep::SharedAsyncSleep;
|
||||||
|
use aws_smithy_types::config_bag::{Storable, StoreReplace};
|
||||||
use aws_smithy_types::timeout::TimeoutConfig;
|
use aws_smithy_types::timeout::TimeoutConfig;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use std::{fmt::Debug, sync::Arc};
|
use std::{fmt::Debug, sync::Arc};
|
||||||
|
@ -41,6 +42,10 @@ impl Debug for HttpConnector {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Storable for HttpConnector {
|
||||||
|
type Storer = StoreReplace<HttpConnector>;
|
||||||
|
}
|
||||||
|
|
||||||
impl HttpConnector {
|
impl HttpConnector {
|
||||||
/// If `HttpConnector` is `Prebuilt`, return a clone of that connector.
|
/// If `HttpConnector` is `Prebuilt`, return a clone of that connector.
|
||||||
/// If `HttpConnector` is `ConnectorFn`, generate a new connector from settings and return it.
|
/// If `HttpConnector` is `ConnectorFn`, generate a new connector from settings and return it.
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
use crate::endpoint::error::InvalidEndpointError;
|
use crate::endpoint::error::InvalidEndpointError;
|
||||||
use crate::operation::error::BuildError;
|
use crate::operation::error::BuildError;
|
||||||
|
use aws_smithy_types::config_bag::{Storable, StoreReplace};
|
||||||
use http::uri::{Authority, Uri};
|
use http::uri::{Authority, Uri};
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::fmt::{Debug, Formatter};
|
use std::fmt::{Debug, Formatter};
|
||||||
|
@ -66,6 +67,10 @@ impl<T> From<Arc<dyn ResolveEndpoint<T>>> for SharedEndpointResolver<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T: 'static> Storable for SharedEndpointResolver<T> {
|
||||||
|
type Storer = StoreReplace<SharedEndpointResolver<T>>;
|
||||||
|
}
|
||||||
|
|
||||||
impl<T> ResolveEndpoint<T> for SharedEndpointResolver<T> {
|
impl<T> ResolveEndpoint<T> for SharedEndpointResolver<T> {
|
||||||
fn resolve_endpoint(&self, params: &T) -> Result {
|
fn resolve_endpoint(&self, params: &T) -> Result {
|
||||||
self.0.resolve_endpoint(params)
|
self.0.resolve_endpoint(params)
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
use crate::client::auth::AuthSchemeId;
|
use crate::client::auth::AuthSchemeId;
|
||||||
use crate::client::orchestrator::Future;
|
use crate::client::orchestrator::Future;
|
||||||
use aws_smithy_types::config_bag::ConfigBag;
|
use aws_smithy_types::config_bag::{ConfigBag, Storable, StoreReplace};
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
@ -23,6 +23,10 @@ pub struct IdentityResolvers {
|
||||||
identity_resolvers: Vec<(AuthSchemeId, Arc<dyn IdentityResolver>)>,
|
identity_resolvers: Vec<(AuthSchemeId, Arc<dyn IdentityResolver>)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Storable for IdentityResolvers {
|
||||||
|
type Storer = StoreReplace<IdentityResolvers>;
|
||||||
|
}
|
||||||
|
|
||||||
impl IdentityResolvers {
|
impl IdentityResolvers {
|
||||||
pub fn builder() -> builders::IdentityResolversBuilder {
|
pub fn builder() -> builders::IdentityResolversBuilder {
|
||||||
builders::IdentityResolversBuilder::new()
|
builders::IdentityResolversBuilder::new()
|
||||||
|
|
|
@ -9,7 +9,7 @@ pub mod error;
|
||||||
use crate::client::interceptors::context::wrappers::{
|
use crate::client::interceptors::context::wrappers::{
|
||||||
FinalizerInterceptorContextMut, FinalizerInterceptorContextRef,
|
FinalizerInterceptorContextMut, FinalizerInterceptorContextRef,
|
||||||
};
|
};
|
||||||
use aws_smithy_types::config_bag::ConfigBag;
|
use aws_smithy_types::config_bag::{ConfigBag, Storable, StoreAppend};
|
||||||
use aws_smithy_types::error::display::DisplayErrorContext;
|
use aws_smithy_types::error::display::DisplayErrorContext;
|
||||||
pub use context::{
|
pub use context::{
|
||||||
wrappers::{
|
wrappers::{
|
||||||
|
@ -635,6 +635,10 @@ impl Deref for SharedInterceptor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Storable for SharedInterceptor {
|
||||||
|
type Storer = StoreAppend<SharedInterceptor>;
|
||||||
|
}
|
||||||
|
|
||||||
/// Collection of [`SharedInterceptor`] that allows for only registration
|
/// Collection of [`SharedInterceptor`] that allows for only registration
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone, Default)]
|
||||||
pub struct InterceptorRegistrar {
|
pub struct InterceptorRegistrar {
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
//! This module defines types that describe when to retry given a response.
|
//! This module defines types that describe when to retry given a response.
|
||||||
|
|
||||||
|
use crate::config_bag::{Storable, StoreReplace};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
@ -278,6 +279,10 @@ pub struct RetryConfig {
|
||||||
reconnect_mode: ReconnectMode,
|
reconnect_mode: ReconnectMode,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Storable for RetryConfig {
|
||||||
|
type Storer = StoreReplace<RetryConfig>;
|
||||||
|
}
|
||||||
|
|
||||||
/// Mode for connection re-establishment
|
/// Mode for connection re-establishment
|
||||||
///
|
///
|
||||||
/// By default, when a transient error is encountered, the connection in use will be poisoned. This
|
/// By default, when a transient error is encountered, the connection in use will be poisoned. This
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
//! This module defines types that describe timeouts that can be applied to various stages of the
|
//! This module defines types that describe timeouts that can be applied to various stages of the
|
||||||
//! Smithy networking stack.
|
//! Smithy networking stack.
|
||||||
|
|
||||||
|
use crate::config_bag::{Storable, StoreReplace};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
/// Builder for [`TimeoutConfig`].
|
/// Builder for [`TimeoutConfig`].
|
||||||
|
@ -208,6 +209,10 @@ pub struct TimeoutConfig {
|
||||||
operation_attempt_timeout: Option<Duration>,
|
operation_attempt_timeout: Option<Duration>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Storable for TimeoutConfig {
|
||||||
|
type Storer = StoreReplace<TimeoutConfig>;
|
||||||
|
}
|
||||||
|
|
||||||
impl TimeoutConfig {
|
impl TimeoutConfig {
|
||||||
/// Returns a builder to create a `TimeoutConfig`.
|
/// Returns a builder to create a `TimeoutConfig`.
|
||||||
pub fn builder() -> TimeoutConfigBuilder {
|
pub fn builder() -> TimeoutConfigBuilder {
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
use aws_smithy_types::config_bag::{Storable, StoreReplace};
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
|
|
||||||
pub(crate) fn uuid_v4(input: u128) -> String {
|
pub(crate) fn uuid_v4(input: u128) -> String {
|
||||||
|
@ -58,6 +59,10 @@ impl From<&'static str> for IdempotencyTokenProvider {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Storable for IdempotencyTokenProvider {
|
||||||
|
type Storer = StoreReplace<IdempotencyTokenProvider>;
|
||||||
|
}
|
||||||
|
|
||||||
impl IdempotencyTokenProvider {
|
impl IdempotencyTokenProvider {
|
||||||
pub fn make_idempotency_token(&self) -> String {
|
pub fn make_idempotency_token(&self) -> String {
|
||||||
match &self.inner {
|
match &self.inner {
|
||||||
|
|
Loading…
Reference in New Issue