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_retry_classifier(::aws_smithy_runtime::client::retries::classifiers::TransientErrorClassifier::<
188                crate::operation::put_object::PutObjectError,
189            >::new())
190            .with_retry_classifier(::aws_smithy_runtime::client::retries::classifiers::ModeledAsRetryableClassifier::<
191                crate::operation::put_object::PutObjectError,
192            >::new())
193            .with_retry_classifier(
194                ::aws_runtime::retries::classifiers::AwsErrorCodeClassifier::<crate::operation::put_object::PutObjectError>::builder()
195                    .transient_errors({
196                        let mut transient_errors: Vec<&'static str> = ::aws_runtime::retries::classifiers::TRANSIENT_ERRORS.into();
197                        transient_errors.push("InternalError");
198                        ::std::borrow::Cow::Owned(transient_errors)
199                    })
200                    .build(),
201            );
202
203        ::std::borrow::Cow::Owned(rcb)
204    }
205}
206
207#[derive(Debug)]
208struct PutObjectResponseDeserializer;
209impl ::aws_smithy_runtime_api::client::ser_de::DeserializeResponse for PutObjectResponseDeserializer {
210    fn deserialize_nonstreaming(
211        &self,
212        response: &::aws_smithy_runtime_api::client::orchestrator::HttpResponse,
213    ) -> ::aws_smithy_runtime_api::client::interceptors::context::OutputOrError {
214        let (success, status) = (response.status().is_success(), response.status().as_u16());
215        let headers = response.headers();
216        let body = response.body().bytes().expect("body loaded");
217        #[allow(unused_mut)]
218        let mut force_error = false;
219        ::tracing::debug!(extended_request_id = ?crate::s3_request_id::RequestIdExt::extended_request_id(response));
220        if matches!(crate::rest_xml_unwrapped_errors::body_is_error(body), Ok(true)) {
221            force_error = true;
222        }
223        ::tracing::debug!(request_id = ?::aws_types::request_id::RequestId::request_id(response));
224        let parse_result = if !success && status != 200 || force_error {
225            crate::protocol_serde::shape_put_object::de_put_object_http_error(status, headers, body)
226        } else {
227            crate::protocol_serde::shape_put_object::de_put_object_http_response(status, headers, body)
228        };
229        crate::protocol_serde::type_erase_result(parse_result)
230    }
231}
232#[derive(Debug)]
233struct PutObjectRequestSerializer;
234impl ::aws_smithy_runtime_api::client::ser_de::SerializeRequest for PutObjectRequestSerializer {
235    #[allow(unused_mut, clippy::let_and_return, clippy::needless_borrow, clippy::useless_conversion)]
236    fn serialize_input(
237        &self,
238        input: ::aws_smithy_runtime_api::client::interceptors::context::Input,
239        _cfg: &mut ::aws_smithy_types::config_bag::ConfigBag,
240    ) -> ::std::result::Result<::aws_smithy_runtime_api::client::orchestrator::HttpRequest, ::aws_smithy_runtime_api::box_error::BoxError> {
241        let input = input.downcast::<crate::operation::put_object::PutObjectInput>().expect("correct type");
242        let _header_serialization_settings = _cfg
243            .load::<crate::serialization_settings::HeaderSerializationSettings>()
244            .cloned()
245            .unwrap_or_default();
246        let mut request_builder = {
247            #[allow(clippy::uninlined_format_args)]
248            fn uri_base(
249                _input: &crate::operation::put_object::PutObjectInput,
250                output: &mut ::std::string::String,
251            ) -> ::std::result::Result<(), ::aws_smithy_types::error::operation::BuildError> {
252                use ::std::fmt::Write as _;
253                let input_1 = &_input.key;
254                let input_1 = input_1
255                    .as_ref()
256                    .ok_or_else(|| ::aws_smithy_types::error::operation::BuildError::missing_field("key", "cannot be empty or unset"))?;
257                let key = ::aws_smithy_http::label::fmt_string(input_1, ::aws_smithy_http::label::EncodingStrategy::Greedy);
258                if key.is_empty() {
259                    return ::std::result::Result::Err(::aws_smithy_types::error::operation::BuildError::missing_field(
260                        "key",
261                        "cannot be empty or unset",
262                    ));
263                }
264                ::std::write!(output, "/{Key}", Key = key).expect("formatting should succeed");
265                ::std::result::Result::Ok(())
266            }
267            fn uri_query(
268                _input: &crate::operation::put_object::PutObjectInput,
269                mut output: &mut ::std::string::String,
270            ) -> ::std::result::Result<(), ::aws_smithy_types::error::operation::BuildError> {
271                let mut query = ::aws_smithy_http::query::Writer::new(output);
272                query.push_kv("x-id", "PutObject");
273                ::std::result::Result::Ok(())
274            }
275            #[allow(clippy::unnecessary_wraps)]
276            fn update_http_builder(
277                input: &crate::operation::put_object::PutObjectInput,
278                builder: ::http::request::Builder,
279            ) -> ::std::result::Result<::http::request::Builder, ::aws_smithy_types::error::operation::BuildError> {
280                let mut uri = ::std::string::String::new();
281                uri_base(input, &mut uri)?;
282                uri_query(input, &mut uri)?;
283                let builder = crate::protocol_serde::shape_put_object::ser_put_object_headers(input, builder)?;
284                ::std::result::Result::Ok(builder.method("PUT").uri(uri))
285            }
286            let mut builder = update_http_builder(&input, ::http::request::Builder::new())?;
287            builder = _header_serialization_settings.set_default_header(builder, ::http::header::CONTENT_TYPE, "application/octet-stream");
288            builder
289        };
290        let body = crate::protocol_serde::shape_put_object_input::ser_body_http_payload(input.body)?.into_inner();
291        if let Some(content_length) = body.content_length() {
292            let content_length = content_length.to_string();
293            request_builder = _header_serialization_settings.set_default_header(request_builder, ::http::header::CONTENT_LENGTH, &content_length);
294        }
295        ::std::result::Result::Ok(request_builder.body(body).expect("valid request").try_into().unwrap())
296    }
297}
298#[derive(Debug)]
299struct PutObjectEndpointParamsInterceptor;
300
301impl ::aws_smithy_runtime_api::client::interceptors::Intercept for PutObjectEndpointParamsInterceptor {
302    fn name(&self) -> &'static str {
303        "PutObjectEndpointParamsInterceptor"
304    }
305
306    fn read_before_execution(
307        &self,
308        context: &::aws_smithy_runtime_api::client::interceptors::context::BeforeSerializationInterceptorContextRef<
309            '_,
310            ::aws_smithy_runtime_api::client::interceptors::context::Input,
311            ::aws_smithy_runtime_api::client::interceptors::context::Output,
312            ::aws_smithy_runtime_api::client::interceptors::context::Error,
313        >,
314        cfg: &mut ::aws_smithy_types::config_bag::ConfigBag,
315    ) -> ::std::result::Result<(), ::aws_smithy_runtime_api::box_error::BoxError> {
316        let _input = context
317            .input()
318            .downcast_ref::<PutObjectInput>()
319            .ok_or("failed to downcast to PutObjectInput")?;
320
321        let params = crate::config::endpoint::Params::builder()
322            .set_region(cfg.load::<::aws_types::region::Region>().map(|r| r.as_ref().to_owned()))
323            .set_use_fips(cfg.load::<::aws_types::endpoint_config::UseFips>().map(|ty| ty.0))
324            .set_use_dual_stack(cfg.load::<::aws_types::endpoint_config::UseDualStack>().map(|ty| ty.0))
325            .set_endpoint(cfg.load::<::aws_types::endpoint_config::EndpointUrl>().map(|ty| ty.0.clone()))
326            .set_force_path_style(cfg.load::<crate::config::ForcePathStyle>().map(|ty| ty.0))
327            .set_use_arn_region(cfg.load::<crate::config::UseArnRegion>().map(|ty| ty.0))
328            .set_disable_multi_region_access_points(cfg.load::<crate::config::DisableMultiRegionAccessPoints>().map(|ty| ty.0))
329            .set_accelerate(cfg.load::<crate::config::Accelerate>().map(|ty| ty.0))
330            .set_disable_s3_express_session_auth(cfg.load::<crate::config::DisableS3ExpressSessionAuth>().map(|ty| ty.0))
331            .set_bucket(Some(
332                _input
333                    .bucket
334                    .clone()
335                    .filter(|f| !AsRef::<str>::as_ref(f).trim().is_empty())
336                    .ok_or_else(|| ::aws_smithy_types::error::operation::BuildError::missing_field("bucket", "A required field was not set"))?,
337            ))
338            .set_key(Some(
339                _input
340                    .key
341                    .clone()
342                    .filter(|f| !AsRef::<str>::as_ref(f).trim().is_empty())
343                    .ok_or_else(|| ::aws_smithy_types::error::operation::BuildError::missing_field("key", "A required field was not set"))?,
344            ))
345            .build()
346            .map_err(|err| {
347                ::aws_smithy_runtime_api::client::interceptors::error::ContextAttachedError::new("endpoint params could not be built", err)
348            })?;
349        cfg.interceptor_state()
350            .store_put(::aws_smithy_runtime_api::client::endpoint::EndpointResolverParams::new(params));
351        ::std::result::Result::Ok(())
352    }
353}
354
355// The get_* functions below are generated from JMESPath expressions in the
356// operationContextParams trait. They target the operation's input shape.
357
358#[allow(unreachable_code, unused_variables)]
359#[cfg(test)]
360mod put_object_test {
361
362    /// This test validates that if a content-type is specified, that only one content-type header is sent
363    /// Test ID: DontSendDuplicateContentType
364    #[::tokio::test]
365    #[::tracing_test::traced_test]
366    async fn dont_send_duplicate_content_type_request() {
367        let (http_client, request_receiver) = ::aws_smithy_http_client::test_util::capture_request(None);
368        let config_builder = crate::config::Config::builder().with_test_defaults().endpoint_url("https://example.com");
369        let config_builder = config_builder.region(::aws_types::region::Region::new("us-east-1"));
370        let mut config_builder = config_builder;
371        config_builder.set_region(Some(crate::config::Region::new("us-east-1")));
372
373        let config = config_builder.http_client(http_client).build();
374        let client = crate::Client::from_conf(config);
375        let result = client
376            .put_object()
377            .set_bucket(::std::option::Option::Some("test-bucket".to_owned()))
378            .set_key(::std::option::Option::Some("test-key".to_owned()))
379            .set_content_type(::std::option::Option::Some("text/html".to_owned()))
380            .send()
381            .await;
382        let _ = dbg!(result);
383        let http_request = request_receiver.expect_request();
384        let expected_headers = [("content-type", "text/html")];
385        ::aws_smithy_protocol_test::assert_ok(::aws_smithy_protocol_test::validate_headers(http_request.headers(), expected_headers));
386        let uri: ::http::Uri = http_request.uri().parse().expect("invalid URI sent");
387        ::pretty_assertions::assert_eq!(http_request.method(), "PUT", "method was incorrect");
388        ::pretty_assertions::assert_eq!(uri.path(), "/test-key", "path was incorrect");
389    }
390
391    /// This test validates that if a content-length is specified, that only one content-length header is sent
392    /// Test ID: DontSendDuplicateContentLength
393    #[::tokio::test]
394    #[::tracing_test::traced_test]
395    async fn dont_send_duplicate_content_length_request() {
396        let (http_client, request_receiver) = ::aws_smithy_http_client::test_util::capture_request(None);
397        let config_builder = crate::config::Config::builder().with_test_defaults().endpoint_url("https://example.com");
398        let config_builder = config_builder.region(::aws_types::region::Region::new("us-east-1"));
399        let mut config_builder = config_builder;
400        config_builder.set_region(Some(crate::config::Region::new("us-east-1")));
401
402        let config = config_builder.http_client(http_client).build();
403        let client = crate::Client::from_conf(config);
404        let result = client
405            .put_object()
406            .set_bucket(::std::option::Option::Some("test-bucket".to_owned()))
407            .set_key(::std::option::Option::Some("test-key".to_owned()))
408            .set_content_length(::std::option::Option::Some(2))
409            .set_body(::std::option::Option::Some(::aws_smithy_types::byte_stream::ByteStream::from_static(
410                b"ab",
411            )))
412            .send()
413            .await;
414        let _ = dbg!(result);
415        let http_request = request_receiver.expect_request();
416        let expected_headers = [("content-length", "2")];
417        ::aws_smithy_protocol_test::assert_ok(::aws_smithy_protocol_test::validate_headers(http_request.headers(), expected_headers));
418        let uri: ::http::Uri = http_request.uri().parse().expect("invalid URI sent");
419        ::pretty_assertions::assert_eq!(http_request.method(), "PUT", "method was incorrect");
420        ::pretty_assertions::assert_eq!(uri.path(), "/test-key", "path was incorrect");
421    }
422}
423
424/// Error type for the `PutObjectError` operation.
425#[non_exhaustive]
426#[derive(::std::fmt::Debug)]
427pub enum PutObjectError {
428    /// <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>
429    EncryptionTypeMismatch(crate::types::error::EncryptionTypeMismatch),
430    /// <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>
431    /// <ul>
432    /// <li>
433    /// <p>Cannot specify both a write offset value and user-defined object metadata for existing objects.</p></li>
434    /// <li>
435    /// <p>Checksum Type mismatch occurred, expected checksum Type: sha1, actual checksum Type: crc32c.</p></li>
436    /// <li>
437    /// <p>Request body cannot be empty when 'write offset' is specified.</p></li>
438    /// </ul>
439    InvalidRequest(crate::types::error::InvalidRequest),
440    /// <p>The write offset value that you specified does not match the current object size.</p>
441    InvalidWriteOffset(crate::types::error::InvalidWriteOffset),
442    /// <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>
443    TooManyParts(crate::types::error::TooManyParts),
444    /// An unexpected error occurred (e.g., invalid JSON returned by the service or an unknown error code).
445    #[deprecated(note = "Matching `Unhandled` directly is not forwards compatible. Instead, match using a \
446    variable wildcard pattern and check `.code()`:
447     \
448    &nbsp;&nbsp;&nbsp;`err if err.code() == Some(\"SpecificExceptionCode\") => { /* handle the error */ }`
449     \
450    See [`ProvideErrorMetadata`](#impl-ProvideErrorMetadata-for-PutObjectError) for what information is available for the error.")]
451    Unhandled(crate::error::sealed_unhandled::Unhandled),
452}
453impl PutObjectError {
454    /// Creates the `PutObjectError::Unhandled` variant from any error type.
455    pub fn unhandled(
456        err: impl ::std::convert::Into<::std::boxed::Box<dyn ::std::error::Error + ::std::marker::Send + ::std::marker::Sync + 'static>>,
457    ) -> Self {
458        Self::Unhandled(crate::error::sealed_unhandled::Unhandled {
459            source: err.into(),
460            meta: ::std::default::Default::default(),
461        })
462    }
463
464    /// Creates the `PutObjectError::Unhandled` variant from an [`ErrorMetadata`](::aws_smithy_types::error::ErrorMetadata).
465    pub fn generic(err: ::aws_smithy_types::error::ErrorMetadata) -> Self {
466        Self::Unhandled(crate::error::sealed_unhandled::Unhandled {
467            source: err.clone().into(),
468            meta: err,
469        })
470    }
471    ///
472    /// Returns error metadata, which includes the error code, message,
473    /// request ID, and potentially additional information.
474    ///
475    pub fn meta(&self) -> &::aws_smithy_types::error::ErrorMetadata {
476        match self {
477            Self::EncryptionTypeMismatch(e) => ::aws_smithy_types::error::metadata::ProvideErrorMetadata::meta(e),
478            Self::InvalidRequest(e) => ::aws_smithy_types::error::metadata::ProvideErrorMetadata::meta(e),
479            Self::InvalidWriteOffset(e) => ::aws_smithy_types::error::metadata::ProvideErrorMetadata::meta(e),
480            Self::TooManyParts(e) => ::aws_smithy_types::error::metadata::ProvideErrorMetadata::meta(e),
481            Self::Unhandled(e) => &e.meta,
482        }
483    }
484    /// Returns `true` if the error kind is `PutObjectError::EncryptionTypeMismatch`.
485    pub fn is_encryption_type_mismatch(&self) -> bool {
486        matches!(self, Self::EncryptionTypeMismatch(_))
487    }
488    /// Returns `true` if the error kind is `PutObjectError::InvalidRequest`.
489    pub fn is_invalid_request(&self) -> bool {
490        matches!(self, Self::InvalidRequest(_))
491    }
492    /// Returns `true` if the error kind is `PutObjectError::InvalidWriteOffset`.
493    pub fn is_invalid_write_offset(&self) -> bool {
494        matches!(self, Self::InvalidWriteOffset(_))
495    }
496    /// Returns `true` if the error kind is `PutObjectError::TooManyParts`.
497    pub fn is_too_many_parts(&self) -> bool {
498        matches!(self, Self::TooManyParts(_))
499    }
500}
501impl ::std::error::Error for PutObjectError {
502    fn source(&self) -> ::std::option::Option<&(dyn ::std::error::Error + 'static)> {
503        match self {
504            Self::EncryptionTypeMismatch(_inner) => ::std::option::Option::Some(_inner),
505            Self::InvalidRequest(_inner) => ::std::option::Option::Some(_inner),
506            Self::InvalidWriteOffset(_inner) => ::std::option::Option::Some(_inner),
507            Self::TooManyParts(_inner) => ::std::option::Option::Some(_inner),
508            Self::Unhandled(_inner) => ::std::option::Option::Some(&*_inner.source),
509        }
510    }
511}
512impl ::std::fmt::Display for PutObjectError {
513    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
514        match self {
515            Self::EncryptionTypeMismatch(_inner) => _inner.fmt(f),
516            Self::InvalidRequest(_inner) => _inner.fmt(f),
517            Self::InvalidWriteOffset(_inner) => _inner.fmt(f),
518            Self::TooManyParts(_inner) => _inner.fmt(f),
519            Self::Unhandled(_inner) => {
520                if let ::std::option::Option::Some(code) = ::aws_smithy_types::error::metadata::ProvideErrorMetadata::code(self) {
521                    write!(f, "unhandled error ({code})")
522                } else {
523                    f.write_str("unhandled error")
524                }
525            }
526        }
527    }
528}
529impl ::aws_smithy_types::retry::ProvideErrorKind for PutObjectError {
530    fn code(&self) -> ::std::option::Option<&str> {
531        ::aws_smithy_types::error::metadata::ProvideErrorMetadata::code(self)
532    }
533    fn retryable_error_kind(&self) -> ::std::option::Option<::aws_smithy_types::retry::ErrorKind> {
534        ::std::option::Option::None
535    }
536}
537impl ::aws_smithy_types::error::metadata::ProvideErrorMetadata for PutObjectError {
538    fn meta(&self) -> &::aws_smithy_types::error::ErrorMetadata {
539        match self {
540            Self::EncryptionTypeMismatch(_inner) => ::aws_smithy_types::error::metadata::ProvideErrorMetadata::meta(_inner),
541            Self::InvalidRequest(_inner) => ::aws_smithy_types::error::metadata::ProvideErrorMetadata::meta(_inner),
542            Self::InvalidWriteOffset(_inner) => ::aws_smithy_types::error::metadata::ProvideErrorMetadata::meta(_inner),
543            Self::TooManyParts(_inner) => ::aws_smithy_types::error::metadata::ProvideErrorMetadata::meta(_inner),
544            Self::Unhandled(_inner) => &_inner.meta,
545        }
546    }
547}
548impl ::aws_smithy_runtime_api::client::result::CreateUnhandledError for PutObjectError {
549    fn create_unhandled_error(
550        source: ::std::boxed::Box<dyn ::std::error::Error + ::std::marker::Send + ::std::marker::Sync + 'static>,
551        meta: ::std::option::Option<::aws_smithy_types::error::ErrorMetadata>,
552    ) -> Self {
553        Self::Unhandled(crate::error::sealed_unhandled::Unhandled {
554            source,
555            meta: meta.unwrap_or_default(),
556        })
557    }
558}
559impl crate::s3_request_id::RequestIdExt for crate::operation::put_object::PutObjectError {
560    fn extended_request_id(&self) -> Option<&str> {
561        self.meta().extended_request_id()
562    }
563}
564impl ::aws_types::request_id::RequestId for crate::operation::put_object::PutObjectError {
565    fn request_id(&self) -> Option<&str> {
566        self.meta().request_id()
567    }
568}
569
570pub use crate::operation::put_object::_put_object_output::PutObjectOutput;
571
572pub use crate::operation::put_object::_put_object_input::PutObjectInput;
573
574mod _put_object_input;
575
576mod _put_object_output;
577
578/// Builders
579pub mod builders;