Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Jmespath shape traversal codegen to support multi-select lists following projection expressions #3987

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ async fn assert_error_not_transient(error: ReplayedEvent) {
let client = Client::from_conf(config);
let _item = client
.get_item()
.table_name("arn:aws:dynamodb:us-east-2:333333333333:table/table_name")
.key("foo", AttributeValue::Bool(true))
.send()
.await
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import software.amazon.smithy.rust.codegen.client.smithy.generators.config.confi
import software.amazon.smithy.rust.codegen.client.smithy.generators.config.loadFromConfigBag
import software.amazon.smithy.rust.codegen.client.smithy.generators.waiters.RustJmespathShapeTraversalGenerator
import software.amazon.smithy.rust.codegen.client.smithy.generators.waiters.TraversalBinding
import software.amazon.smithy.rust.codegen.client.smithy.generators.waiters.TraversalContext
import software.amazon.smithy.rust.codegen.client.smithy.generators.waiters.TraversedShape
import software.amazon.smithy.rust.codegen.core.rustlang.CargoDependency
import software.amazon.smithy.rust.codegen.core.rustlang.RustType
Expand Down Expand Up @@ -168,16 +169,18 @@ class EndpointParamsInterceptorGenerator(
TraversedShape.from(model, operationShape.inputShape(model)),
),
),
TraversalContext(retainOption = false),
)

when (pathTraversal.outputType) {
is RustType.Vec -> {
rust(".$setterName($getterName(_input))")
}

else -> {
rust(".$setterName($getterName(_input).cloned())")
if (pathTraversal.outputType.member is RustType.Reference) {
rust(".$setterName($getterName(_input).map(|v| v.into_iter().cloned().collect::<Vec<_>>()))")
} else {
rust(".$setterName($getterName(_input))")
}
}
else -> rust(".$setterName($getterName(_input).cloned())")
}
}

Expand Down Expand Up @@ -211,6 +214,7 @@ class EndpointParamsInterceptorGenerator(
TraversedShape.from(model, operationShape.inputShape(model)),
),
),
TraversalContext(retainOption = false),
)

rust("// Generated from JMESPath Expression: $pathValue")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,8 @@ internal class EndpointResolverGenerator(
"clippy::comparison_to_empty",
// we generate `if let Some(_) = ... { ... }`
"clippy::redundant_pattern_matching",
// we generate `if (s.as_ref() as &str) == ("arn:") { ... }`, and `s` can be either `String` or `&str`
"clippy::useless_asref",
)
private val context = Context(registry, runtimeConfig)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import software.amazon.smithy.rulesengine.traits.ExpectedEndpoint
import software.amazon.smithy.rust.codegen.client.smithy.ClientCodegenContext
import software.amazon.smithy.rust.codegen.client.smithy.endpoint.Types
import software.amazon.smithy.rust.codegen.client.smithy.endpoint.rustName
import software.amazon.smithy.rust.codegen.client.smithy.generators.ClientInstantiator
import software.amazon.smithy.rust.codegen.core.rustlang.Writable
import software.amazon.smithy.rust.codegen.core.rustlang.docs
import software.amazon.smithy.rust.codegen.core.rustlang.escape
Expand Down Expand Up @@ -50,8 +49,6 @@ internal class EndpointTestGenerator(
"capture_request" to RuntimeType.captureRequest(runtimeConfig),
)

private val instantiator = ClientInstantiator(codegenContext)

private fun EndpointTestCase.docs(): Writable {
val self = this
return writable { docs(self.documentation.orElse("no docs")) }
Expand Down Expand Up @@ -134,7 +131,23 @@ internal class EndpointTestGenerator(
value.values.map { member ->
writable {
rustTemplate(
"#{Document}::from(#{value:W})",
/*
* If we wrote "#{Document}::from(#{value:W})" here, we could encounter a
* compile error due to the following type mismatch:
* the trait `From<Vec<Document>>` is not implemented for `Vec<std::string::String>`
*
* given the following method signature:
* fn resource_arn_list(mut self, value: impl Into<::std::vec::Vec<::std::string::String>>)
*
* with a call site like this:
* .resource_arn_list(vec![::aws_smithy_types::Document::from(
* "arn:aws:dynamodb:us-east-1:333333333333:table/table_name".to_string(),
* )])
*
* For this reason we use `into()` instead to allow types that need to be converted
* to `Document` to continue working as before, and to support the above use case.
*/
"#{value:W}.into()",
*codegenScope,
"value" to generateValue(member),
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ package software.amazon.smithy.rust.codegen.client.smithy.endpoint.rulesgen
import org.jetbrains.annotations.Contract
import software.amazon.smithy.rulesengine.language.evaluation.type.BooleanType
import software.amazon.smithy.rulesengine.language.evaluation.type.OptionalType
import software.amazon.smithy.rulesengine.language.evaluation.type.StringType
import software.amazon.smithy.rulesengine.language.evaluation.type.Type
import software.amazon.smithy.rulesengine.language.syntax.expressions.Expression
import software.amazon.smithy.rulesengine.language.syntax.expressions.ExpressionVisitor
Expand All @@ -24,6 +25,7 @@ import software.amazon.smithy.rust.codegen.core.rustlang.rust
import software.amazon.smithy.rust.codegen.core.rustlang.rustTemplate
import software.amazon.smithy.rust.codegen.core.rustlang.writable
import software.amazon.smithy.rust.codegen.core.util.PANIC
import java.lang.RuntimeException

/**
* Root expression generator.
Expand Down Expand Up @@ -56,7 +58,18 @@ class ExpressionGenerator(
else -> rust("${ref.name.rustName()}.to_owned()")
}
} else {
rust(ref.name.rustName())
try {
when (ref.type()) {
// This ensures we obtain a `&str`, regardless of whether `ref.name.rustName()` returns a `String` or a `&str`.
// Typically, we don't know which type will be returned due to code generation.
is StringType -> rust("${ref.name.rustName()}.as_ref() as &str")
else -> rust(ref.name.rustName())
}
} catch (_: RuntimeException) {
// Because Typechecking was never invoked upon calling `.type()` on Reference for an expression
// like "{ref}: rust". See `generateLiterals2` in ExprGeneratorTest.
rust(ref.name.rustName())
}
}
}

Expand Down
Loading
Loading