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

Fixes for RustWriter bugs #1465 & #1459 (#1467)

parent c3f37303
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -22,3 +22,9 @@ message = "Add `Debug` implementation to several types in `aws-config`"
references = ["smithy-rs#1421"]
meta = { "breaking" = false, "tada" = false, "bug" = false }
author = "jdisanti"

[[smithy-rs]]
message = "Fix RustWriter bugs for `rustTemplate` and `docs` utility methods"
references = ["smithy-rs#1427", "smithy-rs#1465", "smithy-rs#1459"]
meta = { "breaking" = false, "tada" = false, "bug" = true }
author = "rcoh"
+6 −2
Original line number Diff line number Diff line
@@ -136,8 +136,9 @@ fun <T : AbstractCodeWriter<T>> T.rust(
/* rewrite #{foo} to #{foo:T} (the smithy template format) */
private fun transformTemplate(template: String, scope: Array<out Pair<String, Any>>): String {
    check(scope.distinctBy { it.first.lowercase() }.size == scope.size) { "Duplicate cased keys not supported" }
    return template.replace(Regex("""#\{([a-zA-Z_0-9]+)\}""")) { matchResult ->
    return template.replace(Regex("""#\{([a-zA-Z_0-9]+)(:\w)?\}""")) { matchResult ->
        val keyName = matchResult.groupValues[1]
        val templateType = matchResult.groupValues[2].ifEmpty { ":T" }
        if (!scope.toMap().keys.contains(keyName)) {
            throw CodegenException(
                "Rust block template expected `$keyName` but was not present in template.\n  hint: Template contains: ${
@@ -145,7 +146,7 @@ private fun transformTemplate(template: String, scope: Array<out Pair<String, An
                }"
            )
        }
        "#{${keyName.lowercase()}:T}"
        "#{${keyName.lowercase()}$templateType}"
    }.trim()
}

@@ -259,6 +260,9 @@ fun <T : AbstractCodeWriter<T>> T.docs(text: String, vararg args: Any, newlinePr
            // Rustdoc warns on tabs in documentation
            it.trimStart().replace("\t", "  ")
        }
    // Because writing docs relies on the newline prefix, ensure that there was a new line written
    // before we write the docs
    this.ensureNewline()
    write(cleaned, *args)
    popState()
    return this
+32 −0
Original line number Diff line number Diff line
@@ -15,12 +15,16 @@ import software.amazon.smithy.model.Model
import software.amazon.smithy.model.shapes.SetShape
import software.amazon.smithy.model.shapes.StringShape
import software.amazon.smithy.model.shapes.StructureShape
import software.amazon.smithy.rust.codegen.rustlang.Attribute
import software.amazon.smithy.rust.codegen.rustlang.CargoDependency
import software.amazon.smithy.rust.codegen.rustlang.RustType
import software.amazon.smithy.rust.codegen.rustlang.RustWriter
import software.amazon.smithy.rust.codegen.rustlang.asType
import software.amazon.smithy.rust.codegen.rustlang.docs
import software.amazon.smithy.rust.codegen.rustlang.isEmpty
import software.amazon.smithy.rust.codegen.rustlang.rust
import software.amazon.smithy.rust.codegen.rustlang.rustBlock
import software.amazon.smithy.rust.codegen.rustlang.rustTemplate
import software.amazon.smithy.rust.codegen.rustlang.writable
import software.amazon.smithy.rust.codegen.smithy.RuntimeType
import software.amazon.smithy.rust.codegen.testutil.asSmithyModel
@@ -111,4 +115,32 @@ class RustWriterTest {
        val w = writable {}
        w.isEmpty() shouldBe true
    }

    @Test
    fun `attributes with comments when using rust`() {
        val sut = RustWriter.forModule("lib")
        Attribute.Custom("foo").render(sut)
        sut.rust("// heres an attribute")
        sut.toString().shouldContain("#[foo]// heres an attribute")
    }

    @Test
    fun `attributes with comments when using docs`() {
        val sut = RustWriter.forModule("lib")
        Attribute.Custom("foo").render(sut)
        sut.docs("heres an attribute")
        sut.toString().shouldContain("#[foo]\n/// heres an attribute")
    }

    @Test
    fun `template writables with upper case names`() {
        val inner = writable { rust("hello") }
        val sut = RustWriter.forModule("lib")
        sut.rustTemplate(
            "inner: #{Inner:W}, regular: #{http}",
            "Inner" to inner,
            "http" to CargoDependency.Http.asType().member("foo")
        )
        sut.toString().shouldContain("inner: hello, regular: http::foo")
    }
}