mirror of https://github.com/smithy-lang/smithy-rs
Add Polly, ApiGateway, fix bugs. (#283)
* wip * Fixes for Polly & API Gateway * Add ApiGateway and Polly Models * Fix ktLint issues * backport clippy ignores * remap timeout error * Format * Fix error handling on timeout * Ignore another clippy lint
This commit is contained in:
parent
138320e99e
commit
9aa7881a1d
|
@ -21,7 +21,6 @@ val kotestVersion: String by project
|
|||
|
||||
dependencies {
|
||||
implementation(project(":codegen"))
|
||||
implementation("software.amazon.smithy:smithy-aws-protocol-tests:$smithyVersion")
|
||||
implementation("software.amazon.smithy:smithy-protocol-test-traits:$smithyVersion")
|
||||
implementation("software.amazon.smithy:smithy-aws-traits:$smithyVersion")
|
||||
testImplementation("org.junit.jupiter:junit-jupiter:5.6.1")
|
||||
|
|
|
@ -31,7 +31,6 @@ buildscript {
|
|||
|
||||
dependencies {
|
||||
implementation(project(":aws:sdk-codegen"))
|
||||
implementation("software.amazon.smithy:smithy-aws-protocol-tests:$smithyVersion")
|
||||
implementation("software.amazon.smithy:smithy-protocol-test-traits:$smithyVersion")
|
||||
implementation("software.amazon.smithy:smithy-aws-traits:$smithyVersion")
|
||||
}
|
||||
|
@ -221,8 +220,7 @@ tasks.register<Exec>("cargoDocs") {
|
|||
tasks.register<Exec>("cargoClippy") {
|
||||
workingDir(sdkOutputDir)
|
||||
// disallow warnings
|
||||
environment("RUSTFLAGS", "-D warnings")
|
||||
commandLine("cargo", "clippy")
|
||||
commandLine("cargo", "clippy", "--", "-D", "warnings", "-Aclippy::upper_case_acronyms", "-Aclippy::large-enum-variant", "-Aclippy::module-inception")
|
||||
dependsOn("assemble")
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
|
@ -132,8 +132,7 @@ tasks.register<Exec>("cargoDocs") {
|
|||
tasks.register<Exec>("cargoClippy") {
|
||||
workingDir("build/smithyprojections/codegen-test/")
|
||||
// disallow warnings
|
||||
environment("RUSTFLAGS", "-D warnings")
|
||||
commandLine("cargo", "clippy")
|
||||
commandLine("cargo", "clippy", "--", "-D", "warnings", "-Aclippy::upper_case_acronyms", "-Aclippy::large-enum-variant")
|
||||
dependsOn("assemble")
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ namespace aws.protocoltests.restjson
|
|||
use aws.protocols#restJson1
|
||||
use aws.api#service
|
||||
use smithy.test#httpRequestTests
|
||||
use smithy.test#httpResponseTests
|
||||
|
||||
|
||||
/// A REST JSON service that sends JSON requests and responses.
|
||||
|
@ -12,7 +13,7 @@ use smithy.test#httpRequestTests
|
|||
@restJson1
|
||||
service RestJsonExtras {
|
||||
version: "2019-12-16",
|
||||
operations: [EnumPayload, StringPayload]
|
||||
operations: [EnumPayload, StringPayload, PrimitiveIntHeader, EnumQuery]
|
||||
}
|
||||
|
||||
@http(uri: "/EnumPayload", method: "POST")
|
||||
|
@ -59,3 +60,45 @@ structure StringPayloadInput {
|
|||
@httpPayload
|
||||
payload: String
|
||||
}
|
||||
|
||||
@httpResponseTests([
|
||||
{
|
||||
id: "DeserPrimitiveHeader",
|
||||
protocol: "aws.protocols#restJson1",
|
||||
code: 200,
|
||||
headers: { "x-field": "123" },
|
||||
params: { field: 123 }
|
||||
}
|
||||
])
|
||||
@http(uri: "/primitive", method: "POST")
|
||||
operation PrimitiveIntHeader {
|
||||
output: PrimitiveIntHeaderInput
|
||||
}
|
||||
|
||||
integer PrimitiveInt
|
||||
|
||||
structure PrimitiveIntHeaderInput {
|
||||
@httpHeader("x-field")
|
||||
@required
|
||||
field: PrimitiveInt
|
||||
}
|
||||
|
||||
@http(uri: "/foo/{enum}", method: "GET")
|
||||
@httpRequestTests([
|
||||
{
|
||||
id: "EnumQueryRequest",
|
||||
uri: "/foo/enumvalue",
|
||||
params: { enum: "enumvalue" },
|
||||
method: "GET",
|
||||
protocol: "aws.protocols#restJson1"
|
||||
}
|
||||
])
|
||||
operation EnumQuery {
|
||||
input: EnumQueryInput
|
||||
}
|
||||
|
||||
structure EnumQueryInput {
|
||||
@httpLabel
|
||||
@required
|
||||
enum: StringEnum
|
||||
}
|
|
@ -17,7 +17,6 @@ import software.amazon.smithy.model.shapes.NumberShape
|
|||
import software.amazon.smithy.model.shapes.Shape
|
||||
import software.amazon.smithy.model.shapes.ShapeId
|
||||
import software.amazon.smithy.model.traits.DocumentationTrait
|
||||
import software.amazon.smithy.model.traits.EnumTrait
|
||||
import software.amazon.smithy.rust.codegen.smithy.RuntimeType
|
||||
import software.amazon.smithy.rust.codegen.smithy.isOptional
|
||||
import software.amazon.smithy.rust.codegen.smithy.rustType
|
||||
|
@ -309,14 +308,6 @@ class RustWriter private constructor(
|
|||
return formatter.apply(r, "")
|
||||
}
|
||||
|
||||
fun useAs(target: Shape, base: String): String {
|
||||
return if (target.hasTrait(EnumTrait::class.java)) {
|
||||
"$base.as_str()"
|
||||
} else {
|
||||
base
|
||||
}
|
||||
}
|
||||
|
||||
fun addDepsRecursively(symbol: Symbol) {
|
||||
addDependency(symbol)
|
||||
symbol.references.forEach { addDepsRecursively(it.symbol) }
|
||||
|
|
|
@ -91,7 +91,7 @@ class CodegenVisitor(context: PluginContext, private val codegenDecorator: RustC
|
|||
)
|
||||
)
|
||||
try {
|
||||
"cargo fmt".runCommand(fileManifest.baseDir, timeout = 5)
|
||||
"cargo fmt".runCommand(fileManifest.baseDir, timeout = 10)
|
||||
} catch (_: CommandFailed) {
|
||||
logger.warning("Generated output did not parse [${service.id}]")
|
||||
}
|
||||
|
|
|
@ -45,6 +45,11 @@ class EnumGenerator(
|
|||
writer.insertTrailingNewline()
|
||||
// impl Blah { pub fn as_str(&self) -> &str
|
||||
implBlock()
|
||||
writer.rustBlock("impl AsRef<str> for $enumName") {
|
||||
writer.rustBlock("fn as_ref(&self) -> &str") {
|
||||
rust("self.as_str()")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
renderUnamedEnum()
|
||||
}
|
||||
|
@ -132,9 +137,9 @@ class EnumGenerator(
|
|||
}
|
||||
|
||||
private fun renderFromStr() {
|
||||
writer.rustBlock("impl <T> #T<T> for $enumName where T: #T<str>", RuntimeType.From, RuntimeType.AsRef) {
|
||||
writer.rustBlock("fn from(s: T) -> Self") {
|
||||
writer.rustBlock("match s.as_ref()") {
|
||||
writer.rustBlock("impl #T<&str> for $enumName", RuntimeType.From) {
|
||||
writer.rustBlock("fn from(s: &str) -> Self") {
|
||||
writer.rustBlock("match s") {
|
||||
sortedMembers.forEach { member ->
|
||||
write(""""${member.value}" => $enumName::${member.derivedName()},""")
|
||||
}
|
||||
|
|
|
@ -203,12 +203,11 @@ class RequestBindingGenerator(
|
|||
private fun headerFmtFun(target: Shape, member: MemberShape, targetName: String): String {
|
||||
return when {
|
||||
target.isStringShape -> {
|
||||
/*val func = */ if (target.hasTrait(MediaTypeTrait::class.java)) {
|
||||
if (target.hasTrait(MediaTypeTrait::class.java)) {
|
||||
val func = writer.format(RuntimeType.Base64Encode(runtimeConfig))
|
||||
"$func(&${writer.useAs(target, targetName)})"
|
||||
"$func(&$targetName)"
|
||||
} else {
|
||||
writer.useAs(target, targetName)
|
||||
// writer.format(RuntimeType.QueryFormat(runtimeConfig, "fmt_string"))
|
||||
"AsRef::<str>::as_ref($targetName)"
|
||||
}
|
||||
}
|
||||
target.isTimestampShape -> {
|
||||
|
@ -311,7 +310,7 @@ class RequestBindingGenerator(
|
|||
return when {
|
||||
target.isStringShape -> {
|
||||
val func = writer.format(RuntimeType.QueryFormat(runtimeConfig, "fmt_string"))
|
||||
"$func(&${writer.useAs(target, targetName)})"
|
||||
"$func(&$targetName)"
|
||||
}
|
||||
target.isTimestampShape -> {
|
||||
val timestampFormat =
|
||||
|
|
|
@ -181,6 +181,7 @@ class ResponseBindingGenerator(protocolConfig: ProtocolConfig, private val opera
|
|||
*/
|
||||
private fun RustWriter.deserializeFromHeader(targetType: Shape, memberShape: MemberShape) {
|
||||
val rustType = symbolProvider.toSymbol(targetType).rustType().stripOuter<RustType.Option>()
|
||||
val fieldRequired = symbolProvider.toSymbol(memberShape).rustType() !is RustType.Option
|
||||
val (coreType, coreShape) = if (targetType is CollectionShape) {
|
||||
rustType.stripOuter<RustType.Container>() to model.expectShape(targetType.member.target)
|
||||
} else {
|
||||
|
@ -240,8 +241,9 @@ class ResponseBindingGenerator(protocolConfig: ProtocolConfig, private val opera
|
|||
"""
|
||||
)
|
||||
else ->
|
||||
rustTemplate(
|
||||
"""
|
||||
if (!fieldRequired) {
|
||||
rustTemplate(
|
||||
"""
|
||||
if $parsedValue.len() > 1 {
|
||||
Err(#{header_util}::ParseError)
|
||||
} else {
|
||||
|
@ -249,8 +251,21 @@ class ResponseBindingGenerator(protocolConfig: ProtocolConfig, private val opera
|
|||
Ok($parsedValue.pop())
|
||||
}
|
||||
""",
|
||||
"header_util" to headerUtil
|
||||
)
|
||||
"header_util" to headerUtil
|
||||
)
|
||||
} else {
|
||||
rustTemplate(
|
||||
"""
|
||||
if $parsedValue.len() > 1 {
|
||||
Err(#{header_util}::ParseError)
|
||||
} else {
|
||||
let mut $parsedValue = $parsedValue;
|
||||
$parsedValue.pop().ok_or(#{header_util}::ParseError)
|
||||
}
|
||||
""",
|
||||
"header_util" to headerUtil
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,13 +23,16 @@ fun String.runCommand(workdir: Path? = null, environment: Map<String, String> =
|
|||
val env = builder.environment()
|
||||
environment.forEach { (k, v) -> env[k] = v }
|
||||
val proc = builder.start()
|
||||
|
||||
proc.waitFor(timeout, TimeUnit.SECONDS)
|
||||
val stdErr = proc.errorStream.bufferedReader().readText()
|
||||
val stdOut = proc.inputStream.bufferedReader().readText()
|
||||
val output = "$stdErr\n$stdOut"
|
||||
return when (proc.exitValue()) {
|
||||
0 -> output
|
||||
else -> throw CommandFailed("Command Failed\n$output")
|
||||
try {
|
||||
return when (proc.exitValue()) {
|
||||
0 -> output
|
||||
else -> throw CommandFailed("Command Failed\n$output")
|
||||
}
|
||||
} catch (_: IllegalThreadStateException) {
|
||||
throw CommandFailed("Timeout")
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue