Skip to content

Commit

Permalink
Merge branch 'awslabs:main' into rfc30/number
Browse files Browse the repository at this point in the history
  • Loading branch information
thomas-k-cameron committed Jan 20, 2023
2 parents af18f92 + 4436d9a commit d75eafd
Show file tree
Hide file tree
Showing 46 changed files with 549 additions and 2,257 deletions.
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v2.3.0
rev: v4.4.0
hooks:
- id: check-yaml
- id: end-of-file-fixer
Expand All @@ -20,7 +20,7 @@ repos:
files: ^.*$
pass_filenames: false
- repo: https://github.com/macisamuele/language-formatters-pre-commit-hooks
rev: v1.6.1
rev: v2.5.0
hooks:
- id: pretty-format-kotlin
args: [--autofix, --ktlint-version, 0.46.1]
Expand Down
2 changes: 1 addition & 1 deletion aws/SDK_CHANGELOG.next.json
Original file line number Diff line number Diff line change
Expand Up @@ -774,4 +774,4 @@
}
],
"aws-sdk-model": []
}
}
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ allprojects.forEach {

it.the<JacocoPluginExtension>().apply {
toolVersion = "0.8.8"
reportsDirectory.set(file("${buildDir}/jacoco-reports"))
reportsDirectory.set(file("$buildDir/jacoco-reports"))
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -229,12 +229,12 @@ class InstantiatorTest {
fun `generate maps of maps`() {
val data = Node.parse(
"""
{
"k1": { "map": {} },
"k2": { "map": { "k3": {} } },
"k3": { }
}
""",
{
"k1": { "map": {} },
"k2": { "map": { "k3": {} } },
"k3": { }
}
""",
)
val sut = Instantiator(
symbolProvider,
Expand All @@ -254,11 +254,11 @@ class InstantiatorTest {
}
rust(
"""
assert_eq!(result.len(), 3);
assert_eq!(result.get("k1").unwrap().map.as_ref().unwrap().len(), 0);
assert_eq!(result.get("k2").unwrap().map.as_ref().unwrap().len(), 1);
assert_eq!(result.get("k3").unwrap().map, None);
""",
assert_eq!(result.len(), 3);
assert_eq!(result.get("k1").unwrap().map.as_ref().unwrap().len(), 0);
assert_eq!(result.get("k2").unwrap().map.as_ref().unwrap().len(), 1);
assert_eq!(result.get("k3").unwrap().map, None);
""",
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,19 @@ import software.amazon.smithy.build.PluginContext
import software.amazon.smithy.codegen.core.CodegenException
import software.amazon.smithy.model.Model
import software.amazon.smithy.model.knowledge.NullableIndex
import software.amazon.smithy.model.shapes.OperationShape
import software.amazon.smithy.model.shapes.ServiceShape
import software.amazon.smithy.model.shapes.StringShape
import software.amazon.smithy.model.shapes.StructureShape
import software.amazon.smithy.model.shapes.UnionShape
import software.amazon.smithy.model.traits.EnumTrait
import software.amazon.smithy.rust.codegen.core.rustlang.RustModule
import software.amazon.smithy.rust.codegen.core.rustlang.RustWriter
import software.amazon.smithy.rust.codegen.core.smithy.CodegenTarget
import software.amazon.smithy.rust.codegen.core.smithy.RustCrate
import software.amazon.smithy.rust.codegen.core.smithy.SymbolVisitorConfig
import software.amazon.smithy.rust.codegen.server.python.smithy.generators.PythonServerEnumGenerator
import software.amazon.smithy.rust.codegen.server.python.smithy.generators.PythonServerOperationHandlerGenerator
import software.amazon.smithy.rust.codegen.server.python.smithy.generators.PythonServerServiceGenerator
import software.amazon.smithy.rust.codegen.server.python.smithy.generators.PythonServerStructureGenerator
import software.amazon.smithy.rust.codegen.server.smithy.ServerCodegenContext
Expand Down Expand Up @@ -164,4 +167,11 @@ class PythonServerCodegenVisitor(
)
.render()
}

override fun operationShape(shape: OperationShape) {
super.operationShape(shape)
rustCrate.withModule(RustModule.public("python_operation_adaptor")) {
PythonServerOperationHandlerGenerator(codegenContext, shape).render(this)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ class PythonApplicationGenerator(
let ${name}_locals = #{pyo3_asyncio}::TaskLocals::new(event_loop);
let handler = self.handlers.get("$name").expect("Python handler for operation `$name` not found").clone();
let builder = builder.$name(move |input, state| {
#{pyo3_asyncio}::tokio::scope(${name}_locals.clone(), crate::operation_handler::$name(input, state, handler.clone()))
#{pyo3_asyncio}::tokio::scope(${name}_locals.clone(), crate::python_operation_adaptor::$name(input, state, handler.clone()))
});
""",
*codegenScope,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ import software.amazon.smithy.rust.codegen.core.rustlang.writable
import software.amazon.smithy.rust.codegen.core.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.core.util.toSnakeCase
import software.amazon.smithy.rust.codegen.server.python.smithy.PythonServerCargoDependency
import software.amazon.smithy.rust.codegen.server.smithy.generators.ServerOperationHandlerGenerator
import software.amazon.smithy.rust.codegen.server.smithy.generators.protocol.ServerProtocol

/**
* The Rust code responsible to run the Python business logic on the Python interpreter
Expand All @@ -32,9 +30,8 @@ import software.amazon.smithy.rust.codegen.server.smithy.generators.protocol.Ser
*/
class PythonServerOperationHandlerGenerator(
codegenContext: CodegenContext,
protocol: ServerProtocol,
private val operations: List<OperationShape>,
) : ServerOperationHandlerGenerator(codegenContext, protocol, operations) {
private val operation: OperationShape,
) {
private val symbolProvider = codegenContext.symbolProvider
private val runtimeConfig = codegenContext.runtimeConfig
private val codegenScope =
Expand All @@ -47,42 +44,39 @@ class PythonServerOperationHandlerGenerator(
"tracing" to PythonServerCargoDependency.Tracing.toType(),
)

override fun render(writer: RustWriter) {
super.render(writer)
fun render(writer: RustWriter) {
renderPythonOperationHandlerImpl(writer)
}

private fun renderPythonOperationHandlerImpl(writer: RustWriter) {
for (operation in operations) {
val operationName = symbolProvider.toSymbol(operation).name
val input = "crate::input::${operationName}Input"
val output = "crate::output::${operationName}Output"
val error = "crate::error::${operationName}Error"
val fnName = operationName.toSnakeCase()
val operationName = symbolProvider.toSymbol(operation).name
val input = "crate::input::${operationName}Input"
val output = "crate::output::${operationName}Output"
val error = "crate::error::${operationName}Error"
val fnName = operationName.toSnakeCase()

writer.rustTemplate(
"""
/// Python handler for operation `$operationName`.
pub(crate) async fn $fnName(
input: $input,
state: #{SmithyServer}::Extension<#{SmithyPython}::context::PyContext>,
handler: #{SmithyPython}::PyHandler,
) -> std::result::Result<$output, $error> {
// Async block used to run the handler and catch any Python error.
let result = if handler.is_coroutine {
#{PyCoroutine:W}
} else {
#{PyFunction:W}
};
#{PyError:W}
}
""",
*codegenScope,
"PyCoroutine" to renderPyCoroutine(fnName, output),
"PyFunction" to renderPyFunction(fnName, output),
"PyError" to renderPyError(),
)
}
writer.rustTemplate(
"""
/// Python handler for operation `$operationName`.
pub(crate) async fn $fnName(
input: $input,
state: #{SmithyServer}::Extension<#{SmithyPython}::context::PyContext>,
handler: #{SmithyPython}::PyHandler,
) -> std::result::Result<$output, $error> {
// Async block used to run the handler and catch any Python error.
let result = if handler.is_coroutine {
#{PyCoroutine:W}
} else {
#{PyFunction:W}
};
#{PyError:W}
}
""",
*codegenScope,
"PyCoroutine" to renderPyCoroutine(fnName, output),
"PyFunction" to renderPyFunction(fnName, output),
"PyError" to renderPyError(),
)
}

private fun renderPyFunction(name: String, output: String): Writable =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,6 @@ class PythonServerServiceGenerator(
PythonServerOperationErrorGenerator(context.model, context.symbolProvider, operation).render(writer)
}

override fun renderOperationHandler(writer: RustWriter, operations: List<OperationShape>) {
PythonServerOperationHandlerGenerator(context, protocol, operations).render(writer)
}

override fun renderExtras(operations: List<OperationShape>) {
rustCrate.withModule(RustModule.public("python_server_application", "Python server and application implementation.")) {
PythonApplicationGenerator(context, protocol, operations)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ package software.amazon.smithy.rust.codegen.server.smithy
import software.amazon.smithy.rust.codegen.core.rustlang.CargoDependency
import software.amazon.smithy.rust.codegen.core.rustlang.CratesIo
import software.amazon.smithy.rust.codegen.core.rustlang.DependencyScope
import software.amazon.smithy.rust.codegen.core.rustlang.InlineDependency
import software.amazon.smithy.rust.codegen.core.rustlang.RustModule
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeConfig

/**
Expand All @@ -27,32 +25,8 @@ object ServerCargoDependency {
val Tower: CargoDependency = CargoDependency("tower", CratesIo("0.4"))
val TokioDev: CargoDependency = CargoDependency("tokio", CratesIo("1.8.4"), scope = DependencyScope.Dev)
val Regex: CargoDependency = CargoDependency("regex", CratesIo("1.5.5"))
val HyperDev: CargoDependency = CargoDependency("hyper", CratesIo("0.14.12"), DependencyScope.Dev)

fun smithyHttpServer(runtimeConfig: RuntimeConfig) = runtimeConfig.smithyRuntimeCrate("smithy-http-server")
fun smithyTypes(runtimeConfig: RuntimeConfig) = runtimeConfig.smithyRuntimeCrate("smithy-types")
}

/**
* A dependency on a snippet of code
*
* ServerInlineDependency should not be instantiated directly, rather, it should be constructed with
* [software.amazon.smithy.rust.codegen.core.smithy.RuntimeType.forInlineFun]
*
* ServerInlineDependencies are created as private modules within the main crate. This is useful for any code that
* doesn't need to exist in a shared crate, but must still be generated exactly once during codegen.
*
* CodegenVisitor de-duplicates inline dependencies by (module, name) during code generation.
*/
object ServerInlineDependency {
fun serverOperationHandler(runtimeConfig: RuntimeConfig): InlineDependency =
InlineDependency.forRustFile(
RustModule.private("server_operation_handler_trait"),
"/inlineable/src/server_operation_handler_trait.rs",
ServerCargoDependency.smithyHttpServer(runtimeConfig),
CargoDependency.Http,
ServerCargoDependency.PinProjectLite,
ServerCargoDependency.Tower,
ServerCargoDependency.FuturesUtil,
ServerCargoDependency.AsyncTrait,
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,6 @@ object ServerRuntimeType {

fun router(runtimeConfig: RuntimeConfig) = ServerCargoDependency.smithyHttpServer(runtimeConfig).toType().resolve("routing::Router")

fun operationHandler(runtimeConfig: RuntimeConfig) =
forInlineDependency(ServerInlineDependency.serverOperationHandler(runtimeConfig))

fun runtimeError(runtimeConfig: RuntimeConfig) = ServerCargoDependency.smithyHttpServer(runtimeConfig).toType().resolve("runtime_error::RuntimeError")

fun requestRejection(runtimeConfig: RuntimeConfig) = ServerCargoDependency.smithyHttpServer(runtimeConfig).toType().resolve("rejection::RequestRejection")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ private sealed class UnsupportedConstraintMessageKind {
fun intoLogMessage(ignoreUnsupportedConstraints: Boolean): LogMessage {
fun buildMessage(intro: String, willSupport: Boolean, trackingIssue: String, canBeIgnored: Boolean = true): String {
var msg = """
$intro
$intro
This is not supported in the smithy-rs server SDK."""
if (willSupport) {
msg += """
Expand Down Expand Up @@ -161,10 +161,10 @@ fun validateOperationsWithConstrainedInputHaveValidationExceptionAttached(
LogMessage(
Level.SEVERE,
"""
Operation ${it.shape.id} takes in input that is constrained
(https://awslabs.github.io/smithy/2.0/spec/constraint-traits.html), and as such can fail with a
Operation ${it.shape.id} takes in input that is constrained
(https://awslabs.github.io/smithy/2.0/spec/constraint-traits.html), and as such can fail with a
validation exception. You must model this behavior in the operation shape in your model file.
""".trimIndent().replace("\n", "") +
""".trimIndent().replace("\n", " ") +
"""
```smithy
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ package software.amazon.smithy.rust.codegen.server.smithy.generators
*/

fun rustDocsConstrainedTypeEpilogue(typeName: String) = """
This is a constrained type because its corresponding modeled Smithy shape has one or more
[constraint traits]. Use [`$typeName::try_from`] to construct values of this type.
This is a constrained type because its corresponding modeled Smithy shape has one or more
[constraint traits]. Use [`$typeName::try_from`] to construct values of this type.
[constraint traits]: https://awslabs.github.io/smithy/1.0/spec/core/constraint-traits.html
[constraint traits]: https://awslabs.github.io/smithy/1.0/spec/core/constraint-traits.html
"""

fun rustDocsTryFromMethod(typeName: String, inner: String) =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,12 +88,12 @@ fun generateFallbackCodeToDefaultValue(
// storing the result in a `OnceCell` that could be reused.
writer.rustTemplate(
"""
.unwrap_or_else(||
#{DefaultValue:W}
.try_into()
.expect("this check should have failed at generation time; please file a bug report under https://github.com/awslabs/smithy-rs/issues")
)
""",
.unwrap_or_else(||
#{DefaultValue:W}
.try_into()
.expect("this check should have failed at generation time; please file a bug report under https://github.com/awslabs/smithy-rs/issues")
)
""",
"DefaultValue" to defaultValue,
)
} else {
Expand Down

0 comments on commit d75eafd

Please sign in to comment.