Loading codegen-test/model/rest-json-extras.smithy +76 −1 Original line number Diff line number Diff line Loading @@ -53,7 +53,16 @@ apply QueryPrecedence @httpRequestTests([ @restJson1 service RestJsonExtras { version: "2019-12-16", operations: [StringPayload, PrimitiveIntHeader, EnumQuery, StatusResponse, MapWithEnumKeyOp, PrimitiveIntOp] operations: [ StringPayload, PrimitiveIntHeader, EnumQuery, StatusResponse, MapWithEnumKeyOp, PrimitiveIntOp, EscapedStringValues, NullInNonSparse, ] } @http(uri: "/StringPayload", method: "POST") Loading Loading @@ -188,3 +197,69 @@ operation MapWithEnumKeyOp { input: MapWithEnumKeyInputOutput, output: MapWithEnumKeyInputOutput, } @enum([ { value: "has\"quotes", name: "HAS_QUOTES" }, { value: "normal", name: "NORMAL" }, ]) string EnumWithEscapedChars structure EscapedStringValuesInputOutput { enum: EnumWithEscapedChars, @jsonName("also\"has\"quotes") someString: String, } @http(uri: "/escaped-string-values", method: "POST") @httpRequestTests([ { id: "EscapedStringValuesRequest", uri: "/escaped-string-values", method: "POST", protocol: "aws.protocols#restJson1", body: "{\"enum\":\"has\\\"quotes\",\"also\\\"has\\\"quotes\":\"test\"}", params: { enum: "has\"quotes", someString: "test" }, } ]) @httpResponseTests([ { id: "EscapedStringValuesResponse", protocol: "aws.protocols#restJson1", code: 200, body: "{\"enum\":\"has\\\"quotes\",\"also\\\"has\\\"quotes\":\"test\"}", params: { enum: "has\"quotes", someString: "test" }, } ]) operation EscapedStringValues { input: EscapedStringValuesInputOutput, output: EscapedStringValuesInputOutput, } list NonSparseList { member: String, } map NonSparseMap { key: String, value: String, } structure NullInNonSparseOutput { list: NonSparseList, map: NonSparseMap, } @http(uri: "/null-in-non-sparse", method: "POST") @httpResponseTests([ { id: "NullInNonSparse", protocol: "aws.protocols#restJson1", code: 200, body: "{\"list\":[null,\"one\",null,\"two\",null],\"map\":{\"zero\":null,\"one\":\"1\"}}", params: { list: ["one", "two"], map: { "one": "1" } }, } ]) operation NullInNonSparse { output: NullInNonSparseOutput, } codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/generators/EnumGenerator.kt +3 −2 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import software.amazon.smithy.rust.codegen.smithy.RuntimeType import software.amazon.smithy.rust.codegen.smithy.RustSymbolProvider import software.amazon.smithy.rust.codegen.smithy.expectRustMetadata import software.amazon.smithy.rust.codegen.util.doubleQuote import software.amazon.smithy.rust.codegen.util.dq import software.amazon.smithy.rust.codegen.util.getTrait import software.amazon.smithy.rust.codegen.util.orNull Loading Loading @@ -154,7 +155,7 @@ class EnumGenerator( writer.rustBlock("pub fn as_str(&self) -> &str") { writer.rustBlock("match self") { sortedMembers.forEach { member -> write("""$enumName::${member.derivedName()} => "${member.value}",""") write("""$enumName::${member.derivedName()} => ${member.value.dq()},""") } write("$enumName::$UnknownVariant(s) => s.as_ref()") } Loading Loading @@ -182,7 +183,7 @@ class EnumGenerator( writer.rustBlock("fn from(s: &str) -> Self") { writer.rustBlock("match s") { sortedMembers.forEach { member -> write(""""${member.value}" => $enumName::${member.derivedName()},""") write("""${member.value.dq()} => $enumName::${member.derivedName()},""") } write("other => $enumName::$UnknownVariant(other.to_owned())") } Loading codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/protocols/AwsJson.kt +2 −2 Original line number Diff line number Diff line Loading @@ -39,7 +39,7 @@ import software.amazon.smithy.rust.codegen.smithy.generators.error.errorSymbol import software.amazon.smithy.rust.codegen.smithy.generators.operationBuildError import software.amazon.smithy.rust.codegen.smithy.locatedIn import software.amazon.smithy.rust.codegen.smithy.meta import software.amazon.smithy.rust.codegen.smithy.protocols.parse.SerdeJsonParserGenerator import software.amazon.smithy.rust.codegen.smithy.protocols.parse.JsonParserGenerator import software.amazon.smithy.rust.codegen.smithy.protocols.serialize.JsonSerializerGenerator import software.amazon.smithy.rust.codegen.smithy.rustType import software.amazon.smithy.rust.codegen.smithy.traits.InputBodyTrait Loading Loading @@ -250,7 +250,7 @@ class BasicAwsJsonGenerator( val outputShape = operationIndex.getOutput(operationShape).get() val errorSymbol = operationShape.errorSymbol(symbolProvider) val jsonErrors = RuntimeType.awsJsonErrors(protocolConfig.runtimeConfig) val generator = SerdeJsonParserGenerator(protocolConfig) val generator = JsonParserGenerator(protocolConfig, AwsJsonHttpBindingResolver(model, awsJsonVersion)) fromResponseFun(implBlockWriter, operationShape) { rustBlock("if #T::is_error(&response)", jsonErrors) { Loading codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/protocols/HttpBindingResolver.kt +6 −0 Original line number Diff line number Diff line Loading @@ -59,6 +59,12 @@ interface HttpBindingResolver { fun requestMembers(operationShape: OperationShape, location: HttpLocation): List<MemberShape> = requestBindings(operationShape).filter { it.location == location }.map { it.member } /** * Returns a list of member shapes bound to a given response [location] for a given [operationShape] */ fun responseMembers(operationShape: OperationShape, location: HttpLocation): List<MemberShape> = responseBindings(operationShape).filter { it.location == location }.map { it.member } /** * Determine the timestamp format based on the input parameters. */ Loading codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/protocols/RestJson.kt +3 −3 Original line number Diff line number Diff line Loading @@ -18,7 +18,7 @@ import software.amazon.smithy.rust.codegen.smithy.RustSymbolProvider 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.ProtocolSupport import software.amazon.smithy.rust.codegen.smithy.protocols.parse.SerdeJsonParserGenerator import software.amazon.smithy.rust.codegen.smithy.protocols.parse.JsonParserGenerator import software.amazon.smithy.rust.codegen.smithy.protocols.parse.StructuredDataParserGenerator import software.amazon.smithy.rust.codegen.smithy.protocols.serialize.JsonSerializerGenerator import software.amazon.smithy.rust.codegen.smithy.protocols.serialize.StructuredDataSerializerGenerator Loading Loading @@ -83,7 +83,7 @@ class RestJson(private val protocolConfig: ProtocolConfig) : Protocol { override val defaultTimestampFormat: TimestampFormatTrait.Format = TimestampFormatTrait.Format.EPOCH_SECONDS override fun structuredDataParser(operationShape: OperationShape): StructuredDataParserGenerator { return SerdeJsonParserGenerator(protocolConfig) return JsonParserGenerator(protocolConfig, httpBindingResolver) } override fun structuredDataSerializer(operationShape: OperationShape): StructuredDataSerializerGenerator { Loading Loading
codegen-test/model/rest-json-extras.smithy +76 −1 Original line number Diff line number Diff line Loading @@ -53,7 +53,16 @@ apply QueryPrecedence @httpRequestTests([ @restJson1 service RestJsonExtras { version: "2019-12-16", operations: [StringPayload, PrimitiveIntHeader, EnumQuery, StatusResponse, MapWithEnumKeyOp, PrimitiveIntOp] operations: [ StringPayload, PrimitiveIntHeader, EnumQuery, StatusResponse, MapWithEnumKeyOp, PrimitiveIntOp, EscapedStringValues, NullInNonSparse, ] } @http(uri: "/StringPayload", method: "POST") Loading Loading @@ -188,3 +197,69 @@ operation MapWithEnumKeyOp { input: MapWithEnumKeyInputOutput, output: MapWithEnumKeyInputOutput, } @enum([ { value: "has\"quotes", name: "HAS_QUOTES" }, { value: "normal", name: "NORMAL" }, ]) string EnumWithEscapedChars structure EscapedStringValuesInputOutput { enum: EnumWithEscapedChars, @jsonName("also\"has\"quotes") someString: String, } @http(uri: "/escaped-string-values", method: "POST") @httpRequestTests([ { id: "EscapedStringValuesRequest", uri: "/escaped-string-values", method: "POST", protocol: "aws.protocols#restJson1", body: "{\"enum\":\"has\\\"quotes\",\"also\\\"has\\\"quotes\":\"test\"}", params: { enum: "has\"quotes", someString: "test" }, } ]) @httpResponseTests([ { id: "EscapedStringValuesResponse", protocol: "aws.protocols#restJson1", code: 200, body: "{\"enum\":\"has\\\"quotes\",\"also\\\"has\\\"quotes\":\"test\"}", params: { enum: "has\"quotes", someString: "test" }, } ]) operation EscapedStringValues { input: EscapedStringValuesInputOutput, output: EscapedStringValuesInputOutput, } list NonSparseList { member: String, } map NonSparseMap { key: String, value: String, } structure NullInNonSparseOutput { list: NonSparseList, map: NonSparseMap, } @http(uri: "/null-in-non-sparse", method: "POST") @httpResponseTests([ { id: "NullInNonSparse", protocol: "aws.protocols#restJson1", code: 200, body: "{\"list\":[null,\"one\",null,\"two\",null],\"map\":{\"zero\":null,\"one\":\"1\"}}", params: { list: ["one", "two"], map: { "one": "1" } }, } ]) operation NullInNonSparse { output: NullInNonSparseOutput, }
codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/generators/EnumGenerator.kt +3 −2 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import software.amazon.smithy.rust.codegen.smithy.RuntimeType import software.amazon.smithy.rust.codegen.smithy.RustSymbolProvider import software.amazon.smithy.rust.codegen.smithy.expectRustMetadata import software.amazon.smithy.rust.codegen.util.doubleQuote import software.amazon.smithy.rust.codegen.util.dq import software.amazon.smithy.rust.codegen.util.getTrait import software.amazon.smithy.rust.codegen.util.orNull Loading Loading @@ -154,7 +155,7 @@ class EnumGenerator( writer.rustBlock("pub fn as_str(&self) -> &str") { writer.rustBlock("match self") { sortedMembers.forEach { member -> write("""$enumName::${member.derivedName()} => "${member.value}",""") write("""$enumName::${member.derivedName()} => ${member.value.dq()},""") } write("$enumName::$UnknownVariant(s) => s.as_ref()") } Loading Loading @@ -182,7 +183,7 @@ class EnumGenerator( writer.rustBlock("fn from(s: &str) -> Self") { writer.rustBlock("match s") { sortedMembers.forEach { member -> write(""""${member.value}" => $enumName::${member.derivedName()},""") write("""${member.value.dq()} => $enumName::${member.derivedName()},""") } write("other => $enumName::$UnknownVariant(other.to_owned())") } Loading
codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/protocols/AwsJson.kt +2 −2 Original line number Diff line number Diff line Loading @@ -39,7 +39,7 @@ import software.amazon.smithy.rust.codegen.smithy.generators.error.errorSymbol import software.amazon.smithy.rust.codegen.smithy.generators.operationBuildError import software.amazon.smithy.rust.codegen.smithy.locatedIn import software.amazon.smithy.rust.codegen.smithy.meta import software.amazon.smithy.rust.codegen.smithy.protocols.parse.SerdeJsonParserGenerator import software.amazon.smithy.rust.codegen.smithy.protocols.parse.JsonParserGenerator import software.amazon.smithy.rust.codegen.smithy.protocols.serialize.JsonSerializerGenerator import software.amazon.smithy.rust.codegen.smithy.rustType import software.amazon.smithy.rust.codegen.smithy.traits.InputBodyTrait Loading Loading @@ -250,7 +250,7 @@ class BasicAwsJsonGenerator( val outputShape = operationIndex.getOutput(operationShape).get() val errorSymbol = operationShape.errorSymbol(symbolProvider) val jsonErrors = RuntimeType.awsJsonErrors(protocolConfig.runtimeConfig) val generator = SerdeJsonParserGenerator(protocolConfig) val generator = JsonParserGenerator(protocolConfig, AwsJsonHttpBindingResolver(model, awsJsonVersion)) fromResponseFun(implBlockWriter, operationShape) { rustBlock("if #T::is_error(&response)", jsonErrors) { Loading
codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/protocols/HttpBindingResolver.kt +6 −0 Original line number Diff line number Diff line Loading @@ -59,6 +59,12 @@ interface HttpBindingResolver { fun requestMembers(operationShape: OperationShape, location: HttpLocation): List<MemberShape> = requestBindings(operationShape).filter { it.location == location }.map { it.member } /** * Returns a list of member shapes bound to a given response [location] for a given [operationShape] */ fun responseMembers(operationShape: OperationShape, location: HttpLocation): List<MemberShape> = responseBindings(operationShape).filter { it.location == location }.map { it.member } /** * Determine the timestamp format based on the input parameters. */ Loading
codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/protocols/RestJson.kt +3 −3 Original line number Diff line number Diff line Loading @@ -18,7 +18,7 @@ import software.amazon.smithy.rust.codegen.smithy.RustSymbolProvider 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.ProtocolSupport import software.amazon.smithy.rust.codegen.smithy.protocols.parse.SerdeJsonParserGenerator import software.amazon.smithy.rust.codegen.smithy.protocols.parse.JsonParserGenerator import software.amazon.smithy.rust.codegen.smithy.protocols.parse.StructuredDataParserGenerator import software.amazon.smithy.rust.codegen.smithy.protocols.serialize.JsonSerializerGenerator import software.amazon.smithy.rust.codegen.smithy.protocols.serialize.StructuredDataSerializerGenerator Loading Loading @@ -83,7 +83,7 @@ class RestJson(private val protocolConfig: ProtocolConfig) : Protocol { override val defaultTimestampFormat: TimestampFormatTrait.Format = TimestampFormatTrait.Format.EPOCH_SECONDS override fun structuredDataParser(operationShape: OperationShape): StructuredDataParserGenerator { return SerdeJsonParserGenerator(protocolConfig) return JsonParserGenerator(protocolConfig, httpBindingResolver) } override fun structuredDataSerializer(operationShape: OperationShape): StructuredDataSerializerGenerator { Loading