Loading codegen-test/build.gradle.kts +12 −0 Original line number Diff line number Diff line Loading @@ -44,6 +44,18 @@ val CodegenTests = listOf( "aws.protocoltests.restxml#RestXml", "rest_xml" ), CodegenTest( "aws.protocoltests.restxml.xmlns#RestXmlWithNamespace", "rest_xml_namespace" ), CodegenTest( "aws.protocoltests.restxml#RestXmlExtras", "rest_xml_extras" ), CodegenTest( "aws.protocoltests.restxmlunwrapped#RestXmlExtrasUnwrappedErrors", "rest_xml_extras_unwrapped" ), CodegenTest( "crate#Config", "naming_test", """ Loading codegen-test/model/rest-xml-extras.smithy 0 → 100644 +100 −0 Original line number Diff line number Diff line $version: "1.0" namespace aws.protocoltests.restxml use aws.protocols#restXml use aws.api#service use smithy.test#httpResponseTests /// A REST XML service that sends XML requests and responses. @service(sdkId: "Rest XML Protocol") @restXml service RestXmlExtras { version: "2019-12-16", operations: [AttributeParty, XmlMapsFlattenedNestedXmlNamespace] } @enum([{"value": "enumvalue", "name": "V"}]) string StringEnum integer PrimitiveInt structure AttributePartyInputOutput { @xmlAttribute enum: StringEnum, @xmlAttribute @xmlName("prefix:anumber") number: PrimitiveInt, @xmlAttribute ts: Timestamp, @xmlAttribute bool: Boolean } @httpResponseTests([{ id: "DeserAttributes", code: 200, body: "<AttributePartyInputOutput enum=\"enumvalue\" prefix:anumber=\"5\" ts=\"1985-04-12T23:20:50.00Z\" bool=\"true\"/>", params: { enum: "enumvalue", number: 5, ts: 482196050, bool: true }, protocol: "aws.protocols#restXml" }]) @http(uri: "/AttributeParty", method: "POST") operation AttributeParty { output: AttributePartyInputOutput } @httpResponseTests([{ id: "DeserFlatNamespaceMaps", code: 200, body: "<XmlMapsFlattenedNestedXmlNamespaceInputOutput xmlns=\"http://aoo.com\"><myMap><yek xmlns=\"http://doo.com\">map2</yek><eulav xmlns=\"http://eoo.com\"><entry><K xmlns=\"http://goo.com\">third</K><V xmlns=\"http://hoo.com\">plz</V></entry><entry><K xmlns=\"http://goo.com\">fourth</K><V xmlns=\"http://hoo.com\">onegai</V></entry></eulav></myMap><myMap><yek xmlns=\"http://doo.com\">map1</yek><eulav xmlns=\"http://eoo.com\"><entry><K xmlns=\"http://goo.com\">second</K><V xmlns=\"http://hoo.com\">konnichiwa</V></entry><entry><K xmlns=\"http://goo.com\">first</K><V xmlns=\"http://hoo.com\">hi</V></entry></eulav></myMap></XmlMapsFlattenedNestedXmlNamespaceInput>", params: { "myMap": { "map2": {"fourth": "onegai", "third": "plz" }, "map1": {"second": "konnichiwa", "first": "hi" } } }, protocol: "aws.protocols#restXml" }]) @http(uri: "/XmlMapsFlattenedNestedXmlNamespace", method: "POST") operation XmlMapsFlattenedNestedXmlNamespace { input: XmlMapsFlattenedNestedXmlNamespaceInputOutput, output: XmlMapsFlattenedNestedXmlNamespaceInputOutput } @xmlNamespace(uri: "http://aoo.com") structure XmlMapsFlattenedNestedXmlNamespaceInputOutput { @xmlNamespace(uri: "http://boo.com") @xmlFlattened myMap: XmlMapsNestedNamespaceInputOutputMap, } @xmlNamespace(uri: "http://coo.com") map XmlMapsNestedNamespaceInputOutputMap { @xmlNamespace(uri: "http://doo.com") @xmlName("yek") key: String, @xmlNamespace(uri: "http://eoo.com") @xmlName("eulav") value: XmlMapsNestedNestedNamespaceInputOutputMap } @xmlNamespace(uri: "http://foo.com") map XmlMapsNestedNestedNamespaceInputOutputMap { @xmlNamespace(uri: "http://goo.com") @xmlName("K") key: String, @xmlNamespace(uri: "http://hoo.com") @xmlName("V") value: String } codegen-test/model/rest-xml-unwrapped-errors.smithy 0 → 100644 +137 −0 Original line number Diff line number Diff line // This file defines test cases that test error serialization. $version: "1.0" namespace aws.protocoltests.restxmlunwrapped use aws.protocols#restXml use smithy.test#httpRequestTests use smithy.test#httpResponseTests use aws.api#service /// A REST XML service that sends XML requests and responses. @service(sdkId: "Rest XML Protocol") @restXml(noErrorWrapping: true) service RestXmlExtrasUnwrappedErrors { version: "2019-12-16", operations: [GreetingWithUnwrappedErrors] } /// This operation has three possible return values: /// /// 1. A successful response in the form of GreetingWithErrorsOutput /// 2. An InvalidGreeting error. /// 3. A BadRequest error. /// /// Implementations must be able to successfully take a response and /// properly (de)serialize successful and error responses based on the /// the presence of the @idempotent @http(uri: "/GreetingWithErrors", method: "PUT") operation GreetingWithUnwrappedErrors { output: GreetingWithErrorsOutput, errors: [InvalidGreetingUnwrapped, ComplexErrorUnwrapped] } apply GreetingWithUnwrappedErrors @httpResponseTests([ { id: "GreetingWithErrorsUnwrapped", documentation: "Ensures that operations with errors successfully know how to deserialize the successful response", protocol: restXml, code: 200, body: "", headers: { "X-Greeting": "Hello" }, params: { greeting: "Hello" } } ]) structure GreetingWithErrorsOutput { @httpHeader("X-Greeting") greeting: String, } /// This error is thrown when an invalid greeting value is provided. @error("client") @httpError(400) structure InvalidGreetingUnwrapped { Message: String, } apply InvalidGreetingUnwrapped @httpResponseTests([ { id: "InvalidGreetingErrorUnwrapped", documentation: "Parses simple XML errors", protocol: restXml, params: { Message: "Hi" }, code: 400, headers: { "Content-Type": "application/xml" }, body: """ <Error> <Type>Sender</Type> <Code>InvalidGreetingUnwrapped</Code> <Message>Hi</Message> <AnotherSetting>setting</AnotherSetting> <RequestId>foo-id</RequestId> </Error> """, bodyMediaType: "application/xml", } ]) /// This error is thrown when a request is invalid. @error("client") @httpError(403) structure ComplexErrorUnwrapped { // Errors support HTTP bindings! @httpHeader("X-Header") Header: String, TopLevel: String, Nested: ComplexNestedErrorData, } apply ComplexErrorUnwrapped @httpResponseTests([ { id: "ComplexErrorUnwrapped", protocol: restXml, params: { Header: "Header", TopLevel: "Top level", Nested: { Foo: "bar" } }, code: 400, headers: { "Content-Type": "application/xml", "X-Header": "Header", }, body: """ <Error> <Type>Sender</Type> <Code>ComplexErrorUnwrapped</Code> <Message>Hi</Message> <TopLevel>Top level</TopLevel> <Nested> <Foo>bar</Foo> </Nested> <RequestId>foo-id</RequestId> </Error> """, bodyMediaType: "application/xml", } ]) structure ComplexNestedErrorData { Foo: String, } codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/protocols/parsers/XmlBindingTraitParserGenerator.kt +6 −0 Original line number Diff line number Diff line Loading @@ -135,6 +135,7 @@ class XmlBindingTraitParserGenerator(protocolConfig: ProtocolConfig, private val """ use std::convert::TryFrom; let mut doc = #{Document}::try_from(inp)?; ##[allow(unused_mut)] let mut decoder = doc.root_element()?; let start_el = decoder.start_el(); if !(${shapeName.compareTo("start_el")}) { Loading Loading @@ -189,6 +190,7 @@ class XmlBindingTraitParserGenerator(protocolConfig: ProtocolConfig, private val """ use std::convert::TryFrom; let mut doc = #{Document}::try_from(inp)?; ##[allow(unused_mut)] let mut decoder = doc.root_element()?; let start_el = decoder.start_el(); if !(${shapeName.compareTo("start_el")}) { Loading Loading @@ -249,6 +251,10 @@ class XmlBindingTraitParserGenerator(protocolConfig: ProtocolConfig, private val } rust("$builder.${symbolProvider.toMemberName(member)} = $temp;") } // No need to generate a parse loop if there are no non-attribute members if (members.dataMembers.isEmpty()) { return } parseLoop(outerCtx) { ctx -> members.dataMembers.forEach { member -> case(member) { Loading Loading
codegen-test/build.gradle.kts +12 −0 Original line number Diff line number Diff line Loading @@ -44,6 +44,18 @@ val CodegenTests = listOf( "aws.protocoltests.restxml#RestXml", "rest_xml" ), CodegenTest( "aws.protocoltests.restxml.xmlns#RestXmlWithNamespace", "rest_xml_namespace" ), CodegenTest( "aws.protocoltests.restxml#RestXmlExtras", "rest_xml_extras" ), CodegenTest( "aws.protocoltests.restxmlunwrapped#RestXmlExtrasUnwrappedErrors", "rest_xml_extras_unwrapped" ), CodegenTest( "crate#Config", "naming_test", """ Loading
codegen-test/model/rest-xml-extras.smithy 0 → 100644 +100 −0 Original line number Diff line number Diff line $version: "1.0" namespace aws.protocoltests.restxml use aws.protocols#restXml use aws.api#service use smithy.test#httpResponseTests /// A REST XML service that sends XML requests and responses. @service(sdkId: "Rest XML Protocol") @restXml service RestXmlExtras { version: "2019-12-16", operations: [AttributeParty, XmlMapsFlattenedNestedXmlNamespace] } @enum([{"value": "enumvalue", "name": "V"}]) string StringEnum integer PrimitiveInt structure AttributePartyInputOutput { @xmlAttribute enum: StringEnum, @xmlAttribute @xmlName("prefix:anumber") number: PrimitiveInt, @xmlAttribute ts: Timestamp, @xmlAttribute bool: Boolean } @httpResponseTests([{ id: "DeserAttributes", code: 200, body: "<AttributePartyInputOutput enum=\"enumvalue\" prefix:anumber=\"5\" ts=\"1985-04-12T23:20:50.00Z\" bool=\"true\"/>", params: { enum: "enumvalue", number: 5, ts: 482196050, bool: true }, protocol: "aws.protocols#restXml" }]) @http(uri: "/AttributeParty", method: "POST") operation AttributeParty { output: AttributePartyInputOutput } @httpResponseTests([{ id: "DeserFlatNamespaceMaps", code: 200, body: "<XmlMapsFlattenedNestedXmlNamespaceInputOutput xmlns=\"http://aoo.com\"><myMap><yek xmlns=\"http://doo.com\">map2</yek><eulav xmlns=\"http://eoo.com\"><entry><K xmlns=\"http://goo.com\">third</K><V xmlns=\"http://hoo.com\">plz</V></entry><entry><K xmlns=\"http://goo.com\">fourth</K><V xmlns=\"http://hoo.com\">onegai</V></entry></eulav></myMap><myMap><yek xmlns=\"http://doo.com\">map1</yek><eulav xmlns=\"http://eoo.com\"><entry><K xmlns=\"http://goo.com\">second</K><V xmlns=\"http://hoo.com\">konnichiwa</V></entry><entry><K xmlns=\"http://goo.com\">first</K><V xmlns=\"http://hoo.com\">hi</V></entry></eulav></myMap></XmlMapsFlattenedNestedXmlNamespaceInput>", params: { "myMap": { "map2": {"fourth": "onegai", "third": "plz" }, "map1": {"second": "konnichiwa", "first": "hi" } } }, protocol: "aws.protocols#restXml" }]) @http(uri: "/XmlMapsFlattenedNestedXmlNamespace", method: "POST") operation XmlMapsFlattenedNestedXmlNamespace { input: XmlMapsFlattenedNestedXmlNamespaceInputOutput, output: XmlMapsFlattenedNestedXmlNamespaceInputOutput } @xmlNamespace(uri: "http://aoo.com") structure XmlMapsFlattenedNestedXmlNamespaceInputOutput { @xmlNamespace(uri: "http://boo.com") @xmlFlattened myMap: XmlMapsNestedNamespaceInputOutputMap, } @xmlNamespace(uri: "http://coo.com") map XmlMapsNestedNamespaceInputOutputMap { @xmlNamespace(uri: "http://doo.com") @xmlName("yek") key: String, @xmlNamespace(uri: "http://eoo.com") @xmlName("eulav") value: XmlMapsNestedNestedNamespaceInputOutputMap } @xmlNamespace(uri: "http://foo.com") map XmlMapsNestedNestedNamespaceInputOutputMap { @xmlNamespace(uri: "http://goo.com") @xmlName("K") key: String, @xmlNamespace(uri: "http://hoo.com") @xmlName("V") value: String }
codegen-test/model/rest-xml-unwrapped-errors.smithy 0 → 100644 +137 −0 Original line number Diff line number Diff line // This file defines test cases that test error serialization. $version: "1.0" namespace aws.protocoltests.restxmlunwrapped use aws.protocols#restXml use smithy.test#httpRequestTests use smithy.test#httpResponseTests use aws.api#service /// A REST XML service that sends XML requests and responses. @service(sdkId: "Rest XML Protocol") @restXml(noErrorWrapping: true) service RestXmlExtrasUnwrappedErrors { version: "2019-12-16", operations: [GreetingWithUnwrappedErrors] } /// This operation has three possible return values: /// /// 1. A successful response in the form of GreetingWithErrorsOutput /// 2. An InvalidGreeting error. /// 3. A BadRequest error. /// /// Implementations must be able to successfully take a response and /// properly (de)serialize successful and error responses based on the /// the presence of the @idempotent @http(uri: "/GreetingWithErrors", method: "PUT") operation GreetingWithUnwrappedErrors { output: GreetingWithErrorsOutput, errors: [InvalidGreetingUnwrapped, ComplexErrorUnwrapped] } apply GreetingWithUnwrappedErrors @httpResponseTests([ { id: "GreetingWithErrorsUnwrapped", documentation: "Ensures that operations with errors successfully know how to deserialize the successful response", protocol: restXml, code: 200, body: "", headers: { "X-Greeting": "Hello" }, params: { greeting: "Hello" } } ]) structure GreetingWithErrorsOutput { @httpHeader("X-Greeting") greeting: String, } /// This error is thrown when an invalid greeting value is provided. @error("client") @httpError(400) structure InvalidGreetingUnwrapped { Message: String, } apply InvalidGreetingUnwrapped @httpResponseTests([ { id: "InvalidGreetingErrorUnwrapped", documentation: "Parses simple XML errors", protocol: restXml, params: { Message: "Hi" }, code: 400, headers: { "Content-Type": "application/xml" }, body: """ <Error> <Type>Sender</Type> <Code>InvalidGreetingUnwrapped</Code> <Message>Hi</Message> <AnotherSetting>setting</AnotherSetting> <RequestId>foo-id</RequestId> </Error> """, bodyMediaType: "application/xml", } ]) /// This error is thrown when a request is invalid. @error("client") @httpError(403) structure ComplexErrorUnwrapped { // Errors support HTTP bindings! @httpHeader("X-Header") Header: String, TopLevel: String, Nested: ComplexNestedErrorData, } apply ComplexErrorUnwrapped @httpResponseTests([ { id: "ComplexErrorUnwrapped", protocol: restXml, params: { Header: "Header", TopLevel: "Top level", Nested: { Foo: "bar" } }, code: 400, headers: { "Content-Type": "application/xml", "X-Header": "Header", }, body: """ <Error> <Type>Sender</Type> <Code>ComplexErrorUnwrapped</Code> <Message>Hi</Message> <TopLevel>Top level</TopLevel> <Nested> <Foo>bar</Foo> </Nested> <RequestId>foo-id</RequestId> </Error> """, bodyMediaType: "application/xml", } ]) structure ComplexNestedErrorData { Foo: String, }
codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/protocols/parsers/XmlBindingTraitParserGenerator.kt +6 −0 Original line number Diff line number Diff line Loading @@ -135,6 +135,7 @@ class XmlBindingTraitParserGenerator(protocolConfig: ProtocolConfig, private val """ use std::convert::TryFrom; let mut doc = #{Document}::try_from(inp)?; ##[allow(unused_mut)] let mut decoder = doc.root_element()?; let start_el = decoder.start_el(); if !(${shapeName.compareTo("start_el")}) { Loading Loading @@ -189,6 +190,7 @@ class XmlBindingTraitParserGenerator(protocolConfig: ProtocolConfig, private val """ use std::convert::TryFrom; let mut doc = #{Document}::try_from(inp)?; ##[allow(unused_mut)] let mut decoder = doc.root_element()?; let start_el = decoder.start_el(); if !(${shapeName.compareTo("start_el")}) { Loading Loading @@ -249,6 +251,10 @@ class XmlBindingTraitParserGenerator(protocolConfig: ProtocolConfig, private val } rust("$builder.${symbolProvider.toMemberName(member)} = $temp;") } // No need to generate a parse loop if there are no non-attribute members if (members.dataMembers.isEmpty()) { return } parseLoop(outerCtx) { ctx -> members.dataMembers.forEach { member -> case(member) { Loading