From 56ee9c52e9409e845e4a4a07697992cfca95f489 Mon Sep 17 00:00:00 2001 From: Russell Cohen Date: Fri, 13 Nov 2020 21:27:20 -0500 Subject: [PATCH] ProtocolConfig Refactoring (#25) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mostly mechanical refactoring to remove operation specific fields from ProtocolConfig—this allows protocol config to be used for an entire service rather than being recreated for each operation. --- .../rust/codegen/smithy/CodegenVisitor.kt | 23 +++++++-- .../generators/HttpProtocolGenerator.kt | 21 ++++---- .../generators/HttpProtocolTestGenerator.kt | 13 ++--- .../generators/HttpTraitBindingGenerator.kt | 14 ------ .../smithy/generators/ServiceGenerator.kt | 47 +++--------------- .../codegen/smithy/protocols/AwsJson10.kt | 24 ++++----- .../codegen/smithy/protocols/AwsRestJson.kt | 49 +++++++++---------- .../smithy/protocols/ProtocolLoader.kt | 38 ++++++++++++++ .../amazon/smithy/rust/codegen/util/Smithy.kt | 7 +++ .../HttpTraitBindingGeneratorTest.kt | 20 +++++--- .../HttpProtocolTestGeneratorTest.kt | 10 ++-- 11 files changed, 142 insertions(+), 124 deletions(-) create mode 100644 codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/protocols/ProtocolLoader.kt diff --git a/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/CodegenVisitor.kt b/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/CodegenVisitor.kt index cc3984a0c..2a1e4f1f6 100644 --- a/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/CodegenVisitor.kt +++ b/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/CodegenVisitor.kt @@ -21,10 +21,14 @@ import software.amazon.smithy.rust.codegen.lang.RustDependency import software.amazon.smithy.rust.codegen.lang.RustWriter import software.amazon.smithy.rust.codegen.smithy.generators.CargoTomlGenerator import software.amazon.smithy.rust.codegen.smithy.generators.EnumGenerator +import software.amazon.smithy.rust.codegen.smithy.generators.HttpProtocolGenerator import software.amazon.smithy.rust.codegen.smithy.generators.LibRsGenerator +import software.amazon.smithy.rust.codegen.smithy.generators.ProtocolConfig +import software.amazon.smithy.rust.codegen.smithy.generators.ProtocolGeneratorFactory import software.amazon.smithy.rust.codegen.smithy.generators.ServiceGenerator import software.amazon.smithy.rust.codegen.smithy.generators.StructureGenerator import software.amazon.smithy.rust.codegen.smithy.generators.UnionGenerator +import software.amazon.smithy.rust.codegen.smithy.protocols.ProtocolLoader import software.amazon.smithy.rust.codegen.smithy.transformers.OperationNormalizer import software.amazon.smithy.rust.codegen.util.CommandFailed import software.amazon.smithy.rust.codegen.util.runCommand @@ -40,17 +44,28 @@ class CodegenVisitor(context: PluginContext) : ShapeVisitor.Default() { private val symbolProvider: SymbolProvider private val writers: CodegenWriterDelegator private val fileManifest = context.fileManifest - val model: Model + private val model: Model + private val protocolConfig: ProtocolConfig + private val protocolGenerator: ProtocolGeneratorFactory + private val httpGenerator: HttpProtocolGenerator init { - val bootstrapProvider = SymbolVisitor(context.model, config = SymbolVisitorConfig(runtimeConfig = settings.runtimeConfig)) - model = OperationNormalizer(bootstrapProvider).addOperationInputs(context.model) + val service = settings.getService(context.model) + val (protocol, generator) = ProtocolLoader.Default.protocolFor(context.model, service) + protocolGenerator = generator + + val baseVisitor = SymbolVisitor(context.model, config = SymbolVisitorConfig(runtimeConfig = settings.runtimeConfig)) + val normalizer = OperationNormalizer(baseVisitor) + + model = normalizer.addOperationInputs(context.model) symbolProvider = SymbolVisitor(model, config = SymbolVisitorConfig(runtimeConfig = settings.runtimeConfig)) + protocolConfig = ProtocolConfig(model, symbolProvider, settings.runtimeConfig, service, protocol) writers = CodegenWriterDelegator( context.fileManifest, // TODO: load symbol visitor from integrations; 2d symbolProvider, RustWriter.Factory ) + httpGenerator = protocolGenerator.buildProtocolGenerator(protocolConfig) } fun execute() { @@ -105,6 +120,6 @@ class CodegenVisitor(context: PluginContext) : ShapeVisitor.Default() { } override fun serviceShape(shape: ServiceShape) { - ServiceGenerator(model, symbolProvider, settings.runtimeConfig, shape, writers).render() + ServiceGenerator(writers, httpGenerator, protocolConfig).render() } } diff --git a/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/generators/HttpProtocolGenerator.kt b/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/generators/HttpProtocolGenerator.kt index 3a6da590a..6fadcd63a 100644 --- a/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/generators/HttpProtocolGenerator.kt +++ b/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/generators/HttpProtocolGenerator.kt @@ -16,29 +16,30 @@ import software.amazon.smithy.rust.codegen.lang.rustBlock import software.amazon.smithy.rust.codegen.smithy.RuntimeConfig import software.amazon.smithy.rust.codegen.smithy.RuntimeType +/** + * Configuration needed to generate the client for a given Service<->Protocol pair + */ data class ProtocolConfig( val model: Model, val symbolProvider: SymbolProvider, val runtimeConfig: RuntimeConfig, - val writer: RustWriter, val serviceShape: ServiceShape, - val operationShape: OperationShape, - val inputShape: StructureShape, val protocol: ShapeId ) interface ProtocolGeneratorFactory { - fun build(protocolConfig: ProtocolConfig): T + fun buildProtocolGenerator(protocolConfig: ProtocolConfig): T } abstract class HttpProtocolGenerator( - private val symbolProvider: SymbolProvider, - private val writer: RustWriter, - private val inputShape: StructureShape + protocolConfig: ProtocolConfig ) { - fun render() { + private val symbolProvider = protocolConfig.symbolProvider + private val model = protocolConfig.model + fun renderOperation(writer: RustWriter, operationShape: OperationShape) { + val inputShape = model.expectShape(operationShape.input.get(), StructureShape::class.java) writer.rustBlock("impl ${symbolProvider.toSymbol(inputShape).name}") { - toHttpRequestImpl(this) + toHttpRequestImpl(this, operationShape, inputShape) } } @@ -56,5 +57,5 @@ abstract class HttpProtocolGenerator( * * Your implementation MUST call `httpBuilderFun` to create the public method. */ - abstract fun toHttpRequestImpl(implBlockWriter: RustWriter) + abstract fun toHttpRequestImpl(implBlockWriter: RustWriter, operationShape: OperationShape, inputShape: StructureShape) } diff --git a/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/generators/HttpProtocolTestGenerator.kt b/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/generators/HttpProtocolTestGenerator.kt index 8279164ae..6016c8ae7 100644 --- a/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/generators/HttpProtocolTestGenerator.kt +++ b/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/generators/HttpProtocolTestGenerator.kt @@ -1,5 +1,6 @@ package software.amazon.smithy.rust.codegen.smithy.generators +import software.amazon.smithy.model.shapes.OperationShape import software.amazon.smithy.protocoltests.traits.HttpRequestTestCase import software.amazon.smithy.protocoltests.traits.HttpRequestTestsTrait import software.amazon.smithy.rust.codegen.lang.RustWriter @@ -7,16 +8,16 @@ import software.amazon.smithy.rust.codegen.lang.rustBlock import software.amazon.smithy.rust.codegen.lang.withBlock import software.amazon.smithy.rust.codegen.smithy.RuntimeType import software.amazon.smithy.rust.codegen.util.dq +import software.amazon.smithy.rust.codegen.util.inputShape /** * Generate protocol tests for an operation */ -class HttpProtocolTestGenerator(private val protocolConfig: ProtocolConfig) { +class HttpProtocolTestGenerator(private val protocolConfig: ProtocolConfig, private val operationShape: OperationShape, private val writer: RustWriter) { + private val inputShape = operationShape.inputShape(protocolConfig.model) fun render() { - with(protocolConfig) { - operationShape.getTrait(HttpRequestTestsTrait::class.java).map { - renderHttpRequestTests(it) - } + operationShape.getTrait(HttpRequestTestsTrait::class.java).map { + renderHttpRequestTests(it) } } @@ -44,7 +45,7 @@ class HttpProtocolTestGenerator(private val protocolConfig: ProtocolConfig) { testModuleWriter.write("#[test]") testModuleWriter.rustBlock("fn test_${httpRequestTestCase.id.toSnakeCase()}()") { writeInline("let input =") - instantiator.render(httpRequestTestCase.params, protocolConfig.inputShape, this) + instantiator.render(httpRequestTestCase.params, inputShape, this) write(";") write("let http_request = input.build_http_request().body(()).unwrap();") checkQueryParams(this, httpRequestTestCase.queryParams) diff --git a/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/generators/HttpTraitBindingGenerator.kt b/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/generators/HttpTraitBindingGenerator.kt index 125c597ff..f2df1281d 100644 --- a/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/generators/HttpTraitBindingGenerator.kt +++ b/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/generators/HttpTraitBindingGenerator.kt @@ -93,20 +93,6 @@ class HttpTraitBindingGenerator( } } - /** - * Default implementation of HttpTraitBindings. A `build_http_request()` method is added that - * simply calls `update_http_builder()` - */ - inner class Default : HttpProtocolGenerator(symbolProvider, writer, inputShape) { - override fun toHttpRequestImpl(implBlockWriter: RustWriter) { - renderUpdateHttpBuilder(implBlockWriter) - httpBuilderFun(implBlockWriter) { - write("let builder = \$T::new();", RuntimeType.HttpRequestBuilder) - write("self.update_http_builder(builder)") - } - } - } - /** Header Generation **/ /** diff --git a/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/generators/ServiceGenerator.kt b/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/generators/ServiceGenerator.kt index 60702bbf1..b318dd2aa 100644 --- a/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/generators/ServiceGenerator.kt +++ b/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/generators/ServiceGenerator.kt @@ -5,57 +5,24 @@ package software.amazon.smithy.rust.codegen.smithy.generators -import software.amazon.smithy.aws.traits.protocols.AwsJson1_0Trait -import software.amazon.smithy.aws.traits.protocols.RestJson1Trait -import software.amazon.smithy.codegen.core.CodegenException -import software.amazon.smithy.codegen.core.SymbolProvider import software.amazon.smithy.codegen.core.writer.CodegenWriterDelegator -import software.amazon.smithy.model.Model -import software.amazon.smithy.model.knowledge.ServiceIndex import software.amazon.smithy.model.knowledge.TopDownIndex -import software.amazon.smithy.model.shapes.ServiceShape -import software.amazon.smithy.model.shapes.ShapeId -import software.amazon.smithy.model.shapes.StructureShape -import software.amazon.smithy.model.traits.Trait import software.amazon.smithy.rust.codegen.lang.RustWriter -import software.amazon.smithy.rust.codegen.smithy.RuntimeConfig -import software.amazon.smithy.rust.codegen.smithy.protocols.AwsJson10Factory -import software.amazon.smithy.rust.codegen.smithy.protocols.AwsRestJsonFactory class ServiceGenerator( - private val model: Model, - private val symbolProvider: SymbolProvider, - private val runtimeConfig: RuntimeConfig, - private val serviceShape: ServiceShape, - private val writers: CodegenWriterDelegator + private val writers: CodegenWriterDelegator, + private val protocolGenerator: HttpProtocolGenerator, + private val config: ProtocolConfig ) { - // TODO: refactor to be runtime pluggable; 2d - private val index = TopDownIndex(model) - private val supportedProtocols = mapOf( - AwsJson1_0Trait.ID to AwsJson10Factory(), - RestJson1Trait.ID to AwsRestJsonFactory() - - ) - private val protocols: MutableMap = ServiceIndex(model).getProtocols(serviceShape) - private val matchingProtocols = protocols.keys.mapNotNull { protocolId -> supportedProtocols[protocolId]?.let { protocolId to it } } - - init { - if (matchingProtocols.isEmpty()) { - throw CodegenException("No matching protocol — service offers: ${protocols.keys}. We offer: ${supportedProtocols.keys}") - } - } + private val index = TopDownIndex(config.model) fun render() { - val operations = index.getContainedOperations(serviceShape) - val (protocol, generator) = matchingProtocols.first() + val operations = index.getContainedOperations(config.serviceShape) // TODO: refactor so that we don't need to re-instantiate the protocol for every operation operations.map { operation -> writers.useShapeWriter(operation) { writer -> - // transform ensures that all models have input shapes - val input = operation.input.get().let { model.expectShape(it, StructureShape::class.java) } - val config = ProtocolConfig(model, symbolProvider, runtimeConfig, writer, serviceShape, operation, input, protocol) - generator.build(config).render() - HttpProtocolTestGenerator(config).render() + protocolGenerator.renderOperation(writer, operation) + HttpProtocolTestGenerator(config, operation, writer).render() } } } diff --git a/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/protocols/AwsJson10.kt b/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/protocols/AwsJson10.kt index 7729f1cfb..7f8eea928 100644 --- a/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/protocols/AwsJson10.kt +++ b/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/protocols/AwsJson10.kt @@ -5,9 +5,7 @@ package software.amazon.smithy.rust.codegen.smithy.protocols -import software.amazon.smithy.codegen.core.SymbolProvider import software.amazon.smithy.model.shapes.OperationShape -import software.amazon.smithy.model.shapes.ServiceShape import software.amazon.smithy.model.shapes.StructureShape import software.amazon.smithy.rust.codegen.lang.RustWriter import software.amazon.smithy.rust.codegen.lang.rustBlock @@ -17,21 +15,19 @@ import software.amazon.smithy.rust.codegen.smithy.generators.ProtocolConfig import software.amazon.smithy.rust.codegen.smithy.generators.ProtocolGeneratorFactory class AwsJson10Factory : ProtocolGeneratorFactory { - override fun build( + override fun buildProtocolGenerator( protocolConfig: ProtocolConfig - ): AwsJson10Generator = with(protocolConfig) { - AwsJson10Generator(symbolProvider, writer, serviceShape, operationShape, inputShape) - } + ): AwsJson10Generator = AwsJson10Generator(protocolConfig) } class AwsJson10Generator( - symbolProvider: SymbolProvider, - writer: RustWriter, - private val serviceShape: ServiceShape, - private val operationShape: OperationShape, - inputShape: StructureShape -) : HttpProtocolGenerator(symbolProvider, writer, inputShape) { - override fun toHttpRequestImpl(implBlockWriter: RustWriter) { + private val protocolConfig: ProtocolConfig +) : HttpProtocolGenerator(protocolConfig) { + override fun toHttpRequestImpl( + implBlockWriter: RustWriter, + operationShape: OperationShape, + inputShape: StructureShape + ) { implBlockWriter.rustBlock("pub fn build_http_request(&self) -> \$T", RuntimeType.HttpRequestBuilder) { write("let builder = \$T::new();", RuntimeType.HttpRequestBuilder) write( @@ -39,7 +35,7 @@ class AwsJson10Generator( builder .method("POST") .header("Content-Type", "application/x-amz-json-1.0") - .header("X-Amz-Target", "${serviceShape.id.name}.${operationShape.id.name}") + .header("X-Amz-Target", "${protocolConfig.serviceShape.id.name}.${operationShape.id.name}") """.trimMargin() ) } diff --git a/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/protocols/AwsRestJson.kt b/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/protocols/AwsRestJson.kt index 5f4e96569..0775a8c33 100644 --- a/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/protocols/AwsRestJson.kt +++ b/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/protocols/AwsRestJson.kt @@ -5,14 +5,11 @@ package software.amazon.smithy.rust.codegen.smithy.protocols -import software.amazon.smithy.codegen.core.SymbolProvider -import software.amazon.smithy.model.Model import software.amazon.smithy.model.knowledge.HttpBindingIndex import software.amazon.smithy.model.shapes.OperationShape import software.amazon.smithy.model.shapes.StructureShape import software.amazon.smithy.model.traits.HttpTrait import software.amazon.smithy.rust.codegen.lang.RustWriter -import software.amazon.smithy.rust.codegen.smithy.RuntimeConfig import software.amazon.smithy.rust.codegen.smithy.RuntimeType import software.amazon.smithy.rust.codegen.smithy.generators.HttpProtocolGenerator import software.amazon.smithy.rust.codegen.smithy.generators.HttpTraitBindingGenerator @@ -21,38 +18,38 @@ import software.amazon.smithy.rust.codegen.smithy.generators.ProtocolGeneratorFa import software.amazon.smithy.rust.codegen.util.dq class AwsRestJsonFactory : ProtocolGeneratorFactory { - override fun build( + override fun buildProtocolGenerator( protocolConfig: ProtocolConfig - ): AwsRestJsonGenerator = with(protocolConfig) { - AwsRestJsonGenerator(model, symbolProvider, runtimeConfig, writer, operationShape, inputShape) - } + ): AwsRestJsonGenerator = AwsRestJsonGenerator(protocolConfig) } class AwsRestJsonGenerator( - private val model: Model, - private val symbolProvider: SymbolProvider, - private val runtimeConfig: RuntimeConfig, - private val writer: RustWriter, - private val operationShape: OperationShape, - private val inputShape: StructureShape -) : HttpProtocolGenerator(symbolProvider, writer, inputShape) { + protocolConfig: ProtocolConfig +) : HttpProtocolGenerator(protocolConfig) { // restJson1 requires all operations to use the HTTP trait - private val httpTrait = operationShape.expectTrait(HttpTrait::class.java) - - private val httpBindingGenerator = HttpTraitBindingGenerator( - model, - symbolProvider, - runtimeConfig, - writer, - operationShape, - inputShape, - httpTrait - ) + private val model = protocolConfig.model + private val symbolProvider = protocolConfig.symbolProvider + private val runtimeConfig = protocolConfig.runtimeConfig private val httpIndex = HttpBindingIndex(model) private val requestBuilder = RuntimeType.Http("request::Builder") - override fun toHttpRequestImpl(implBlockWriter: RustWriter) { + override fun toHttpRequestImpl( + implBlockWriter: RustWriter, + operationShape: OperationShape, + inputShape: StructureShape + ) { + val httpTrait = operationShape.expectTrait(HttpTrait::class.java) + + val httpBindingGenerator = HttpTraitBindingGenerator( + model, + symbolProvider, + runtimeConfig, + implBlockWriter, + operationShape, + inputShape, + httpTrait + ) val contentType = httpIndex.determineRequestContentType(operationShape, "application/json").orElse("application/json") httpBindingGenerator.renderUpdateHttpBuilder(implBlockWriter) httpBuilderFun(implBlockWriter) { diff --git a/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/protocols/ProtocolLoader.kt b/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/protocols/ProtocolLoader.kt new file mode 100644 index 000000000..73db7e5c3 --- /dev/null +++ b/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/protocols/ProtocolLoader.kt @@ -0,0 +1,38 @@ +package software.amazon.smithy.rust.codegen.smithy.protocols + +import software.amazon.smithy.aws.traits.protocols.AwsJson1_0Trait +import software.amazon.smithy.aws.traits.protocols.AwsJson1_1Trait +import software.amazon.smithy.aws.traits.protocols.RestJson1Trait +import software.amazon.smithy.codegen.core.CodegenException +import software.amazon.smithy.model.Model +import software.amazon.smithy.model.knowledge.ServiceIndex +import software.amazon.smithy.model.shapes.ServiceShape +import software.amazon.smithy.model.shapes.ShapeId +import software.amazon.smithy.model.traits.Trait +import software.amazon.smithy.rust.codegen.smithy.generators.HttpProtocolGenerator +import software.amazon.smithy.rust.codegen.smithy.generators.ProtocolGeneratorFactory + +// TODO: supportedProtocols must be runtime loadable via SPI; 2d +class ProtocolLoader(private val supportedProtocols: Map>) { + fun protocolFor( + model: Model, + serviceShape: ServiceShape + ): Pair> { + val protocols: MutableMap = ServiceIndex(model).getProtocols(serviceShape) + val matchingProtocols = + protocols.keys.mapNotNull { protocolId -> supportedProtocols[protocolId]?.let { protocolId to it } } + if (matchingProtocols.isEmpty()) { + throw CodegenException("No matching protocol — service offers: ${protocols.keys}. We offer: ${supportedProtocols.keys}") + } + return matchingProtocols.first() + } + + companion object { + private val Protocols = mapOf( + AwsJson1_0Trait.ID to AwsJson10Factory(), + AwsJson1_1Trait.ID to AwsJson10Factory(), + RestJson1Trait.ID to AwsRestJsonFactory() + ) + val Default = ProtocolLoader(Protocols) + } +} diff --git a/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/util/Smithy.kt b/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/util/Smithy.kt index 9dd894110..134ff9add 100644 --- a/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/util/Smithy.kt +++ b/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/util/Smithy.kt @@ -1,9 +1,16 @@ package software.amazon.smithy.rust.codegen.util import software.amazon.smithy.model.Model +import software.amazon.smithy.model.shapes.OperationShape import software.amazon.smithy.model.shapes.Shape import software.amazon.smithy.model.shapes.ShapeId +import software.amazon.smithy.model.shapes.StructureShape inline fun Model.lookup(shapeId: String): T { return this.expectShape(ShapeId.from(shapeId), T::class.java) } + +fun OperationShape.inputShape(model: Model): StructureShape { + // The Rust Smithy generator adds an input to all shapes automatically + return model.expectShape(this.input.get(), StructureShape::class.java) +} diff --git a/codegen/src/test/kotlin/software/amazon/smithy/rust/codegen/generators/HttpTraitBindingGeneratorTest.kt b/codegen/src/test/kotlin/software/amazon/smithy/rust/codegen/generators/HttpTraitBindingGeneratorTest.kt index 052267ac7..5e26bf695 100644 --- a/codegen/src/test/kotlin/software/amazon/smithy/rust/codegen/generators/HttpTraitBindingGeneratorTest.kt +++ b/codegen/src/test/kotlin/software/amazon/smithy/rust/codegen/generators/HttpTraitBindingGeneratorTest.kt @@ -22,6 +22,8 @@ import software.amazon.smithy.model.shapes.ShapeId import software.amazon.smithy.model.shapes.StructureShape import software.amazon.smithy.model.traits.HttpTrait import software.amazon.smithy.rust.codegen.lang.RustWriter +import software.amazon.smithy.rust.codegen.lang.rustBlock +import software.amazon.smithy.rust.codegen.smithy.RuntimeType import software.amazon.smithy.rust.codegen.smithy.generators.HttpTraitBindingGenerator import software.amazon.smithy.rust.codegen.smithy.generators.StructureGenerator import software.amazon.smithy.rust.codegen.smithy.generators.uriFormatString @@ -97,12 +99,18 @@ class HttpTraitBindingGeneratorTest { private val symbolProvider = testSymbolProvider(model) private fun renderOperation(writer: RustWriter) { StructureGenerator(model, symbolProvider, writer, inputShape).render() - HttpTraitBindingGenerator( - model, - symbolProvider, - TestRuntimeConfig, writer, operationShape, inputShape, httpTrait - ) - .Default().render() + val inputShape = model.expectShape(operationShape.input.get(), StructureShape::class.java) + writer.rustBlock("impl PutObjectInput") { + HttpTraitBindingGenerator( + model, + symbolProvider, + TestRuntimeConfig, writer, operationShape, inputShape, httpTrait + ).renderUpdateHttpBuilder(this) + rustBlock("pub fn build_http_request(&self) -> \$T", RuntimeType.HttpRequestBuilder) { + write("let builder = \$T::new();", RuntimeType.HttpRequestBuilder) + write("self.update_http_builder(builder)") + } + } } @Test diff --git a/codegen/src/test/kotlin/software/amazon/smithy/rust/codegen/smithy/generators/HttpProtocolTestGeneratorTest.kt b/codegen/src/test/kotlin/software/amazon/smithy/rust/codegen/smithy/generators/HttpProtocolTestGeneratorTest.kt index a696b0871..67ccdf1b7 100644 --- a/codegen/src/test/kotlin/software/amazon/smithy/rust/codegen/smithy/generators/HttpProtocolTestGeneratorTest.kt +++ b/codegen/src/test/kotlin/software/amazon/smithy/rust/codegen/smithy/generators/HttpProtocolTestGeneratorTest.kt @@ -72,6 +72,9 @@ class HttpProtocolTestGeneratorTest { private val symbolProvider = testSymbolProvider(model) private val runtimeConfig = TestRuntimeConfig + /** + * Creates an fake HTTP implementation for SayHello & generates the protocol test + */ private fun writeHttpImpl(writer: RustWriter, body: String) { writer.withModule("operation") { StructureGenerator(model, symbolProvider, this, model.lookup("com.example#SayHelloInput")).render() @@ -85,14 +88,13 @@ class HttpProtocolTestGeneratorTest { model, symbolProvider, runtimeConfig, - this, model.lookup("com.example#HelloService"), - model.lookup("com.example#SayHello"), - model.lookup("com.example#SayHelloInput"), RestJson1Trait.ID ) HttpProtocolTestGenerator( - protocolConfig + protocolConfig, + model.lookup("com.example#SayHello"), + this ).render() } } -- GitLab