Skip to content

Commit

Permalink
Produce &[T] instead of Option<&[T]> for list fields
Browse files Browse the repository at this point in the history
This improves API ergonomics when the output is a list
  • Loading branch information
rcoh committed Sep 21, 2023
1 parent 1331dc5 commit 3a4e5f5
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@ import software.amazon.smithy.rust.codegen.core.rustlang.RustWriter
import software.amazon.smithy.rust.codegen.core.rustlang.asDeref
import software.amazon.smithy.rust.codegen.core.rustlang.asRef
import software.amazon.smithy.rust.codegen.core.rustlang.deprecatedShape
import software.amazon.smithy.rust.codegen.core.rustlang.docs
import software.amazon.smithy.rust.codegen.core.rustlang.documentShape
import software.amazon.smithy.rust.codegen.core.rustlang.isCopy
import software.amazon.smithy.rust.codegen.core.rustlang.isDeref
import software.amazon.smithy.rust.codegen.core.rustlang.render
import software.amazon.smithy.rust.codegen.core.rustlang.rust
import software.amazon.smithy.rust.codegen.core.rustlang.rustBlock
import software.amazon.smithy.rust.codegen.core.rustlang.stripOuter
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeType
import software.amazon.smithy.rust.codegen.core.smithy.RustSymbolProvider
import software.amazon.smithy.rust.codegen.core.smithy.customize.NamedCustomization
Expand Down Expand Up @@ -131,15 +133,26 @@ open class StructureGenerator(
writer.rustBlock("impl $name") {
// Render field accessor methods
forEachMember(accessorMembers) { member, memberName, memberSymbol ->
writer.renderMemberDoc(member, memberSymbol)
writer.deprecatedShape(member)
val memberType = memberSymbol.rustType()
var unwrapOrDefault = false
val returnType = when {
// Automatically flatten vecs
memberType is RustType.Option && memberType.stripOuter<RustType.Option>() is RustType.Vec -> {
unwrapOrDefault = true
memberType.stripOuter<RustType.Option>().asDeref().asRef()
}
memberType.isCopy() -> memberType
memberType is RustType.Option && memberType.member.isDeref() -> memberType.asDeref()
memberType.isDeref() -> memberType.asDeref().asRef()
else -> memberType.asRef()
}
writer.renderMemberDoc(member, memberSymbol)
if (unwrapOrDefault) {
// Add a newline
writer.docs("")
writer.docs("If no value was sent for this field, a default will be set. If you want to determine if no value was sent, use `.$memberName.is_none()`.")
}
writer.deprecatedShape(member)
writer.rustBlock("pub fn $memberName(&self) -> ${returnType.render()}") {
when {
memberType.isCopy() -> rust("self.$memberName")
Expand All @@ -148,6 +161,9 @@ open class StructureGenerator(
memberType.isDeref() -> rust("use std::ops::Deref; self.$memberName.deref()")
else -> rust("&self.$memberName")
}
if (unwrapOrDefault) {
rust(".unwrap_or_default()")
}
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions design/src/rfcs/rfc0035_collection_defaults.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ RFC: Collection Defaults
=============

<!-- RFCs start with the "RFC" status and are then either "Implemented" or "Rejected". -->
> Status: Accepted
> Status: Implemented
>
> Applies to: client
Expand Down Expand Up @@ -78,5 +78,5 @@ No, many existing APIs don't have the default trait.
Changes checklist
-----------------
Estimated total work: 2 days
- [ ] Update accessor method generation to auto flatten lists
- [ ] Update docs for accessors to guide users to `.field.is_some()` if they MUST determine if the field was set.
- [x] Update accessor method generation to auto flatten lists
- [x] Update docs for accessors to guide users to `.field.is_some()` if they MUST determine if the field was set.

0 comments on commit 3a4e5f5

Please sign in to comment.