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

Add support for serializing document types (#75)

* Add support for serializing document types

* Delete unused conversion function

* Add test for NaN behavior

* Fix test flakiness
parent 22f85e12
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -82,8 +82,9 @@ class InlineDependency(

        fun uuid() = forRustFile("v4", "uuid", "uuid.rs")

        // TODO: putting this in the "error" module risks conflicting with a modeled error named "GenericError"
        fun genericError() = forRustFile("GenericError", "types", "generic_error.rs", CargoDependency.Serde)

        fun docJson() = forRustFile("doc_json", "doc_json", "doc_json.rs", CargoDependency.Serde)
    }
}

+2 −0
Original line number Diff line number Diff line
@@ -126,6 +126,8 @@ data class RuntimeType(val name: String, val dependency: RustDependency?, val na

        val GenericError = RuntimeType("GenericError", InlineDependency.genericError(), "crate::types")

        val DocJson = RuntimeType("doc_json", InlineDependency.docJson(), "crate")

        fun forInlineFun(name: String, module: String, func: (RustWriter) -> Unit) = RuntimeType(
            name = name,
            dependency = InlineDependency(name, module, listOf(), func),
+34 −29
Original line number Diff line number Diff line
@@ -42,32 +42,6 @@ class HttpProtocolTestGenerator(
) {
    private val logger = Logger.getLogger(javaClass.name)

    // TODO: remove these once Smithy publishes fixes.
    // These tests are not even attempted to be compiled
    val DisableTests = setOf(
        // This test is flaky because of set ordering serialization https://github.com/awslabs/smithy-rs/issues/37
        "AwsJson11Enums"
    )

    // These tests fail due to shortcomings in our implementation.
    // These could be configured via runtime configuration, but since this won't be long-lasting,
    // it makes sense to do the simplest thing for now.
    // The test will _fail_ if these pass, so we will discover & remove if we fix them by accident
    val ExpectFail = setOf(
        // Document support: https://github.com/awslabs/smithy-rs/issues/31
        "PutAndGetInlineDocumentsInput",
        "InlineDocumentInput",
        "InlineDocumentAsPayloadInput",

        // Query literals: https://github.com/awslabs/smithy-rs/issues/36
        "RestJsonConstantQueryString",
        "RestJsonConstantAndVariableQueryStringMissingOneValue",
        "RestJsonConstantAndVariableQueryStringAllValues",

        // Misc:
        "RestJsonQueryIdempotencyTokenAutoFill", // https://github.com/awslabs/smithy-rs/issues/34
        "RestJsonHttpPrefixHeadersArePresent" // https://github.com/awslabs/smithy-rs/issues/35
    )
    private val inputShape = operationShape.inputShape(protocolConfig.model)
    private val outputShape = operationShape.outputShape(protocolConfig.model)
    private val operationSymbol = protocolConfig.symbolProvider.toSymbol(operationShape)
@@ -126,10 +100,16 @@ class HttpProtocolTestGenerator(
    /**
     * Filter out test cases that are disabled or don't match the service protocol
     */
    private fun List<TestCase>.filterMatching(): List<TestCase> = this.filter { testCase ->
    private fun List<TestCase>.filterMatching(): List<TestCase> {
        return if (RunOnly.isNullOrEmpty()) {
            this.filter { testCase ->
                testCase.testCase.protocol == protocolConfig.protocol &&
                    !DisableTests.contains(testCase.testCase.id)
            }
        } else {
            this.filter { RunOnly.contains(it.testCase.id) }
        }
    }

    private fun renderTestCaseBlock(
        testCase: HttpMessageTestCase,
@@ -336,4 +316,29 @@ class HttpProtocolTestGenerator(
            write(args.joinToString(",") { it.dq() })
        }
    }

    companion object {
        // These tests fail due to shortcomings in our implementation.
        // These could be configured via runtime configuration, but since this won't be long-lasting,
        // it makes sense to do the simplest thing for now.
        // The test will _fail_ if these pass, so we will discover & remove if we fix them by accident
        private val ExpectFail = setOf(
            // Query literals: https://github.com/awslabs/smithy-rs/issues/36
            "RestJsonConstantQueryString",
            "RestJsonConstantAndVariableQueryStringMissingOneValue",
            "RestJsonConstantAndVariableQueryStringAllValues",

            // Misc:
            "RestJsonQueryIdempotencyTokenAutoFill", // https://github.com/awslabs/smithy-rs/issues/34
            "RestJsonHttpPrefixHeadersArePresent" // https://github.com/awslabs/smithy-rs/issues/35
        )
        private val RunOnly: Set<String>? = null

        // These tests are not even attempted to be compiled, either because they will not compile
        // or because they are flaky
        private val DisableTests = setOf(
            // This test is flaky because of set ordering serialization https://github.com/awslabs/smithy-rs/issues/37
            "AwsJson11Enums"
        )
    }
}
+11 −0
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@ import software.amazon.smithy.model.node.StringNode
import software.amazon.smithy.model.shapes.BlobShape
import software.amazon.smithy.model.shapes.BooleanShape
import software.amazon.smithy.model.shapes.CollectionShape
import software.amazon.smithy.model.shapes.DocumentShape
import software.amazon.smithy.model.shapes.ListShape
import software.amazon.smithy.model.shapes.MapShape
import software.amazon.smithy.model.shapes.MemberShape
@@ -25,6 +26,7 @@ import software.amazon.smithy.model.traits.EnumTrait
import software.amazon.smithy.rust.codegen.lang.RustType
import software.amazon.smithy.rust.codegen.lang.RustWriter
import software.amazon.smithy.rust.codegen.lang.conditionalBlock
import software.amazon.smithy.rust.codegen.lang.rust
import software.amazon.smithy.rust.codegen.lang.rustBlock
import software.amazon.smithy.rust.codegen.lang.withBlock
import software.amazon.smithy.rust.codegen.smithy.RuntimeConfig
@@ -79,6 +81,15 @@ class Instantiator(
            is StringShape -> renderString(writer, shape, arg as StringNode)
            is NumberShape -> writer.write(arg.asNumberNode().get())
            is BooleanShape -> writer.write(arg.asBooleanNode().get().toString())
            is DocumentShape -> {
                writer.rust(
                    """{
                    let as_json = #T! { ${Node.prettyPrintJson(arg)} };
                    #T::json_to_doc(as_json)
                }""",
                    RuntimeType.SerdeJson("json"), RuntimeType.DocJson
                )
            }
            else -> writer.writeWithNoFormatting("todo!() /* $shape $arg */")
        }
    }
+4 −0
Original line number Diff line number Diff line
@@ -158,6 +158,10 @@ class SerializerBuilder(
        },
        "instant_epoch_seconds_ser" to { writer ->
            writer.write("$ser.serialize_i64($inp.epoch_seconds())")
        },
        "document_ser" to { writer ->
            writer.write("use #T;", RuntimeType.Serialize)
            writer.write("#T::SerDoc($inp).serialize($ser)", RuntimeType.DocJson)
        }
    )

Loading