Unverified Commit e9aa14e1 authored by Russell Cohen's avatar Russell Cohen Committed by GitHub
Browse files

Generate better docs when fields are required (#2996)

## Motivation and Context
With required builders, builders return errors in more cases now. This
clearly indicates which fields that the service considers required.

## Description
Add more docs for required status.
<img width="1037" alt="Screenshot 2023-09-22 at 3 38 42 PM"
src="https://github.com/awslabs/smithy-rs/assets/492903/082b4950-7edd-4f25-9081-a3c9fe3f870a">
<img width="998" alt="Screenshot 2023-09-22 at 3 39 01 PM"
src="https://github.com/awslabs/smithy-rs/assets/492903/98acd359-5572-4e01-afba-7af5b0264d18">

## Testing
<!--- Please describe in detail how you tested your changes -->
<!--- Include details of your testing environment, and the tests you ran
to -->
<!--- see how your change affects other areas of the code, etc. -->

## Checklist
<!--- If a checkbox below is not applicable, then please DELETE it
rather than leaving it unchecked -->
- [ ] I have updated `CHANGELOG.next.toml` if I made changes to the
smithy-rs codegen or runtime crates
- [ ] I have updated `CHANGELOG.next.toml` if I made changes to the AWS
SDK, generated SDK code, or SDK runtime crates

----

_By submitting this pull request, I confirm that you can use, modify,
copy, and redistribute this contribution, under the terms of your
choice._
parent 32655552
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -177,3 +177,9 @@ message = "Source defaults from the default trait instead of implicitly based on
references = ["smithy-rs#2985"]
meta = { "breaking" = false, "tada" = false, "bug" = true, "target" = "client" }
author = "rcoh"

[[smithy-rs]]
message = "Produce better docs when items are marked @required"
references = ["smithy-rs#2996"]
meta = { "breaking" = false, "tada" = false, "bug" = false, "target" = "client" }
author = "rcoh"
+1 −1
Original line number Diff line number Diff line
@@ -528,7 +528,7 @@ private fun generateOperationShapeDocs(
            else -> "(undocumented)"
        }

        "[`$builderInputDoc`]($builderInputLink) / [`$builderSetterDoc`]($builderSetterLink): $docs"
        "[`$builderInputDoc`]($builderInputLink) / [`$builderSetterDoc`]($builderSetterLink):<br>required: **${memberShape.isRequired}**<br>$docs<br>"
    }
}

+15 −0
Original line number Diff line number Diff line
@@ -186,6 +186,14 @@ class BuilderGenerator(
            false -> implBlockWriter.format(outputSymbol)
        }
        implBlockWriter.docs("Consumes the builder and constructs a #D.", outputSymbol)
        val trulyRequiredMembers = members.filter { trulyRequired(it) }
        if (trulyRequiredMembers.isNotEmpty()) {
            implBlockWriter.docs("This method will fail if any of the following fields are not set:")
            trulyRequiredMembers.forEach {
                val memberName = symbolProvider.toMemberName(it)
                implBlockWriter.docs("- [`$memberName`](#T::$memberName)", symbolProvider.symbolForBuilder(shape))
            }
        }
        implBlockWriter.rustBlockTemplate("pub fn build(self) -> $returnType", *preludeScope) {
            conditionalBlockTemplate("#{Ok}(", ")", conditional = fallibleBuilder, *preludeScope) {
                // If a wrapper is specified, use the `::new` associated function to construct the wrapper
@@ -216,6 +224,9 @@ class BuilderGenerator(
        val input = coreType.asArgument("input")

        writer.documentShape(member, model)
        if (member.isRequired) {
            writer.docs("This field is required.")
        }
        writer.deprecatedShape(member)
        writer.rustBlock("pub fn $memberName(mut self, ${input.argument}) -> Self") {
            rustTemplate("self.$memberName = #{Some}(${input.value});", *preludeScope)
@@ -369,6 +380,10 @@ class BuilderGenerator(
        }
    }

    private fun trulyRequired(member: MemberShape) = symbolProvider.toSymbol(member).let {
        !it.isOptional() && !it.canUseDefault()
    }

    /**
     * The core builder of the inner type. If the structure requires a fallible builder, this may use `?` to return
     * errors.