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

Add new service builder codegen #1693

Merged
merged 81 commits into from
Sep 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
81 commits
Select commit Hold shift + click to select a range
9ac6968
Add version getter to AwsJson
Aug 31, 2022
4c1b6ed
Add ServerProtocol interface and implement it
Aug 31, 2022
1c95114
Add ServerOperationGenerator
Aug 31, 2022
5689727
Make routing machinery public
Aug 31, 2022
2269aef
Add basic ServerServiceGeneratorV2
Aug 31, 2022
fc33fbc
Add temporary module rendering
Aug 31, 2022
40540fe
Fix namespacing
Sep 1, 2022
44c1068
Add struct Service implementation
Sep 1, 2022
9397cc0
Fix lints
Sep 1, 2022
8a67560
Add Upgradable
Sep 1, 2022
cc7f6fe
Make Route::new public
Sep 1, 2022
b90d73a
Add code generated build method
Sep 1, 2022
a3dc74a
Fix lints
Sep 1, 2022
12bb2f4
Add RestXmlServerProtocol
Sep 2, 2022
57afed9
Fix documentation lints and name cases
Sep 2, 2022
ba11257
Fix ServerProtocol naming
Sep 2, 2022
7814d18
Include all service operations
Sep 2, 2022
6966d33
Add BuildModifier mechanism
Sep 2, 2022
c1ab8f6
Fix Rust documentation
Sep 2, 2022
efa0635
Fix missing :W
Sep 2, 2022
39b9c0c
Add convenience setter
Sep 3, 2022
7c8828c
Add blanket conversion implementations
Sep 3, 2022
04a1fa2
Add FromRequest impl for input structs
Sep 3, 2022
a243fbf
Add IntoResponse for Output and Error
Sep 3, 2022
fda3b0f
Add IntoResponse for RuntimeError
Sep 3, 2022
d3c2484
Move generics
Sep 4, 2022
0be9c19
Add into_make_service method
Sep 4, 2022
a33c621
Make RoutingService more flexible
Sep 4, 2022
ca78b04
Add layer method to service
Sep 4, 2022
322c8f2
Tweak example
Sep 4, 2022
7e4fbf4
Fix missing routes
Sep 4, 2022
306fddc
Allow unused parens
Sep 4, 2022
b4cee92
Improve documentation
Sep 5, 2022
d1d8383
Extend example
Sep 5, 2022
1690cd6
Fix // / kotlin documentation
Sep 5, 2022
e7d889d
Remove excess rust call
Sep 5, 2022
98f6615
Cleanup upgrade
Sep 5, 2022
e0673aa
Cleanup ServerProtocol
Sep 5, 2022
53404c0
Fix another // /
Sep 5, 2022
9cef47e
Rework modules
Sep 5, 2022
6f8576a
Update RFC
Sep 5, 2022
1df5792
Change OperatioNotSet to MissingOperation
Sep 5, 2022
d1b1639
Move Ext inference into setters
Sep 5, 2022
c75b97f
Use correct documentation idiom
Sep 6, 2022
38b8677
Use documentShape
Sep 6, 2022
3ce3687
Remove excess argument in ServerServiceGeneratorV2
Sep 6, 2022
5e93545
Fix documentation
Sep 6, 2022
0da952a
Revert RustModule hidden argument
Sep 6, 2022
e0768f2
Revert changes to example
Sep 6, 2022
fc26734
Improve formatting
Sep 6, 2022
dfad5f0
Inline ServerOperationGenerator::operation method
Sep 7, 2022
e5c0cd5
Remove "$x"
Sep 7, 2022
45a9126
Remove dependency on #{Tower}::Error
Sep 7, 2022
f24de0c
Fix missing writer.
Sep 7, 2022
0ce4d6a
Remove unnecessary brackets
Sep 7, 2022
cb89589
Remove unnecessary brackets
Sep 7, 2022
14e094d
Use double quotes inline
Sep 7, 2022
d1c5657
Use inheritance
Sep 7, 2022
48f2680
Remove excess brackets
Sep 7, 2022
59c82d7
Fix double quotes
Sep 7, 2022
e35a7f1
Add general ServerRuntimeType.Protocol
Sep 7, 2022
6d3cbeb
Switch to Protocol inheritance
Sep 7, 2022
35c1fd1
Merge branch 'main' into harryb/service-builder-codegen
Sep 7, 2022
5399ae3
Improve TODOs
Sep 7, 2022
a2ab7e7
Remove BuildModifier
Sep 7, 2022
9a77fe9
Merge branch 'main' into harryb/service-builder-codegen
hlbarber Sep 7, 2022
6ae1a6e
Merge branch 'main' into harryb/service-builder-codegen
hlbarber Sep 8, 2022
a048715
Use TopDownIndex to collect all operations
Sep 8, 2022
da62ae6
Link server specific SymbolProvider issue in TODO
Sep 9, 2022
ba9ea60
Add InternalFailure operation
Sep 9, 2022
f2ba048
Mem replace the service for safety
Sep 9, 2022
925ed1f
Fix documentation
Sep 9, 2022
5a5cde7
Merge branch 'main' into harryb/service-builder-codegen
hlbarber Sep 9, 2022
0717fc1
Better use of iterators
Sep 9, 2022
d9c3628
Restore escapeIfNeeded
Sep 9, 2022
ac1142d
Merge branch 'main' into harryb/service-builder-codegen
Sep 9, 2022
a10189f
Merge branch 'main' into harryb/service-builder-codegen
hlbarber Sep 9, 2022
32dc9b7
Ensure service name is PascalCase
Sep 9, 2022
ba8d772
Integrate new service builder into protocol tests
Sep 9, 2022
a19fdf6
Add service builder test assertion
Sep 10, 2022
e89e4b0
Merge branch 'main' into harryb/service-builder-codegen
hlbarber Sep 10, 2022
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 @@ -26,6 +26,13 @@ fun Writable.isEmpty(): Boolean {
return writer.toString() == RustWriter.root().toString()
}

operator fun Writable.plus(other: Writable): Writable {
val first = this
return writable {
rustTemplate("#{First:W}#{Second:W}", "First" to first, "Second" to other)
}
}

/**
* Helper allowing a `Iterable<Writable>` to be joined together using a `String` separator.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ class AwsJsonSerializerGenerator(
}

open class AwsJson(
private val coreCodegenContext: CoreCodegenContext,
val coreCodegenContext: CoreCodegenContext,
private val awsJsonVersion: AwsJsonVersion,
) : Protocol {
private val runtimeConfig = coreCodegenContext.runtimeConfig
Expand All @@ -143,6 +143,8 @@ open class AwsJson(
)
private val jsonDeserModule = RustModule.private("json_deser")

val version: AwsJsonVersion get() = awsJsonVersion

override val httpBindingResolver: HttpBindingResolver =
AwsJsonHttpBindingResolver(coreCodegenContext.model, awsJsonVersion)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ class RestJsonHttpBindingResolver(
}
}

class RestJson(private val coreCodegenContext: CoreCodegenContext) : Protocol {
open class RestJson(val coreCodegenContext: CoreCodegenContext) : Protocol {
private val runtimeConfig = coreCodegenContext.runtimeConfig
private val errorScope = arrayOf(
"Bytes" to RuntimeType.Bytes,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class RestXmlFactory(
}
}

open class RestXml(private val coreCodegenContext: CoreCodegenContext) : Protocol {
open class RestXml(val coreCodegenContext: CoreCodegenContext) : Protocol {
private val restXml = coreCodegenContext.serviceShape.expectTrait<RestXmlTrait>()
private val runtimeConfig = coreCodegenContext.runtimeConfig
private val errorScope = arrayOf(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ object ServerRuntimeType {
fun ResponseRejection(runtimeConfig: RuntimeConfig) =
RuntimeType("ResponseRejection", ServerCargoDependency.SmithyHttpServer(runtimeConfig), "${runtimeConfig.crateSrcPrefix}_http_server::rejection")

fun Protocol(runtimeConfig: RuntimeConfig) =
RuntimeType("Protocol", ServerCargoDependency.SmithyHttpServer(runtimeConfig), "${runtimeConfig.crateSrcPrefix}_http_server::protocols")
fun Protocol(name: String, runtimeConfig: RuntimeConfig) =
RuntimeType(name, ServerCargoDependency.SmithyHttpServer(runtimeConfig), "${runtimeConfig.crateSrcPrefix}_http_server::protocols")

fun Protocol(runtimeConfig: RuntimeConfig) = Protocol("Protocol", runtimeConfig)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/

package software.amazon.smithy.rust.codegen.server.smithy.generators

import software.amazon.smithy.model.shapes.OperationShape
import software.amazon.smithy.rust.codegen.client.rustlang.RustWriter
import software.amazon.smithy.rust.codegen.client.rustlang.Writable
import software.amazon.smithy.rust.codegen.client.rustlang.asType
import software.amazon.smithy.rust.codegen.client.rustlang.documentShape
import software.amazon.smithy.rust.codegen.client.rustlang.rust
import software.amazon.smithy.rust.codegen.client.rustlang.rustTemplate
import software.amazon.smithy.rust.codegen.client.rustlang.writable
import software.amazon.smithy.rust.codegen.client.smithy.CoreCodegenContext
import software.amazon.smithy.rust.codegen.client.util.toPascalCase
import software.amazon.smithy.rust.codegen.server.smithy.ServerCargoDependency

class ServerOperationGenerator(
coreCodegenContext: CoreCodegenContext,
private val operation: OperationShape,
) {
private val runtimeConfig = coreCodegenContext.runtimeConfig
private val codegenScope =
arrayOf(
"SmithyHttpServer" to
ServerCargoDependency.SmithyHttpServer(runtimeConfig).asType(),
)
private val symbolProvider = coreCodegenContext.symbolProvider
private val model = coreCodegenContext.model

private val operationName = symbolProvider.toSymbol(operation).name.toPascalCase()
private val operationId = operation.id

/** Returns `std::convert::Infallible` if the model provides no errors. */
private fun operationError(): Writable = writable {
if (operation.errors.isEmpty()) {
rust("std::convert::Infallible")
} else {
rust("crate::error::${operationName}Error")
}
}

fun render(writer: RustWriter) {
writer.documentShape(operation, model)

writer.rustTemplate(
"""
pub struct $operationName;

impl #{SmithyHttpServer}::operation::OperationShape for $operationName {
const NAME: &'static str = "${operationId.toString().replace("#", "##")}";

type Input = crate::input::${operationName}Input;
type Output = crate::output::${operationName}Output;
type Error = #{Error:W};
}
""",
"Error" to operationError(),
*codegenScope,
)
// Adds newline to end of render
writer.rust("")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,18 @@ package software.amazon.smithy.rust.codegen.server.smithy.generators

import software.amazon.smithy.model.knowledge.TopDownIndex
import software.amazon.smithy.model.shapes.OperationShape
import software.amazon.smithy.rust.codegen.client.rustlang.Attribute
import software.amazon.smithy.rust.codegen.client.rustlang.RustMetadata
import software.amazon.smithy.rust.codegen.client.rustlang.RustModule
import software.amazon.smithy.rust.codegen.client.rustlang.RustWriter
import software.amazon.smithy.rust.codegen.client.rustlang.Visibility
import software.amazon.smithy.rust.codegen.client.smithy.CoreCodegenContext
import software.amazon.smithy.rust.codegen.client.smithy.DefaultPublicModules
import software.amazon.smithy.rust.codegen.client.smithy.RustCrate
import software.amazon.smithy.rust.codegen.client.smithy.generators.protocol.ProtocolGenerator
import software.amazon.smithy.rust.codegen.client.smithy.generators.protocol.ProtocolSupport
import software.amazon.smithy.rust.codegen.client.smithy.protocols.Protocol
import software.amazon.smithy.rust.codegen.server.smithy.generators.protocol.ServerProtocol
import software.amazon.smithy.rust.codegen.server.smithy.generators.protocol.ServerProtocolTestGenerator

/**
Expand Down Expand Up @@ -63,6 +67,36 @@ open class ServerServiceGenerator(
) { writer ->
renderOperationRegistry(writer, operations)
}

// TODO(https://github.com/awslabs/smithy-rs/issues/1707): Remove, this is temporary.
rustCrate.withModule(
RustModule(
"operation_shape",
RustMetadata(
visibility = Visibility.PUBLIC,
additionalAttributes = listOf(
Attribute.DocHidden,
),
),
null,
),
) { writer ->
for (operation in operations) {
ServerOperationGenerator(coreCodegenContext, operation).render(writer)
}
}

// TODO(https://github.com/awslabs/smithy-rs/issues/1707): Remove, this is temporary.
rustCrate.withModule(
RustModule("service", RustMetadata(visibility = Visibility.PUBLIC, additionalAttributes = listOf(Attribute.DocHidden)), null),
) { writer ->
val serverProtocol = ServerProtocol.fromCoreProtocol(protocol)
ServerServiceGeneratorV2(
coreCodegenContext,
serverProtocol,
).render(writer)
}

renderExtras(operations)
}

Expand Down
Loading