mirror of https://github.com/smithy-lang/smithy-rs
update generic clients to support user-configurable runtime plugins (#2864)
_This PR also updates `pre-commit ktlint` runner. Now it won't spit out a bazillion debug logs when run_ ---- _By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice._
This commit is contained in:
parent
7875278a2b
commit
6aa585fa2d
|
@ -20,7 +20,7 @@ repos:
|
||||||
files: ^.*$
|
files: ^.*$
|
||||||
pass_filenames: false
|
pass_filenames: false
|
||||||
- repo: https://github.com/macisamuele/language-formatters-pre-commit-hooks
|
- repo: https://github.com/macisamuele/language-formatters-pre-commit-hooks
|
||||||
rev: v2.6.0
|
rev: v2.10.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: pretty-format-kotlin
|
- id: pretty-format-kotlin
|
||||||
args: [--autofix, --ktlint-version, 0.48.2]
|
args: [--autofix, --ktlint-version, 0.48.2]
|
||||||
|
|
|
@ -105,7 +105,8 @@ fun generateSmithyBuild(services: AwsServices): String {
|
||||||
"renameErrors": false,
|
"renameErrors": false,
|
||||||
"debugMode": $debugMode,
|
"debugMode": $debugMode,
|
||||||
"eventStreamAllowList": [$eventStreamAllowListMembers],
|
"eventStreamAllowList": [$eventStreamAllowListMembers],
|
||||||
"enableNewSmithyRuntime": "${getSmithyRuntimeMode()}"
|
"enableNewSmithyRuntime": "${getSmithyRuntimeMode()}",
|
||||||
|
"enableUserConfigurableRuntimePlugins": false
|
||||||
},
|
},
|
||||||
"service": "${service.service}",
|
"service": "${service.service}",
|
||||||
"module": "$moduleName",
|
"module": "$moduleName",
|
||||||
|
|
|
@ -36,4 +36,5 @@ data class ClientCodegenContext(
|
||||||
model, symbolProvider, moduleDocProvider, serviceShape, protocol, settings, CodegenTarget.CLIENT,
|
model, symbolProvider, moduleDocProvider, serviceShape, protocol, settings, CodegenTarget.CLIENT,
|
||||||
) {
|
) {
|
||||||
val smithyRuntimeMode: SmithyRuntimeMode get() = settings.codegenConfig.enableNewSmithyRuntime
|
val smithyRuntimeMode: SmithyRuntimeMode get() = settings.codegenConfig.enableNewSmithyRuntime
|
||||||
|
val enableUserConfigurableRuntimePlugins: Boolean get() = settings.codegenConfig.enableUserConfigurableRuntimePlugins
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,28 +74,28 @@ data class ClientRustSettings(
|
||||||
|
|
||||||
// TODO(enableNewSmithyRuntimeCleanup): Remove this mode after switching to the orchestrator
|
// TODO(enableNewSmithyRuntimeCleanup): Remove this mode after switching to the orchestrator
|
||||||
enum class SmithyRuntimeMode {
|
enum class SmithyRuntimeMode {
|
||||||
Middleware,
|
Middleware, BothDefaultMiddleware, BothDefaultOrchestrator, Orchestrator,
|
||||||
BothDefaultMiddleware,
|
|
||||||
BothDefaultOrchestrator,
|
|
||||||
Orchestrator,
|
|
||||||
;
|
;
|
||||||
|
|
||||||
val exclusivelyGenerateMiddleware: Boolean get() = generateMiddleware && !generateOrchestrator
|
val exclusivelyGenerateMiddleware: Boolean get() = generateMiddleware && !generateOrchestrator
|
||||||
|
|
||||||
val generateMiddleware: Boolean get() = when (this) {
|
val generateMiddleware: Boolean
|
||||||
Middleware, BothDefaultMiddleware, BothDefaultOrchestrator -> true
|
get() = when (this) {
|
||||||
else -> false
|
Middleware, BothDefaultMiddleware, BothDefaultOrchestrator -> true
|
||||||
}
|
else -> false
|
||||||
|
}
|
||||||
|
|
||||||
val generateOrchestrator: Boolean get() = when (this) {
|
val generateOrchestrator: Boolean
|
||||||
Orchestrator, BothDefaultMiddleware, BothDefaultOrchestrator -> true
|
get() = when (this) {
|
||||||
else -> false
|
Orchestrator, BothDefaultMiddleware, BothDefaultOrchestrator -> true
|
||||||
}
|
else -> false
|
||||||
|
}
|
||||||
|
|
||||||
val defaultToMiddleware: Boolean get() = when (this) {
|
val defaultToMiddleware: Boolean
|
||||||
Middleware, BothDefaultMiddleware -> true
|
get() = when (this) {
|
||||||
else -> false
|
Middleware, BothDefaultMiddleware -> true
|
||||||
}
|
else -> false
|
||||||
|
}
|
||||||
val defaultToOrchestrator: Boolean get() = !defaultToMiddleware
|
val defaultToOrchestrator: Boolean get() = !defaultToMiddleware
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
@ -127,6 +127,7 @@ data class ClientCodegenConfig(
|
||||||
val enableNewSmithyRuntime: SmithyRuntimeMode = defaultEnableNewSmithyRuntime,
|
val enableNewSmithyRuntime: SmithyRuntimeMode = defaultEnableNewSmithyRuntime,
|
||||||
/** If true, adds `endpoint_url`/`set_endpoint_url` methods to the service config */
|
/** If true, adds `endpoint_url`/`set_endpoint_url` methods to the service config */
|
||||||
val includeEndpointUrlConfig: Boolean = defaultIncludeEndpointUrlConfig,
|
val includeEndpointUrlConfig: Boolean = defaultIncludeEndpointUrlConfig,
|
||||||
|
val enableUserConfigurableRuntimePlugins: Boolean = defaultEnableUserConfigurableRuntimePlugins,
|
||||||
) : CoreCodegenConfig(
|
) : CoreCodegenConfig(
|
||||||
formatTimeoutSeconds, debugMode,
|
formatTimeoutSeconds, debugMode,
|
||||||
) {
|
) {
|
||||||
|
@ -137,25 +138,24 @@ data class ClientCodegenConfig(
|
||||||
private val defaultEventStreamAllowList: Set<String> = emptySet()
|
private val defaultEventStreamAllowList: Set<String> = emptySet()
|
||||||
private val defaultEnableNewSmithyRuntime = SmithyRuntimeMode.Orchestrator
|
private val defaultEnableNewSmithyRuntime = SmithyRuntimeMode.Orchestrator
|
||||||
private const val defaultIncludeEndpointUrlConfig = true
|
private const val defaultIncludeEndpointUrlConfig = true
|
||||||
|
private const val defaultEnableUserConfigurableRuntimePlugins = true
|
||||||
|
|
||||||
fun fromCodegenConfigAndNode(coreCodegenConfig: CoreCodegenConfig, node: Optional<ObjectNode>) =
|
fun fromCodegenConfigAndNode(coreCodegenConfig: CoreCodegenConfig, node: Optional<ObjectNode>) =
|
||||||
if (node.isPresent) {
|
if (node.isPresent) {
|
||||||
ClientCodegenConfig(
|
ClientCodegenConfig(
|
||||||
formatTimeoutSeconds = coreCodegenConfig.formatTimeoutSeconds,
|
formatTimeoutSeconds = coreCodegenConfig.formatTimeoutSeconds,
|
||||||
debugMode = coreCodegenConfig.debugMode,
|
debugMode = coreCodegenConfig.debugMode,
|
||||||
eventStreamAllowList = node.get().getArrayMember("eventStreamAllowList")
|
eventStreamAllowList = node.get().getArrayMember("eventStreamAllowList").map { array ->
|
||||||
.map { array -> array.toList().mapNotNull { node -> node.asStringNode().orNull()?.value } }
|
array.toList().mapNotNull { node ->
|
||||||
.orNull()?.toSet() ?: defaultEventStreamAllowList,
|
node.asStringNode().orNull()?.value
|
||||||
|
}
|
||||||
|
}.orNull()?.toSet() ?: defaultEventStreamAllowList,
|
||||||
renameExceptions = node.get().getBooleanMemberOrDefault("renameErrors", defaultRenameExceptions),
|
renameExceptions = node.get().getBooleanMemberOrDefault("renameErrors", defaultRenameExceptions),
|
||||||
includeFluentClient = node.get()
|
includeFluentClient = node.get().getBooleanMemberOrDefault("includeFluentClient", defaultIncludeFluentClient),
|
||||||
.getBooleanMemberOrDefault("includeFluentClient", defaultIncludeFluentClient),
|
addMessageToErrors = node.get().getBooleanMemberOrDefault("addMessageToErrors", defaultAddMessageToErrors),
|
||||||
addMessageToErrors = node.get()
|
enableNewSmithyRuntime = SmithyRuntimeMode.fromString(node.get().getStringMemberOrDefault("enableNewSmithyRuntime", "middleware")),
|
||||||
.getBooleanMemberOrDefault("addMessageToErrors", defaultAddMessageToErrors),
|
includeEndpointUrlConfig = node.get().getBooleanMemberOrDefault("includeEndpointUrlConfig", defaultIncludeEndpointUrlConfig),
|
||||||
enableNewSmithyRuntime = SmithyRuntimeMode.fromString(
|
enableUserConfigurableRuntimePlugins = node.get().getBooleanMemberOrDefault("userConfigurableRuntimePlugins", defaultEnableUserConfigurableRuntimePlugins),
|
||||||
node.get().getStringMemberOrDefault("enableNewSmithyRuntime", "middleware"),
|
|
||||||
),
|
|
||||||
includeEndpointUrlConfig = node.get()
|
|
||||||
.getBooleanMemberOrDefault("includeEndpointUrlConfig", defaultIncludeEndpointUrlConfig),
|
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
ClientCodegenConfig(
|
ClientCodegenConfig(
|
||||||
|
|
|
@ -34,6 +34,17 @@ class ClientRuntimeTypesReExportGenerator(
|
||||||
"Interceptor" to RuntimeType.interceptor(rc),
|
"Interceptor" to RuntimeType.interceptor(rc),
|
||||||
"SharedInterceptor" to RuntimeType.sharedInterceptor(rc),
|
"SharedInterceptor" to RuntimeType.sharedInterceptor(rc),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (codegenContext.enableUserConfigurableRuntimePlugins) {
|
||||||
|
rustTemplate(
|
||||||
|
"""
|
||||||
|
pub use #{runtime_plugin}::{RuntimePlugin, SharedRuntimePlugin};
|
||||||
|
pub use #{config_bag}::FrozenLayer;
|
||||||
|
""",
|
||||||
|
"runtime_plugin" to RuntimeType.smithyRuntimeApi(rc).resolve("client::runtime_plugin"),
|
||||||
|
"config_bag" to RuntimeType.smithyTypes(rc).resolve("config_bag"),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
rustCrate.withModule(ClientRustModule.endpoint(codegenContext)) {
|
rustCrate.withModule(ClientRustModule.endpoint(codegenContext)) {
|
||||||
rustTemplate(
|
rustTemplate(
|
||||||
|
|
|
@ -19,7 +19,6 @@ import software.amazon.smithy.rust.codegen.core.rustlang.RustWriter
|
||||||
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.docsOrFallback
|
import software.amazon.smithy.rust.codegen.core.rustlang.docsOrFallback
|
||||||
import software.amazon.smithy.rust.codegen.core.rustlang.raw
|
|
||||||
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.rustBlock
|
import software.amazon.smithy.rust.codegen.core.rustlang.rustBlock
|
||||||
import software.amazon.smithy.rust.codegen.core.rustlang.rustBlockTemplate
|
import software.amazon.smithy.rust.codegen.core.rustlang.rustBlockTemplate
|
||||||
|
@ -305,26 +304,29 @@ class ServiceConfigGenerator(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val smithyTypes = RuntimeType.smithyTypes(codegenContext.runtimeConfig)
|
private val moduleUseName = codegenContext.moduleUseName()
|
||||||
|
private val runtimeMode = codegenContext.smithyRuntimeMode
|
||||||
|
private val runtimeConfig = codegenContext.runtimeConfig
|
||||||
|
private val enableUserConfigurableRuntimePlugins = codegenContext.enableUserConfigurableRuntimePlugins
|
||||||
|
private val smithyTypes = RuntimeType.smithyTypes(runtimeConfig)
|
||||||
val codegenScope = arrayOf(
|
val codegenScope = arrayOf(
|
||||||
*preludeScope,
|
*preludeScope,
|
||||||
"BoxError" to RuntimeType.boxError(codegenContext.runtimeConfig),
|
"BoxError" to RuntimeType.boxError(runtimeConfig),
|
||||||
"CloneableLayer" to smithyTypes.resolve("config_bag::CloneableLayer"),
|
"CloneableLayer" to smithyTypes.resolve("config_bag::CloneableLayer"),
|
||||||
"ConfigBag" to RuntimeType.configBag(codegenContext.runtimeConfig),
|
"ConfigBag" to RuntimeType.configBag(runtimeConfig),
|
||||||
"ConfigBagAccessors" to RuntimeType.configBagAccessors(codegenContext.runtimeConfig),
|
"ConfigBagAccessors" to RuntimeType.configBagAccessors(runtimeConfig),
|
||||||
"Cow" to RuntimeType.Cow,
|
"Cow" to RuntimeType.Cow,
|
||||||
"FrozenLayer" to smithyTypes.resolve("config_bag::FrozenLayer"),
|
"FrozenLayer" to smithyTypes.resolve("config_bag::FrozenLayer"),
|
||||||
"Layer" to smithyTypes.resolve("config_bag::Layer"),
|
"Layer" to smithyTypes.resolve("config_bag::Layer"),
|
||||||
"Resolver" to RuntimeType.smithyRuntime(codegenContext.runtimeConfig).resolve("client::config_override::Resolver"),
|
"Resolver" to RuntimeType.smithyRuntime(runtimeConfig).resolve("client::config_override::Resolver"),
|
||||||
"RuntimeComponentsBuilder" to RuntimeType.runtimeComponentsBuilder(codegenContext.runtimeConfig),
|
"RuntimeComponentsBuilder" to RuntimeType.runtimeComponentsBuilder(runtimeConfig),
|
||||||
"RuntimePlugin" to RuntimeType.runtimePlugin(codegenContext.runtimeConfig),
|
"RuntimePlugin" to RuntimeType.runtimePlugin(runtimeConfig),
|
||||||
"SharedRuntimePlugin" to RuntimeType.sharedRuntimePlugin(codegenContext.runtimeConfig),
|
"SharedRuntimePlugin" to RuntimeType.sharedRuntimePlugin(runtimeConfig),
|
||||||
|
"runtime_plugin" to RuntimeType.smithyRuntimeApi(runtimeConfig).resolve("client::runtime_plugin"),
|
||||||
)
|
)
|
||||||
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("Configuration for a $moduleUseName service client.\n")
|
||||||
customizations.forEach {
|
customizations.forEach {
|
||||||
it.section(ServiceConfig.ConfigStructAdditionalDocs)(writer)
|
it.section(ServiceConfig.ConfigStructAdditionalDocs)(writer)
|
||||||
}
|
}
|
||||||
|
@ -394,9 +396,9 @@ class ServiceConfigGenerator(
|
||||||
|
|
||||||
writer.docs("Builder for creating a `Config`.")
|
writer.docs("Builder for creating a `Config`.")
|
||||||
if (runtimeMode.defaultToMiddleware) {
|
if (runtimeMode.defaultToMiddleware) {
|
||||||
writer.raw("#[derive(Clone, Default)]")
|
Attribute(Attribute.derive(RuntimeType.Clone, RuntimeType.Default)).render(writer)
|
||||||
} else {
|
} else {
|
||||||
writer.raw("#[derive(Clone, Debug)]")
|
Attribute(Attribute.derive(RuntimeType.Clone, RuntimeType.Debug)).render(writer)
|
||||||
}
|
}
|
||||||
writer.rustBlock("pub struct Builder") {
|
writer.rustBlock("pub struct Builder") {
|
||||||
if (runtimeMode.defaultToOrchestrator) {
|
if (runtimeMode.defaultToOrchestrator) {
|
||||||
|
@ -451,19 +453,25 @@ class ServiceConfigGenerator(
|
||||||
it.section(ServiceConfig.BuilderImpl)(this)
|
it.section(ServiceConfig.BuilderImpl)(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (runtimeMode.defaultToOrchestrator) {
|
if (runtimeMode.generateOrchestrator) {
|
||||||
|
val visibility = if (enableUserConfigurableRuntimePlugins) { "pub" } else { "pub(crate)" }
|
||||||
|
|
||||||
|
docs("Adds a runtime plugin to the config.")
|
||||||
|
if (!enableUserConfigurableRuntimePlugins) { Attribute.AllowUnused.render(this) }
|
||||||
rustTemplate(
|
rustTemplate(
|
||||||
"""
|
"""
|
||||||
/// Adds a runtime plugin to the config.
|
$visibility fn runtime_plugin(mut self, plugin: impl #{RuntimePlugin} + 'static) -> Self {
|
||||||
##[allow(unused)]
|
|
||||||
pub(crate) fn runtime_plugin(mut self, plugin: impl #{RuntimePlugin} + 'static) -> Self {
|
|
||||||
self.push_runtime_plugin(#{SharedRuntimePlugin}::new(plugin));
|
self.push_runtime_plugin(#{SharedRuntimePlugin}::new(plugin));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
""",
|
||||||
/// Adds a runtime plugin to the config.
|
*codegenScope,
|
||||||
##[allow(unused)]
|
)
|
||||||
pub(crate) fn push_runtime_plugin(&mut self, plugin: #{SharedRuntimePlugin}) -> &mut Self {
|
docs("Adds a runtime plugin to the config.")
|
||||||
|
if (!enableUserConfigurableRuntimePlugins) { Attribute.AllowUnused.render(this) }
|
||||||
|
rustTemplate(
|
||||||
|
"""
|
||||||
|
$visibility fn push_runtime_plugin(&mut self, plugin: #{SharedRuntimePlugin}) -> &mut Self {
|
||||||
self.runtime_plugins.push(plugin);
|
self.runtime_plugins.push(plugin);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
@ -528,6 +536,7 @@ class ServiceConfigGenerator(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customizations.forEach {
|
customizations.forEach {
|
||||||
it.section(ServiceConfig.Extras)(writer)
|
it.section(ServiceConfig.Extras)(writer)
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,6 +94,9 @@ fun testClientCodegenContext(
|
||||||
fun ClientCodegenContext.withSmithyRuntimeMode(smithyRuntimeMode: SmithyRuntimeMode): ClientCodegenContext =
|
fun ClientCodegenContext.withSmithyRuntimeMode(smithyRuntimeMode: SmithyRuntimeMode): ClientCodegenContext =
|
||||||
copy(settings = settings.copy(codegenConfig = settings.codegenConfig.copy(enableNewSmithyRuntime = smithyRuntimeMode)))
|
copy(settings = settings.copy(codegenConfig = settings.codegenConfig.copy(enableNewSmithyRuntime = smithyRuntimeMode)))
|
||||||
|
|
||||||
|
fun ClientCodegenContext.withEnableUserConfigurableRuntimePlugins(enableUserConfigurableRuntimePlugins: Boolean): ClientCodegenContext =
|
||||||
|
copy(settings = settings.copy(codegenConfig = settings.codegenConfig.copy(enableUserConfigurableRuntimePlugins = enableUserConfigurableRuntimePlugins)))
|
||||||
|
|
||||||
fun TestWriterDelegator.clientRustSettings() =
|
fun TestWriterDelegator.clientRustSettings() =
|
||||||
testClientRustSettings(
|
testClientRustSettings(
|
||||||
service = ShapeId.from("fake#Fake"),
|
service = ShapeId.from("fake#Fake"),
|
||||||
|
|
|
@ -14,6 +14,7 @@ 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.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.withEnableUserConfigurableRuntimePlugins
|
||||||
import software.amazon.smithy.rust.codegen.client.testutil.withSmithyRuntimeMode
|
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
|
||||||
|
@ -161,7 +162,9 @@ internal class ServiceConfigGeneratorTest {
|
||||||
|
|
||||||
val model = "namespace empty".asSmithyModel()
|
val model = "namespace empty".asSmithyModel()
|
||||||
val smithyRuntimeMode = SmithyRuntimeMode.fromString(smithyRuntimeModeStr)
|
val smithyRuntimeMode = SmithyRuntimeMode.fromString(smithyRuntimeModeStr)
|
||||||
val codegenContext = testClientCodegenContext(model).withSmithyRuntimeMode(smithyRuntimeMode)
|
val codegenContext = testClientCodegenContext(model)
|
||||||
|
.withSmithyRuntimeMode(smithyRuntimeMode)
|
||||||
|
.withEnableUserConfigurableRuntimePlugins(true)
|
||||||
val sut = ServiceConfigGenerator(codegenContext, listOf(ServiceCustomizer(codegenContext)))
|
val sut = ServiceConfigGenerator(codegenContext, listOf(ServiceCustomizer(codegenContext)))
|
||||||
val symbolProvider = codegenContext.symbolProvider
|
val symbolProvider = codegenContext.symbolProvider
|
||||||
val project = TestWorkspace.testProject(symbolProvider)
|
val project = TestWorkspace.testProject(symbolProvider)
|
||||||
|
@ -176,6 +179,28 @@ internal class ServiceConfigGeneratorTest {
|
||||||
assert_eq!(config.config_field(), 99);
|
assert_eq!(config.config_field(), 99);
|
||||||
""",
|
""",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
unitTest(
|
||||||
|
"set_runtime_plugin",
|
||||||
|
"""
|
||||||
|
use aws_smithy_runtime_api::client::runtime_plugin::RuntimePlugin;
|
||||||
|
use aws_smithy_types::config_bag::FrozenLayer;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct TestRuntimePlugin;
|
||||||
|
|
||||||
|
impl RuntimePlugin for TestRuntimePlugin {
|
||||||
|
fn config(&self) -> Option<FrozenLayer> {
|
||||||
|
todo!("ExampleRuntimePlugin.config")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let config = Config::builder()
|
||||||
|
.runtime_plugin(TestRuntimePlugin)
|
||||||
|
.build();
|
||||||
|
assert_eq!(config.runtime_plugins.len(), 1);
|
||||||
|
""",
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
unitTest(
|
unitTest(
|
||||||
"set_config_fields",
|
"set_config_fields",
|
||||||
|
|
|
@ -509,6 +509,7 @@ class Attribute(val inner: Writable, val isDeriveHelper: Boolean = false) {
|
||||||
val AllowNonSnakeCase = Attribute(allow("non_snake_case"))
|
val AllowNonSnakeCase = Attribute(allow("non_snake_case"))
|
||||||
val AllowUnreachableCode = Attribute(allow("unreachable_code"))
|
val AllowUnreachableCode = Attribute(allow("unreachable_code"))
|
||||||
val AllowUnreachablePatterns = Attribute(allow("unreachable_patterns"))
|
val AllowUnreachablePatterns = Attribute(allow("unreachable_patterns"))
|
||||||
|
val AllowUnused = Attribute(allow("unused"))
|
||||||
val AllowUnusedImports = Attribute(allow("unused_imports"))
|
val AllowUnusedImports = Attribute(allow("unused_imports"))
|
||||||
val AllowUnusedMut = Attribute(allow("unused_mut"))
|
val AllowUnusedMut = Attribute(allow("unused_mut"))
|
||||||
val AllowUnusedVariables = Attribute(allow("unused_variables"))
|
val AllowUnusedVariables = Attribute(allow("unused_variables"))
|
||||||
|
|
Loading…
Reference in New Issue