Only write the header warning once per file (#49)

This commit is contained in:
Russell Cohen 2020-11-23 15:46:01 -05:00 committed by GitHub
parent 9609cc3a58
commit 8884657c3a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 17 additions and 4 deletions

View File

@ -74,7 +74,7 @@ fun <T : CodeWriter> T.rustBlock(header: String, vararg args: Any, block: T.() -
return this
}
class RustWriter private constructor(private val filename: String, val namespace: String, private val commentCharacter: String = "//") :
class RustWriter private constructor(private val filename: String, val namespace: String, private val commentCharacter: String = "//", private val printWarning: Boolean = true) :
CodegenWriter<RustWriter, UseDeclarations>(null, UseDeclarations(namespace)) {
companion object {
fun forModule(module: String): RustWriter {
@ -114,13 +114,22 @@ class RustWriter private constructor(private val filename: String, val namespace
/**
* Create an inline module.
*
* Callers must take care to use [this] when writing to ensure code is written to the right place:
* ```kotlin
* val writer = RustWriter.forModule("models")
* writer.withModule("nested") {
* Generator(...).render(this) // GOOD
* Generator(...).render(writer) // WRONG!
* }
* ```
*
* The returned writer will inject any local imports into the module as needed.
*/
fun withModule(moduleName: String, rustMetadata: RustMetadata = RustMetadata(public = true), moduleWriter: RustWriter.() -> Unit) {
// In Rust, modules must specify their own imports—they don't have access to the parent scope.
// To easily handle this, create a new inner writer to collect imports, then dump it
// into an inline module.
val innerWriter = RustWriter(this.filename, "${this.namespace}::$moduleName")
val innerWriter = RustWriter(this.filename, "${this.namespace}::$moduleName", printWarning = false)
moduleWriter(innerWriter)
rustMetadata.render(this)
rustBlock("mod $moduleName") {
@ -158,7 +167,9 @@ class RustWriter private constructor(private val filename: String, val namespace
val contents = super.toString()
// Hack to support TOML
// TODO: consider creating a TOML writer
val header = "$commentCharacter Code generated by software.amazon.smithy.rust.codegen.smithy-rs. DO NOT EDIT."
val header = if (printWarning) {
"$commentCharacter Code generated by software.amazon.smithy.rust.codegen.smithy-rs. DO NOT EDIT."
} else ""
val useDecls = importContainer.toString()
return "$header\n$useDecls\n$contents\n"
}

View File

@ -7,6 +7,7 @@ package software.amazon.smithy.rust.lang
import io.kotest.matchers.collections.shouldContain
import io.kotest.matchers.string.shouldContain
import io.kotest.matchers.string.shouldContainOnlyOnce
import org.junit.jupiter.api.Test
import software.amazon.smithy.codegen.core.SymbolProvider
import software.amazon.smithy.model.Model
@ -34,7 +35,7 @@ class RustWriterTest {
@Test
fun `inner modules correctly handle dependencies`() {
val sut = RustWriter.forModule("lib")
val sut = RustWriter.forModule("parent")
val requestBuilder = RuntimeType.HttpRequestBuilder
sut.withModule("inner") {
rustBlock("fn build(builer: \$T)", requestBuilder) {
@ -42,6 +43,7 @@ class RustWriterTest {
}
val httpDep = CargoDependency.Http.dependencies[0]
sut.dependencies shouldContain httpDep
sut.toString() shouldContainOnlyOnce "DO NOT EDIT"
}
@Test