6
6
package software.amazon.smithy.rust.codegen.server.smithy
7
7
8
8
import software.amazon.smithy.codegen.core.Symbol
9
+ import software.amazon.smithy.model.knowledge.TopDownIndex
9
10
import software.amazon.smithy.model.shapes.OperationShape
10
11
import software.amazon.smithy.model.shapes.Shape
11
12
import software.amazon.smithy.model.shapes.StructureShape
@@ -16,6 +17,8 @@ import software.amazon.smithy.rust.codegen.core.rustlang.RustReservedWords
16
17
import software.amazon.smithy.rust.codegen.core.rustlang.Visibility
17
18
import software.amazon.smithy.rust.codegen.core.rustlang.Writable
18
19
import software.amazon.smithy.rust.codegen.core.rustlang.docs
20
+ import software.amazon.smithy.rust.codegen.core.rustlang.escape
21
+ import software.amazon.smithy.rust.codegen.core.rustlang.rustTemplate
19
22
import software.amazon.smithy.rust.codegen.core.rustlang.writable
20
23
import software.amazon.smithy.rust.codegen.core.smithy.ModuleDocProvider
21
24
import software.amazon.smithy.rust.codegen.core.smithy.ModuleProvider
@@ -24,8 +27,10 @@ import software.amazon.smithy.rust.codegen.core.smithy.module
24
27
import software.amazon.smithy.rust.codegen.core.smithy.traits.SyntheticInputTrait
25
28
import software.amazon.smithy.rust.codegen.core.smithy.traits.SyntheticOutputTrait
26
29
import software.amazon.smithy.rust.codegen.core.util.hasTrait
30
+ import software.amazon.smithy.rust.codegen.core.util.toPascalCase
27
31
import software.amazon.smithy.rust.codegen.core.util.toSnakeCase
28
-
32
+ import software.amazon.smithy.rust.codegen.server.smithy.generators.DocHandlerGenerator
33
+ import software.amazon.smithy.rust.codegen.server.smithy.generators.handlerImports
29
34
object ServerRustModule {
30
35
val root = RustModule .LibRs
31
36
@@ -44,23 +49,73 @@ object ServerRustModule {
44
49
software.amazon.smithy.rust.codegen.core.smithy.ConstrainedModule
45
50
}
46
51
47
- class ServerModuleDocProvider : ModuleDocProvider {
48
- override fun docsWriter (module : RustModule .LeafModule ): Writable ? = writable {
49
- docs(
50
- when (module) {
51
- ServerRustModule .Error -> " All error types that operations can return. Documentation on these types is copied from the model."
52
- ServerRustModule .Operation -> " All operations that this crate can perform."
53
- // TODO(ServerTeam): Document this module (I don't have context)
54
- ServerRustModule .OperationShape -> " "
55
- ServerRustModule .Model -> " Data structures used by operation inputs/outputs. Documentation on these types is copied from the model."
56
- ServerRustModule .Input -> " Input structures for operations. Documentation on these types is copied from the model."
57
- ServerRustModule .Output -> " Output structures for operations. Documentation on these types is copied from the model."
58
- ServerRustModule .Types -> " Data primitives referenced by other data types."
59
- ServerRustModule .Server -> " Contains the types that are re-exported from the `aws-smithy-http-server` crate."
60
- ServerRustModule .UnconstrainedModule -> " Unconstrained types for constrained shapes."
61
- ServerRustModule .ConstrainedModule -> " Constrained types for constrained shapes."
62
- else -> TODO (" Document this module: $module " )
63
- },
52
+ class ServerModuleDocProvider (private val codegenContext : ServerCodegenContext ) : ModuleDocProvider {
53
+ override fun docsWriter (module : RustModule .LeafModule ): Writable ? {
54
+ val strDoc: (String ) -> Writable = { str -> writable { docs(escape(str)) } }
55
+ return when (module) {
56
+ ServerRustModule .Error -> strDoc(" All error types that operations can return. Documentation on these types is copied from the model." )
57
+ ServerRustModule .Operation -> strDoc(" All operations that this crate can perform." )
58
+ ServerRustModule .OperationShape -> operationShapeModuleDoc()
59
+ ServerRustModule .Model -> strDoc(" Data structures used by operation inputs/outputs. Documentation on these types is copied from the model." )
60
+ ServerRustModule .Input -> strDoc(" Input structures for operations. Documentation on these types is copied from the model." )
61
+ ServerRustModule .Output -> strDoc(" Output structures for operations. Documentation on these types is copied from the model." )
62
+ ServerRustModule .Types -> strDoc(" Data primitives referenced by other data types." )
63
+ ServerRustModule .Server -> strDoc(" Contains the types that are re-exported from the `aws-smithy-http-server` crate." )
64
+ ServerRustModule .UnconstrainedModule -> strDoc(" Unconstrained types for constrained shapes." )
65
+ ServerRustModule .ConstrainedModule -> strDoc(" Constrained types for constrained shapes." )
66
+ else -> TODO (" Document this module: $module " )
67
+ }
68
+ }
69
+
70
+ private fun operationShapeModuleDoc (): Writable = writable {
71
+ val index = TopDownIndex .of(codegenContext.model)
72
+ val operations = index.getContainedOperations(codegenContext.serviceShape).toSortedSet(compareBy { it.id })
73
+
74
+ val firstOperation = operations.first() ? : return @writable
75
+ val firstOperationSymbol = codegenContext.symbolProvider.toSymbol(firstOperation)
76
+ val firstOperationName = firstOperationSymbol.name.toPascalCase()
77
+ val crateName = codegenContext.settings.moduleName.toSnakeCase()
78
+
79
+ rustTemplate(
80
+ """
81
+ /// A collection of types representing each operation defined in the service closure.
82
+ ///
83
+ /// ## Constructing an [`Operation`](#{SmithyHttpServer}::operation::OperationShapeExt)
84
+ ///
85
+ /// To apply middleware to specific operations the [`Operation`](#{SmithyHttpServer}::operation::Operation)
86
+ /// API must be used.
87
+ ///
88
+ /// Using the [`OperationShapeExt`](#{SmithyHttpServer}::operation::OperationShapeExt) trait
89
+ /// implemented on each ZST we can construct an [`Operation`](#{SmithyHttpServer}::operation::Operation)
90
+ /// with appropriate constraints given by Smithy.
91
+ ///
92
+ /// #### Example
93
+ ///
94
+ /// ```no_run
95
+ /// use $crateName ::operation_shape::$firstOperationName ;
96
+ /// use #{SmithyHttpServer}::operation::OperationShapeExt;
97
+ ///
98
+ #{HandlerImports:W}
99
+ ///
100
+ #{Handler:W}
101
+ ///
102
+ /// let operation = $firstOperationName ::from_handler(handler)
103
+ /// .layer(todo!("Provide a layer implementation"));
104
+ /// ```
105
+ ///
106
+ /// ## Use as Marker Structs
107
+ ///
108
+ /// The [plugin system](#{SmithyHttpServer}::plugin) also makes use of these
109
+ /// [zero-sized types](https://doc.rust-lang.org/nomicon/exotic-sizes.html##zero-sized-types-zsts) (ZSTs) to
110
+ /// parameterize [`Plugin`](#{SmithyHttpServer}::plugin::Plugin) implementations. The traits, such as
111
+ /// [`OperationShape`](#{SmithyHttpServer}::operation::OperationShape) can be used to provide
112
+ /// operation specific information to the [`Layer`](#{Tower}::Layer) being applied.
113
+ """ .trimIndent(),
114
+ " SmithyHttpServer" to
115
+ ServerCargoDependency .smithyHttpServer(codegenContext.runtimeConfig).toType(),
116
+ " Tower" to ServerCargoDependency .Tower .toType(),
117
+ " Handler" to DocHandlerGenerator (codegenContext, firstOperation, " handler" , commentToken = " ///" )::render,
118
+ " HandlerImports" to handlerImports(crateName, operations, commentToken = " ///" ),
64
119
)
65
120
}
66
121
}
0 commit comments