@@ -8,7 +8,12 @@ package software.amazon.smithy.rustsdk
8
8
import software.amazon.smithy.model.shapes.OperationShape
9
9
import software.amazon.smithy.rust.codegen.client.smithy.ClientCodegenContext
10
10
import software.amazon.smithy.rust.codegen.client.smithy.customize.ClientCodegenDecorator
11
+ import software.amazon.smithy.rust.codegen.client.smithy.generators.OperationRuntimePluginCustomization
12
+ import software.amazon.smithy.rust.codegen.client.smithy.generators.OperationRuntimePluginSection
13
+ import software.amazon.smithy.rust.codegen.core.rustlang.Attribute
14
+ import software.amazon.smithy.rust.codegen.core.rustlang.Attribute.Companion.derive
11
15
import software.amazon.smithy.rust.codegen.core.rustlang.rust
16
+ import software.amazon.smithy.rust.codegen.core.rustlang.rustTemplate
12
17
import software.amazon.smithy.rust.codegen.core.rustlang.writable
13
18
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeConfig
14
19
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeType
@@ -23,13 +28,21 @@ class RetryClassifierDecorator : ClientCodegenDecorator {
23
28
codegenContext : ClientCodegenContext ,
24
29
operation : OperationShape ,
25
30
baseCustomizations : List <OperationCustomization >,
26
- ): List <OperationCustomization > {
27
- return baseCustomizations + RetryClassifierFeature (codegenContext.runtimeConfig)
28
- }
31
+ ): List <OperationCustomization > =
32
+ baseCustomizations + RetryClassifierFeature (codegenContext.runtimeConfig)
33
+
34
+ override fun operationRuntimePluginCustomizations (
35
+ codegenContext : ClientCodegenContext ,
36
+ operation : OperationShape ,
37
+ baseCustomizations : List <OperationRuntimePluginCustomization >,
38
+ ): List <OperationRuntimePluginCustomization > =
39
+ baseCustomizations + OperationRetryClassifiersFeature (codegenContext, operation)
29
40
}
30
41
31
42
class RetryClassifierFeature (private val runtimeConfig : RuntimeConfig ) : OperationCustomization() {
32
- override fun retryType (): RuntimeType = AwsRuntimeType .awsHttp(runtimeConfig).resolve(" retry::AwsResponseRetryClassifier" )
43
+ override fun retryType (): RuntimeType =
44
+ AwsRuntimeType .awsHttp(runtimeConfig).resolve(" retry::AwsResponseRetryClassifier" )
45
+
33
46
override fun section (section : OperationSection ) = when (section) {
34
47
is OperationSection .FinalizeOperation -> writable {
35
48
rust(
@@ -41,3 +54,140 @@ class RetryClassifierFeature(private val runtimeConfig: RuntimeConfig) : Operati
41
54
else -> emptySection
42
55
}
43
56
}
57
+
58
+ class OperationRetryClassifiersFeature (
59
+ codegenContext : ClientCodegenContext ,
60
+ operation : OperationShape ,
61
+ ) : OperationRuntimePluginCustomization() {
62
+ private val runtimeConfig = codegenContext.runtimeConfig
63
+ private val awsRuntime = AwsRuntimeType .awsRuntime(runtimeConfig)
64
+ private val smithyRuntime = RuntimeType .smithyRuntime(runtimeConfig)
65
+ private val smithyRuntimeApi = RuntimeType .smithyRuntimeApi(runtimeConfig)
66
+ private val codegenScope = arrayOf(
67
+ " HttpStatusCodeClassifier" to smithyRuntime.resolve(" client::retries::classifier::HttpStatusCodeClassifier" ),
68
+ " AwsErrorCodeClassifier" to awsRuntime.resolve(" retries::classifier::AwsErrorCodeClassifier" ),
69
+ " ModeledAsRetryableClassifier" to smithyRuntime.resolve(" client::retries::classifier::ModeledAsRetryableClassifier" ),
70
+ " AmzRetryAfterHeaderClassifier" to awsRuntime.resolve(" retries::classifier::AmzRetryAfterHeaderClassifier" ),
71
+ " SmithyErrorClassifier" to smithyRuntime.resolve(" client::retries::classifier::SmithyErrorClassifier" ),
72
+ " RetryReason" to smithyRuntimeApi.resolve(" client::retries::RetryReason" ),
73
+ " ClassifyRetry" to smithyRuntimeApi.resolve(" client::retries::ClassifyRetry" ),
74
+ " RetryClassifiers" to smithyRuntimeApi.resolve(" client::retries::RetryClassifiers" ),
75
+ " OperationError" to codegenContext.symbolProvider.symbolForOperationError(operation),
76
+ " SdkError" to RuntimeType .smithyHttp(runtimeConfig).resolve(" result::SdkError" ),
77
+ " ErasedError" to RuntimeType .smithyRuntimeApi(runtimeConfig).resolve(" type_erasure::TypeErasedBox" ),
78
+ )
79
+
80
+ override fun section (section : OperationRuntimePluginSection ) = when (section) {
81
+ is OperationRuntimePluginSection .RuntimePluginSupportingTypes -> writable {
82
+ Attribute (derive(RuntimeType .Debug )).render(this )
83
+ rustTemplate(
84
+ """
85
+ struct HttpStatusCodeClassifier(#{HttpStatusCodeClassifier});
86
+ impl HttpStatusCodeClassifier {
87
+ fn new() -> Self {
88
+ Self(#{HttpStatusCodeClassifier}::default())
89
+ }
90
+ }
91
+ impl #{ClassifyRetry} for HttpStatusCodeClassifier {
92
+ fn classify_retry(&self, error: &#{ErasedError}) -> Option<#{RetryReason}> {
93
+ let error = error.downcast_ref::<#{SdkError}<#{OperationError}>>().expect("The error type is always known");
94
+ self.0.classify_error(error)
95
+ }
96
+ }
97
+ """ ,
98
+ * codegenScope,
99
+ )
100
+
101
+ Attribute (derive(RuntimeType .Debug )).render(this )
102
+ rustTemplate(
103
+ """
104
+ struct AwsErrorCodeClassifier(#{AwsErrorCodeClassifier});
105
+ impl AwsErrorCodeClassifier {
106
+ fn new() -> Self {
107
+ Self(#{AwsErrorCodeClassifier})
108
+ }
109
+ }
110
+ impl #{ClassifyRetry} for AwsErrorCodeClassifier {
111
+ fn classify_retry(&self, error: &#{ErasedError}) -> Option<#{RetryReason}> {
112
+ let error = error.downcast_ref::<#{SdkError}<#{OperationError}>>().expect("The error type is always known");
113
+ self.0.classify_error(error)
114
+ }
115
+ }
116
+ """ ,
117
+ * codegenScope,
118
+ )
119
+
120
+ Attribute (derive(RuntimeType .Debug )).render(this )
121
+ rustTemplate(
122
+ """
123
+ struct ModeledAsRetryableClassifier(#{ModeledAsRetryableClassifier});
124
+ impl ModeledAsRetryableClassifier {
125
+ fn new() -> Self {
126
+ Self(#{ModeledAsRetryableClassifier})
127
+ }
128
+ }
129
+ impl #{ClassifyRetry} for ModeledAsRetryableClassifier {
130
+ fn classify_retry(&self, error: &#{ErasedError}) -> Option<#{RetryReason}> {
131
+ let error = error.downcast_ref::<#{SdkError}<#{OperationError}>>().expect("The error type is always known");
132
+ self.0.classify_error(error)
133
+ }
134
+ }
135
+ """ ,
136
+ * codegenScope,
137
+ )
138
+
139
+ Attribute (derive(RuntimeType .Debug )).render(this )
140
+ rustTemplate(
141
+ """
142
+ struct AmzRetryAfterHeaderClassifier(#{AmzRetryAfterHeaderClassifier});
143
+ impl AmzRetryAfterHeaderClassifier {
144
+ fn new() -> Self {
145
+ Self(#{AmzRetryAfterHeaderClassifier})
146
+ }
147
+ }
148
+ impl #{ClassifyRetry} for AmzRetryAfterHeaderClassifier {
149
+ fn classify_retry(&self, error: &#{ErasedError}) -> Option<#{RetryReason}> {
150
+ let error = error.downcast_ref::<#{SdkError}<#{OperationError}>>().expect("The error type is always known");
151
+ self.0.classify_error(error)
152
+ }
153
+ }
154
+ """ ,
155
+ * codegenScope,
156
+ )
157
+
158
+ Attribute (derive(RuntimeType .Debug )).render(this )
159
+ rustTemplate(
160
+ """
161
+ struct SmithyErrorClassifier(#{SmithyErrorClassifier});
162
+ impl SmithyErrorClassifier {
163
+ fn new() -> Self {
164
+ Self(#{SmithyErrorClassifier})
165
+ }
166
+ }
167
+ impl #{ClassifyRetry} for SmithyErrorClassifier {
168
+ fn classify_retry(&self, error: &#{ErasedError}) -> Option<#{RetryReason}> {
169
+ let error = error.downcast_ref::<#{SdkError}<#{OperationError}>>().expect("The error type is always known");
170
+ self.0.classify_error(error)
171
+ }
172
+ }
173
+ """ ,
174
+ * codegenScope,
175
+ )
176
+ }
177
+
178
+ is OperationRuntimePluginSection .RetryClassifier -> writable {
179
+ rustTemplate(
180
+ """
181
+ .with_classifier(SmithyErrorClassifier::new())
182
+ .with_classifier(AmzRetryAfterHeaderClassifier::new())
183
+ .with_classifier(ModeledAsRetryableClassifier::new())
184
+ .with_classifier(AwsErrorCodeClassifier::new())
185
+ .with_classifier(HttpStatusCodeClassifier::new())
186
+ """ ,
187
+ * codegenScope,
188
+ )
189
+ }
190
+
191
+ else -> emptySection
192
+ }
193
+ }
0 commit comments