Fixed doc warnings; fixed minor issue with trait separation in append_object (#160)

* minor issues fixed: bucket and object impl trait separated

* fixed doc warnings

* added CI, docs build and docs site to the initial icons

* inline doc updated

* more doc update

* bumped versions
This commit is contained in:
Henk-Jan Lebbink 2025-05-28 20:43:08 +02:00 committed by GitHub
parent 75602b2673
commit 9cbb95747f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
99 changed files with 434 additions and 235 deletions

View File

@ -1,6 +1,6 @@
[package] [package]
name = "minio" name = "minio"
version = "0.2.0" version = "0.3.0"
edition = "2024" edition = "2024"
authors = ["MinIO Dev Team <dev@min.io>"] authors = ["MinIO Dev Team <dev@min.io>"]
description = "MinIO SDK for Amazon S3 compatible object storage access" description = "MinIO SDK for Amazon S3 compatible object storage access"
@ -11,7 +11,7 @@ keywords = ["object-storage", "minio", "s3"]
categories = ["api-bindings", "web-programming::http-client"] categories = ["api-bindings", "web-programming::http-client"]
[dependencies.reqwest] [dependencies.reqwest]
version = "0.12.9" version = "0.12.18"
default-features = false default-features = false
features = ["stream"] features = ["stream"]
@ -28,11 +28,11 @@ async-trait = "0.1.88"
base64 = "0.22.1" base64 = "0.22.1"
byteorder = "1.5.0" byteorder = "1.5.0"
bytes = "1.10.1" bytes = "1.10.1"
chrono = "0.4.40" chrono = "0.4.41"
crc = "3.2.1" crc = "3.3.0"
dashmap = "6.1.0" dashmap = "6.1.0"
derivative = "2.2.0" derivative = "2.2.0"
env_logger = "0.11.7" env_logger = "0.11.8"
futures-util = "0.3.31" futures-util = "0.3.31"
hex = "0.4.3" hex = "0.4.3"
hmac = { version = "0.12.1", optional = true } hmac = { version = "0.12.1", optional = true }
@ -40,7 +40,7 @@ hyper = { version = "1.6.0", features = ["full"] }
lazy_static = "1.5.0" lazy_static = "1.5.0"
log = "0.4.27" log = "0.4.27"
md5 = "0.7.0" md5 = "0.7.0"
multimap = "0.10.0" multimap = "0.10.1"
percent-encoding = "2.3.1" percent-encoding = "2.3.1"
rand = { version = "0.8.5", features = ["small_rng"] } rand = { version = "0.8.5", features = ["small_rng"] }
regex = "1.11.1" regex = "1.11.1"
@ -48,9 +48,9 @@ ring = { version = "0.17.14", optional = true, default-features = false, feature
serde = { version = "1.0.219", features = ["derive"] } serde = { version = "1.0.219", features = ["derive"] }
serde_json = "1.0.140" serde_json = "1.0.140"
sha2 = { version = "0.10.8", optional = true } sha2 = { version = "0.10.8", optional = true }
tokio = { version = "1.44.2", features = ["full"] } tokio = { version = "1.45.1", features = ["full"] }
tokio-stream = "0.1.17" tokio-stream = "0.1.17"
tokio-util = { version = "0.7.14", features = ["io"] } tokio-util = { version = "0.7.15", features = ["io"] }
urlencoding = "2.1.3" urlencoding = "2.1.3"
xmltree = "0.11.0" xmltree = "0.11.0"
futures = "0.3.31" futures = "0.3.31"
@ -59,9 +59,9 @@ http = "1.3.1"
[dev-dependencies] [dev-dependencies]
minio_common = { path = "./common" } minio_common = { path = "./common" }
async-std = { version = "1.13.1", features = ["attributes", "tokio1"] } async-std = { version = "1.13.1", features = ["attributes", "tokio1"] }
clap = { version = "4.5.35", features = ["derive"] } clap = { version = "4.5.39", features = ["derive"] }
quickcheck = "1.0.3" quickcheck = "1.0.3"
criterion = "0.5.1" criterion = "0.6.0"
[lib] [lib]
name = "minio" name = "minio"

View File

@ -1,4 +1,11 @@
# MinIO Rust SDK for Amazon S3 Compatible Cloud Storage [![Slack](https://slack.min.io/slack?type=svg)](https://slack.min.io) [![Sourcegraph](https://sourcegraph.com/github.com/minio/minio-rs/-/badge.svg)](https://sourcegraph.com/github.com/minio/minio-rs?badge) [![Apache V2 License](https://img.shields.io/badge/license-Apache%20V2-blue.svg)](https://github.com/minio/minio-rs/blob/master/LICENSE) # MinIO Rust SDK for Amazon S3 Compatible Cloud Storage
[![CI](https://github.com/minio/minio-rs/actions/workflows/rust.yml/badge.svg?branch=master)](https://github.com/minio/minio-rs/actions/workflows/rust.yml)
[![docs.rs](https://docs.rs/minio/badge.svg)](https://docs.rs/minio/latest/minio/)
[![Slack](https://slack.min.io/slack?type=svg)](https://slack.min.io)
[![Sourcegraph](https://sourcegraph.com/github.com/minio/minio-rs/-/badge.svg)](https://sourcegraph.com/github.com/minio/minio-rs?badge)
[![crates.io](https://img.shields.io/crates/v/minio)](https://crates.io/crates/minio)
[![Apache V2 License](https://img.shields.io/badge/license-Apache%20V2-blue.svg)](https://github.com/minio/minio-rs/blob/master/LICENSE)
The MinIO Rust SDK is a Simple Storage Service (aka S3) client for performing bucket and object operations to any Amazon S3 compatible object storage service. The MinIO Rust SDK is a Simple Storage Service (aka S3) client for performing bucket and object operations to any Amazon S3 compatible object storage service.
It provides a strongly-typed, async-first interface to the MinIO and Amazon S3-compatible object storage APIs. It provides a strongly-typed, async-first interface to the MinIO and Amazon S3-compatible object storage APIs.

View File

@ -17,10 +17,10 @@
//! //!
//! This crate provides a strongly-typed, async-first interface to the MinIO and Amazon S3-compatible object storage APIs. //! This crate provides a strongly-typed, async-first interface to the MinIO and Amazon S3-compatible object storage APIs.
//! //!
//! Each supported S3 operation has a corresponding request builder (e.g., [`BucketExists`], [`PutObject`], [`UploadPartCopy`]), //! Each supported S3 operation has a corresponding request builder (e.g., [`s3::builders::BucketExists`], [`s3::builders::PutObject`], [`s3::builders::UploadPartCopy`]),
//! which allows users to configure request parameters using a fluent builder pattern. //! which allows users to configure request parameters using a fluent builder pattern.
//! //!
//! All request builders implement the [`S3Api`] trait, which provides the async [`send`](crate::s3::types::S3Api::send) method //! All request builders implement the [`s3::types::S3Api`] trait, which provides the async [`send`](crate::s3::types::S3Api::send) method
//! to execute the request and return a typed response. //! to execute the request and return a typed response.
//! //!
//! ## Basic Usage //! ## Basic Usage
@ -51,9 +51,9 @@
//! - Transparent error handling via `Result<T, Error>` //! - Transparent error handling via `Result<T, Error>`
//! //!
//! ## Design //! ## Design
//! - Each API method on the [`Client`] returns a builder struct //! - Each API method on the [`s3::client::Client`] returns a builder struct
//! - Builders implement [`ToS3Request`] for request conversion and [`S3Api`] for execution //! - Builders implement [`s3::types::ToS3Request`] for request conversion and [`s3::types::S3Api`] for execution
//! - Responses implement [`FromS3Response`] for consistent deserialization //! - Responses implement [`s3::types::FromS3Response`] for consistent deserialization
#![allow(clippy::result_large_err)] #![allow(clippy::result_large_err)]
#![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_arguments)]

View File

@ -174,6 +174,7 @@ impl AppendObjectContent {
self self
} }
/// Sets the region for the request
pub fn region(mut self, region: Option<String>) -> Self { pub fn region(mut self, region: Option<String>) -> Self {
self.region = region; self.region = region;
self self

View File

@ -18,6 +18,9 @@ use std::marker::PhantomData;
use crate::s3::client::Client; use crate::s3::client::Client;
use crate::s3::multimap::Multimap; use crate::s3::multimap::Multimap;
/// Common parameters for bucket operations
///
/// See [Amazon S3 Buckets](https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingBucket.html) for more information.
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
pub struct BucketCommon<A> { pub struct BucketCommon<A> {
pub(crate) client: Client, pub(crate) client: Client,
@ -39,16 +42,19 @@ impl<A: Default> BucketCommon<A> {
} }
} }
/// Sets extra headers for the request
pub fn extra_headers(mut self, extra_headers: Option<Multimap>) -> Self { pub fn extra_headers(mut self, extra_headers: Option<Multimap>) -> Self {
self.extra_headers = extra_headers; self.extra_headers = extra_headers;
self self
} }
/// Sets extra query parameters for the request
pub fn extra_query_params(mut self, extra_query_params: Option<Multimap>) -> Self { pub fn extra_query_params(mut self, extra_query_params: Option<Multimap>) -> Self {
self.extra_query_params = extra_query_params; self.extra_query_params = extra_query_params;
self self
} }
/// Sets the region for the request
pub fn region(mut self, region: Option<String>) -> Self { pub fn region(mut self, region: Option<String>) -> Self {
self.region = region; self.region = region;
self self

View File

@ -21,8 +21,12 @@ use crate::s3::utils::check_bucket_name;
use http::Method; use http::Method;
/// This struct constructs the parameters required for the [`Client::bucket_exists`](crate::s3::client::Client::bucket_exists) method. /// This struct constructs the parameters required for the [`Client::bucket_exists`](crate::s3::client::Client::bucket_exists) method.
///
/// See [Amazon S3: Working with Buckets](https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingBucket.html)
/// for more information about checking if a bucket exists.
pub type BucketExists = BucketCommon<BucketExistsPhantomData>; pub type BucketExists = BucketCommon<BucketExistsPhantomData>;
#[doc(hidden)]
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
pub struct BucketExistsPhantomData; pub struct BucketExistsPhantomData;

View File

@ -70,6 +70,7 @@ impl UploadPartCopy {
self self
} }
/// Sets the region for the request
pub fn region(mut self, region: Option<String>) -> Self { pub fn region(mut self, region: Option<String>) -> Self {
self.region = region; self.region = region;
self self
@ -165,6 +166,7 @@ impl CopyObjectInternal {
self self
} }
/// Sets the region for the request
pub fn region(mut self, region: Option<String>) -> Self { pub fn region(mut self, region: Option<String>) -> Self {
self.region = region; self.region = region;
self self
@ -326,7 +328,9 @@ impl ToS3Request for CopyObjectInternal {
} }
} }
/// Argument builder for [copy_object()](Client::copy_object) API /// Argument builder for [`CopyObject`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html) S3 API operation.
///
/// This struct constructs the parameters required for the [`Client::copy_object`](crate::s3::client::Client::copy_object) method.
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
pub struct CopyObject { pub struct CopyObject {
client: Client, client: Client,
@ -368,6 +372,7 @@ impl CopyObject {
self self
} }
/// Sets the region for the request
pub fn region(mut self, region: Option<String>) -> Self { pub fn region(mut self, region: Option<String>) -> Self {
self.region = region; self.region = region;
self self
@ -572,6 +577,7 @@ impl ComposeObjectInternal {
self self
} }
/// Sets the region for the request
pub fn region(mut self, region: Option<String>) -> Self { pub fn region(mut self, region: Option<String>) -> Self {
self.region = region; self.region = region;
self self
@ -804,6 +810,10 @@ impl ComposeObjectInternal {
} }
} }
/// Argument builder for [`CopyObject`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html) S3 API operation.
///
/// See [Amazon S3 Multipart Upload](https://docs.aws.amazon.com/AmazonS3/latest/userguide/mpuoverview.html)
/// This struct constructs the parameters required for the [`Client::copy_object`](crate::s3::client::Client::copy_object) method.
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
pub struct ComposeObject { pub struct ComposeObject {
client: Client, client: Client,
@ -843,6 +853,7 @@ impl ComposeObject {
self self
} }
/// Sets the region for the request
pub fn region(mut self, region: Option<String>) -> Self { pub fn region(mut self, region: Option<String>) -> Self {
self.region = region; self.region = region;
self self

View File

@ -57,6 +57,7 @@ impl CreateBucket {
self self
} }
/// Sets the region for the request
pub fn region(mut self, region: Option<String>) -> Self { pub fn region(mut self, region: Option<String>) -> Self {
self.region = region; self.region = region;
self self

View File

@ -20,11 +20,13 @@ use crate::s3::types::{S3Api, S3Request, ToS3Request};
use crate::s3::utils::check_bucket_name; use crate::s3::utils::check_bucket_name;
use http::Method; use http::Method;
/// Argument builder for the [`GetBucketEncryption`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucket.html) S3 API operation. /// Argument builder for the [`DeleteBucket`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucket.html) S3 API operation.
/// ///
/// This struct constructs the parameters required for the [`Client::delete_bucket`](crate::s3::client::Client::delete_bucket) method. /// This struct constructs the parameters required for the [`Client::delete_bucket`](crate::s3::client::Client::delete_bucket) method.
/// See [Amazon S3: Deleting Buckets](https://docs.aws.amazon.com/AmazonS3/latest/userguide/delete-bucket.html) for more information.
pub type DeleteBucket = BucketCommon<DeleteBucketPhantomData>; pub type DeleteBucket = BucketCommon<DeleteBucketPhantomData>;
#[doc(hidden)]
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
pub struct DeleteBucketPhantomData; pub struct DeleteBucketPhantomData;

View File

@ -25,6 +25,7 @@ use http::Method;
/// This struct constructs the parameters required for the [`Client::delete_bucket_encryption`](crate::s3::client::Client::delete_bucket_encryption) method. /// This struct constructs the parameters required for the [`Client::delete_bucket_encryption`](crate::s3::client::Client::delete_bucket_encryption) method.
pub type DeleteBucketEncryption = BucketCommon<DeleteBucketEncryptionPhantomData>; pub type DeleteBucketEncryption = BucketCommon<DeleteBucketEncryptionPhantomData>;
#[doc(hidden)]
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
pub struct DeleteBucketEncryptionPhantomData; pub struct DeleteBucketEncryptionPhantomData;

View File

@ -25,6 +25,7 @@ use http::Method;
/// This struct constructs the parameters required for the [`Client::delete_bucket_lifecycle`](crate::s3::client::Client::delete_bucket_lifecycle) method. /// This struct constructs the parameters required for the [`Client::delete_bucket_lifecycle`](crate::s3::client::Client::delete_bucket_lifecycle) method.
pub type DeleteBucketLifecycle = BucketCommon<DeleteBucketLifecyclePhantomData>; pub type DeleteBucketLifecycle = BucketCommon<DeleteBucketLifecyclePhantomData>;
#[doc(hidden)]
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
pub struct DeleteBucketLifecyclePhantomData; pub struct DeleteBucketLifecyclePhantomData;

View File

@ -22,9 +22,14 @@ use crate::s3::utils::{check_bucket_name, insert};
use bytes::Bytes; use bytes::Bytes;
use http::Method; use http::Method;
/// Argument builder for the [`DeleteBucketNotification`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketNotificationConfiguration.html) S3 API operation.
/// Note: on Amazon S3, a bucket notification is deleted by setting its configuration to empty.
///
/// This struct constructs the parameters required for the [`Client::delete_bucket_notification`](crate::s3::client::Client::delete_bucket_notification) method. /// This struct constructs the parameters required for the [`Client::delete_bucket_notification`](crate::s3::client::Client::delete_bucket_notification) method.
/// See [Amazon S3: Managing Bucket Notifications](https://docs.aws.amazon.com/AmazonS3/latest/userguide/NotificationHowTo.html) for more information.
pub type DeleteBucketNotification = BucketCommon<DeleteBucketNotificationPhantomData>; pub type DeleteBucketNotification = BucketCommon<DeleteBucketNotificationPhantomData>;
#[doc(hidden)]
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
pub struct DeleteBucketNotificationPhantomData; pub struct DeleteBucketNotificationPhantomData;

View File

@ -25,6 +25,7 @@ use http::Method;
/// This struct constructs the parameters required for the [`Client::delete_bucket_policy`](crate::s3::client::Client::delete_bucket_policy) method. /// This struct constructs the parameters required for the [`Client::delete_bucket_policy`](crate::s3::client::Client::delete_bucket_policy) method.
pub type DeleteBucketPolicy = BucketCommon<DeleteBucketPolicyPhantomData>; pub type DeleteBucketPolicy = BucketCommon<DeleteBucketPolicyPhantomData>;
#[doc(hidden)]
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
pub struct DeleteBucketPolicyPhantomData; pub struct DeleteBucketPolicyPhantomData;

View File

@ -25,6 +25,7 @@ use http::Method;
/// This struct constructs the parameters required for the [`Client::delete_bucket_replication`](crate::s3::client::Client::delete_bucket_replication) method. /// This struct constructs the parameters required for the [`Client::delete_bucket_replication`](crate::s3::client::Client::delete_bucket_replication) method.
pub type DeleteBucketReplication = BucketCommon<DeleteBucketReplicationPhantomData>; pub type DeleteBucketReplication = BucketCommon<DeleteBucketReplicationPhantomData>;
#[doc(hidden)]
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
pub struct DeleteBucketReplicationPhantomData; pub struct DeleteBucketReplicationPhantomData;

View File

@ -25,6 +25,7 @@ use http::Method;
/// This struct constructs the parameters required for the [`Client::delete_bucket_tags`](crate::s3::client::Client::delete_bucket_tagging) method. /// This struct constructs the parameters required for the [`Client::delete_bucket_tags`](crate::s3::client::Client::delete_bucket_tagging) method.
pub type DeleteBucketTagging = BucketCommon<DeleteBucketTaggingPhantomData>; pub type DeleteBucketTagging = BucketCommon<DeleteBucketTaggingPhantomData>;
#[doc(hidden)]
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
pub struct DeleteBucketTaggingPhantomData; pub struct DeleteBucketTaggingPhantomData;

View File

@ -25,6 +25,7 @@ use http::Method;
/// This struct constructs the parameters required for the [`Client::delete_object_lock_config`](crate::s3::client::Client::delete_object_lock_config) method. /// This struct constructs the parameters required for the [`Client::delete_object_lock_config`](crate::s3::client::Client::delete_object_lock_config) method.
pub type DeleteObjectLockConfig = BucketCommon<DeleteObjectLockConfigPhantomData>; pub type DeleteObjectLockConfig = BucketCommon<DeleteObjectLockConfigPhantomData>;
#[doc(hidden)]
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
pub struct DeleteObjectLockConfigPhantomData; pub struct DeleteObjectLockConfigPhantomData;

View File

@ -57,6 +57,7 @@ impl DeleteObjectTagging {
self self
} }
/// Sets the region for the request
pub fn region(mut self, region: Option<String>) -> Self { pub fn region(mut self, region: Option<String>) -> Self {
self.region = region; self.region = region;
self self

View File

@ -31,7 +31,7 @@ use crate::s3::utils::{check_object_name, insert};
use crate::s3::{ use crate::s3::{
Client, Client,
error::Error, error::Error,
response::{RemoveObjectResponse, RemoveObjectsResponse}, response::{DeleteObjectResponse, DeleteObjectsResponse},
types::{S3Api, S3Request, ToS3Request, ToStream}, types::{S3Api, S3Request, ToS3Request, ToStream},
utils::{check_bucket_name, md5sum_hash}, utils::{check_bucket_name, md5sum_hash},
}; };
@ -101,10 +101,13 @@ impl From<DeleteError> for ObjectToDelete {
// endregion: object-to-delete // endregion: object-to-delete
// region: remove-object // region: delete-object
/// Argument builder for the [`RemoveObject`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObject.html) S3 API operation.
///
/// This struct constructs the parameters required for the [`Client::remove_object`](crate::s3::client::Client::delete_object) method.
#[derive(Debug, Clone, Default)] #[derive(Debug, Clone, Default)]
pub struct RemoveObject { pub struct DeleteObject {
client: Client, client: Client,
extra_headers: Option<Multimap>, extra_headers: Option<Multimap>,
@ -116,7 +119,7 @@ pub struct RemoveObject {
bypass_governance_mode: bool, bypass_governance_mode: bool,
} }
impl RemoveObject { impl DeleteObject {
pub fn new(client: Client, bucket: String, object: impl Into<ObjectToDelete>) -> Self { pub fn new(client: Client, bucket: String, object: impl Into<ObjectToDelete>) -> Self {
Self { Self {
client, client,
@ -141,17 +144,18 @@ impl RemoveObject {
self self
} }
/// Sets the region for the request
pub fn region(mut self, region: Option<String>) -> Self { pub fn region(mut self, region: Option<String>) -> Self {
self.region = region; self.region = region;
self self
} }
} }
impl S3Api for RemoveObject { impl S3Api for DeleteObject {
type S3Response = RemoveObjectResponse; type S3Response = DeleteObjectResponse;
} }
impl ToS3Request for RemoveObject { impl ToS3Request for DeleteObject {
fn to_s3request(self) -> Result<S3Request, Error> { fn to_s3request(self) -> Result<S3Request, Error> {
check_bucket_name(&self.bucket, true)?; check_bucket_name(&self.bucket, true)?;
check_object_name(&self.object.key)?; check_object_name(&self.object.key)?;
@ -159,20 +163,25 @@ impl ToS3Request for RemoveObject {
let mut query_params: Multimap = self.extra_query_params.unwrap_or_default(); let mut query_params: Multimap = self.extra_query_params.unwrap_or_default();
query_params.add_version(self.object.version_id); query_params.add_version(self.object.version_id);
let mut headers: Multimap = self.extra_headers.unwrap_or_default();
if self.bypass_governance_mode {
headers.add("x-amz-bypass-governance-retention", "true");
}
Ok(S3Request::new(self.client, Method::DELETE) Ok(S3Request::new(self.client, Method::DELETE)
.region(self.region) .region(self.region)
.bucket(Some(self.bucket)) .bucket(Some(self.bucket))
.object(Some(self.object.key)) .object(Some(self.object.key))
.query_params(query_params) .query_params(query_params)
.headers(self.extra_headers.unwrap_or_default())) .headers(headers))
} }
} }
// endregion: remove-object // endregion: delete-object
// region: remove-object-api // region: delete-objects
#[derive(Debug, Clone, Default)] #[derive(Debug, Clone, Default)]
pub struct RemoveObjectsApi { pub struct DeleteObjects {
client: Client, client: Client,
bucket: String, bucket: String,
@ -186,10 +195,9 @@ pub struct RemoveObjectsApi {
region: Option<String>, region: Option<String>,
} }
impl RemoveObjectsApi { impl DeleteObjects {
#[inline]
pub fn new(client: Client, bucket: String, objects: Vec<ObjectToDelete>) -> Self { pub fn new(client: Client, bucket: String, objects: Vec<ObjectToDelete>) -> Self {
RemoveObjectsApi { DeleteObjects {
client, client,
bucket, bucket,
objects, objects,
@ -220,17 +228,18 @@ impl RemoveObjectsApi {
self self
} }
/// Sets the region for the request
pub fn region(mut self, region: Option<String>) -> Self { pub fn region(mut self, region: Option<String>) -> Self {
self.region = region; self.region = region;
self self
} }
} }
impl S3Api for RemoveObjectsApi { impl S3Api for DeleteObjects {
type S3Response = RemoveObjectsResponse; type S3Response = DeleteObjectsResponse;
} }
impl ToS3Request for RemoveObjectsApi { impl ToS3Request for DeleteObjects {
fn to_s3request(self) -> Result<S3Request, Error> { fn to_s3request(self) -> Result<S3Request, Error> {
check_bucket_name(&self.bucket, true)?; check_bucket_name(&self.bucket, true)?;
@ -271,30 +280,27 @@ impl ToS3Request for RemoveObjectsApi {
} }
} }
// endregion: remove-object-api // endregion: delete-objects
// region: delete-objects // region: object-stream
/// Argument builder for the [`DeleteObjects`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObjects.html) S3 API operation. pub struct ObjectsStream {
///
/// This struct constructs the parameters required for the [`Client::delete`](crate::s3::client::Client::get_bucket_encryption) method.
pub struct DeleteObjects {
items: Pin<Box<dyn Stream<Item = ObjectToDelete> + Send + Sync>>, items: Pin<Box<dyn Stream<Item = ObjectToDelete> + Send + Sync>>,
} }
impl DeleteObjects { impl ObjectsStream {
pub fn from_stream(s: impl Stream<Item = ObjectToDelete> + Send + Sync + 'static) -> Self { pub fn from_stream(s: impl Stream<Item = ObjectToDelete> + Send + Sync + 'static) -> Self {
Self { items: Box::pin(s) } Self { items: Box::pin(s) }
} }
} }
impl From<ObjectToDelete> for DeleteObjects { impl From<ObjectToDelete> for ObjectsStream {
fn from(delete_object: ObjectToDelete) -> Self { fn from(delete_object: ObjectToDelete) -> Self {
Self::from_stream(stream_iter(std::iter::once(delete_object))) Self::from_stream(stream_iter(std::iter::once(delete_object)))
} }
} }
impl<I> From<I> for DeleteObjects impl<I> From<I> for ObjectsStream
where where
I: Iterator<Item = ObjectToDelete> + Send + Sync + 'static, I: Iterator<Item = ObjectToDelete> + Send + Sync + 'static,
{ {
@ -303,15 +309,19 @@ where
} }
} }
// endregion: delete-objects // endregion: object-stream
// region: remove-objects // region: delete-objects-streaming
pub struct RemoveObjects { /// Argument builder for the [`DeleteObjectsStreaming`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObjects.html) S3 API operation.
/// Note that this API is not part of the official S3 API, but is a MinIO extension for streaming deletion of multiple objects.
///
/// This struct constructs the parameters required for the [`Client::`](crate::s3::client::Client::get_bucket_encryption) method.
pub struct DeleteObjectsStreaming {
client: Client, client: Client,
bucket: String, bucket: String,
objects: DeleteObjects, objects: ObjectsStream,
bypass_governance_mode: bool, bypass_governance_mode: bool,
verbose_mode: bool, verbose_mode: bool,
@ -321,8 +331,8 @@ pub struct RemoveObjects {
region: Option<String>, region: Option<String>,
} }
impl RemoveObjects { impl DeleteObjectsStreaming {
pub fn new(client: Client, bucket: String, objects: impl Into<DeleteObjects>) -> Self { pub fn new(client: Client, bucket: String, objects: impl Into<ObjectsStream>) -> Self {
Self { Self {
client, client,
bucket, bucket,
@ -360,12 +370,13 @@ impl RemoveObjects {
self self
} }
/// Sets the region for the request
pub fn region(mut self, region: Option<String>) -> Self { pub fn region(mut self, region: Option<String>) -> Self {
self.region = region; self.region = region;
self self
} }
async fn next_request(&mut self) -> Result<Option<RemoveObjectsApi>, Error> { async fn next_request(&mut self) -> Result<Option<DeleteObjects>, Error> {
let mut objects = Vec::new(); let mut objects = Vec::new();
while let Some(object) = self.objects.items.next().await { while let Some(object) = self.objects.items.next().await {
objects.push(object); objects.push(object);
@ -378,7 +389,7 @@ impl RemoveObjects {
} }
Ok(Some( Ok(Some(
RemoveObjectsApi::new(self.client.clone(), self.bucket.clone(), objects) DeleteObjects::new(self.client.clone(), self.bucket.clone(), objects)
.bypass_governance_mode(self.bypass_governance_mode) .bypass_governance_mode(self.bypass_governance_mode)
.verbose_mode(self.verbose_mode) .verbose_mode(self.verbose_mode)
.extra_headers(self.extra_headers.clone()) .extra_headers(self.extra_headers.clone())
@ -389,8 +400,8 @@ impl RemoveObjects {
} }
#[async_trait] #[async_trait]
impl ToStream for RemoveObjects { impl ToStream for DeleteObjectsStreaming {
type Item = RemoveObjectsResponse; type Item = DeleteObjectsResponse;
async fn to_stream( async fn to_stream(
mut self, mut self,
@ -411,4 +422,4 @@ impl ToStream for RemoveObjects {
} }
} }
// endregion: remove-objects // endregion: delete-objects-streaming

View File

@ -25,6 +25,7 @@ use http::Method;
/// This struct constructs the parameters required for the [`Client::get_bucket_encryption`](crate::s3::client::Client::get_bucket_encryption) method. /// This struct constructs the parameters required for the [`Client::get_bucket_encryption`](crate::s3::client::Client::get_bucket_encryption) method.
pub type GetBucketEncryption = BucketCommon<GetBucketEncryptionPhantomData>; pub type GetBucketEncryption = BucketCommon<GetBucketEncryptionPhantomData>;
#[doc(hidden)]
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
pub struct GetBucketEncryptionPhantomData; pub struct GetBucketEncryptionPhantomData;

View File

@ -25,6 +25,7 @@ use http::Method;
/// This struct constructs the parameters required for the [`Client::get_bucket_notification`](crate::s3::client::Client::get_bucket_notification) method. /// This struct constructs the parameters required for the [`Client::get_bucket_notification`](crate::s3::client::Client::get_bucket_notification) method.
pub type GetBucketNotification = BucketCommon<GetBucketNotificationPhantomData>; pub type GetBucketNotification = BucketCommon<GetBucketNotificationPhantomData>;
#[doc(hidden)]
#[derive(Default, Debug)] #[derive(Default, Debug)]
pub struct GetBucketNotificationPhantomData; pub struct GetBucketNotificationPhantomData;

View File

@ -25,6 +25,7 @@ use http::Method;
/// This struct constructs the parameters required for the [`Client::get_bucket_policy`](crate::s3::client::Client::get_bucket_policy) method. /// This struct constructs the parameters required for the [`Client::get_bucket_policy`](crate::s3::client::Client::get_bucket_policy) method.
pub type GetBucketPolicy = BucketCommon<GetBucketPolicyPhantomData>; pub type GetBucketPolicy = BucketCommon<GetBucketPolicyPhantomData>;
#[doc(hidden)]
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
pub struct GetBucketPolicyPhantomData; pub struct GetBucketPolicyPhantomData;

View File

@ -25,6 +25,7 @@ use http::Method;
/// This struct constructs the parameters required for the [`Client::get_bucket_replication`](crate::s3::client::Client::get_bucket_replication) method. /// This struct constructs the parameters required for the [`Client::get_bucket_replication`](crate::s3::client::Client::get_bucket_replication) method.
pub type GetBucketReplication = BucketCommon<GetBucketReplicationPhantomData>; pub type GetBucketReplication = BucketCommon<GetBucketReplicationPhantomData>;
#[doc(hidden)]
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
pub struct GetBucketReplicationPhantomData; pub struct GetBucketReplicationPhantomData;

View File

@ -56,6 +56,7 @@ impl GetBucketTagging {
self self
} }
/// Sets the region for the request
pub fn region(mut self, region: Option<String>) -> Self { pub fn region(mut self, region: Option<String>) -> Self {
self.region = region; self.region = region;
self self

View File

@ -25,6 +25,7 @@ use http::Method;
/// This struct constructs the parameters required for the [`Client::get_bucket_versioning`](crate::s3::client::Client::get_bucket_versioning) method. /// This struct constructs the parameters required for the [`Client::get_bucket_versioning`](crate::s3::client::Client::get_bucket_versioning) method.
pub type GetBucketVersioning = BucketCommon<GetBucketVersioningPhantomData>; pub type GetBucketVersioning = BucketCommon<GetBucketVersioningPhantomData>;
#[doc(hidden)]
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
pub struct GetBucketVersioningPhantomData; pub struct GetBucketVersioningPhantomData;

View File

@ -85,6 +85,7 @@ impl GetObject {
self self
} }
/// Sets the region for the request
pub fn region(mut self, region: Option<String>) -> Self { pub fn region(mut self, region: Option<String>) -> Self {
self.region = region; self.region = region;
self self

View File

@ -25,6 +25,7 @@ use http::Method;
/// This struct constructs the parameters required for the [`Client::get_object_lock_config`](crate::s3::client::Client::get_object_lock_config) method. /// This struct constructs the parameters required for the [`Client::get_object_lock_config`](crate::s3::client::Client::get_object_lock_config) method.
pub type GetObjectLockConfig = BucketCommon<GetObjectLockConfigPhantomData>; pub type GetObjectLockConfig = BucketCommon<GetObjectLockConfigPhantomData>;
#[doc(hidden)]
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
pub struct GetObjectLockConfigPhantomData; pub struct GetObjectLockConfigPhantomData;

View File

@ -27,6 +27,9 @@ use bytes::Bytes;
use http::Method; use http::Method;
use serde_json::json; use serde_json::json;
/// Argument builder for the `GetObjectPrompt` operation.
///
/// This struct constructs the parameters required for the [`Client::get_object_prompt`](crate::s3::client::Client::get_object_prompt) method.
#[derive(Debug, Clone, Default)] #[derive(Debug, Clone, Default)]
pub struct GetObjectPrompt { pub struct GetObjectPrompt {
client: Client, client: Client,
@ -74,6 +77,7 @@ impl GetObjectPrompt {
self self
} }
/// Sets the region for the request
pub fn region(mut self, region: Option<String>) -> Self { pub fn region(mut self, region: Option<String>) -> Self {
self.region = region; self.region = region;
self self

View File

@ -57,6 +57,7 @@ impl GetObjectRetention {
self self
} }
/// Sets the region for the request
pub fn region(mut self, region: Option<String>) -> Self { pub fn region(mut self, region: Option<String>) -> Self {
self.region = region; self.region = region;
self self

View File

@ -21,7 +21,9 @@ use crate::s3::types::{S3Api, S3Request, ToS3Request};
use crate::s3::utils::{check_bucket_name, check_object_name, insert}; use crate::s3::utils::{check_bucket_name, check_object_name, insert};
use http::Method; use http::Method;
/// Argument builder for [get_object_tags()](crate::s3::client::Client::get_object_tagging) API /// Argument builder for the [`GetObjectTagging`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectTagging.html) S3 API operation.
///
/// This struct constructs the parameters required for the [`Client::get_object_tagging`](crate::s3::client::Client::get_object_tagging) method.
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
pub struct GetObjectTagging { pub struct GetObjectTagging {
client: Client, client: Client,
@ -55,6 +57,7 @@ impl GetObjectTagging {
self self
} }
/// Sets the region for the request
pub fn region(mut self, region: Option<String>) -> Self { pub fn region(mut self, region: Option<String>) -> Self {
self.region = region; self.region = region;
self self

View File

@ -14,7 +14,6 @@
// limitations under the License. // limitations under the License.
use crate::s3::Client; use crate::s3::Client;
use crate::s3::client::DEFAULT_EXPIRY_SECONDS;
use crate::s3::creds::Credentials; use crate::s3::creds::Credentials;
use crate::s3::error::Error; use crate::s3::error::Error;
use crate::s3::multimap::{Multimap, MultimapExt}; use crate::s3::multimap::{Multimap, MultimapExt};
@ -23,6 +22,9 @@ use crate::s3::signer::presign_v4;
use crate::s3::utils::{UtcTime, check_bucket_name, check_object_name, utc_now}; use crate::s3::utils::{UtcTime, check_bucket_name, check_object_name, utc_now};
use http::Method; use http::Method;
/// The default expiry time in seconds for a [`GetPresignedObjectUrl`].
pub const DEFAULT_EXPIRY_SECONDS: u32 = 604_800; // 7 days
/// This struct constructs the parameters required for the [`Client::get_presigned_object_url`](crate::s3::client::Client::get_presigned_object_url) method. /// This struct constructs the parameters required for the [`Client::get_presigned_object_url`](crate::s3::client::Client::get_presigned_object_url) method.
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
pub struct GetPresignedObjectUrl { pub struct GetPresignedObjectUrl {
@ -35,6 +37,7 @@ pub struct GetPresignedObjectUrl {
object: String, object: String,
version_id: Option<String>, version_id: Option<String>,
method: Method, method: Method,
expiry_seconds: Option<u32>, expiry_seconds: Option<u32>,
request_time: Option<UtcTime>, request_time: Option<UtcTime>,
} }
@ -51,8 +54,21 @@ impl GetPresignedObjectUrl {
} }
} }
/// Sets the expiry time for the presigned URL, defaulting to 7 days if not specified.
pub fn expiry_seconds(mut self, seconds: u32) -> Self {
self.expiry_seconds = Some(seconds);
self
}
/// Sets the request time for the presigned URL, defaulting to the current time if not specified.
pub fn request_time(mut self, time: UtcTime) -> Self {
self.request_time = Some(time);
self
}
/// Sends the request to generate a presigned URL for an S3 object.
pub async fn send(self) -> Result<GetPresignedObjectUrlResponse, Error> { pub async fn send(self) -> Result<GetPresignedObjectUrlResponse, Error> {
// NOTE: this send function is async to be comparable with other functions... // NOTE: this send function is async and because of that, not comparable with other send functions...
check_bucket_name(&self.bucket, true)?; check_bucket_name(&self.bucket, true)?;
check_object_name(&self.object)?; check_object_name(&self.object)?;

View File

@ -22,6 +22,8 @@ use crate::s3::types::{S3Api, S3Request, ToS3Request};
use crate::s3::utils::{check_bucket_name, insert}; use crate::s3::utils::{check_bucket_name, insert};
use http::Method; use http::Method;
/// Argument builder for the [`GetRegion`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_HeadBucket.html) S3 API operation.
///
/// This struct constructs the parameters required for the [`Client::get_region`](crate::s3::client::Client::get_region) method. /// This struct constructs the parameters required for the [`Client::get_region`](crate::s3::client::Client::get_region) method.
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
pub struct GetRegion { pub struct GetRegion {
@ -52,6 +54,7 @@ impl GetRegion {
} }
} }
#[doc(hidden)]
#[derive(Default, Debug)] #[derive(Default, Debug)]
pub struct GetRegionPhantomData; pub struct GetRegionPhantomData;

View File

@ -469,6 +469,7 @@ impl ListObjects {
self self
} }
/// Sets the region for the request
pub fn region(mut self, region: Option<String>) -> Self { pub fn region(mut self, region: Option<String>) -> Self {
self.region = region; self.region = region;
self self

View File

@ -61,6 +61,7 @@ impl ListenBucketNotification {
self self
} }
/// Sets the region for the request
pub fn region(mut self, region: Option<String>) -> Self { pub fn region(mut self, region: Option<String>) -> Self {
self.region = region; self.region = region;
self self

View File

@ -23,7 +23,9 @@ use crate::s3::utils::{check_bucket_name, insert};
use bytes::Bytes; use bytes::Bytes;
use http::Method; use http::Method;
/// Argument builder for [put_bucket_encryption()](crate::s3::client::Client::put_bucket_encryption) API /// Argument builder for the [`PutBucketEncryption`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketEncryption.html) S3 API operation.
///
/// This struct constructs the parameters required for the [`Client::put_bucket_encryption`](crate::s3::client::Client::put_bucket_encryption) method.
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
pub struct PutBucketEncryption { pub struct PutBucketEncryption {
client: Client, client: Client,
@ -55,11 +57,13 @@ impl PutBucketEncryption {
self self
} }
/// Sets the region for the request
pub fn region(mut self, region: Option<String>) -> Self { pub fn region(mut self, region: Option<String>) -> Self {
self.region = region; self.region = region;
self self
} }
/// Sets the server-side encryption configuration for the bucket.
pub fn sse_config(mut self, config: SseConfig) -> Self { pub fn sse_config(mut self, config: SseConfig) -> Self {
self.config = config; self.config = config;
self self

View File

@ -58,6 +58,7 @@ impl PutBucketLifecycle {
self self
} }
/// Sets the region for the request
pub fn region(mut self, region: Option<String>) -> Self { pub fn region(mut self, region: Option<String>) -> Self {
self.region = region; self.region = region;
self self

View File

@ -57,6 +57,7 @@ impl PutBucketNotification {
self self
} }
/// Sets the region for the request
pub fn region(mut self, region: Option<String>) -> Self { pub fn region(mut self, region: Option<String>) -> Self {
self.region = region; self.region = region;
self self

View File

@ -57,6 +57,7 @@ impl PutBucketPolicy {
self self
} }
/// Sets the region for the request
pub fn region(mut self, region: Option<String>) -> Self { pub fn region(mut self, region: Option<String>) -> Self {
self.region = region; self.region = region;
self self

View File

@ -57,6 +57,7 @@ impl PutBucketReplication {
self self
} }
/// Sets the region for the request
pub fn region(mut self, region: Option<String>) -> Self { pub fn region(mut self, region: Option<String>) -> Self {
self.region = region; self.region = region;
self self

View File

@ -58,6 +58,7 @@ impl PutBucketTagging {
self self
} }
/// Sets the region for the request
pub fn region(mut self, region: Option<String>) -> Self { pub fn region(mut self, region: Option<String>) -> Self {
self.region = region; self.region = region;
self self

View File

@ -104,6 +104,7 @@ impl PutBucketVersioning {
self self
} }
/// Sets the region for the request
pub fn region(mut self, region: Option<String>) -> Self { pub fn region(mut self, region: Option<String>) -> Self {
self.region = region; self.region = region;
self self

View File

@ -76,6 +76,7 @@ impl CreateMultipartUpload {
self self
} }
/// Sets the region for the request
pub fn region(mut self, region: Option<String>) -> Self { pub fn region(mut self, region: Option<String>) -> Self {
self.region = region; self.region = region;
self self
@ -181,6 +182,7 @@ impl AbortMultipartUpload {
self self
} }
/// Sets the region for the request
pub fn region(mut self, region: Option<String>) -> Self { pub fn region(mut self, region: Option<String>) -> Self {
self.region = region; self.region = region;
self self
@ -261,6 +263,7 @@ impl CompleteMultipartUpload {
self self
} }
/// Sets the region for the request
pub fn region(mut self, region: Option<String>) -> Self { pub fn region(mut self, region: Option<String>) -> Self {
self.region = region; self.region = region;
self self
@ -373,6 +376,7 @@ impl UploadPart {
self self
} }
/// Sets the region for the request
pub fn region(mut self, region: Option<String>) -> Self { pub fn region(mut self, region: Option<String>) -> Self {
self.region = region; self.region = region;
self self
@ -481,6 +485,7 @@ impl PutObject {
self self
} }
/// Sets the region for the request
pub fn region(mut self, region: Option<String>) -> Self { pub fn region(mut self, region: Option<String>) -> Self {
self.0.region = region; self.0.region = region;
self self
@ -581,6 +586,7 @@ impl PutObjectContent {
self self
} }
/// Sets the region for the request
pub fn region(mut self, region: Option<String>) -> Self { pub fn region(mut self, region: Option<String>) -> Self {
self.region = region; self.region = region;
self self

View File

@ -57,6 +57,7 @@ impl PutObjectLockConfig {
self self
} }
/// Sets the region for the request
pub fn region(mut self, region: Option<String>) -> Self { pub fn region(mut self, region: Option<String>) -> Self {
self.region = region; self.region = region;
self self

View File

@ -64,6 +64,7 @@ impl PutObjectRetention {
self self
} }
/// Sets the region for the request
pub fn region(mut self, region: Option<String>) -> Self { pub fn region(mut self, region: Option<String>) -> Self {
self.region = region; self.region = region;
self self

View File

@ -24,7 +24,9 @@ use bytes::Bytes;
use http::Method; use http::Method;
use std::collections::HashMap; use std::collections::HashMap;
/// Argument builder for [put_object_tagging()](crate::s3::client::Client::put_object_tagging) API /// Argument builder for the [`PutObjectTagging`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObjectTagging.html) S3 API operation.
///
/// This struct constructs the parameters required for the [`Client::put_object_tagging`](crate::s3::client::Client::put_object_tagging) method.
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
pub struct PutObjectTagging { pub struct PutObjectTagging {
client: Client, client: Client,
@ -59,6 +61,7 @@ impl PutObjectTagging {
self self
} }
/// Sets the region for the request
pub fn region(mut self, region: Option<String>) -> Self { pub fn region(mut self, region: Option<String>) -> Self {
self.region = region; self.region = region;
self self

View File

@ -63,6 +63,7 @@ impl SelectObjectContent {
self self
} }
/// Sets the region for the request
pub fn region(mut self, region: Option<String>) -> Self { pub fn region(mut self, region: Option<String>) -> Self {
self.region = region; self.region = region;
self self

View File

@ -27,6 +27,9 @@ use crate::s3::{
utils::{UtcTime, check_bucket_name, to_http_header_value}, utils::{UtcTime, check_bucket_name, to_http_header_value},
}; };
/// Argument builder for the [`StatObject`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectAttributes.html) S3 API operation.
/// Retrieves all of the metadata from an object without returning the object itself.
///
/// This struct constructs the parameters required for the [`Client::stat_object`](crate::s3::client::Client::stat_object) method. /// This struct constructs the parameters required for the [`Client::stat_object`](crate::s3::client::Client::stat_object) method.
#[derive(Debug, Clone, Default)] #[derive(Debug, Clone, Default)]
pub struct StatObject { pub struct StatObject {
@ -84,6 +87,7 @@ impl StatObject {
self self
} }
/// Sets the region for the request
pub fn region(mut self, region: Option<String>) -> Self { pub fn region(mut self, region: Option<String>) -> Self {
self.region = region; self.region = region;
self self

View File

@ -90,12 +90,34 @@ mod stat_object;
use super::types::S3Api; use super::types::S3Api;
/// The default AWS region to be used if no other region is specified.
pub const DEFAULT_REGION: &str = "us-east-1"; pub const DEFAULT_REGION: &str = "us-east-1";
/// Minimum allowed size (in bytes) for a multipart upload part (except the last).
///
/// Used in multipart uploads to ensure each part (except the final one)
/// meets the required minimum size for transfer or storage.
pub const MIN_PART_SIZE: u64 = 5_242_880; // 5 MiB pub const MIN_PART_SIZE: u64 = 5_242_880; // 5 MiB
/// Maximum allowed size (in bytes) for a single multipart upload part.
///
/// In multipart uploads, no part can exceed this size limit.
/// This constraint ensures compatibility with services that enforce
/// a 5 GiB maximum per part.
pub const MAX_PART_SIZE: u64 = 5_368_709_120; // 5 GiB pub const MAX_PART_SIZE: u64 = 5_368_709_120; // 5 GiB
/// Maximum allowed size (in bytes) for a single object upload.
///
/// This is the upper limit for the total size of an object stored using
/// multipart uploads. It applies to the combined size of all parts,
/// ensuring the object does not exceed 5 TiB.
pub const MAX_OBJECT_SIZE: u64 = 5_497_558_138_880; // 5 TiB pub const MAX_OBJECT_SIZE: u64 = 5_497_558_138_880; // 5 TiB
/// Maximum number of parts allowed in a multipart upload.
///
/// Multipart uploads are limited to a total of 10,000 parts. If the object
/// exceeds this count, each part must be larger to remain within the limit.
pub const MAX_MULTIPART_COUNT: u16 = 10_000; pub const MAX_MULTIPART_COUNT: u16 = 10_000;
pub const DEFAULT_EXPIRY_SECONDS: u32 = 604_800; // 7 days
/// Client Builder manufactures a Client using given parameters. /// Client Builder manufactures a Client using given parameters.
#[derive(Debug, Default)] #[derive(Debug, Default)]

View File

@ -52,10 +52,10 @@ impl Client {
/// println!("size of the final object is {} bytes", resp.object_size); /// println!("size of the final object is {} bytes", resp.object_size);
/// } /// }
/// ``` /// ```
pub fn append_object<S: Into<String>>( pub fn append_object<S1: Into<String>, S2: Into<String>>(
&self, &self,
bucket: S, bucket: S1,
object: S, object: S2,
data: SegmentedBytes, data: SegmentedBytes,
offset_bytes: u64, offset_bytes: u64,
) -> AppendObject { ) -> AppendObject {
@ -100,10 +100,10 @@ impl Client {
/// println!("size of the final object is {} bytes", resp.object_size); /// println!("size of the final object is {} bytes", resp.object_size);
/// } /// }
/// ``` /// ```
pub fn append_object_content<S: Into<String>, C: Into<ObjectContent>>( pub fn append_object_content<S1: Into<String>, S2: Into<String>, C: Into<ObjectContent>>(
&self, &self,
bucket: S, bucket: S1,
object: S, object: S2,
content: C, content: C,
) -> AppendObjectContent { ) -> AppendObjectContent {
AppendObjectContent::new(self.clone(), bucket.into(), object.into(), content) AppendObjectContent::new(self.clone(), bucket.into(), object.into(), content)

View File

@ -13,13 +13,11 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//! S3 APIs for bucket objects.
use super::Client; use super::Client;
use crate::s3::builders::BucketExists; use crate::s3::builders::BucketExists;
impl Client { impl Client {
/// Creates a [`BucketExists`] request builder. /// Creates a [`BucketExists`] request builder to check if a bucket exists in S3.
/// ///
/// To execute the request, call [`BucketExists::send()`](crate::s3::types::S3Api::send), /// To execute the request, call [`BucketExists::send()`](crate::s3::types::S3Api::send),
/// which returns a [`Result`] containing a [`BucketExistsResponse`](crate::s3::response::BucketExistsResponse). /// which returns a [`Result`] containing a [`BucketExistsResponse`](crate::s3::response::BucketExistsResponse).

View File

@ -13,8 +13,6 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//! S3 APIs for bucket objects.
use super::Client; use super::Client;
use crate::s3::builders::{ use crate::s3::builders::{
ComposeObject, ComposeObjectInternal, ComposeSource, CopyObject, CopyObjectInternal, ComposeObject, ComposeObjectInternal, ComposeSource, CopyObject, CopyObjectInternal,
@ -66,8 +64,8 @@ impl Client {
CopyObjectInternal::new(self.clone(), bucket.into(), object.into()) CopyObjectInternal::new(self.clone(), bucket.into(), object.into())
} }
/// copy object is a high-order API that calls [stat_object](Client::stat_object) and based on the results calls /// copy object is a higher-level API that calls [stat_object](Client::stat_object) and based on the results calls
/// either [compose_object](Client::compose_object) or [`copy_object_internal`](Client::copy_object_internal) to copy the object. /// [compose_object](Client::compose_object) to copy the object.
pub fn copy_object<S1: Into<String>, S2: Into<String>>( pub fn copy_object<S1: Into<String>, S2: Into<String>>(
&self, &self,
bucket: S1, bucket: S1,
@ -76,6 +74,8 @@ impl Client {
CopyObject::new(self.clone(), bucket.into(), object.into()) CopyObject::new(self.clone(), bucket.into(), object.into())
} }
/// Create a ComposeObjectInternal request builder. This is a higher-level API that
/// performs a multipart object compose.
pub(crate) fn compose_object_internal<S1: Into<String>, S2: Into<String>>( pub(crate) fn compose_object_internal<S1: Into<String>, S2: Into<String>>(
&self, &self,
bucket: S1, bucket: S1,
@ -84,7 +84,7 @@ impl Client {
ComposeObjectInternal::new(self.clone(), bucket.into(), object.into()) ComposeObjectInternal::new(self.clone(), bucket.into(), object.into())
} }
/// compose object is high-order API that calls [`compose_object_internal`](Client::compose_object_internal) and if that call fails, /// compose object is higher-level API that calls an internal compose object, and if that call fails,
/// it calls ['abort_multipart_upload`](Client::abort_multipart_upload). /// it calls ['abort_multipart_upload`](Client::abort_multipart_upload).
pub fn compose_object<S1: Into<String>, S2: Into<String>>( pub fn compose_object<S1: Into<String>, S2: Into<String>>(
&self, &self,

View File

@ -13,8 +13,6 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//! S3 APIs for bucket objects.
use super::Client; use super::Client;
use crate::s3::builders::CreateBucket; use crate::s3::builders::CreateBucket;

View File

@ -13,14 +13,12 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//! S3 APIs for bucket objects.
use super::Client; use super::Client;
use crate::s3::builders::{DeleteBucket, ObjectToDelete, RemoveObject}; use crate::s3::builders::{DeleteBucket, DeleteObject, ObjectToDelete};
use crate::s3::error::{Error, ErrorCode}; use crate::s3::error::{Error, ErrorCode};
use crate::s3::response::DeleteResult; use crate::s3::response::DeleteResult;
use crate::s3::response::{ use crate::s3::response::{
DeleteBucketResponse, PutObjectLegalHoldResponse, RemoveObjectResponse, RemoveObjectsResponse, DeleteBucketResponse, DeleteObjectResponse, DeleteObjectsResponse, PutObjectLegalHoldResponse,
}; };
use crate::s3::types::{S3Api, ToStream}; use crate::s3::types::{S3Api, ToStream};
use futures::StreamExt; use futures::StreamExt;
@ -62,14 +60,14 @@ impl Client {
while let Some(items) = stream.next().await { while let Some(items) = stream.next().await {
let mut resp = self let mut resp = self
.remove_objects( .delete_objects_streaming(
&bucket, &bucket,
items?.contents.into_iter().map(ObjectToDelete::from), items?.contents.into_iter().map(ObjectToDelete::from),
) )
.to_stream() .to_stream()
.await; .await;
while let Some(item) = resp.next().await { while let Some(item) = resp.next().await {
let _resp: RemoveObjectsResponse = item?; let _resp: DeleteObjectsResponse = item?;
} }
} }
} else { } else {
@ -81,7 +79,7 @@ impl Client {
while let Some(items) = stream.next().await { while let Some(items) = stream.next().await {
let mut resp = self let mut resp = self
.remove_objects( .delete_objects_streaming(
&bucket, &bucket,
items?.contents.into_iter().map(ObjectToDelete::from), items?.contents.into_iter().map(ObjectToDelete::from),
) )
@ -90,7 +88,7 @@ impl Client {
.await; .await;
while let Some(item) = resp.next().await { while let Some(item) = resp.next().await {
let resp: RemoveObjectsResponse = item?; let resp: DeleteObjectsResponse = item?;
for obj in resp.result.into_iter() { for obj in resp.result.into_iter() {
match obj { match obj {
DeleteResult::Deleted(_) => {} DeleteResult::Deleted(_) => {}
@ -102,7 +100,7 @@ impl Client {
.send() .send()
.await?; .await?;
let _resp: RemoveObjectResponse = RemoveObject::new( let _resp: DeleteObjectResponse = DeleteObject::new(
self.clone(), self.clone(),
bucket.clone(), bucket.clone(),
ObjectToDelete::from(v), ObjectToDelete::from(v),

View File

@ -13,8 +13,6 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//! S3 APIs for bucket objects.
use super::Client; use super::Client;
use crate::s3::builders::DeleteBucketEncryption; use crate::s3::builders::DeleteBucketEncryption;

View File

@ -13,8 +13,6 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//! S3 APIs for bucket objects.
use super::Client; use super::Client;
use crate::s3::builders::DeleteBucketLifecycle; use crate::s3::builders::DeleteBucketLifecycle;

View File

@ -13,8 +13,6 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//! S3 APIs for bucket objects.
use super::Client; use super::Client;
use crate::s3::builders::DeleteBucketNotification; use crate::s3::builders::DeleteBucketNotification;

View File

@ -13,8 +13,6 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//! S3 APIs for bucket objects.
use super::Client; use super::Client;
use crate::s3::builders::DeleteBucketPolicy; use crate::s3::builders::DeleteBucketPolicy;

View File

@ -13,8 +13,6 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//! S3 APIs for bucket objects.
use super::Client; use super::Client;
use crate::s3::builders::DeleteBucketReplication; use crate::s3::builders::DeleteBucketReplication;

View File

@ -13,8 +13,6 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//! S3 APIs for bucket objects.
use super::Client; use super::Client;
use crate::s3::builders::DeleteBucketTagging; use crate::s3::builders::DeleteBucketTagging;

View File

@ -13,8 +13,6 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//! S3 APIs for bucket objects.
use super::Client; use super::Client;
use crate::s3::builders::DeleteObjectLockConfig; use crate::s3::builders::DeleteObjectLockConfig;

View File

@ -13,8 +13,6 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//! S3 APIs for bucket objects.
use super::Client; use super::Client;
use crate::s3::builders::DeleteObjectTagging; use crate::s3::builders::DeleteObjectTagging;

View File

@ -13,61 +13,65 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//! APIs to remove objects.
use crate::s3::builders::RemoveObjectsApi;
use crate::s3::{ use crate::s3::{
builders::{DeleteObjects, ObjectToDelete, RemoveObject, RemoveObjects}, builders::{
DeleteObject, DeleteObjects, DeleteObjectsStreaming, ObjectToDelete, ObjectsStream,
},
client::Client, client::Client,
}; };
impl Client { impl Client {
/// Creates a [`RemoveObject`] request builder. /// Creates a [`DeleteObject`] request builder to delete a single object from an S3 bucket.
/// ///
/// To execute the request, call [`RemoveObject::send()`](crate::s3::types::S3Api::send), /// To execute the request, call [`DeleteObject::send()`](crate::s3::types::S3Api::send),
/// which returns a [`Result`] containing a [`RemoveObjectResponse`](crate::s3::response::RemoveObjectResponse). /// which returns a [`Result`] containing a [`DeleteObjectResponse`](crate::s3::response::DeleteObjectResponse).
/// ///
/// # Example /// # Example
/// ///
/// ```no_run /// ```no_run
/// use minio::s3::Client; /// use minio::s3::Client;
/// use minio::s3::response::RemoveObjectResponse; /// use minio::s3::response::DeleteObjectResponse;
/// use minio::s3::builders::ObjectToDelete; /// use minio::s3::builders::ObjectToDelete;
/// use minio::s3::types::S3Api; /// use minio::s3::types::S3Api;
/// ///
/// #[tokio::main] /// #[tokio::main]
/// async fn main() { /// async fn main() {
/// let client: Client = Default::default(); // configure your client here /// let client: Client = Default::default(); // configure your client here
/// let resp: RemoveObjectResponse = client /// let resp: DeleteObjectResponse = client
/// .remove_object("bucket-name", ObjectToDelete::from("object-name")) /// .delete_object("bucket-name", ObjectToDelete::from("object-name"))
/// .send().await.unwrap(); /// .send().await.unwrap();
/// println!("the object is deleted. The delete marker has version '{:?}'", resp.version_id); /// println!("the object is deleted. The delete marker has version '{:?}'", resp.version_id);
/// } /// }
/// ``` /// ```
pub fn remove_object<S: Into<String>, D: Into<ObjectToDelete>>( pub fn delete_object<S: Into<String>, D: Into<ObjectToDelete>>(
&self, &self,
bucket: S, bucket: S,
object: D, object: D,
) -> RemoveObject { ) -> DeleteObject {
RemoveObject::new(self.clone(), bucket.into(), object) DeleteObject::new(self.clone(), bucket.into(), object)
} }
pub fn remove_objects<S: Into<String>, D: Into<DeleteObjects>>( /// Creates a [`DeleteObjects`] request builder to delete multiple objects from an S3 bucket.
&self, ///
bucket: S, /// To execute the request, call [`DeleteObjects::send()`](crate::s3::types::S3Api::send),
objects: D, /// which returns a [`Result`] containing a [`DeleteObjectsResponse`](crate::s3::response::DeleteObjectsResponse).
) -> RemoveObjects {
RemoveObjects::new(self.clone(), bucket.into(), objects)
}
/// Creates a builder to execute
/// [DeleteObjects](https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObjects.html)
/// S3 API
pub fn delete_objects<S: Into<String>, D: Into<ObjectToDelete>>( pub fn delete_objects<S: Into<String>, D: Into<ObjectToDelete>>(
&self, &self,
bucket: S, bucket: S,
object: Vec<ObjectToDelete>, object: Vec<ObjectToDelete>,
) -> RemoveObjectsApi { ) -> DeleteObjects {
RemoveObjectsApi::new(self.clone(), bucket.into(), object) DeleteObjects::new(self.clone(), bucket.into(), object)
}
/// Creates a [`DeleteObjectsStreaming`] request builder to delete a stream of objects from an S3 bucket.
///
/// to execute the request, call [`DeleteObjectsStreaming::to_stream()`](crate::s3::types::S3Api::send),
/// which returns a [`Result`] containing a [`DeleteObjectsResponse`](crate::s3::response::DeleteObjectsResponse).
pub fn delete_objects_streaming<S: Into<String>, D: Into<ObjectsStream>>(
&self,
bucket: S,
objects: D,
) -> DeleteObjectsStreaming {
DeleteObjectsStreaming::new(self.clone(), bucket.into(), objects)
} }
} }

View File

@ -13,8 +13,6 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//! S3 APIs for bucket objects.
use super::Client; use super::Client;
use crate::s3::builders::GetBucketEncryption; use crate::s3::builders::GetBucketEncryption;

View File

@ -13,14 +13,10 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//! S3 APIs for bucket objects.
use super::Client; use super::Client;
use crate::s3::builders::GetBucketLifecycle; use crate::s3::builders::GetBucketLifecycle;
impl Client { impl Client {
/// Create a GetBucketLifecycle request builder.
///
/// Creates a [`GetBucketLifecycle`] request builder. /// Creates a [`GetBucketLifecycle`] request builder.
/// ///
/// To execute the request, call [`GetBucketLifecycle::send()`](crate::s3::types::S3Api::send), /// To execute the request, call [`GetBucketLifecycle::send()`](crate::s3::types::S3Api::send),

View File

@ -13,8 +13,6 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//! S3 APIs for bucket objects.
use super::Client; use super::Client;
use crate::s3::builders::GetBucketNotification; use crate::s3::builders::GetBucketNotification;

View File

@ -13,8 +13,6 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//! S3 APIs for bucket objects.
use super::Client; use super::Client;
use crate::s3::builders::GetBucketPolicy; use crate::s3::builders::GetBucketPolicy;

View File

@ -13,8 +13,6 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//! S3 APIs for bucket objects.
use super::Client; use super::Client;
use crate::s3::builders::GetBucketReplication; use crate::s3::builders::GetBucketReplication;

View File

@ -13,8 +13,6 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//! S3 APIs for bucket objects.
use super::Client; use super::Client;
use crate::s3::builders::GetBucketTagging; use crate::s3::builders::GetBucketTagging;

View File

@ -13,8 +13,6 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//! S3 APIs for bucket objects.
use super::Client; use super::Client;
use crate::s3::builders::GetBucketVersioning; use crate::s3::builders::GetBucketVersioning;

View File

@ -13,17 +13,18 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//! S3 APIs for downloading objects.
use super::Client; use super::Client;
use crate::s3::builders::GetObject; use crate::s3::builders::GetObject;
impl Client { impl Client {
/// Creates a [`GetObject`] request builder. /// Creates a [`GetObject`] request builder to download an object from a specified S3 bucket.
/// /// This allows retrieval of the full content and metadata for the object.
///
/// To execute the request, call [`GetObject::send()`](crate::s3::types::S3Api::send), /// To execute the request, call [`GetObject::send()`](crate::s3::types::S3Api::send),
/// which returns a [`Result`] containing a [`GetObjectResponse`](crate::s3::response::GetObjectResponse). /// which returns a [`Result`] containing a [`GetObjectResponse`](crate::s3::response::GetObjectResponse).
/// ///
/// For more information, refer to the [AWS S3 GetObject API documentation](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html).
///
/// # Example /// # Example
/// ///
/// ```no_run /// ```no_run
@ -39,7 +40,7 @@ impl Client {
/// .send().await.unwrap(); /// .send().await.unwrap();
/// let content_bytes = resp.content.to_segmented_bytes().await.unwrap().to_bytes(); /// let content_bytes = resp.content.to_segmented_bytes().await.unwrap().to_bytes();
/// let content_str = String::from_utf8(content_bytes.to_vec()).unwrap(); /// let content_str = String::from_utf8(content_bytes.to_vec()).unwrap();
/// println!("retrieved content '{}'", content_str); /// println!("retrieved content '{content_str}'");
/// } /// }
/// ``` /// ```
pub fn get_object<S1: Into<String>, S2: Into<String>>( pub fn get_object<S1: Into<String>, S2: Into<String>>(

View File

@ -13,8 +13,6 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//! S3 APIs for bucket objects.
use super::Client; use super::Client;
use crate::s3::builders::GetObjectLegalHold; use crate::s3::builders::GetObjectLegalHold;

View File

@ -13,8 +13,6 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//! S3 APIs for bucket objects.
use super::Client; use super::Client;
use crate::s3::builders::GetObjectLockConfig; use crate::s3::builders::GetObjectLockConfig;

View File

@ -13,8 +13,6 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//! S3 APIs for downloading objects.
use crate::s3::builders::GetObjectPrompt; use crate::s3::builders::GetObjectPrompt;
use super::Client; use super::Client;

View File

@ -13,8 +13,6 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//! S3 APIs for bucket objects.
use super::Client; use super::Client;
use crate::s3::builders::GetObjectRetention; use crate::s3::builders::GetObjectRetention;

View File

@ -13,8 +13,6 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//! S3 APIs for bucket objects.
use super::Client; use super::Client;
use crate::s3::builders::GetObjectTagging; use crate::s3::builders::GetObjectTagging;

View File

@ -13,8 +13,6 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//! S3 APIs for downloading objects.
use super::{Client, DEFAULT_REGION}; use super::{Client, DEFAULT_REGION};
use crate::s3::builders::GetRegion; use crate::s3::builders::GetRegion;
use crate::s3::error::Error; use crate::s3::error::Error;

View File

@ -13,28 +13,27 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//! S3 APIs for listing objects.
use super::Client; use super::Client;
use crate::s3::builders::ListBuckets; use crate::s3::builders::ListBuckets;
impl Client { impl Client {
/// Creates a [`ListBuckets`] request builder. /// Creates a [`ListBuckets`] request builder to retrieve the list of all buckets owned by the authenticated sender of the request.
/// ///
/// To execute the request, call [`ListBuckets::send()`](crate::s3::types::S3Api::send), /// To execute the request, call [`ListBuckets::send()`](crate::s3::types::S3Api::send),
/// which returns a [`Result`] containing a [`ListBucketsResponse`](crate::s3::response::ListBucketsResponse). /// which returns a [`Result`] containing a [`ListBucketsResponse`](crate::s3::response::ListBucketsResponse).
/// ///
/// For more information, refer to the [AWS S3 ListBuckets API documentation](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBuckets.html).
///
/// # Example /// # Example
/// ///
/// ```no_run /// ```no_run
/// use minio::s3::Client; /// use minio::s3::Client;
/// use minio::s3::response::ListBucketsResponse; /// use minio::s3::response::ListBucketsResponse;
/// use minio::s3::types::S3Api; /// use minio::s3::types::S3Api;
/// use std::sync::Arc;
/// ///
/// #[tokio::main] /// #[tokio::main]
/// async fn main() { /// async fn main() {
/// let client: Client = Default::default(); // configure your client here /// let client: Client = Default::default(); // configure your client here
/// let resp: ListBucketsResponse = client /// let resp: ListBucketsResponse = client
/// .list_buckets() /// .list_buckets()
/// .send().await.unwrap(); /// .send().await.unwrap();

View File

@ -13,8 +13,6 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//! S3 APIs for listing objects.
use super::Client; use super::Client;
use crate::s3::builders::ListObjects; use crate::s3::builders::ListObjects;

View File

@ -13,8 +13,6 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//! S3 APIs for bucket objects.
use super::Client; use super::Client;
use crate::s3::builders::PutBucketEncryption; use crate::s3::builders::PutBucketEncryption;

View File

@ -13,8 +13,6 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//! S3 APIs for bucket objects.
use super::Client; use super::Client;
use crate::s3::builders::PutBucketLifecycle; use crate::s3::builders::PutBucketLifecycle;

View File

@ -13,8 +13,6 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//! S3 APIs for bucket objects.
use super::Client; use super::Client;
use crate::s3::builders::PutBucketNotification; use crate::s3::builders::PutBucketNotification;

View File

@ -13,8 +13,6 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//! S3 APIs for bucket objects.
use super::Client; use super::Client;
use crate::s3::builders::PutBucketPolicy; use crate::s3::builders::PutBucketPolicy;

View File

@ -13,8 +13,6 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//! S3 APIs for bucket objects.
use super::Client; use super::Client;
use crate::s3::builders::PutBucketReplication; use crate::s3::builders::PutBucketReplication;

View File

@ -13,8 +13,6 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//! S3 APIs for bucket objects.
use super::Client; use super::Client;
use crate::s3::builders::PutBucketTagging; use crate::s3::builders::PutBucketTagging;

View File

@ -13,8 +13,6 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//! S3 APIs for bucket objects.
use super::Client; use super::Client;
use crate::s3::builders::PutBucketVersioning; use crate::s3::builders::PutBucketVersioning;

View File

@ -1,5 +1,5 @@
// MinIO Rust Library for Amazon S3 Compatible Cloud Storage // MinIO Rust Library for Amazon S3 Compatible Cloud Storage
// Copyright 2023 MinIO, Inc. // Copyright 2025 MinIO, Inc.
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
@ -13,8 +13,6 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//! S3 APIs for uploading objects.
use super::Client; use super::Client;
use crate::s3::segmented_bytes::SegmentedBytes; use crate::s3::segmented_bytes::SegmentedBytes;
use crate::s3::{ use crate::s3::{
@ -26,12 +24,16 @@ use crate::s3::{
}; };
impl Client { impl Client {
/// Creates a [`PutObject`] request builder. This is a lower-level API that /// Creates a [`PutObject`] request builder to upload an object to a specified bucket in S3-compatible storage.
/// performs a non-multipart object upload. /// This method performs a simple, non-multipart upload of the provided content as an object.
///
/// For handling large files requiring multipart upload, see [`create_multipart_upload`](#method.create_multipart_upload).
/// ///
/// To execute the request, call [`PutObject::send()`](crate::s3::types::S3Api::send), /// To execute the request, call [`PutObject::send()`](crate::s3::types::S3Api::send),
/// which returns a [`Result`] containing a [`PutObjectResponse`](crate::s3::response::PutObjectResponse). /// which returns a [`Result`] containing a [`PutObjectResponse`](crate::s3::response::PutObjectResponse).
/// ///
/// For more information, refer to the [AWS S3 PutObject API documentation](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html).
///
/// # Example /// # Example
/// ///
/// ```no_run /// ```no_run
@ -58,7 +60,29 @@ impl Client {
PutObject::new(self.clone(), bucket.into(), object.into(), data) PutObject::new(self.clone(), bucket.into(), object.into(), data)
} }
/// Create a CreateMultipartUpload request builder. /// Creates a [`CreateMultipartUpload`] request builder to initiate a new multipart upload for a specified object in a bucket.
/// This allows uploading large objects as a series of parts, which can be uploaded independently and in parallel.
///
/// To execute the request, call [`CreateMultipartUpload::send()`](crate::s3::types::S3Api::send),
/// which returns a [`Result`] containing a [`CreateMultipartUploadResponse`](crate::s3::response::CreateMultipartUploadResponse).
///
/// For more information, refer to the [AWS S3 CreateMultipartUpload API documentation](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html).
///
/// # Example
/// ```no_run
/// use minio::s3::Client;
/// use minio::s3::response::CreateMultipartUploadResponse;
/// use minio::s3::types::S3Api;
///
/// #[tokio::main]
/// async fn main() {
/// let client: Client = Default::default();
/// let resp: CreateMultipartUploadResponse = client
/// .create_multipart_upload("bucket-name", "large-object")
/// .send().await.unwrap();
/// println!("Initiated multipart upload with UploadId '{}'", resp.upload_id);
/// }
/// ```
pub fn create_multipart_upload<S1: Into<String>, S2: Into<String>>( pub fn create_multipart_upload<S1: Into<String>, S2: Into<String>>(
&self, &self,
bucket: S1, bucket: S1,
@ -67,6 +91,29 @@ impl Client {
CreateMultipartUpload::new(self.clone(), bucket.into(), object.into()) CreateMultipartUpload::new(self.clone(), bucket.into(), object.into())
} }
/// Creates an [`AbortMultipartUpload`] request builder to abort an ongoing multipart upload for an object.
/// This operation stops the multipart upload and discards all uploaded parts, freeing storage.
///
/// To execute the request, call [`AbortMultipartUpload::send()`](crate::s3::types::S3Api::send),
/// which returns a [`Result`] containing a [`AbortMultipartUploadResponse`](crate::s3::response::AbortMultipartUploadResponse).
///
/// For more information, refer to the [AWS S3 AbortMultipartUpload API documentation](https://docs.aws.amazon.com/AmazonS3/latest/API/API_AbortMultipartUpload.html).
///
/// # Example
/// ```no_run
/// use minio::s3::Client;
/// use minio::s3::response::AbortMultipartUploadResponse;
/// use minio::s3::types::S3Api;
///
/// #[tokio::main]
/// async fn main() {
/// let client: Client = Default::default();
/// let resp: AbortMultipartUploadResponse = client
/// .abort_multipart_upload("bucket-name", "object-name", "upload-id-123")
/// .send().await.unwrap();
/// println!("Aborted multipart upload for '{}', upload id '{}'", "object-name", "upload-id-123");
/// }
/// ```
pub fn abort_multipart_upload<S1: Into<String>, S2: Into<String>, S3: Into<String>>( pub fn abort_multipart_upload<S1: Into<String>, S2: Into<String>, S3: Into<String>>(
&self, &self,
bucket: S1, bucket: S1,
@ -76,6 +123,31 @@ impl Client {
AbortMultipartUpload::new(self.clone(), bucket.into(), object.into(), upload_id.into()) AbortMultipartUpload::new(self.clone(), bucket.into(), object.into(), upload_id.into())
} }
/// Creates a [`CompleteMultipartUpload`] request builder to complete a multipart upload by assembling previously uploaded parts into a single object.
/// This finalizes the upload and makes the object available in the bucket.
///
/// To execute the request, call [`CompleteMultipartUpload::send()`](crate::s3::types::S3Api::send),
/// which returns a [`Result`] containing a [`CompleteMultipartUploadResponse`](crate::s3::response::CompleteMultipartUploadResponse).
///
/// For more information, refer to the [AWS S3 CompleteMultipartUpload API documentation](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html).
///
/// # Example
/// ```no_run
/// use minio::s3::Client;
/// use minio::s3::response::CompleteMultipartUploadResponse;
/// use minio::s3::types::S3Api;
/// use minio::s3::types::PartInfo;
///
/// #[tokio::main]
/// async fn main() {
/// let client: Client = Default::default();
/// let parts: Vec<PartInfo> = vec![]; // fill with your uploaded part info
/// let resp: CompleteMultipartUploadResponse = client
/// .complete_multipart_upload("bucket-name", "object-name", "upload-id-123", parts)
/// .send().await.unwrap();
/// println!("Completed multipart upload for '{}'", resp.object);
/// }
/// ```
pub fn complete_multipart_upload<S1: Into<String>, S2: Into<String>, S3: Into<String>>( pub fn complete_multipart_upload<S1: Into<String>, S2: Into<String>, S3: Into<String>>(
&self, &self,
bucket: S1, bucket: S1,
@ -92,6 +164,31 @@ impl Client {
) )
} }
/// Creates an [`UploadPart`] request builder to upload a single part as part of a multipart upload.
/// Each part is uploaded independently, enabling parallel uploads for large objects.
///
/// To execute the request, call [`UploadPart::send()`](crate::s3::types::S3Api::send),
/// which returns a [`Result`] containing a [`UploadPartResponse`](crate::s3::response::UploadPartResponse).
///
/// For more information, refer to the [AWS S3 UploadPart API documentation](https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html).
///
/// # Example
/// ```no_run
/// use minio::s3::Client;
/// use minio::s3::response::UploadPartResponse;
/// use minio::s3::types::S3Api;
/// use minio::s3::segmented_bytes::SegmentedBytes;
///
/// #[tokio::main]
/// async fn main() {
/// let client: Client = Default::default();
/// let data = SegmentedBytes::from("Some part data".to_string());
/// let resp: UploadPartResponse = client
/// .upload_part("bucket-name", "object-name", "upload-id", 1, data)
/// .send().await.unwrap();
/// println!("Uploaded object: {}", resp.object);
/// }
/// ```
pub fn upload_part<S1: Into<String>, S2: Into<String>, S3: Into<String>>( pub fn upload_part<S1: Into<String>, S2: Into<String>, S3: Into<String>>(
&self, &self,
bucket: S1, bucket: S1,
@ -110,8 +207,30 @@ impl Client {
) )
} }
/// Creates a PutObjectContent request builder to upload data to MinIO/S3. /// Creates a [`PutObjectContent`] request builder to upload data to MinIO/S3, automatically handling multipart uploads for large content.
/// The content is streamed, and this higher-level API handles multipart uploads transparently. /// This higher-level API efficiently streams and uploads content, splitting it into parts as needed.
///
/// To execute the request, call [`PutObjectContent::send()`](crate::s3::types::S3Api::send),
/// which returns a [`Result`] containing a [`PutObjectContentResponse`](crate::s3::response::PutObjectContentResponse).
///
/// For more information, see the [AWS S3 Multipart Upload Overview](https://docs.aws.amazon.com/AmazonS3/latest/userguide/mpuoverview.html).
///
/// # Example
/// ```no_run
/// use minio::s3::Client;
/// use minio::s3::response::PutObjectContentResponse;
/// use minio::s3::types::S3Api;
///
/// #[tokio::main]
/// async fn main() {
/// let client: Client = Default::default();
/// let content = "Hello, world!".to_string();
/// let resp: PutObjectContentResponse = client
/// .put_object_content("bucket", "object", content)
/// .send().await.unwrap();
/// println!("Uploaded object '{}' with ETag '{}'", resp.object, resp.etag);
/// }
/// ```
pub fn put_object_content<S1: Into<String>, S2: Into<String>, C: Into<ObjectContent>>( pub fn put_object_content<S1: Into<String>, S2: Into<String>, C: Into<ObjectContent>>(
&self, &self,
bucket: S1, bucket: S1,

View File

@ -13,8 +13,6 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//! S3 APIs for bucket objects.
use super::Client; use super::Client;
use crate::s3::builders::PutObjectLegalHold; use crate::s3::builders::PutObjectLegalHold;

View File

@ -13,8 +13,6 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//! S3 APIs for bucket objects.
use super::Client; use super::Client;
use crate::s3::builders::PutObjectLockConfig; use crate::s3::builders::PutObjectLockConfig;

View File

@ -13,8 +13,6 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//! S3 APIs for bucket objects.
use super::Client; use super::Client;
use crate::s3::builders::PutObjectRetention; use crate::s3::builders::PutObjectRetention;

View File

@ -13,8 +13,6 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//! S3 APIs for bucket objects.
use super::Client; use super::Client;
use crate::s3::builders::PutObjectTagging; use crate::s3::builders::PutObjectTagging;

View File

@ -13,8 +13,6 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//! S3 APIs for bucket objects.
use super::Client; use super::Client;
use crate::s3::builders::SelectObjectContent; use crate::s3::builders::SelectObjectContent;
use crate::s3::types::SelectRequest; use crate::s3::types::SelectRequest;

View File

@ -13,8 +13,6 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//! S3 APIs for bucket objects.
use super::Client; use super::Client;
use crate::s3::builders::StatObject; use crate::s3::builders::StatObject;

View File

@ -13,8 +13,6 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//! Responses for [minio::s3::client::Client](crate::s3::client::Client) APIs
mod append_object; mod append_object;
mod bucket_exists; mod bucket_exists;
mod copy_object; mod copy_object;
@ -26,6 +24,7 @@ mod delete_bucket_notification;
mod delete_bucket_policy; mod delete_bucket_policy;
mod delete_bucket_replication; mod delete_bucket_replication;
mod delete_bucket_tagging; mod delete_bucket_tagging;
mod delete_object;
mod delete_object_lock_config; mod delete_object_lock_config;
mod delete_object_tagging; mod delete_object_tagging;
mod get_bucket_encryption; mod get_bucket_encryption;
@ -58,7 +57,6 @@ mod put_object_legal_hold;
mod put_object_lock_config; mod put_object_lock_config;
mod put_object_retention; mod put_object_retention;
mod put_object_tagging; mod put_object_tagging;
mod remove_objects;
mod select_object_content; mod select_object_content;
mod stat_object; mod stat_object;
@ -73,6 +71,9 @@ pub use delete_bucket_notification::DeleteBucketNotificationResponse;
pub use delete_bucket_policy::DeleteBucketPolicyResponse; pub use delete_bucket_policy::DeleteBucketPolicyResponse;
pub use delete_bucket_replication::DeleteBucketReplicationResponse; pub use delete_bucket_replication::DeleteBucketReplicationResponse;
pub use delete_bucket_tagging::DeleteBucketTaggingResponse; pub use delete_bucket_tagging::DeleteBucketTaggingResponse;
pub use delete_object::{
DeleteError, DeleteObjectResponse, DeleteObjectsResponse, DeleteResult, DeletedObject,
};
pub use delete_object_lock_config::DeleteObjectLockConfigResponse; pub use delete_object_lock_config::DeleteObjectLockConfigResponse;
pub use delete_object_tagging::DeleteObjectTaggingResponse; pub use delete_object_tagging::DeleteObjectTaggingResponse;
pub use get_bucket_encryption::GetBucketEncryptionResponse; pub use get_bucket_encryption::GetBucketEncryptionResponse;
@ -108,8 +109,5 @@ pub use put_object_legal_hold::PutObjectLegalHoldResponse;
pub use put_object_lock_config::PutObjectLockConfigResponse; pub use put_object_lock_config::PutObjectLockConfigResponse;
pub use put_object_retention::PutObjectRetentionResponse; pub use put_object_retention::PutObjectRetentionResponse;
pub use put_object_tagging::PutObjectTaggingResponse; pub use put_object_tagging::PutObjectTaggingResponse;
pub use remove_objects::{
DeleteError, DeleteResult, DeletedObject, RemoveObjectResponse, RemoveObjectsResponse,
};
pub use select_object_content::SelectObjectContentResponse; pub use select_object_content::SelectObjectContentResponse;
pub use stat_object::StatObjectResponse; pub use stat_object::StatObjectResponse;

View File

@ -1,5 +1,5 @@
// MinIO Rust Library for Amazon S3 Compatible Cloud Storage // MinIO Rust Library for Amazon S3 Compatible Cloud Storage
// Copyright 2022-2024 MinIO, Inc. // Copyright 2022-2025 MinIO, Inc.
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
@ -13,8 +13,6 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//! Responses for RemoveObject APIs.
use async_trait::async_trait; use async_trait::async_trait;
use bytes::Buf; use bytes::Buf;
use http::HeaderMap; use http::HeaderMap;
@ -28,20 +26,23 @@ use crate::s3::{
}; };
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct RemoveObjectResponse { pub struct DeleteObjectResponse {
/// HTTP headers returned by the server, containing metadata such as `Content-Type`, `ETag`, etc. /// HTTP headers returned by the server, containing metadata such as `Content-Type`, `ETag`, etc.
pub headers: HeaderMap, pub headers: HeaderMap,
/// Value of the `x-amz-delete-marker` header. /// Value of the `x-amz-delete-marker` header.
/// Indicates whether the specified object version that was permanently deleted was (true) or
/// was not (false) a delete marker before deletion. In a simple DELETE, this header indicates
/// whether (true) or not (false) the current version of the object is a delete marker.
pub is_delete_marker: bool, pub is_delete_marker: bool,
/// If a delete marker was created, this field will contain the version_id /// Value of the `x-amz-version-id` header.
/// of the delete marker. Value of the `x-amz-version-id` header. /// If a delete marker was created, this field will contain the version_id of the delete marker.
pub version_id: Option<String>, pub version_id: Option<String>,
} }
#[async_trait] #[async_trait]
impl FromS3Response for RemoveObjectResponse { impl FromS3Response for DeleteObjectResponse {
async fn from_s3response( async fn from_s3response(
_req: S3Request, _req: S3Request,
resp: Result<reqwest::Response, Error>, resp: Result<reqwest::Response, Error>,
@ -57,7 +58,7 @@ impl FromS3Response for RemoveObjectResponse {
.get("x-amz-version-id") .get("x-amz-version-id")
.and_then(|v| v.to_str().ok().map(String::from)); .and_then(|v| v.to_str().ok().map(String::from));
Ok(RemoveObjectResponse { Ok(DeleteObjectResponse {
headers, headers,
is_delete_marker, is_delete_marker,
version_id, version_id,
@ -86,10 +87,10 @@ pub struct DeletedObject {
/// Response of /// Response of
/// [delete_objects()](crate::s3::client::Client::delete_objects) /// [delete_objects()](crate::s3::client::Client::delete_objects)
/// S3 API. It is also returned by the /// S3 API. It is also returned by the
/// [remove_objects()](crate::s3::client::Client::remove_objects) API in the /// [remove_objects()](crate::s3::client::Client::delete_objects_streaming) API in the
/// form of a stream. /// form of a stream.
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct RemoveObjectsResponse { pub struct DeleteObjectsResponse {
/// HTTP headers returned by the server, containing metadata such as `Content-Type`, `ETag`, etc. /// HTTP headers returned by the server, containing metadata such as `Content-Type`, `ETag`, etc.
pub headers: HeaderMap, pub headers: HeaderMap,
pub result: Vec<DeleteResult>, pub result: Vec<DeleteResult>,
@ -122,7 +123,7 @@ impl DeleteResult {
} }
#[async_trait] #[async_trait]
impl FromS3Response for RemoveObjectsResponse { impl FromS3Response for DeleteObjectsResponse {
async fn from_s3response( async fn from_s3response(
_req: S3Request, _req: S3Request,
resp: Result<reqwest::Response, Error>, resp: Result<reqwest::Response, Error>,

View File

@ -69,6 +69,7 @@ impl FromS3Response for PutObjectResponse {
} }
} }
/// Response of [create_multipart_upload()](crate::s3::client::Client::create_multipart_upload) API
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct CreateMultipartUploadResponse { pub struct CreateMultipartUploadResponse {
/// HTTP headers returned by the server, containing metadata such as `Content-Type`, `ETag`, etc. /// HTTP headers returned by the server, containing metadata such as `Content-Type`, `ETag`, etc.
@ -103,10 +104,13 @@ impl FromS3Response for CreateMultipartUploadResponse {
} }
} }
/// Response of [abort_multipart_upload()](crate::s3::client::Client::abort_multipart_upload) API
pub type AbortMultipartUploadResponse = CreateMultipartUploadResponse; pub type AbortMultipartUploadResponse = CreateMultipartUploadResponse;
/// Response of [complete_multipart_upload()](crate::s3::client::Client::complete_multipart_upload) API
pub type CompleteMultipartUploadResponse = PutObjectResponse; pub type CompleteMultipartUploadResponse = PutObjectResponse;
/// Response of [upload_part()](crate::s3::client::Client::upload_part) API
pub type UploadPartResponse = PutObjectResponse; pub type UploadPartResponse = PutObjectResponse;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]

View File

@ -56,6 +56,7 @@ impl S3Request {
} }
} }
/// Sets the region for the request
pub fn region(mut self, region: Option<String>) -> Self { pub fn region(mut self, region: Option<String>) -> Self {
self.region = region; self.region = region;
self self
@ -715,6 +716,7 @@ impl RequestParameters {
self.0.get("principalId") self.0.get("principalId")
} }
/// Gets the region for the request
pub fn region(&self) -> Option<&String> { pub fn region(&self) -> Option<&String> {
self.0.get("region") self.0.get("region")
} }

View File

@ -546,7 +546,7 @@ async fn append_object_content_3() {
assert_eq!(resp.size, sizes[idx] + initial_size); assert_eq!(resp.size, sizes[idx] + initial_size);
assert_eq!(resp.etag, etag); assert_eq!(resp.etag, etag);
client client
.remove_object(&test_bucket, &object_name) .delete_object(&test_bucket, &object_name)
.send() .send()
.await .await
.unwrap(); .unwrap();

View File

@ -192,7 +192,7 @@ async fn put_object_content_2() {
assert_eq!(resp.size, sizes[idx]); assert_eq!(resp.size, sizes[idx]);
assert_eq!(resp.etag, etag); assert_eq!(resp.etag, etag);
client client
.remove_object(&test_bucket, &object_name) .delete_object(&test_bucket, &object_name)
.send() .send()
.await .await
.unwrap(); .unwrap();

View File

@ -45,7 +45,7 @@ async fn remove_objects() {
let mut resp = ctx let mut resp = ctx
.client .client
.remove_objects(&bucket_name, del_items.into_iter()) .delete_objects_streaming(&bucket_name, del_items.into_iter())
.verbose_mode(true) .verbose_mode(true)
.to_stream() .to_stream()
.await; .await;

View File

@ -15,8 +15,9 @@
use http::header; use http::header;
use minio::s3::builders::ObjectContent; use minio::s3::builders::ObjectContent;
use minio::s3::client;
use minio::s3::error::{Error, ErrorCode}; use minio::s3::error::{Error, ErrorCode};
use minio::s3::response::{PutObjectContentResponse, RemoveObjectResponse, StatObjectResponse}; use minio::s3::response::{DeleteObjectResponse, PutObjectContentResponse, StatObjectResponse};
use minio::s3::types::S3Api; use minio::s3::types::S3Api;
use minio_common::rand_src::RandSrc; use minio_common::rand_src::RandSrc;
use minio_common::test_context::TestContext; use minio_common::test_context::TestContext;
@ -54,9 +55,9 @@ async fn put_object() {
assert_eq!(resp.object, object_name); assert_eq!(resp.object, object_name);
assert_eq!(resp.size, size); assert_eq!(resp.size, size);
let resp: RemoveObjectResponse = ctx let resp: DeleteObjectResponse = ctx
.client .client
.remove_object(&bucket_name, &object_name) .delete_object(&bucket_name, &object_name)
.send() .send()
.await .await
.unwrap(); .unwrap();
@ -83,9 +84,10 @@ async fn put_object_multipart() {
let (bucket_name, _cleanup) = ctx.create_bucket_helper().await; let (bucket_name, _cleanup) = ctx.create_bucket_helper().await;
let object_name = rand_object_name(); let object_name = rand_object_name();
let size: u64 = 16 + 5 * 1024 * 1024; let size: u64 = 16 + client::MIN_PART_SIZE;
ctx.client let resp: PutObjectContentResponse = ctx
.client
.put_object_content( .put_object_content(
&bucket_name, &bucket_name,
&object_name, &object_name,
@ -94,7 +96,11 @@ async fn put_object_multipart() {
.send() .send()
.await .await
.unwrap(); .unwrap();
let resp = ctx assert_eq!(resp.bucket, bucket_name);
assert_eq!(resp.object, object_name);
assert_eq!(resp.object_size, size);
let resp: StatObjectResponse = ctx
.client .client
.stat_object(&bucket_name, &object_name) .stat_object(&bucket_name, &object_name)
.send() .send()
@ -102,12 +108,15 @@ async fn put_object_multipart() {
.unwrap(); .unwrap();
assert_eq!(resp.bucket, bucket_name); assert_eq!(resp.bucket, bucket_name);
assert_eq!(resp.object, object_name); assert_eq!(resp.object, object_name);
assert_eq!(resp.size as u64, size); assert_eq!(resp.size, size);
ctx.client
.remove_object(&bucket_name, &object_name) let resp: DeleteObjectResponse = ctx
.client
.delete_object(&bucket_name, &object_name)
.send() .send()
.await .await
.unwrap(); .unwrap();
assert_eq!(resp.version_id, None);
} }
#[tokio::test(flavor = "multi_thread", worker_threads = 10)] #[tokio::test(flavor = "multi_thread", worker_threads = 10)]
@ -143,9 +152,9 @@ async fn put_object_content_1() {
resp.headers.get(header::CONTENT_TYPE).unwrap(), resp.headers.get(header::CONTENT_TYPE).unwrap(),
"image/jpeg" "image/jpeg"
); );
let resp: RemoveObjectResponse = ctx let resp: DeleteObjectResponse = ctx
.client .client
.remove_object(&bucket_name, &object_name) .delete_object(&bucket_name, &object_name)
.send() .send()
.await .await
.unwrap(); .unwrap();
@ -185,7 +194,7 @@ async fn put_object_content_2() {
assert_eq!(resp.size, *size); assert_eq!(resp.size, *size);
assert_eq!(resp.etag, etag); assert_eq!(resp.etag, etag);
ctx.client ctx.client
.remove_object(&bucket_name, &object_name) .delete_object(&bucket_name, &object_name)
.send() .send()
.await .await
.unwrap(); .unwrap();
@ -239,7 +248,7 @@ async fn put_object_content_3() {
assert_eq!(resp.size, sizes[idx]); assert_eq!(resp.size, sizes[idx]);
assert_eq!(resp.etag, etag); assert_eq!(resp.etag, etag);
client client
.remove_object(&test_bucket, &object_name) .delete_object(&test_bucket, &object_name)
.send() .send()
.await .await
.unwrap(); .unwrap();