Skip to content

Commit

Permalink
Fixes for RustWriter bugs #1465 & #1459 (#1467)
Browse files Browse the repository at this point in the history
  • Loading branch information
rcoh authored and crisidev committed Jun 15, 2022
1 parent 0ec4da2 commit 50ce747
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 3 deletions.
8 changes: 7 additions & 1 deletion CHANGELOG.next.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,10 @@ author = "rcoh"
message = "Add `Debug` implementation to several types in `aws-config`"
references = ["smithy-rs#1421"]
meta = { "breaking" = false, "tada" = false, "bug" = false }
author = "jdisanti"
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"
Original file line number Diff line number Diff line change
Expand Up @@ -136,16 +136,17 @@ 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: ${
scope.map { it.first }
}"
)
}
"#{${keyName.lowercase()}:T}"
"#{${keyName.lowercase()}$templateType}"
}.trim()
}

Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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")
}
}

0 comments on commit 50ce747

Please sign in to comment.