aws_sdk_s3/operation/
put_object.rs

1// Code generated by software.amazon.smithy.rust.codegen.smithy-rs. DO NOT EDIT.
2/// Orchestration and serialization glue logic for `PutObject`.
3#[derive(::std::clone::Clone, ::std::default::Default, ::std::fmt::Debug)]
4#[non_exhaustive]
5pub struct PutObject;
6impl PutObject {
7    /// Creates a new `PutObject`
8    pub fn new() -> Self {
9        Self
10    }
11    pub(crate) async fn orchestrate(
12        runtime_plugins: &::aws_smithy_runtime_api::client::runtime_plugin::RuntimePlugins,
13        input: crate::operation::put_object::PutObjectInput,
14    ) -> ::std::result::Result<
15        crate::operation::put_object::PutObjectOutput,
16        ::aws_smithy_runtime_api::client::result::SdkError<
17            crate::operation::put_object::PutObjectError,
18            ::aws_smithy_runtime_api::client::orchestrator::HttpResponse,
19        >,
20    > {
21        let map_err = |err: ::aws_smithy_runtime_api::client::result::SdkError<
22            ::aws_smithy_runtime_api::client::interceptors::context::Error,
23            ::aws_smithy_runtime_api::client::orchestrator::HttpResponse,
24        >| {
25            err.map_service_error(|err| {
26                err.downcast::<crate::operation::put_object::PutObjectError>()
27                    .expect("correct error type")
28            })
29        };
30        let context = Self::orchestrate_with_stop_point(runtime_plugins, input, ::aws_smithy_runtime::client::orchestrator::StopPoint::None)
31            .await
32            .map_err(map_err)?;
33        let output = context.finalize().map_err(map_err)?;
34        ::std::result::Result::Ok(
35            output
36                .downcast::<crate::operation::put_object::PutObjectOutput>()
37                .expect("correct output type"),
38        )
39    }
40
41    pub(crate) async fn orchestrate_with_stop_point(
42        runtime_plugins: &::aws_smithy_runtime_api::client::runtime_plugin::RuntimePlugins,
43        input: crate::operation::put_object::PutObjectInput,
44        stop_point: ::aws_smithy_runtime::client::orchestrator::StopPoint,
45    ) -> ::std::result::Result<
46        ::aws_smithy_runtime_api::client::interceptors::context::InterceptorContext,
47        ::aws_smithy_runtime_api::client::result::SdkError<
48            ::aws_smithy_runtime_api::client::interceptors::context::Error,
49            ::aws_smithy_runtime_api::client::orchestrator::HttpResponse,
50        >,
51    > {
52        let input = ::aws_smithy_runtime_api::client::interceptors::context::Input::erase(input);
53        use ::tracing::Instrument;
54        ::aws_smithy_runtime::client::orchestrator::invoke_with_stop_point("S3", "PutObject", input, runtime_plugins, stop_point)
55            // Create a parent span for the entire operation. Includes a random, internal-only,
56            // seven-digit ID for the operation orchestration so that it can be correlated in the logs.
57            .instrument(::tracing::debug_span!(
58                "S3.PutObject",
59                "rpc.service" = "S3",
60                "rpc.method" = "PutObject",
61                "sdk_invocation_id" = ::fastrand::u32(1_000_000..10_000_000),
62                "rpc.system" = "aws-api",
63            ))
64            .await
65    }
66
67    pub(crate) fn operation_runtime_plugins(
68        client_runtime_plugins: ::aws_smithy_runtime_api::client::runtime_plugin::RuntimePlugins,
69        client_config: &crate::config::Config,
70        config_override: ::std::option::Option<crate::config::Builder>,
71    ) -> ::aws_smithy_runtime_api::client::runtime_plugin::RuntimePlugins {
72        let mut runtime_plugins = client_runtime_plugins.with_operation_plugin(Self::new());
73
74        if let ::std::option::Option::Some(config_override) = config_override {
75            for plugin in config_override.runtime_plugins.iter().cloned() {
76                runtime_plugins = runtime_plugins.with_operation_plugin(plugin);
77            }
78            runtime_plugins = runtime_plugins.with_operation_plugin(crate::config::ConfigOverrideRuntimePlugin::new(
79                config_override,
80                client_config.config.clone(),
81                &client_config.runtime_components,
82            ));
83        }
84        runtime_plugins
85    }
86}
87impl ::aws_smithy_runtime_api::client::runtime_plugin::RuntimePlugin for PutObject {
88    fn config(&self) -> ::std::option::Option<::aws_smithy_types::config_bag::FrozenLayer> {
89        let mut cfg = ::aws_smithy_types::config_bag::Layer::new("PutObject");
90
91        cfg.store_put(::aws_smithy_runtime_api::client::ser_de::SharedRequestSerializer::new(
92            PutObjectRequestSerializer,
93        ));
94        cfg.store_put(::aws_smithy_runtime_api::client::ser_de::SharedResponseDeserializer::new(
95            PutObjectResponseDeserializer,
96        ));
97
98        cfg.store_put(::aws_smithy_runtime_api::client::auth::AuthSchemeOptionResolverParams::new(
99            crate::config::auth::Params::builder()
100                .operation_name("PutObject")
101                .build()
102                .expect("required fields set"),
103        ));
104
105        cfg.store_put(::aws_smithy_runtime_api::client::orchestrator::SensitiveOutput);
106        cfg.store_put(::aws_smithy_runtime_api::client::orchestrator::Metadata::new("PutObject", "S3"));
107        let mut signing_options = ::aws_runtime::auth::SigningOptions::default();
108        signing_options.double_uri_encode = false;
109        signing_options.content_sha256_header = true;
110        signing_options.normalize_uri_path = false;
111        signing_options.payload_override = None;
112
113        cfg.store_put(::aws_runtime::auth::SigV4OperationSigningConfig {
114            signing_options,
115            ..::std::default::Default::default()
116        });
117
118        ::std::option::Option::Some(cfg.freeze())
119    }
120
121    fn runtime_components(
122        &self,
123        _: &::aws_smithy_runtime_api::client::runtime_components::RuntimeComponentsBuilder,
124    ) -> ::std::borrow::Cow<'_, ::aws_smithy_runtime_api::client::runtime_components::RuntimeComponentsBuilder> {
125        #[allow(unused_mut)]
126        let mut rcb = ::aws_smithy_runtime_api::client::runtime_components::RuntimeComponentsBuilder::new("PutObject")
127            .with_interceptor(::aws_smithy_runtime::client::stalled_stream_protection::StalledStreamProtectionInterceptor::default())
128            .with_interceptor(PutObjectEndpointParamsInterceptor)
129            .with_interceptor(crate::http_request_checksum::RequestChecksumInterceptor::new(
130                |input: &::aws_smithy_runtime_api::client::interceptors::context::Input| {
131                    let input: &crate::operation::put_object::PutObjectInput = input.downcast_ref().expect("correct type");
132                    let checksum_algorithm = input.checksum_algorithm();
133                    let checksum_algorithm = checksum_algorithm.map(|algorithm| algorithm.as_str());
134                    (checksum_algorithm.map(|s| s.to_string()), false)
135                },
136                |request: &mut ::aws_smithy_runtime_api::http::Request, cfg: &::aws_smithy_types::config_bag::ConfigBag| {
137                    // We check if the user has set any of the checksum values manually
138                    let mut user_set_checksum_value = false;
139                    let headers_to_check =
140                        request
141                            .headers()
142                            .iter()
143                            .filter_map(|(name, _val)| if name.starts_with("x-amz-checksum-") { Some(name) } else { None });
144                    for algo_header in headers_to_check {
145                        if request.headers().get(algo_header).is_some() {
146                            user_set_checksum_value = true;
147                        }
148                    }
149
150                    // We check if the user set the checksum algo manually
151                    let user_set_checksum_algo = request.headers().get("x-amz-sdk-checksum-algorithm").is_some();
152
153                    // This value is set by the user on the SdkConfig to indicate their preference
154                    let request_checksum_calculation = cfg
155                        .load::<::aws_smithy_types::checksum_config::RequestChecksumCalculation>()
156                        .unwrap_or(&::aws_smithy_types::checksum_config::RequestChecksumCalculation::WhenSupported);
157
158                    // From the httpChecksum trait
159                    let http_checksum_required = false;
160
161                    let is_presigned_req = cfg.load::<crate::presigning::PresigningMarker>().is_some();
162
163                    // If the request is presigned we do not set a default.
164                    // If the RequestChecksumCalculation is WhenSupported and the user has not set a checksum value or algo
165                    // we set the default. If it is WhenRequired and a checksum is required by the trait and the user has not
166                    // set a checksum value or algo we also set the default. In all other cases we do nothing.
167                    match (
168                        request_checksum_calculation,
169                        http_checksum_required,
170                        user_set_checksum_value,
171                        user_set_checksum_algo,
172                        is_presigned_req,
173                    ) {
174                        (_, _, _, _, true) => {}
175                        (::aws_smithy_types::checksum_config::RequestChecksumCalculation::WhenSupported, _, false, false, _)
176                        | (::aws_smithy_types::checksum_config::RequestChecksumCalculation::WhenRequired, true, false, false, _) => {
177                            request.headers_mut().insert("x-amz-sdk-checksum-algorithm", "CRC32");
178                        }
179                        _ => {}
180                    }
181
182                    // We return a bool indicating if the user did set the checksum value, if they did
183                    // we can short circuit and exit the interceptor early.
184                    Ok(user_set_checksum_value)
185                },
186            ))
187            .with_interceptor(crate::aws_chunked::AwsChunkedContentEncodingInterceptor)
188            .with_retry_classifier(::aws_smithy_runtime::client::retries::classifiers::TransientErrorClassifier::<
189                crate::operation::put_object::PutObjectError,
190            >::new())
191            .with_retry_classifier(::aws_smithy_runtime::client::retries::classifiers::ModeledAsRetryableClassifier::<
192                crate::operation::put_object::PutObjectError,
193            >::new())
194            .with_retry_classifier(
195                ::aws_runtime::retries::classifiers::AwsErrorCodeClassifier::<crate::operation::put_object::PutObjectError>::builder()
196                    .transient_errors({
197                        let mut transient_errors: Vec<&'static str> = ::aws_runtime::retries::classifiers::TRANSIENT_ERRORS.into();
198                        transient_errors.push("InternalError");
199                        ::std::borrow::Cow::Owned(transient_errors)
200                    })
201                    .build(),
202            );
203
204        ::std::borrow::Cow::Owned(rcb)
205    }
206}
207
208#[derive(Debug)]
209struct PutObjectResponseDeserializer;
210impl ::aws_smithy_runtime_api::client::ser_de::DeserializeResponse for PutObjectResponseDeserializer {
211    fn deserialize_nonstreaming(
212        &self,
213        response: &::aws_smithy_runtime_api::client::orchestrator::HttpResponse,
214    ) -> ::aws_smithy_runtime_api::client::interceptors::context::OutputOrError {
215        let (success, status) = (response.status().is_success(), response.status().as_u16());
216        let headers = response.headers();
217        let body = response.body().bytes().expect("body loaded");
218        #[allow(unused_mut)]
219        let mut force_error = false;
220        ::tracing::debug!(extended_request_id = ?crate::s3_request_id::RequestIdExt::extended_request_id(response));
221        if matches!(crate::rest_xml_unwrapped_errors::body_is_error(body), Ok(true)) {
222            force_error = true;
223        }
224        ::tracing::debug!(request_id = ?::aws_types::request_id::RequestId::request_id(response));
225        let parse_result = if !success && status != 200 || force_error {
226            crate::protocol_serde::shape_put_object::de_put_object_http_error(status, headers, body)
227        } else {
228            crate::protocol_serde::shape_put_object::de_put_object_http_response(status, headers, body)
229        };
230        crate::protocol_serde::type_erase_result(parse_result)
231    }
232}
233#[derive(Debug)]
234struct PutObjectRequestSerializer;
235impl ::aws_smithy_runtime_api::client::ser_de::SerializeRequest for PutObjectRequestSerializer {
236    #[allow(unused_mut, clippy::let_and_return, clippy::needless_borrow, clippy::useless_conversion)]
237    fn serialize_input(
238        &self,
239        input: ::aws_smithy_runtime_api::client::interceptors::context::Input,
240        _cfg: &mut ::aws_smithy_types::config_bag::ConfigBag,
241    ) -> ::std::result::Result<::aws_smithy_runtime_api::client::orchestrator::HttpRequest, ::aws_smithy_runtime_api::box_error::BoxError> {
242        let input = input.downcast::<crate::operation::put_object::PutObjectInput>().expect("correct type");
243        let _header_serialization_settings = _cfg
244            .load::<crate::serialization_settings::HeaderSerializationSettings>()
245            .cloned()
246            .unwrap_or_default();
247        let mut request_builder = {
248            #[allow(clippy::uninlined_format_args)]
249            fn uri_base(
250                _input: &crate::operation::put_object::PutObjectInput,
251                output: &mut ::std::string::String,
252            ) -> ::std::result::Result<(), ::aws_smithy_types::error::operation::BuildError> {
253                use ::std::fmt::Write as _;
254                let input_1 = &_input.key;
255                let input_1 = input_1
256                    .as_ref()
257                    .ok_or_else(|| ::aws_smithy_types::error::operation::BuildError::missing_field("key", "cannot be empty or unset"))?;
258                let key = ::aws_smithy_http::label::fmt_string(input_1, ::aws_smithy_http::label::EncodingStrategy::Greedy);
259                if key.is_empty() {
260                    return ::std::result::Result::Err(::aws_smithy_types::error::operation::BuildError::missing_field(
261                        "key",
262                        "cannot be empty or unset",
263                    ));
264                }
265                ::std::write!(output, "/{Key}", Key = key).expect("formatting should succeed");
266                ::std::result::Result::Ok(())
267            }
268            fn uri_query(
269                _input: &crate::operation::put_object::PutObjectInput,
270                mut output: &mut ::std::string::String,
271            ) -> ::std::result::Result<(), ::aws_smithy_types::error::operation::BuildError> {
272                let mut query = ::aws_smithy_http::query::Writer::new(output);
273                query.push_kv("x-id", "PutObject");
274                ::std::result::Result::Ok(())
275            }
276            #[allow(clippy::unnecessary_wraps)]
277            fn update_http_builder(
278                input: &crate::operation::put_object::PutObjectInput,
279                builder: ::http::request::Builder,
280            ) -> ::std::result::Result<::http::request::Builder, ::aws_smithy_types::error::operation::BuildError> {
281                let mut uri = ::std::string::String::new();
282                uri_base(input, &mut uri)?;
283                uri_query(input, &mut uri)?;
284                let builder = crate::protocol_serde::shape_put_object::ser_put_object_headers(input, builder)?;
285                ::std::result::Result::Ok(builder.method("PUT").uri(uri))
286            }
287            let mut builder = update_http_builder(&input, ::http::request::Builder::new())?;
288            builder = _header_serialization_settings.set_default_header(builder, ::http::header::CONTENT_TYPE, "application/octet-stream");
289            builder
290        };
291        let body = crate::protocol_serde::shape_put_object_input::ser_body_http_payload(input.body)?.into_inner();
292        if let Some(content_length) = body.content_length() {
293            let content_length = content_length.to_string();
294            request_builder = _header_serialization_settings.set_default_header(request_builder, ::http::header::CONTENT_LENGTH, &content_length);
295        }
296        ::std::result::Result::Ok(request_builder.body(body).expect("valid request").try_into().unwrap())
297    }
298}
299#[derive(Debug)]
300struct PutObjectEndpointParamsInterceptor;
301
302impl ::aws_smithy_runtime_api::client::interceptors::Intercept for PutObjectEndpointParamsInterceptor {
303    fn name(&self) -> &'static str {
304        "PutObjectEndpointParamsInterceptor"
305    }
306
307    fn read_before_execution(
308        &self,
309        context: &::aws_smithy_runtime_api::client::interceptors::context::BeforeSerializationInterceptorContextRef<
310            '_,
311            ::aws_smithy_runtime_api::client::interceptors::context::Input,
312            ::aws_smithy_runtime_api::client::interceptors::context::Output,
313            ::aws_smithy_runtime_api::client::interceptors::context::Error,
314        >,
315        cfg: &mut ::aws_smithy_types::config_bag::ConfigBag,
316    ) -> ::std::result::Result<(), ::aws_smithy_runtime_api::box_error::BoxError> {
317        let _input = context
318            .input()
319            .downcast_ref::<PutObjectInput>()
320            .ok_or("failed to downcast to PutObjectInput")?;
321
322        let params = crate::config::endpoint::Params::builder()
323            .set_region(cfg.load::<::aws_types::region::Region>().map(|r| r.as_ref().to_owned()))
324            .set_use_fips(cfg.load::<::aws_types::endpoint_config::UseFips>().map(|ty| ty.0))
325            .set_use_dual_stack(cfg.load::<::aws_types::endpoint_config::UseDualStack>().map(|ty| ty.0))
326            .set_endpoint(cfg.load::<::aws_types::endpoint_config::EndpointUrl>().map(|ty| ty.0.clone()))
327            .set_force_path_style(cfg.load::<crate::config::ForcePathStyle>().map(|ty| ty.0))
328            .set_use_arn_region(cfg.load::<crate::config::UseArnRegion>().map(|ty| ty.0))
329            .set_disable_multi_region_access_points(cfg.load::<crate::config::DisableMultiRegionAccessPoints>().map(|ty| ty.0))
330            .set_accelerate(cfg.load::<crate::config::Accelerate>().map(|ty| ty.0))
331            .set_disable_s3_express_session_auth(cfg.load::<crate::config::DisableS3ExpressSessionAuth>().map(|ty| ty.0))
332            .set_bucket(Some(
333                _input
334                    .bucket
335                    .clone()
336                    .filter(|f| !AsRef::<str>::as_ref(f).trim().is_empty())
337                    .ok_or_else(|| ::aws_smithy_types::error::operation::BuildError::missing_field("bucket", "A required field was not set"))?,
338            ))
339            .set_key(Some(
340                _input
341                    .key
342                    .clone()
343                    .filter(|f| !AsRef::<str>::as_ref(f).trim().is_empty())
344                    .ok_or_else(|| ::aws_smithy_types::error::operation::BuildError::missing_field("key", "A required field was not set"))?,
345            ))
346            .build()
347            .map_err(|err| {
348                ::aws_smithy_runtime_api::client::interceptors::error::ContextAttachedError::new("endpoint params could not be built", err)
349            })?;
350        cfg.interceptor_state()
351            .store_put(::aws_smithy_runtime_api::client::endpoint::EndpointResolverParams::new(params));
352        ::std::result::Result::Ok(())
353    }
354}
355
356// The get_* functions below are generated from JMESPath expressions in the
357// operationContextParams trait. They target the operation's input shape.
358
359#[allow(unreachable_code, unused_variables)]
360#[cfg(test)]
361mod put_object_test {
362
363    /// This test validates that if a content-type is specified, that only one content-type header is sent
364    /// Test ID: DontSendDuplicateContentType
365    #[::tokio::test]
366    #[::tracing_test::traced_test]
367    async fn dont_send_duplicate_content_type_request() {
368        let (http_client, request_receiver) = ::aws_smithy_http_client::test_util::capture_request(None);
369        let config_builder = crate::config::Config::builder().with_test_defaults().endpoint_url("https://example.com");
370        let config_builder = config_builder.region(::aws_types::region::Region::new("us-east-1"));
371        let mut config_builder = config_builder;
372        config_builder.set_region(Some(crate::config::Region::new("us-east-1")));
373
374        let config = config_builder.http_client(http_client).build();
375        let client = crate::Client::from_conf(config);
376        let result = client
377            .put_object()
378            .set_bucket(::std::option::Option::Some("test-bucket".to_owned()))
379            .set_key(::std::option::Option::Some("test-key".to_owned()))
380            .set_content_type(::std::option::Option::Some("text/html".to_owned()))
381            .send()
382            .await;
383        let _ = dbg!(result);
384        let http_request = request_receiver.expect_request();
385        let expected_headers = [("content-type", "text/html")];
386        ::aws_smithy_protocol_test::assert_ok(::aws_smithy_protocol_test::validate_headers(http_request.headers(), expected_headers));
387        let uri: ::http::Uri = http_request.uri().parse().expect("invalid URI sent");
388        ::pretty_assertions::assert_eq!(http_request.method(), "PUT", "method was incorrect");
389        ::pretty_assertions::assert_eq!(uri.path(), "/test-key", "path was incorrect");
390    }
391
392    /// This test validates that if a content-length is specified, that only one content-length header is sent
393    /// Test ID: DontSendDuplicateContentLength
394    #[::tokio::test]
395    #[::tracing_test::traced_test]
396    async fn dont_send_duplicate_content_length_request() {
397        let (http_client, request_receiver) = ::aws_smithy_http_client::test_util::capture_request(None);
398        let config_builder = crate::config::Config::builder().with_test_defaults().endpoint_url("https://example.com");
399        let config_builder = config_builder.region(::aws_types::region::Region::new("us-east-1"));
400        let mut config_builder = config_builder;
401        config_builder.set_region(Some(crate::config::Region::new("us-east-1")));
402
403        let config = config_builder.http_client(http_client).build();
404        let client = crate::Client::from_conf(config);
405        let result = client
406            .put_object()
407            .set_bucket(::std::option::Option::Some("test-bucket".to_owned()))
408            .set_key(::std::option::Option::Some("test-key".to_owned()))
409            .set_content_length(::std::option::Option::Some(2))
410            .set_body(::std::option::Option::Some(::aws_smithy_types::byte_stream::ByteStream::from_static(
411                b"ab",
412            )))
413            .send()
414            .await;
415        let _ = dbg!(result);
416        let http_request = request_receiver.expect_request();
417        let expected_headers = [("content-length", "2")];
418        ::aws_smithy_protocol_test::assert_ok(::aws_smithy_protocol_test::validate_headers(http_request.headers(), expected_headers));
419        let uri: ::http::Uri = http_request.uri().parse().expect("invalid URI sent");
420        ::pretty_assertions::assert_eq!(http_request.method(), "PUT", "method was incorrect");
421        ::pretty_assertions::assert_eq!(uri.path(), "/test-key", "path was incorrect");
422    }
423}
424
425/// Error type for the `PutObjectError` operation.
426#[non_exhaustive]
427#[derive(::std::fmt::Debug)]
428pub enum PutObjectError {
429    /// <p>The existing object was created with a different encryption type. Subsequent write requests must include the appropriate encryption parameters in the request or while creating the session.</p>
430    EncryptionTypeMismatch(crate::types::error::EncryptionTypeMismatch),
431    /// <p>You may receive this error in multiple cases. Depending on the reason for the error, you may receive one of the messages below:</p>
432    /// <ul>
433    /// <li>
434    /// <p>Cannot specify both a write offset value and user-defined object metadata for existing objects.</p></li>
435    /// <li>
436    /// <p>Checksum Type mismatch occurred, expected checksum Type: sha1, actual checksum Type: crc32c.</p></li>
437    /// <li>
438    /// <p>Request body cannot be empty when 'write offset' is specified.</p></li>
439    /// </ul>
440    InvalidRequest(crate::types::error::InvalidRequest),
441    /// <p>The write offset value that you specified does not match the current object size.</p>
442    InvalidWriteOffset(crate::types::error::InvalidWriteOffset),
443    /// <p>You have attempted to add more parts than the maximum of 10000 that are allowed for this object. You can use the CopyObject operation to copy this object to another and then add more data to the newly copied object.</p>
444    TooManyParts(crate::types::error::TooManyParts),
445    /// An unexpected error occurred (e.g., invalid JSON returned by the service or an unknown error code).
446    #[deprecated(note = "Matching `Unhandled` directly is not forwards compatible. Instead, match using a \
447    variable wildcard pattern and check `.code()`:
448     \
449    &nbsp;&nbsp;&nbsp;`err if err.code() == Some(\"SpecificExceptionCode\") => { /* handle the error */ }`
450     \
451    See [`ProvideErrorMetadata`](#impl-ProvideErrorMetadata-for-PutObjectError) for what information is available for the error.")]
452    Unhandled(crate::error::sealed_unhandled::Unhandled),
453}
454impl PutObjectError {
455    /// Creates the `PutObjectError::Unhandled` variant from any error type.
456    pub fn unhandled(
457        err: impl ::std::convert::Into<::std::boxed::Box<dyn ::std::error::Error + ::std::marker::Send + ::std::marker::Sync + 'static>>,
458    ) -> Self {
459        Self::Unhandled(crate::error::sealed_unhandled::Unhandled {
460            source: err.into(),
461            meta: ::std::default::Default::default(),
462        })
463    }
464
465    /// Creates the `PutObjectError::Unhandled` variant from an [`ErrorMetadata`](::aws_smithy_types::error::ErrorMetadata).
466    pub fn generic(err: ::aws_smithy_types::error::ErrorMetadata) -> Self {
467        Self::Unhandled(crate::error::sealed_unhandled::Unhandled {
468            source: err.clone().into(),
469            meta: err,
470        })
471    }
472    ///
473    /// Returns error metadata, which includes the error code, message,
474    /// request ID, and potentially additional information.
475    ///
476    pub fn meta(&self) -> &::aws_smithy_types::error::ErrorMetadata {
477        match self {
478            Self::EncryptionTypeMismatch(e) => ::aws_smithy_types::error::metadata::ProvideErrorMetadata::meta(e),
479            Self::InvalidRequest(e) => ::aws_smithy_types::error::metadata::ProvideErrorMetadata::meta(e),
480            Self::InvalidWriteOffset(e) => ::aws_smithy_types::error::metadata::ProvideErrorMetadata::meta(e),
481            Self::TooManyParts(e) => ::aws_smithy_types::error::metadata::ProvideErrorMetadata::meta(e),
482            Self::Unhandled(e) => &e.meta,
483        }
484    }
485    /// Returns `true` if the error kind is `PutObjectError::EncryptionTypeMismatch`.
486    pub fn is_encryption_type_mismatch(&self) -> bool {
487        matches!(self, Self::EncryptionTypeMismatch(_))
488    }
489    /// Returns `true` if the error kind is `PutObjectError::InvalidRequest`.
490    pub fn is_invalid_request(&self) -> bool {
491        matches!(self, Self::InvalidRequest(_))
492    }
493    /// Returns `true` if the error kind is `PutObjectError::InvalidWriteOffset`.
494    pub fn is_invalid_write_offset(&self) -> bool {
495        matches!(self, Self::InvalidWriteOffset(_))
496    }
497    /// Returns `true` if the error kind is `PutObjectError::TooManyParts`.
498    pub fn is_too_many_parts(&self) -> bool {
499        matches!(self, Self::TooManyParts(_))
500    }
501}
502impl ::std::error::Error for PutObjectError {
503    fn source(&self) -> ::std::option::Option<&(dyn ::std::error::Error + 'static)> {
504        match self {
505            Self::EncryptionTypeMismatch(_inner) => ::std::option::Option::Some(_inner),
506            Self::InvalidRequest(_inner) => ::std::option::Option::Some(_inner),
507            Self::InvalidWriteOffset(_inner) => ::std::option::Option::Some(_inner),
508            Self::TooManyParts(_inner) => ::std::option::Option::Some(_inner),
509            Self::Unhandled(_inner) => ::std::option::Option::Some(&*_inner.source),
510        }
511    }
512}
513impl ::std::fmt::Display for PutObjectError {
514    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
515        match self {
516            Self::EncryptionTypeMismatch(_inner) => _inner.fmt(f),
517            Self::InvalidRequest(_inner) => _inner.fmt(f),
518            Self::InvalidWriteOffset(_inner) => _inner.fmt(f),
519            Self::TooManyParts(_inner) => _inner.fmt(f),
520            Self::Unhandled(_inner) => {
521                if let ::std::option::Option::Some(code) = ::aws_smithy_types::error::metadata::ProvideErrorMetadata::code(self) {
522                    write!(f, "unhandled error ({code})")
523                } else {
524                    f.write_str("unhandled error")
525                }
526            }
527        }
528    }
529}
530impl ::aws_smithy_types::retry::ProvideErrorKind for PutObjectError {
531    fn code(&self) -> ::std::option::Option<&str> {
532        ::aws_smithy_types::error::metadata::ProvideErrorMetadata::code(self)
533    }
534    fn retryable_error_kind(&self) -> ::std::option::Option<::aws_smithy_types::retry::ErrorKind> {
535        ::std::option::Option::None
536    }
537}
538impl ::aws_smithy_types::error::metadata::ProvideErrorMetadata for PutObjectError {
539    fn meta(&self) -> &::aws_smithy_types::error::ErrorMetadata {
540        match self {
541            Self::EncryptionTypeMismatch(_inner) => ::aws_smithy_types::error::metadata::ProvideErrorMetadata::meta(_inner),
542            Self::InvalidRequest(_inner) => ::aws_smithy_types::error::metadata::ProvideErrorMetadata::meta(_inner),
543            Self::InvalidWriteOffset(_inner) => ::aws_smithy_types::error::metadata::ProvideErrorMetadata::meta(_inner),
544            Self::TooManyParts(_inner) => ::aws_smithy_types::error::metadata::ProvideErrorMetadata::meta(_inner),
545            Self::Unhandled(_inner) => &_inner.meta,
546        }
547    }
548}
549impl ::aws_smithy_runtime_api::client::result::CreateUnhandledError for PutObjectError {
550    fn create_unhandled_error(
551        source: ::std::boxed::Box<dyn ::std::error::Error + ::std::marker::Send + ::std::marker::Sync + 'static>,
552        meta: ::std::option::Option<::aws_smithy_types::error::ErrorMetadata>,
553    ) -> Self {
554        Self::Unhandled(crate::error::sealed_unhandled::Unhandled {
555            source,
556            meta: meta.unwrap_or_default(),
557        })
558    }
559}
560impl crate::s3_request_id::RequestIdExt for crate::operation::put_object::PutObjectError {
561    fn extended_request_id(&self) -> Option<&str> {
562        self.meta().extended_request_id()
563    }
564}
565impl ::aws_types::request_id::RequestId for crate::operation::put_object::PutObjectError {
566    fn request_id(&self) -> Option<&str> {
567        self.meta().request_id()
568    }
569}
570
571pub use crate::operation::put_object::_put_object_output::PutObjectOutput;
572
573pub use crate::operation::put_object::_put_object_input::PutObjectInput;
574
575mod _put_object_input;
576
577mod _put_object_output;
578
579/// Builders
580pub mod builders;