Skip to content

Commit

Permalink
Make module docs customizable and update mod docs for crate reorg (#2418
Browse files Browse the repository at this point in the history
)
  • Loading branch information
jdisanti authored Mar 9, 2023
1 parent 7f4152c commit 51df475
Show file tree
Hide file tree
Showing 45 changed files with 382 additions and 185 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,9 @@ object InlineAwsDependency {
forRustFileAs(file, file, visibility, *additionalDependency)

fun forRustFileAs(file: String, moduleName: String, visibility: Visibility = Visibility.PRIVATE, vararg additionalDependency: RustDependency): InlineDependency =
InlineDependency.Companion.forRustFile(RustModule.new(moduleName, visibility), "/aws-inlineable/src/$file.rs", *additionalDependency)
InlineDependency.Companion.forRustFile(
RustModule.new(moduleName, visibility, documentationOverride = ""),
"/aws-inlineable/src/$file.rs",
*additionalDependency,
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ import software.amazon.smithy.rulesengine.language.syntax.parameters.Builtins
import software.amazon.smithy.rulesengine.language.syntax.parameters.Parameters
import software.amazon.smithy.rulesengine.traits.EndpointRuleSetTrait
import software.amazon.smithy.rust.codegen.client.smithy.ClientCodegenContext
import software.amazon.smithy.rust.codegen.client.smithy.ClientRustModule
import software.amazon.smithy.rust.codegen.client.smithy.customize.ClientCodegenDecorator
import software.amazon.smithy.rust.codegen.client.smithy.endpoint.EndpointTypesGenerator
import software.amazon.smithy.rust.codegen.client.smithy.endpoint.generators.EndpointsModule
import software.amazon.smithy.rust.codegen.client.smithy.featureGatedConfigModule
import software.amazon.smithy.rust.codegen.client.smithy.generators.config.ConfigCustomization
import software.amazon.smithy.rust.codegen.client.smithy.generators.config.ServiceConfig
Expand Down Expand Up @@ -109,7 +109,7 @@ class AwsEndpointDecorator : ClientCodegenDecorator {
println("not generating a resolver for ${codegenContext.serviceShape}")
return
}
rustCrate.withModule(EndpointsModule) {
rustCrate.withModule(ClientRustModule.Endpoint) {
// TODO(https://github.com/awslabs/smithy-rs/issues/1784) cleanup task
rustTemplate(
"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import software.amazon.smithy.model.shapes.ShapeId
import software.amazon.smithy.rust.codegen.client.smithy.customize.ClientCodegenDecorator
import software.amazon.smithy.rust.codegen.core.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.core.smithy.CodegenTarget
import software.amazon.smithy.rust.codegen.core.smithy.ModuleDocProvider
import software.amazon.smithy.rust.codegen.core.smithy.RustSymbolProvider

/**
Expand All @@ -22,12 +23,13 @@ import software.amazon.smithy.rust.codegen.core.smithy.RustSymbolProvider
data class ClientCodegenContext(
override val model: Model,
override val symbolProvider: RustSymbolProvider,
override val moduleDocProvider: ModuleDocProvider?,
override val serviceShape: ServiceShape,
override val protocol: ShapeId,
override val settings: ClientRustSettings,
// Expose the `rootDecorator`, enabling customizations to compose by referencing information from the root codegen
// decorator
val rootDecorator: ClientCodegenDecorator,
) : CodegenContext(
model, symbolProvider, serviceShape, protocol, settings, CodegenTarget.CLIENT,
model, symbolProvider, moduleDocProvider, serviceShape, protocol, settings, CodegenTarget.CLIENT,
)
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ 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.model.traits.ErrorTrait
import software.amazon.smithy.model.traits.TitleTrait
import software.amazon.smithy.model.transform.ModelTransformer
import software.amazon.smithy.rust.codegen.client.smithy.customize.ClientCodegenDecorator
import software.amazon.smithy.rust.codegen.client.smithy.generators.ClientEnumGenerator
Expand Down Expand Up @@ -69,7 +70,7 @@ class ClientCodegenVisitor(
private val rustCrate: RustCrate
private val fileManifest = context.fileManifest
private val model: Model
private val codegenContext: ClientCodegenContext
private var codegenContext: ClientCodegenContext
private val protocolGeneratorFactory: ProtocolGeneratorFactory<ClientProtocolGenerator, ClientCodegenContext>
private val protocolGenerator: ClientProtocolGenerator

Expand Down Expand Up @@ -100,12 +101,31 @@ class ClientCodegenVisitor(
val service = settings.getService(model)
symbolProvider = RustClientCodegenPlugin.baseSymbolProvider(settings, model, service, rustSymbolProviderConfig, codegenDecorator)

codegenContext = ClientCodegenContext(model, symbolProvider, service, protocol, settings, codegenDecorator)
codegenContext = ClientCodegenContext(
model,
symbolProvider,
null,
service,
protocol,
settings,
codegenDecorator,
)

codegenContext = codegenContext.copy(
moduleDocProvider = codegenDecorator.moduleDocumentationCustomization(
codegenContext,
ClientModuleDocProvider(
settings.codegenConfig,
service.getTrait<TitleTrait>()?.value ?: "the service",
),
),
)

rustCrate = RustCrate(
context.fileManifest,
symbolProvider,
codegenContext.settings.codegenConfig,
codegenContext.expectModuleDocProvider(),
)
protocolGenerator = protocolGeneratorFactory.buildProtocolGenerator(codegenContext)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,15 @@ import software.amazon.smithy.model.traits.ErrorTrait
import software.amazon.smithy.rust.codegen.core.rustlang.RustModule
import software.amazon.smithy.rust.codegen.core.rustlang.RustReservedWords
import software.amazon.smithy.rust.codegen.core.rustlang.Visibility
import software.amazon.smithy.rust.codegen.core.smithy.ModuleDocProvider
import software.amazon.smithy.rust.codegen.core.smithy.ModuleProvider
import software.amazon.smithy.rust.codegen.core.smithy.ModuleProviderContext
import software.amazon.smithy.rust.codegen.core.smithy.RustSymbolProvider
import software.amazon.smithy.rust.codegen.core.smithy.contextName
import software.amazon.smithy.rust.codegen.core.smithy.module
import software.amazon.smithy.rust.codegen.core.smithy.traits.SyntheticInputTrait
import software.amazon.smithy.rust.codegen.core.smithy.traits.SyntheticOutputTrait
import software.amazon.smithy.rust.codegen.core.util.PANIC
import software.amazon.smithy.rust.codegen.core.util.UNREACHABLE
import software.amazon.smithy.rust.codegen.core.util.getTrait
import software.amazon.smithy.rust.codegen.core.util.hasTrait
Expand All @@ -38,32 +40,74 @@ object ClientRustModule {
val client = Client.self
object Client {
/** crate::client */
val self = RustModule.public("client", "Client and fluent builders for calling the service.")
val self = RustModule.public("client")

/** crate::client::customize */
val customize = RustModule.public("customize", parent = self, documentation = "Operation customization and supporting types")
val customize = RustModule.public("customize", parent = self)
}

val Config = RustModule.public("config", documentation = "Configuration for the service.")
val Error = RustModule.public("error", documentation = "All error types that operations can return. Documentation on these types is copied from the model.")
val Operation = RustModule.public("operation", documentation = "All operations that this crate can perform.")
val Meta = RustModule.public("meta", documentation = "Information about this crate.")
val Input = RustModule.public("input", documentation = "Input structures for operations. Documentation on these types is copied from the model.")
val Output = RustModule.public("output", documentation = "Output structures for operations. Documentation on these types is copied from the model.")
val Primitives = RustModule.public("primitives", documentation = "Data primitives referenced by other data types.")
val Config = RustModule.public("config")
val Error = RustModule.public("error")
val Endpoint = RustModule.public("endpoint")
val Operation = RustModule.public("operation")
val Meta = RustModule.public("meta")
val Input = RustModule.public("input")
val Output = RustModule.public("output")
val Primitives = RustModule.public("primitives")

/** crate::types */
val types = Types.self
object Types {
/** crate::types */
val self = RustModule.public("types", documentation = "Data primitives referenced by other data types.")
val self = RustModule.public("types")

/** crate::types::error */
val Error = RustModule.public("error", parent = self, documentation = "All error types that operations can return. Documentation on these types is copied from the model.")
val Error = RustModule.public("error", parent = self)
}

// TODO(CrateReorganization): Remove this module when cleaning up `enableNewCrateOrganizationScheme`
val Model = RustModule.public("model", documentation = "Data structures used by operation inputs/outputs. Documentation on these types is copied from the model.")
val Model = RustModule.public("model")
}

class ClientModuleDocProvider(
private val config: ClientCodegenConfig,
private val serviceName: String,
) : ModuleDocProvider {
override fun docs(module: RustModule.LeafModule): String? =
when (config.enableNewCrateOrganizationScheme) {
true -> when (module) {
ClientRustModule.client -> "Client for calling $serviceName."
ClientRustModule.Client.customize -> "Operation customization and supporting types."
ClientRustModule.Config -> "Configuration for $serviceName."
ClientRustModule.Error -> "Common errors and error handling utilities."
ClientRustModule.Endpoint -> "Endpoint resolution functionality."
ClientRustModule.Operation -> "All operations that this crate can perform."
ClientRustModule.Meta -> "Information about this crate."
ClientRustModule.Input -> PANIC("this module shouldn't exist in the new scheme")
ClientRustModule.Output -> PANIC("this module shouldn't exist in the new scheme")
ClientRustModule.Primitives -> "Primitives such as `Blob` or `DateTime` used by other types."
ClientRustModule.types -> "Data primitives referenced by other data types."
ClientRustModule.Types.Error -> "Error types that $serviceName can respond with."
ClientRustModule.Model -> PANIC("this module shouldn't exist in the new scheme")
else -> TODO("Document this module: $module")
}
else -> when (module) {
ClientRustModule.client -> "Client and fluent builders for calling $serviceName."
ClientRustModule.Client.customize -> "Operation customization and supporting types."
ClientRustModule.Config -> "Configuration for $serviceName."
ClientRustModule.Error -> "All error types that operations can return. Documentation on these types is copied from the model."
ClientRustModule.Endpoint -> "Endpoint resolution functionality."
ClientRustModule.Operation -> "All operations that this crate can perform."
ClientRustModule.Meta -> PANIC("this module shouldn't exist in the old scheme")
ClientRustModule.Input -> "Input structures for operations. Documentation on these types is copied from the model."
ClientRustModule.Output -> "Output structures for operations. Documentation on these types is copied from the model."
ClientRustModule.Primitives -> PANIC("this module shouldn't exist in the old scheme")
ClientRustModule.types -> "Data primitives referenced by other data types."
ClientRustModule.Types.Error -> PANIC("this module shouldn't exist in the old scheme")
ClientRustModule.Model -> "Data structures used by operation inputs/outputs."
else -> TODO("Document this module: $module")
}
}
}

object ClientModuleProvider : ModuleProvider {
Expand All @@ -90,7 +134,7 @@ object ClientModuleProvider : ModuleProvider {
): RustModule.LeafModule = ClientRustModule.Error

override fun moduleForBuilder(context: ModuleProviderContext, shape: Shape, symbol: Symbol): RustModule.LeafModule =
RustModule.public("builders", parent = symbol.module(), documentation = "Builders")
RustModule.public("builders", parent = symbol.module(), documentationOverride = "Builders")

private fun Shape.findOperation(model: Model): OperationShape {
val inputTrait = getTrait<SyntheticInputTrait>()
Expand All @@ -111,7 +155,7 @@ object ClientModuleProvider : ModuleProvider {
return RustModule.public(
operationModuleName,
parent = ClientRustModule.Operation,
documentation = "Types for the `$contextName` operation.",
documentationOverride = "Types for the `$contextName` operation.",
)
}
}
Expand Down Expand Up @@ -147,7 +191,7 @@ object OldModuleSchemeClientModuleProvider : ModuleProvider {
visibility = Visibility.PUBLIC,
parent = symbol.module(),
inline = true,
documentation = "See [`${symbol.name}`](${symbol.module().fullyQualifiedPath()}::${symbol.name}).",
documentationOverride = "See [`${symbol.name}`](${symbol.module().fullyQualifiedPath()}::${symbol.name}).",
)
}
}
Expand All @@ -163,8 +207,8 @@ fun ClientCodegenContext.featureGatedCustomizeModule() = when (settings.codegenC
true -> ClientRustModule.Client.customize
else -> RustModule.public(
"customize",
"Operation customization and supporting types",
parent = ClientRustModule.Operation,
documentationOverride = "Operation customization and supporting types",
)
}

Expand All @@ -180,9 +224,9 @@ fun ClientCodegenContext.featureGatedPaginatorModule(symbolProvider: RustSymbolP
true -> RustModule.public(
"paginator",
parent = symbolProvider.moduleForShape(operation),
documentation = "Paginator for this operation",
documentationOverride = "Paginator for this operation",
)
else -> RustModule.public("paginator", "Paginators for the service")
else -> RustModule.public("paginator", documentationOverride = "Paginators for the service")
}

// TODO(CrateReorganization): Remove when cleaning up `enableNewCrateOrganizationScheme`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
package software.amazon.smithy.rust.codegen.client.smithy.endpoint

import software.amazon.smithy.rust.codegen.client.smithy.ClientCodegenContext
import software.amazon.smithy.rust.codegen.client.smithy.endpoint.generators.EndpointsModule
import software.amazon.smithy.rust.codegen.client.smithy.ClientRustModule
import software.amazon.smithy.rust.codegen.client.smithy.generators.config.ConfigCustomization
import software.amazon.smithy.rust.codegen.client.smithy.generators.config.ServiceConfig
import software.amazon.smithy.rust.codegen.core.rustlang.Writable
Expand Down Expand Up @@ -128,21 +128,22 @@ internal class EndpointConfigCustomization(
"DefaultResolver" to defaultResolver,
)
} else {
val alwaysFailsResolver = RuntimeType.forInlineFun("MissingResolver", EndpointsModule) {
rustTemplate(
"""
pub(crate) struct MissingResolver;
impl<T> #{ResolveEndpoint}<T> for MissingResolver {
fn resolve_endpoint(&self, _params: &T) -> #{Result} {
Err(#{ResolveEndpointError}::message("an endpoint resolver must be provided."))
val alwaysFailsResolver =
RuntimeType.forInlineFun("MissingResolver", ClientRustModule.Endpoint) {
rustTemplate(
"""
pub(crate) struct MissingResolver;
impl<T> #{ResolveEndpoint}<T> for MissingResolver {
fn resolve_endpoint(&self, _params: &T) -> #{Result} {
Err(#{ResolveEndpointError}::message("an endpoint resolver must be provided."))
}
}
}
""",
"ResolveEndpoint" to types.resolveEndpoint,
"ResolveEndpointError" to types.resolveEndpointError,
"Result" to types.smithyHttpEndpointModule.resolve("Result"),
)
}
""",
"ResolveEndpoint" to types.resolveEndpoint,
"ResolveEndpointError" to types.resolveEndpointError,
"Result" to types.smithyHttpEndpointModule.resolve("Result"),
)
}
// To keep this diff under control, rather than `.expect` here, insert a resolver that will
// always fail. In the future, this will be changed to an `expect()`
rustTemplate(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ import software.amazon.smithy.rulesengine.language.syntax.parameters.Parameter
import software.amazon.smithy.rulesengine.language.syntax.parameters.Parameters
import software.amazon.smithy.rulesengine.traits.ContextIndex
import software.amazon.smithy.rust.codegen.client.smithy.ClientCodegenContext
import software.amazon.smithy.rust.codegen.client.smithy.ClientRustModule
import software.amazon.smithy.rust.codegen.client.smithy.customize.ClientCodegenDecorator
import software.amazon.smithy.rust.codegen.client.smithy.endpoint.generators.CustomRuntimeFunction
import software.amazon.smithy.rust.codegen.client.smithy.endpoint.generators.EndpointParamsGenerator
import software.amazon.smithy.rust.codegen.client.smithy.endpoint.generators.EndpointTests
import software.amazon.smithy.rust.codegen.client.smithy.endpoint.generators.EndpointsModule
import software.amazon.smithy.rust.codegen.client.smithy.endpoint.rulesgen.SmithyEndpointsStdLib
import software.amazon.smithy.rust.codegen.client.smithy.generators.config.ConfigCustomization
import software.amazon.smithy.rust.codegen.core.rustlang.Writable
Expand Down Expand Up @@ -133,8 +133,8 @@ class EndpointsDecorator : ClientCodegenDecorator {

override fun extras(codegenContext: ClientCodegenContext, rustCrate: RustCrate) {
val generator = EndpointTypesGenerator.fromContext(codegenContext)
rustCrate.withModule(EndpointsModule) {
withInlineModule(EndpointTests) {
rustCrate.withModule(ClientRustModule.Endpoint) {
withInlineModule(EndpointTests, rustCrate.moduleDocProvider) {
generator.testGenerator()(this)
}
}
Expand Down
Loading

0 comments on commit 51df475

Please sign in to comment.