Skip to content
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

Add send_with method to fluent builders #2652

Merged
merged 60 commits into from
Jun 14, 2023
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
88b3c43
- Add feature gates
thomas-k-cameron Apr 27, 2023
82d296c
Add CfgUnstable feature gate
thomas-k-cameron Apr 27, 2023
5cc6ac9
add serde to runtime type
thomas-k-cameron Apr 27, 2023
900cf67
Merge commit '82d296c38fa6794e7a986639d82456f1587b185f' into RFC30/ru…
thomas-k-cameron Apr 27, 2023
72ed5b7
Merge commit '900cf67356e3d697cf2e330708e00810aa8665da' into RFC30/fe…
thomas-k-cameron Apr 27, 2023
f701ae1
add set field
thomas-k-cameron Apr 27, 2023
78d2e0b
Merge commit '72ed5b78f1018e64095cfded1f5a9e756edff9ac' into RFC30/ad…
thomas-k-cameron Apr 27, 2023
356bde7
Merge branch 'main' into RFC30/add-set-fields
thomas-k-cameron Apr 29, 2023
c9a4ae0
Merge branch 'main' into RFC30/add-set-fields
thomas-k-cameron May 31, 2023
893692a
Update FluentClientGenerator.kt
thomas-k-cameron May 31, 2023
c2cce08
update
thomas-k-cameron May 31, 2023
48c04f8
update
thomas-k-cameron Jun 1, 2023
bbd94ba
update
thomas-k-cameron Jun 1, 2023
75e84e7
Update FluentClientGenerator.kt
thomas-k-cameron Jun 1, 2023
7115727
Merge branch 'main' into RFC30/add-set-fields
thomas-k-cameron Jun 1, 2023
ad8f413
update fluent client
thomas-k-cameron Jun 2, 2023
d1069dc
fix
thomas-k-cameron Jun 2, 2023
2cb1e9b
update
thomas-k-cameron Jun 2, 2023
663dff3
update
thomas-k-cameron Jun 2, 2023
8b38afc
update
thomas-k-cameron Jun 2, 2023
525f572
update
thomas-k-cameron Jun 2, 2023
e3367dd
update
thomas-k-cameron Jun 2, 2023
dc21f19
update
thomas-k-cameron Jun 2, 2023
5972800
update
thomas-k-cameron Jun 2, 2023
54a187b
Merge branch 'main' into RFC30/add-set-fields
thomas-k-cameron Jun 2, 2023
e850ea2
update
thomas-k-cameron Jun 2, 2023
8b2877e
update
thomas-k-cameron Jun 2, 2023
ca47afe
change input path
thomas-k-cameron Jun 2, 2023
3bd1a7b
update
thomas-k-cameron Jun 2, 2023
a0a4651
update
thomas-k-cameron Jun 2, 2023
299e5ec
FIX
thomas-k-cameron Jun 3, 2023
605689e
updater
thomas-k-cameron Jun 3, 2023
ef38bbd
Merge branch 'main' into RFC30/add-set-fields
thomas-k-cameron Jun 3, 2023
857f3d4
FIX
thomas-k-cameron Jun 3, 2023
7bd1365
asdf
thomas-k-cameron Jun 3, 2023
e5cd52f
update
thomas-k-cameron Jun 3, 2023
7908333
Merge branch 'main' into RFC30/add-set-fields
thomas-k-cameron Jun 7, 2023
2e83422
update
thomas-k-cameron Jun 7, 2023
212506c
update
thomas-k-cameron Jun 7, 2023
54517f1
asdf
thomas-k-cameron Jun 7, 2023
140c040
precommit
thomas-k-cameron Jun 7, 2023
338ae8f
update
thomas-k-cameron Jun 7, 2023
edc62e8
Merge branch 'main' into RFC30/add-set-fields
thomas-k-cameron Jun 7, 2023
3d29cf9
asdf
thomas-k-cameron Jun 7, 2023
7f44d06
Merge branch 'RFC30/add-set-fields' of https://github.com/thomas-k-ca…
thomas-k-cameron Jun 7, 2023
6cd4b6b
Merge branch 'main' into RFC30/add-set-fields
thomas-k-cameron Jun 8, 2023
11af526
Merge branch 'main' into RFC30/add-set-fields
thomas-k-cameron Jun 11, 2023
8fc4751
Update codegen-client/src/main/kotlin/software/amazon/smithy/rust/cod…
thomas-k-cameron Jun 13, 2023
20ea34b
Merge branch 'main' into RFC30/add-set-fields
thomas-k-cameron Jun 13, 2023
ddc8c71
update
thomas-k-cameron Jun 13, 2023
3531f10
update
thomas-k-cameron Jun 13, 2023
08440b8
Merge branch 'main' into RFC30/add-set-fields
thomas-k-cameron Jun 13, 2023
c76dada
Merge branch 'main' into RFC30/add-set-fields
jdisanti Jun 13, 2023
79662af
Merge branch 'main' into RFC30/add-set-fields
thomas-k-cameron Jun 14, 2023
4251f97
update changelog
thomas-k-cameron Jun 14, 2023
0e478b2
FIX
thomas-k-cameron Jun 14, 2023
fa6e681
update
thomas-k-cameron Jun 14, 2023
ef451bb
update
thomas-k-cameron Jun 14, 2023
d8c5135
Update CHANGELOG.next.toml
jdisanti Jun 14, 2023
073d873
Merge branch 'main' into RFC30/add-set-fields
thomas-k-cameron Jun 14, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,8 @@ class FluentClientGenerator(
) {
val outputType = symbolProvider.toSymbol(operation.outputShape(model))
val errorType = symbolProvider.symbolForOperationError(operation)
val inputBuilderType = symbolProvider.symbolForBuilder(input)
val fnName = clientOperationFnName(operation, symbolProvider)

rust("/// Creates a new `${operationSymbol.name}`.")
withBlockTemplate(
Expand All @@ -370,6 +372,43 @@ class FluentClientGenerator(
}
}
}

// this fixes this error
// error[E0592]: duplicate definitions with name `set_fields`
// --> sdk/connectcases/src/operation/update_case/builders.rs:115:5
// |
// 78 | / pub fn set_fields(
// 79 | | mut self,
// 80 | | data: crate::operation::update_case::builders::UpdateCaseInputBuilder,
// 81 | | ) -> Self {
// | |_____________- other definition for `set_fields`
// ...
// 115 | / pub fn set_fields(
// 116 | | mut self,
// 117 | | input: std::option::Option<std::vec::Vec<crate::types::FieldValue>>,
// 118 | | ) -> Self {
// | |_____________^ duplicate definitions for `set_fields`
if (inputBuilderType.toString().endsWith("Builder")) {
thomas-k-cameron marked this conversation as resolved.
Show resolved Hide resolved
rustTemplate(
"""
##[#{AwsSdkUnstableAttribute}]
/// This function replaces the parameter with new one.
/// It is useful when you want to replace the existing data with de-serialized data.
/// ```compile_fail
/// let result_future = async {
/// let deserialized_parameters: $inputBuilderType = serde_json::from_str(&json_string).unwrap();
/// client.$fnName().set_fields(&deserialized_parameters).send().await
/// };
/// ```
pub fn set_fields(mut self, data: $inputBuilderType) -> Self {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be possible to go in the other direction and have an input take a client to form a fluent builder? Something like:

SomeInput::builder()
    .some_field("foo")
    .with_client(client) // returns the fluent builder corresponding to the SomeInput operation
    .send()
    .await

My reasoning is that set_fields could be called after some fields are set, and it would overwrite those fields, which could be confusing. If the API is designed so that that's not possible, all the better.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is lot better. I'm not quite sure if you can do this though. Let me investigate.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I implemented like this.

Example::builder().into_fluent_builder(client).send().await;

Example:

impl AddPermissionInputBuilder {
    #[cfg(aws_sdk_unstable)]
    /// Creates a fluent builder from this builder.
    pub fn into_fluent_builder(self, client: &crate::Client) -> AddPermissionFluentBuilder {
        let fluent_builder = client.add_permission();
        fluent_builder.inner = self;
        fluent_builder
    }
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fn into_* is used when it takes up the ownership to create a value as another datatype so I think this name is good.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Talking to the team a bit more about this, would making this into a send_with function be better? Something like:

SomeInput::builder()
    .some_field("foo")
    .send_with(&client)
    .await

self.inner = data;
self
}
""",
"AwsSdkUnstableAttribute" to Attribute.AwsSdkUnstableAttribute.inner,
)
}

if (smithyRuntimeMode.generateMiddleware) {
val middlewareScope = arrayOf(
*preludeScope,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import java.nio.file.Path
sealed class DependencyScope {
object Dev : DependencyScope()
object Compile : DependencyScope()
object CfgUnstable : DependencyScope()
object Build : DependencyScope()
}

Expand Down Expand Up @@ -277,5 +278,8 @@ data class CargoDependency(
fun smithyRuntimeApi(runtimeConfig: RuntimeConfig) = runtimeConfig.smithyRuntimeCrate("smithy-runtime-api")
fun smithyTypes(runtimeConfig: RuntimeConfig) = runtimeConfig.smithyRuntimeCrate("smithy-types")
fun smithyXml(runtimeConfig: RuntimeConfig) = runtimeConfig.smithyRuntimeCrate("smithy-xml")

// behind feature-gate
val Serde = CargoDependency("serde", CratesIo("1.0"), features = setOf("derive"), scope = DependencyScope.CfgUnstable)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,23 @@ class Attribute(val inner: Writable, val isDeriveHelper: Boolean = false) {
}
}

// These were supposed to be a part of companion object but we decided to move it out to here to avoid NPE
// You can find the discussion here.
// https://github.com/awslabs/smithy-rs/discussions/2248
public fun SerdeSerialize(): Attribute {
return Attribute(cfgAttr(all(writable("aws_sdk_unstable"), feature("serde-serialize")), derive(RuntimeType.SerdeSerialize)))
}
public fun SerdeDeserialize(): Attribute {
return Attribute(cfgAttr(all(writable("aws_sdk_unstable"), feature("serde-deserialize")), derive(RuntimeType.SerdeDeserialize)))
}
public fun SerdeSkip(): Attribute {
return Attribute(cfgAttr(all(writable("aws_sdk_unstable"), any(feature("serde-serialize"), feature("serde-deserialize"))), serde("skip")))
}

public fun SerdeSerializeOrDeserialize(): Attribute {
return Attribute(cfg(all(writable("aws_sdk_unstable"), any(feature("serde-serialize"), feature("serde-deserialize")))))
}

companion object {
val AllowClippyBoxedLocal = Attribute(allow("clippy::boxed_local"))
val AllowClippyLetAndReturn = Attribute(allow("clippy::let_and_return"))
Expand Down Expand Up @@ -504,6 +521,7 @@ class Attribute(val inner: Writable, val isDeriveHelper: Boolean = false) {

val Test = Attribute("test")
val TokioTest = Attribute(RuntimeType.Tokio.resolve("test").writable)
val AwsSdkUnstableAttribute = Attribute(cfg("aws_sdk_unstable"))

/**
* [non_exhaustive](https://doc.rust-lang.org/reference/attributes/type_system.html#the-non_exhaustive-attribute)
Expand Down Expand Up @@ -532,10 +550,12 @@ class Attribute(val inner: Writable, val isDeriveHelper: Boolean = false) {
}

fun all(vararg attrMacros: Writable): Writable = macroWithArgs("all", *attrMacros)
fun cfgAttr(vararg attrMacros: Writable): Writable = macroWithArgs("cfg_attr", *attrMacros)

fun allow(lints: Collection<String>): Writable = macroWithArgs("allow", *lints.toTypedArray())
fun allow(vararg lints: String): Writable = macroWithArgs("allow", *lints)
fun deny(vararg lints: String): Writable = macroWithArgs("deny", *lints)
fun serde(vararg lints: String): Writable = macroWithArgs("serde", *lints)
fun any(vararg attrMacros: Writable): Writable = macroWithArgs("any", *attrMacros)
fun cfg(vararg attrMacros: Writable): Writable = macroWithArgs("cfg", *attrMacros)
fun cfg(vararg attrMacros: String): Writable = macroWithArgs("cfg", *attrMacros)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,11 @@ data class RuntimeType(val path: String, val dependency: RustDependency? = null)
val ConstrainedTrait = RuntimeType("crate::constrained::Constrained", InlineDependency.constrained())
val MaybeConstrained = RuntimeType("crate::constrained::MaybeConstrained", InlineDependency.constrained())

// serde types. Gated behind `CfgUnstable`.
val Serde = CargoDependency.Serde.toType()
val SerdeSerialize = Serde.resolve("Serialize")
val SerdeDeserialize = Serde.resolve("Deserialize")

// smithy runtime types
fun smithyAsync(runtimeConfig: RuntimeConfig) = CargoDependency.smithyAsync(runtimeConfig).toType()
fun smithyChecksums(runtimeConfig: RuntimeConfig) = CargoDependency.smithyChecksums(runtimeConfig).toType()
Expand Down