-
Notifications
You must be signed in to change notification settings - Fork 203
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
Use a newtyped IndexSet to back the "set" shape #1446
Conversation
A new generated diff is ready to view.
A new doc preview is ready to view. Rust Wrk benchmark report:Duration: 90 sec, Connections: 32, Threads: 2
|
A new generated diff is ready to view.
A new doc preview is ready to view. Rust Wrk benchmark report:Duration: 90 sec, Connections: 32, Threads: 2
|
@@ -864,7 +865,12 @@ private class ServerHttpBoundProtocolTraitImplGenerator( | |||
rust("let mut seen_${symbolProvider.toMemberName(it.member)} = false;") | |||
} | |||
queryBindingsTargettingCollection.forEach { | |||
rust("let mut ${symbolProvider.toMemberName(it.member)} = Vec::new();") | |||
val collection = if (model.expectShape(it.member.target) is SetShape) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR introduces a ton of branches like this. Is there a way to reduce them?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah—you can change them to:
val collectionType = symbolProvider.toSymbol(model.expectShape(it.member.target))
val memberName = symbolProvider.toMemberName(it.member)
rustTemplate("let mut $memberName = #{collection}::new();, "Collection" to collectionType)
(or similar)
const val Type = "Set" | ||
const val Namespace = "aws_smithy_types" | ||
|
||
fun RuntimeType(runtimeConfig: RuntimeConfig): RuntimeType { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We've promoted this from a val
to a function in order to accommodate the need for a dependency
.
assert_eq!(test.otherMember, "hello"); | ||
assert_eq!(test.member.is_empty(), true); | ||
""", | ||
"Set" to RuntimeType.Set(TestRuntimeConfig) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These tests have been "modernized" (using TestWorkspace.testProject()
) in order to allow for dependency injection here.
write("member: #T,", setSymbol) | ||
write("otherMember: #T,", stringSymbol) | ||
} | ||
it.rustBlock("fn inner()") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We cannot do this within unitTest
because it takes a string
rather than provide a writer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#1450 addresses this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed b8c70b8
A new generated diff is ready to view.
A new doc preview is ready to view. Rust Wrk benchmark report:Duration: 90 sec, Connections: 32, Threads: 2
|
A new generated diff is ready to view.
A new doc preview is ready to view. Rust Wrk benchmark report:Duration: 90 sec, Connections: 32, Threads: 2
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
overall I love the direction! And thanks for modernizing some tests :-)
I think we can completely remove the differential behavior for Vec and Set with a couple of ideas I mentioned in a comment above:
- Use
symbolProvider.toSymbol()
instead ofVec
to get the type of the collection - Add a
push
method toSet
Thanks for addressing this extremely long standing issue!
(And hopefully someone already told you about "debug mode" codegen which makes tracking down where code is coming from much easier)
@@ -864,7 +865,12 @@ private class ServerHttpBoundProtocolTraitImplGenerator( | |||
rust("let mut seen_${symbolProvider.toMemberName(it.member)} = false;") | |||
} | |||
queryBindingsTargettingCollection.forEach { | |||
rust("let mut ${symbolProvider.toMemberName(it.member)} = Vec::new();") | |||
val collection = if (model.expectShape(it.member.target) is SetShape) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah—you can change them to:
val collectionType = symbolProvider.toSymbol(model.expectShape(it.member.target))
val memberName = symbolProvider.toMemberName(it.member)
rustTemplate("let mut $memberName = #{collection}::new();, "Collection" to collectionType)
(or similar)
@@ -926,7 +932,12 @@ private class ServerHttpBoundProtocolTraitImplGenerator( | |||
) | |||
} | |||
} | |||
rust("${symbolProvider.toMemberName(it.member)}.push(v);") | |||
val method = if (model.expectShape(it.member.target) is SetShape) { | |||
"insert" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since we own Set
why don't we add a push method for convenience? you can make it #[doc(hidden)]
if you want
return RuntimeType(name = Type, namespace = Namespace, dependency = CargoDependency.SmithyTypes(runtimeConfig)) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for slightly cleaner code:
CargoDependency.SmithyTypes(runtimeConfig).asType().member("aws_smithy_types::Set")
var container = if (shape.isSetShape) { | ||
RuntimeType.Set(runtimeConfig) | ||
} else { | ||
RuntimeType("Vec", dependency = null, namespace = "std::vec") | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we don't need this—just use symbolProvider.toSymbol(shape)
val builder = if (model.expectShape(shape.member.target).isStringShape) { | ||
symbolBuilder(shape, RustType.HashSet(inner.rustType())) | ||
} else { | ||
// only strings get put into actual sets because floats are unhashable | ||
symbolBuilder(shape, RustType.Vec(inner.rustType())) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's a comment that justifies why this is OK—when this code was written, sets could contain floats but that was changed:
A set shape requires a single member named member, and the member MUST target either a string, blob, byte, short, integer, long, bigInteger, or bigDecimal shape. The targeted shape MUST NOT be marked with the streaming trait.
pub mod timeout; | ||
pub mod tristate; | ||
|
||
pub use crate::date_time::DateTime; | ||
pub use crate::set::*; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
especially with pub use
, lets enumerate these for clarity
A new generated diff is ready to view.
A new doc preview is ready to view. |
A new generated diff is ready to view.
A new doc preview is ready to view. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looking good so far!
docs("Appends an item to `$memberName`.") | ||
rust("///") | ||
docs("To override the contents of this collection use [`${member.setterName()}`](Self::${member.setterName()}).") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
might as well have some custom docs that call out the deduplication
if replaced { | ||
return Err(#{JsonDeserialize}::custom("duplicate elements found while deserializing to a set")) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we want to error here? or just deduplicate?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The team had a little back and forth on this (semantics =? deserialization failure cases) and opened this issue.
Will no longer throw an error but perhaps log a warning?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
references = ["smithy-rs#1446"] | ||
meta = { "breaking" = true, "tada" = false, "bug" = false } | ||
author = "hlbarber" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we'll need to call out the exact breaking change and provide upgrade instructions
A new generated diff is ready to view.
A new doc preview is ready to view. |
A new generated diff is ready to view.
A new doc preview is ready to view. |
Closing this due to smithy-lang/smithy#1278 |
Motivation and Context
set
with astd::vec::Vec
, however this does not prevent duplicates.@httpQuery
and@httpQueryParams
to a Smithy set #972Description
Set<T>
toaws-smithy-types
Set<T>
into smithy codegenChecklist
CHANGELOG.next.toml
if I made changes to the smithy-rs codegen or runtime crates