Function names updated to reflect AWS names. Updated docs (#150)

* updated inline doc

* updated inline doc

* API naming conform AWS

* fixed clippy issues

* fixed minor API naming issues
This commit is contained in:
Henk-Jan Lebbink 2025-05-10 00:53:44 +02:00 committed by GitHub
parent 1869cfeba7
commit 20d8654e34
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
192 changed files with 2033 additions and 1593 deletions

View File

@ -19,11 +19,12 @@ jobs:
- uses: actions/checkout@v4
- name: Build
run: |
cargo --version
cargo fmt --all -- --check
cargo clippy --all-targets --all-features
cargo build --bins --examples --tests --benches --verbose
- name: Run tests S3
- name: Run tests
run: |
./tests/start-server.sh
export SERVER_ENDPOINT=localhost:9000

View File

@ -18,7 +18,7 @@ mod bench_bucket_lifecycle;
mod bench_bucket_notification;
mod bench_bucket_policy;
mod bench_bucket_replication;
mod bench_bucket_tags;
mod bench_bucket_tagging;
mod bench_bucket_versioning;
mod bench_list_bucket;
mod bench_object_append;
@ -27,7 +27,7 @@ mod bench_object_legal_hold;
mod bench_object_lock_config;
mod bench_object_put;
mod bench_object_retention;
mod bench_object_tags;
mod bench_object_tagging;
mod common_benches;
use criterion::{Criterion, criterion_group, criterion_main};
@ -40,7 +40,7 @@ use crate::bench_bucket_notification::*;
use crate::bench_bucket_policy::*;
#[allow(unused_imports)]
use crate::bench_bucket_replication::*;
use crate::bench_bucket_tags::*;
use crate::bench_bucket_tagging::*;
use crate::bench_bucket_versioning::*;
use crate::bench_list_bucket::*;
#[allow(unused_imports)]
@ -51,7 +51,7 @@ use crate::bench_object_legal_hold::*;
use crate::bench_object_lock_config::*;
use crate::bench_object_put::bench_object_put;
use crate::bench_object_retention::*;
use crate::bench_object_tags::*;
use crate::bench_object_tagging::*;
criterion_group!(
name = benches;
@ -63,27 +63,27 @@ criterion_group!(
.measurement_time(Duration::from_secs_f32(10.0));
targets =
bench_bucket_exists,
bench_set_bucket_lifecycle,
bench_put_bucket_lifecycle,
bench_get_bucket_lifecycle,
bench_delete_bucket_lifecycle,
//
//bench_set_bucket_notification, //A specified destination ARN does not exist or is not well-formed
//bench_put_bucket_notification, //A specified destination ARN does not exist or is not well-formed
//bench_get_bucket_notification,
//bench_delete_bucket_notification,
//
bench_set_bucket_policy,
bench_put_bucket_policy,
bench_get_bucket_policy,
bench_delete_bucket_policy,
//
//bench_set_bucket_replication, //TODO setup permissions to allow replication
//bench_put_bucket_replication, //TODO setup permissions to allow replication
//bench_get_bucket_replication,
//bench_delete_bucket_replication,
//
bench_set_bucket_tags,
bench_get_bucket_tags,
bench_delete_bucket_tags,
bench_put_bucket_tagging,
bench_get_bucket_tagging,
bench_delete_bucket_tagging,
//
bench_set_bucket_versioning,
bench_put_bucket_versioning,
bench_get_bucket_versioning,
//
bench_list_buckets,
@ -91,19 +91,18 @@ criterion_group!(
bench_object_append,
bench_object_put,
//
bench_enable_object_legal_hold,
bench_disable_object_legal_hold,
bench_is_object_legal_hold,
bench_put_object_legal_hold,
bench_get_object_legal_hold,
//
bench_set_object_lock_config,
bench_put_object_lock_config,
bench_get_object_lock_config,
bench_delete_object_lock_config,
//
bench_set_object_retention,
bench_put_object_retention,
bench_get_object_retention,
//
bench_set_object_tags,
bench_get_object_tags
bench_put_object_tagging,
bench_get_object_tagging
);
criterion_main!(benches);

View File

@ -16,18 +16,18 @@
use crate::common_benches::{Ctx2, benchmark_s3_api};
use criterion::Criterion;
use minio::s3::builders::{DeleteBucketLifecycle, GetBucketLifecycle, SetBucketLifecycle};
use minio::s3::builders::{DeleteBucketLifecycle, GetBucketLifecycle, PutBucketLifecycle};
use minio::s3::types::S3Api;
use minio_common::example::create_bucket_lifecycle_config_examples;
pub(crate) fn bench_set_bucket_lifecycle(criterion: &mut Criterion) {
pub(crate) fn bench_put_bucket_lifecycle(criterion: &mut Criterion) {
benchmark_s3_api(
"set_bucket_lifecycle",
"put_bucket_lifecycle",
criterion,
|| async { Ctx2::new().await },
|ctx| {
let config = create_bucket_lifecycle_config_examples();
SetBucketLifecycle::new(ctx.client.clone(), ctx.bucket.clone())
PutBucketLifecycle::new(ctx.client.clone(), ctx.bucket.clone())
.life_cycle_config(config)
},
)
@ -40,7 +40,7 @@ pub(crate) fn bench_get_bucket_lifecycle(criterion: &mut Criterion) {
let ctx = Ctx2::new().await;
let config = create_bucket_lifecycle_config_examples();
ctx.client
.set_bucket_lifecycle(&ctx.bucket)
.put_bucket_lifecycle(&ctx.bucket)
.life_cycle_config(config)
.send()
.await

View File

@ -16,19 +16,19 @@
use crate::common_benches::{Ctx2, benchmark_s3_api};
use criterion::Criterion;
use minio::s3::builders::{DeleteBucketNotification, GetBucketNotification, SetBucketNotification};
use minio::s3::builders::{DeleteBucketNotification, GetBucketNotification, PutBucketNotification};
use minio::s3::types::S3Api;
use minio_common::example::create_bucket_notification_config_example;
#[allow(dead_code)]
pub(crate) fn bench_set_bucket_notification(criterion: &mut Criterion) {
pub(crate) fn bench_put_bucket_notification(criterion: &mut Criterion) {
benchmark_s3_api(
"set_bucket_notification",
"put_bucket_notification",
criterion,
|| async { Ctx2::new().await },
|ctx| {
let config = create_bucket_notification_config_example();
SetBucketNotification::new(ctx.client.clone(), ctx.bucket.clone())
PutBucketNotification::new(ctx.client.clone(), ctx.bucket.clone())
.notification_config(config)
},
)
@ -42,7 +42,7 @@ pub(crate) fn bench_get_bucket_notification(criterion: &mut Criterion) {
let ctx = Ctx2::new().await;
let config = create_bucket_notification_config_example();
ctx.client
.set_bucket_notification(&ctx.bucket)
.put_bucket_notification(&ctx.bucket)
.notification_config(config)
.send()
.await

View File

@ -16,18 +16,18 @@
use crate::common_benches::{Ctx2, benchmark_s3_api};
use criterion::Criterion;
use minio::s3::builders::{DeleteBucketPolicy, GetBucketPolicy, SetBucketPolicy};
use minio::s3::builders::{DeleteBucketPolicy, GetBucketPolicy, PutBucketPolicy};
use minio::s3::types::S3Api;
use minio_common::example::create_bucket_policy_config_example;
pub(crate) fn bench_set_bucket_policy(criterion: &mut Criterion) {
pub(crate) fn bench_put_bucket_policy(criterion: &mut Criterion) {
benchmark_s3_api(
"set_bucket_policy",
"put_bucket_policy",
criterion,
|| async { Ctx2::new().await },
|ctx| {
let config = create_bucket_policy_config_example(&ctx.bucket);
SetBucketPolicy::new(ctx.client.clone(), ctx.bucket.clone()).config(config)
PutBucketPolicy::new(ctx.client.clone(), ctx.bucket.clone()).config(config)
},
)
}
@ -38,7 +38,7 @@ pub(crate) fn bench_get_bucket_policy(criterion: &mut Criterion) {
|| async {
let ctx = Ctx2::new().await;
let config = create_bucket_policy_config_example(&ctx.bucket);
SetBucketPolicy::new(ctx.client.clone(), ctx.bucket.clone())
PutBucketPolicy::new(ctx.client.clone(), ctx.bucket.clone())
.config(config)
.send()
.await

View File

@ -17,32 +17,32 @@ use crate::common_benches::{Ctx2, benchmark_s3_api};
use criterion::Criterion;
use minio::s3::builders::{
DeleteBucketReplication, GetBucketReplication, SetBucketReplication, VersioningStatus,
DeleteBucketReplication, GetBucketReplication, PutBucketReplication, VersioningStatus,
};
use minio::s3::response::SetBucketVersioningResponse;
use minio::s3::response::PutBucketVersioningResponse;
use minio::s3::types::S3Api;
use minio_common::example::create_bucket_replication_config_example;
#[allow(dead_code)]
pub(crate) fn bench_set_bucket_replication(criterion: &mut Criterion) {
pub(crate) fn bench_put_bucket_replication(criterion: &mut Criterion) {
benchmark_s3_api(
"set_bucket_replication",
"put_bucket_replication",
criterion,
|| async {
let mut ctx = Ctx2::new().await;
ctx.new_aux().await;
let _resp: SetBucketVersioningResponse = ctx
let _resp: PutBucketVersioningResponse = ctx
.client
.set_bucket_versioning(&ctx.bucket)
.put_bucket_versioning(&ctx.bucket)
.versioning_status(VersioningStatus::Enabled)
.send()
.await
.unwrap();
let _resp: SetBucketVersioningResponse = ctx
let _resp: PutBucketVersioningResponse = ctx
.client
.set_bucket_versioning(&ctx.aux_bucket.clone().unwrap())
.put_bucket_versioning(&ctx.aux_bucket.clone().unwrap())
.versioning_status(VersioningStatus::Enabled)
.send()
.await
@ -53,7 +53,7 @@ pub(crate) fn bench_set_bucket_replication(criterion: &mut Criterion) {
|ctx| {
let config =
create_bucket_replication_config_example(ctx.aux_bucket.clone().unwrap().as_str());
SetBucketReplication::new(ctx.client.clone(), ctx.bucket.clone())
PutBucketReplication::new(ctx.client.clone(), ctx.bucket.clone())
.replication_config(config)
},
)
@ -67,17 +67,17 @@ pub(crate) fn bench_get_bucket_replication(criterion: &mut Criterion) {
let mut ctx = Ctx2::new().await;
ctx.new_aux().await;
let _resp: SetBucketVersioningResponse = ctx
let _resp: PutBucketVersioningResponse = ctx
.client
.set_bucket_versioning(&ctx.bucket)
.put_bucket_versioning(&ctx.bucket)
.versioning_status(VersioningStatus::Enabled)
.send()
.await
.unwrap();
let _resp: SetBucketVersioningResponse = ctx
let _resp: PutBucketVersioningResponse = ctx
.client
.set_bucket_versioning(&ctx.aux_bucket.clone().unwrap())
.put_bucket_versioning(&ctx.aux_bucket.clone().unwrap())
.versioning_status(VersioningStatus::Enabled)
.send()
.await
@ -97,17 +97,17 @@ pub(crate) fn bench_delete_bucket_replication(criterion: &mut Criterion) {
let mut ctx = Ctx2::new().await;
ctx.new_aux().await;
let _resp: SetBucketVersioningResponse = ctx
let _resp: PutBucketVersioningResponse = ctx
.client
.set_bucket_versioning(&ctx.bucket)
.put_bucket_versioning(&ctx.bucket)
.versioning_status(VersioningStatus::Enabled)
.send()
.await
.unwrap();
let _resp: SetBucketVersioningResponse = ctx
let _resp: PutBucketVersioningResponse = ctx
.client
.set_bucket_versioning(&ctx.aux_bucket.clone().unwrap())
.put_bucket_versioning(&ctx.aux_bucket.clone().unwrap())
.versioning_status(VersioningStatus::Enabled)
.send()
.await

View File

@ -16,51 +16,52 @@
use crate::common_benches::{Ctx2, benchmark_s3_api, skip_express_mode};
use criterion::Criterion;
use minio::s3::builders::{DeleteBucketTags, GetBucketTags, SetBucketTags};
use minio::s3::builders::{DeleteBucketTagging, GetBucketTagging, PutBucketTagging};
use minio::s3::types::S3Api;
use minio_common::example::create_tags_example;
pub(crate) fn bench_set_bucket_tags(criterion: &mut Criterion) {
if skip_express_mode("bench_set_bucket_tags") {
pub(crate) fn bench_put_bucket_tagging(criterion: &mut Criterion) {
if skip_express_mode("bench_put_bucket_tagging") {
return;
}
benchmark_s3_api(
"set_bucket_tags",
"put_bucket_tagging",
criterion,
|| async { Ctx2::new().await },
|ctx| {
SetBucketTags::new(ctx.client.clone(), ctx.bucket.clone()).tags(create_tags_example())
PutBucketTagging::new(ctx.client.clone(), ctx.bucket.clone())
.tags(create_tags_example())
},
)
}
pub(crate) fn bench_get_bucket_tags(criterion: &mut Criterion) {
if skip_express_mode("bench_get_bucket_tags") {
pub(crate) fn bench_get_bucket_tagging(criterion: &mut Criterion) {
if skip_express_mode("bench_get_bucket_tagging") {
return;
}
benchmark_s3_api(
"get_bucket_tags",
"get_bucket_tagging",
criterion,
|| async {
let ctx = Ctx2::new().await;
ctx.client
.set_bucket_tags(&ctx.bucket)
.put_bucket_tagging(&ctx.bucket)
.tags(create_tags_example())
.send()
.await
.unwrap();
ctx
},
|ctx| GetBucketTags::new(ctx.client.clone(), ctx.bucket.clone()),
|ctx| GetBucketTagging::new(ctx.client.clone(), ctx.bucket.clone()),
)
}
pub(crate) fn bench_delete_bucket_tags(criterion: &mut Criterion) {
if skip_express_mode("bench_delete_bucket_tags") {
pub(crate) fn bench_delete_bucket_tagging(criterion: &mut Criterion) {
if skip_express_mode("bench_delete_bucket_tagging") {
return;
}
benchmark_s3_api(
"delete_bucket_tags",
"delete_bucket_tagging",
criterion,
|| async { Ctx2::new().await },
|ctx| DeleteBucketTags::new(ctx.client.clone(), ctx.bucket.clone()),
|ctx| DeleteBucketTagging::new(ctx.client.clone(), ctx.bucket.clone()),
)
}

View File

@ -16,7 +16,7 @@
use crate::common_benches::{Ctx2, benchmark_s3_api, skip_express_mode};
use criterion::Criterion;
use minio::s3::builders::{GetBucketVersioning, SetBucketVersioning, VersioningStatus};
use minio::s3::builders::{GetBucketVersioning, PutBucketVersioning, VersioningStatus};
pub(crate) fn bench_get_bucket_versioning(criterion: &mut Criterion) {
if skip_express_mode("bench_get_bucket_versioning") {
@ -29,16 +29,16 @@ pub(crate) fn bench_get_bucket_versioning(criterion: &mut Criterion) {
|ctx| GetBucketVersioning::new(ctx.client.clone(), ctx.bucket.clone()),
)
}
pub(crate) fn bench_set_bucket_versioning(criterion: &mut Criterion) {
if skip_express_mode("bench_set_bucket_versioning") {
pub(crate) fn bench_put_bucket_versioning(criterion: &mut Criterion) {
if skip_express_mode("bench_put_bucket_versioning") {
return;
}
benchmark_s3_api(
"set_bucket_versioning",
"put_bucket_versioning",
criterion,
|| async { Ctx2::new().await },
|ctx| {
SetBucketVersioning::new(ctx.client.clone(), ctx.bucket.clone())
PutBucketVersioning::new(ctx.client.clone(), ctx.bucket.clone())
.versioning_status(VersioningStatus::Enabled)
},
)

View File

@ -16,59 +16,39 @@
use crate::common_benches::{Ctx2, benchmark_s3_api, skip_express_mode};
use criterion::Criterion;
use minio::s3::builders::{
DisableObjectLegalHold, EnableObjectLegalHold, IsObjectLegalHoldEnabled,
};
use minio::s3::builders::{GetObjectLegalHold, PutObjectLegalHold};
use minio::s3::types::S3Api;
pub(crate) fn bench_enable_object_legal_hold(criterion: &mut Criterion) {
if skip_express_mode("bench_enable_object_legal_hold") {
pub(crate) fn bench_put_object_legal_hold(criterion: &mut Criterion) {
if skip_express_mode("bench_put_object_legal_hold") {
return;
}
benchmark_s3_api(
"enable_object_legal_hold",
"put_object_legal_hold",
criterion,
|| async { Ctx2::new_with_object(true).await },
|ctx| {
EnableObjectLegalHold::new(ctx.client.clone(), ctx.bucket.clone(), ctx.object.clone())
PutObjectLegalHold::new(ctx.client.clone(), ctx.bucket.clone(), ctx.object.clone())
.legal_hold(Some(true))
},
)
}
pub(crate) fn bench_disable_object_legal_hold(criterion: &mut Criterion) {
if skip_express_mode("bench_disable_object_legal_hold") {
pub(crate) fn bench_get_object_legal_hold(criterion: &mut Criterion) {
if skip_express_mode("bench_get_object_legal_hold") {
return;
}
benchmark_s3_api(
"disable_object_legal_hold",
criterion,
|| async { Ctx2::new_with_object(true).await },
|ctx| {
DisableObjectLegalHold::new(ctx.client.clone(), ctx.bucket.clone(), ctx.object.clone())
},
)
}
pub(crate) fn bench_is_object_legal_hold(criterion: &mut Criterion) {
if skip_express_mode("bench_is_object_legal_hold") {
return;
}
benchmark_s3_api(
"is_object_legal_hold",
"get_object_legal_hold",
criterion,
|| async {
let ctx = Ctx2::new_with_object(true).await;
ctx.client
.enable_object_legal_hold(&ctx.bucket, &ctx.object)
.get_object_legal_hold(&ctx.bucket, &ctx.object)
.send()
.await
.unwrap();
ctx
},
|ctx| {
IsObjectLegalHoldEnabled::new(
ctx.client.clone(),
ctx.bucket.clone(),
ctx.object.clone(),
)
},
|ctx| GetObjectLegalHold::new(ctx.client.clone(), ctx.bucket.clone(), ctx.object.clone()),
)
}

View File

@ -15,20 +15,20 @@
use crate::common_benches::{Ctx2, benchmark_s3_api, skip_express_mode};
use criterion::Criterion;
use minio::s3::builders::{DeleteObjectLockConfig, GetObjectLockConfig, SetObjectLockConfig};
use minio::s3::builders::{DeleteObjectLockConfig, GetObjectLockConfig, PutObjectLockConfig};
use minio_common::example::create_object_lock_config_example;
pub(crate) fn bench_set_object_lock_config(criterion: &mut Criterion) {
if skip_express_mode("bench_set_object_lock_config") {
pub(crate) fn bench_put_object_lock_config(criterion: &mut Criterion) {
if skip_express_mode("bench_put_object_lock_config") {
return;
}
benchmark_s3_api(
"set_object_lock_config",
"put_object_lock_config",
criterion,
|| async { Ctx2::new_with_object(true).await },
|ctx| {
let config = create_object_lock_config_example();
SetObjectLockConfig::new(ctx.client.clone(), ctx.bucket.clone()).config(config)
PutObjectLockConfig::new(ctx.client.clone(), ctx.bucket.clone()).config(config)
},
)
}

View File

@ -16,21 +16,21 @@
use crate::common_benches::{Ctx2, benchmark_s3_api, skip_express_mode};
use criterion::Criterion;
use minio::s3::builders::{GetObjectRetention, SetObjectRetention};
use minio::s3::response::SetObjectRetentionResponse;
use minio::s3::builders::{GetObjectRetention, PutObjectRetention};
use minio::s3::response::PutObjectRetentionResponse;
use minio::s3::types::{RetentionMode, S3Api};
use minio::s3::utils::utc_now;
pub(crate) fn bench_set_object_retention(criterion: &mut Criterion) {
if skip_express_mode("bench_set_object_retention") {
pub(crate) fn bench_put_object_retention(criterion: &mut Criterion) {
if skip_express_mode("bench_put_object_retention") {
return;
}
benchmark_s3_api(
"set_object_retention",
"put_object_retention",
criterion,
|| async { Ctx2::new_with_object(true).await },
|ctx| {
SetObjectRetention::new(ctx.client.clone(), ctx.bucket.clone(), ctx.object.clone())
PutObjectRetention::new(ctx.client.clone(), ctx.bucket.clone(), ctx.object.clone())
.retention_mode(Some(RetentionMode::GOVERNANCE))
.retain_until_date(Some(utc_now() + chrono::Duration::days(1)))
},
@ -45,8 +45,8 @@ pub(crate) fn bench_get_object_retention(criterion: &mut Criterion) {
criterion,
|| async {
let ctx = Ctx2::new_with_object(true).await;
let _resp: SetObjectRetentionResponse =
SetObjectRetention::new(ctx.client.clone(), ctx.bucket.clone(), ctx.object.clone())
let _resp: PutObjectRetentionResponse =
PutObjectRetention::new(ctx.client.clone(), ctx.bucket.clone(), ctx.object.clone())
.retention_mode(Some(RetentionMode::GOVERNANCE))
.retain_until_date(Some(utc_now() + chrono::Duration::days(1)))
.send()

View File

@ -16,44 +16,44 @@
use crate::common_benches::{Ctx2, benchmark_s3_api, skip_express_mode};
use criterion::Criterion;
use minio::s3::builders::{GetObjectTags, SetObjectTags};
use minio::s3::response::SetObjectTagsResponse;
use minio::s3::builders::{GetObjectTagging, PutObjectTagging};
use minio::s3::response::PutObjectTaggingResponse;
use minio::s3::types::S3Api;
use minio_common::example::create_tags_example;
pub(crate) fn bench_set_object_tags(criterion: &mut Criterion) {
if skip_express_mode("bench_set_object_tags") {
pub(crate) fn bench_put_object_tagging(criterion: &mut Criterion) {
if skip_express_mode("bench_put_object_tagging") {
return;
}
benchmark_s3_api(
"set_object_tags",
"put_object_tagging",
criterion,
|| async { Ctx2::new_with_object(false).await },
|ctx| {
SetObjectTags::new(ctx.client.clone(), ctx.bucket.clone(), ctx.object.clone())
PutObjectTagging::new(ctx.client.clone(), ctx.bucket.clone(), ctx.object.clone())
.tags(create_tags_example())
},
)
}
pub(crate) fn bench_get_object_tags(criterion: &mut Criterion) {
if skip_express_mode("bench_get_object_tags") {
pub(crate) fn bench_get_object_tagging(criterion: &mut Criterion) {
if skip_express_mode("bench_get_object_tagging") {
return;
}
benchmark_s3_api(
"get_object_tags",
"get_object_tagging",
criterion,
|| async {
let ctx = Ctx2::new_with_object(false).await;
let _resp: SetObjectTagsResponse = ctx
let _resp: PutObjectTaggingResponse = ctx
.client
.set_object_tags(&ctx.bucket, &ctx.object)
.put_object_tagging(&ctx.bucket, &ctx.object)
.tags(create_tags_example())
.send()
.await
.unwrap();
ctx
},
|ctx| GetObjectTags::new(ctx.client.clone(), ctx.bucket.clone(), ctx.object.clone()),
|ctx| GetObjectTagging::new(ctx.client.clone(), ctx.bucket.clone(), ctx.object.clone()),
)
}

View File

@ -16,7 +16,7 @@
use criterion::Criterion;
use minio::s3::Client;
use minio::s3::error::Error;
use minio::s3::response::{MakeBucketResponse, PutObjectContentResponse};
use minio::s3::response::{CreateBucketResponse, PutObjectContentResponse};
use minio::s3::types::{FromS3Response, S3Api, S3Request};
use minio_common::cleanup_guard::CleanupGuard;
use minio_common::test_context::TestContext;
@ -61,9 +61,9 @@ impl Ctx2 {
}
let ctx = TestContext::new_from_env();
let bucket_name: String = rand_bucket_name();
let _resp: MakeBucketResponse = ctx
let _resp: CreateBucketResponse = ctx
.client
.make_bucket(&bucket_name)
.create_bucket(&bucket_name)
.object_lock(object_lock)
.send()
.await
@ -92,9 +92,9 @@ impl Ctx2 {
let bucket_name: String = rand_bucket_name();
self.aux_bucket = Some(bucket_name.clone());
self._aux_cleanup = Some(CleanupGuard::new(self.client.clone(), &bucket_name));
let _resp: MakeBucketResponse = self
let _resp: CreateBucketResponse = self
.client
.make_bucket(&bucket_name)
.create_bucket(&bucket_name)
.object_lock(false)
.send()
.await

View File

@ -50,7 +50,7 @@ impl Drop for CleanupGuard {
// do the actual removal of the bucket
match timeout(
std::time::Duration::from_secs(60),
client.remove_and_purge_bucket(&bucket_name),
client.delete_and_purge_bucket(&bucket_name),
)
.await
{

View File

@ -151,7 +151,12 @@ impl TestContext {
/// ```
pub async fn create_bucket_helper(&self) -> (String, CleanupGuard) {
let bucket_name = rand_bucket_name();
let _resp = self.client.make_bucket(&bucket_name).send().await.unwrap();
let _resp = self
.client
.create_bucket(&bucket_name)
.send()
.await
.unwrap();
let guard = CleanupGuard::new(self.client.clone(), &bucket_name);
(bucket_name, guard)
}

View File

@ -17,7 +17,7 @@ mod common;
use crate::common::{create_bucket_if_not_exists, create_client_on_play};
use minio::s3::Client;
use minio::s3::response::{GetBucketEncryptionResponse, SetBucketEncryptionResponse};
use minio::s3::response::{GetBucketEncryptionResponse, PutBucketEncryptionResponse};
use minio::s3::types::{S3Api, SseConfig};
#[tokio::main]
@ -35,8 +35,8 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let config = SseConfig::default();
log::info!("going to set encryption config={:?}", config);
let _resp: SetBucketEncryptionResponse = client
.set_bucket_encryption(bucket_name)
let _resp: PutBucketEncryptionResponse = client
.put_bucket_encryption(bucket_name)
.sse_config(config.clone())
.send()
.await?;

View File

@ -18,7 +18,7 @@ mod common;
use crate::common::{create_bucket_if_not_exists, create_client_on_play};
use minio::s3::Client;
use minio::s3::response::{
DeleteBucketLifecycleResponse, GetBucketLifecycleResponse, SetBucketLifecycleResponse,
DeleteBucketLifecycleResponse, GetBucketLifecycleResponse, PutBucketLifecycleResponse,
};
use minio::s3::types::{Filter, LifecycleConfig, LifecycleRule, S3Api};
@ -57,8 +57,8 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
transition_storage_class: None,
}];
let resp: SetBucketLifecycleResponse = client
.set_bucket_lifecycle(bucket_name)
let resp: PutBucketLifecycleResponse = client
.put_bucket_lifecycle(bucket_name)
.life_cycle_config(LifecycleConfig { rules })
.send()
.await?;

View File

@ -18,7 +18,7 @@ mod common;
use crate::common::{create_bucket_if_not_exists, create_client_on_play};
use minio::s3::Client;
use minio::s3::builders::VersioningStatus;
use minio::s3::response::{GetBucketVersioningResponse, SetBucketVersioningResponse};
use minio::s3::response::{GetBucketVersioningResponse, PutBucketVersioningResponse};
use minio::s3::types::S3Api;
#[tokio::main]
@ -37,8 +37,8 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
resp.mfa_delete
);
let _resp: SetBucketVersioningResponse = client
.set_bucket_versioning(bucket_name)
let _resp: PutBucketVersioningResponse = client
.put_bucket_versioning(bucket_name)
.versioning_status(VersioningStatus::Enabled)
.send()
.await?;
@ -52,8 +52,8 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
resp.mfa_delete
);
let _resp: SetBucketVersioningResponse = client
.set_bucket_versioning(bucket_name)
let _resp: PutBucketVersioningResponse = client
.put_bucket_versioning(bucket_name)
.versioning_status(VersioningStatus::Suspended)
.send()
.await?;
@ -67,8 +67,8 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
resp.mfa_delete
);
let _resp: SetBucketVersioningResponse = client
.set_bucket_versioning(bucket_name)
let _resp: PutBucketVersioningResponse = client
.put_bucket_versioning(bucket_name)
//.versioning_status(VersioningStatus::Suspended)
.send()
.await?;

View File

@ -43,7 +43,7 @@ pub async fn create_bucket_if_not_exists(
// Make 'bucket_name' bucket if not exist.
if !resp.exists {
client.make_bucket(bucket_name).send().await.unwrap();
client.create_bucket(bucket_name).send().await.unwrap();
};
Ok(())
}

View File

@ -20,7 +20,7 @@ use minio::s3::builders::ObjectContent;
use minio::s3::client::ClientBuilder;
use minio::s3::creds::StaticProvider;
use minio::s3::http::BaseUrl;
use minio::s3::response::ObjectPromptResponse;
use minio::s3::response::GetObjectPromptResponse;
use minio::s3::types::S3Api;
use std::path::Path;
@ -66,8 +66,8 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
filename.display()
);
let resp: ObjectPromptResponse = client
.object_prompt(bucket_name, object_name, "what is it about?")
let resp: GetObjectPromptResponse = client
.get_object_prompt(bucket_name, object_name, "what is it about?")
//.lambda_arn("arn:minio:s3-object-lambda::_:webhook") // this is the default value
.send()
.await?;

View File

@ -48,7 +48,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let resp: BucketExistsResponse = client.bucket_exists(&args.bucket).send().await.unwrap();
if !resp.exists {
client.make_bucket(&args.bucket).send().await.unwrap();
client.create_bucket(&args.bucket).send().await.unwrap();
}
let content = ObjectContent::from(args.file.as_path());

4
rust-toolchain.toml Normal file
View File

@ -0,0 +1,4 @@
[toolchain]
channel = "1.86.0"
components = ["clippy", "rustfmt"]
#targets = ["x86_64-unknown-linux-musl"]

View File

@ -13,7 +13,48 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#![allow(clippy::tabs_in_doc_comments)]
//! # MinIO Rust SDK (`minio-rs`)
//!
//! 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`]),
//! 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
//! to execute the request and return a typed response.
//!
//! ## Basic Usage
//!
//! ```no_run
//! use minio::s3::Client;
//! use minio::s3::types::S3Api;
//! use minio::s3::response::BucketExistsResponse;
//!
//! #[tokio::main]
//! async fn main() {
//! let client: Client = Default::default(); // configure your client
//!
//! let exists: BucketExistsResponse = client
//! .bucket_exists("my-bucket")
//! .send()
//! .await
//! .expect("request failed");
//!
//! println!("Bucket exists: {}", exists.exists);
//! }
//! ```
//!
//! ## Features
//! - Request builder pattern for ergonomic API usage
//! - Full async/await support via [`tokio`]
//! - Strongly-typed responses
//! - Transparent error handling via `Result<T, Error>`
//!
//! ## Design
//! - Each API method on the [`Client`] returns a builder struct
//! - Builders implement [`ToS3Request`] for request conversion and [`S3Api`] for execution
//! - Responses implement [`FromS3Response`] for consistent deserialization
#![allow(clippy::result_large_err)]
#![allow(clippy::too_many_arguments)]
pub mod s3;

View File

@ -19,50 +19,49 @@ mod append_object;
mod bucket_common;
mod bucket_exists;
mod copy_object;
mod create_bucket;
mod delete_bucket;
mod delete_bucket_encryption;
mod delete_bucket_lifecycle;
mod delete_bucket_notification;
mod delete_bucket_policy;
mod delete_bucket_replication;
mod delete_bucket_tags;
mod delete_bucket_tagging;
mod delete_object_lock_config;
mod delete_object_tags;
mod disable_object_legal_hold;
mod enable_object_legal_hold;
mod delete_object_tagging;
mod delete_objects;
mod get_bucket_encryption;
mod get_bucket_lifecycle;
mod get_bucket_notification;
mod get_bucket_policy;
mod get_bucket_replication;
mod get_bucket_tags;
mod get_bucket_tagging;
mod get_bucket_versioning;
mod get_object;
mod get_object_legal_hold;
mod get_object_lock_config;
mod get_object_prompt;
mod get_object_retention;
mod get_object_tags;
mod get_object_tagging;
mod get_presigned_object_url;
mod get_presigned_policy_form_data;
mod get_region;
mod is_object_legal_hold_enabled;
mod list_bucket_notification;
mod list_buckets;
mod list_objects;
mod listen_bucket_notification;
mod make_bucket;
mod object_prompt;
mod put_bucket_encryption;
mod put_bucket_lifecycle;
mod put_bucket_notification;
mod put_bucket_policy;
mod put_bucket_replication;
mod put_bucket_tagging;
mod put_bucket_versioning;
mod put_object;
mod remove_bucket;
mod remove_objects;
mod put_object_legal_hold;
mod put_object_lock_config;
mod put_object_retention;
mod put_object_tagging;
mod select_object_content;
mod set_bucket_encryption;
mod set_bucket_lifecycle;
mod set_bucket_notification;
mod set_bucket_policy;
mod set_bucket_replication;
mod set_bucket_tags;
mod set_bucket_versioning;
mod set_object_lock_config;
mod set_object_retention;
mod set_object_tags;
mod stat_object;
pub use crate::s3::object_content::*;
@ -70,48 +69,47 @@ pub use append_object::*;
pub use bucket_common::*;
pub use bucket_exists::*;
pub use copy_object::*;
pub use create_bucket::*;
pub use delete_bucket::*;
pub use delete_bucket_encryption::*;
pub use delete_bucket_lifecycle::*;
pub use delete_bucket_notification::*;
pub use delete_bucket_policy::*;
pub use delete_bucket_replication::*;
pub use delete_bucket_tags::*;
pub use delete_bucket_tagging::*;
pub use delete_object_lock_config::*;
pub use delete_object_tags::*;
pub use disable_object_legal_hold::*;
pub use enable_object_legal_hold::*;
pub use delete_object_tagging::*;
pub use delete_objects::*;
pub use get_bucket_encryption::*;
pub use get_bucket_lifecycle::*;
pub use get_bucket_notification::*;
pub use get_bucket_policy::*;
pub use get_bucket_replication::*;
pub use get_bucket_tags::*;
pub use get_bucket_tagging::*;
pub use get_bucket_versioning::*;
pub use get_object::*;
pub use get_object_legal_hold::*;
pub use get_object_lock_config::*;
pub use get_object_prompt::*;
pub use get_object_retention::*;
pub use get_object_tags::*;
pub use get_object_tagging::*;
pub use get_presigned_object_url::*;
pub use get_presigned_policy_form_data::*;
pub use get_region::*;
pub use is_object_legal_hold_enabled::*;
pub use list_bucket_notification::*;
pub use list_buckets::*;
pub use list_objects::*;
pub use listen_bucket_notification::*;
pub use make_bucket::*;
pub use object_prompt::*;
pub use put_bucket_encryption::*;
pub use put_bucket_lifecycle::*;
pub use put_bucket_notification::*;
pub use put_bucket_policy::*;
pub use put_bucket_replication::*;
pub use put_bucket_tagging::*;
pub use put_bucket_versioning::*;
pub use put_object::*;
pub use remove_bucket::*;
pub use remove_objects::*;
pub use put_object_legal_hold::*;
pub use put_object_lock_config::*;
pub use put_object_retention::*;
pub use put_object_tagging::*;
pub use select_object_content::*;
pub use set_bucket_encryption::*;
pub use set_bucket_lifecycle::*;
pub use set_bucket_notification::*;
pub use set_bucket_policy::*;
pub use set_bucket_replication::*;
pub use set_bucket_tags::*;
pub use set_bucket_versioning::*;
pub use set_object_lock_config::*;
pub use set_object_retention::*;
pub use set_object_tags::*;
pub use stat_object::*;

View File

@ -28,7 +28,11 @@ use http::Method;
use std::sync::Arc;
// region: append-object
#[derive(Debug, Clone, Default)]
/// Argument builder for the [`AppendObject`](https://docs.aws.amazon.com/AmazonS3/latest/userguide/directory-buckets-objects-append.html) S3 API operation.
///
/// This struct constructs the parameters required for the [`Client::append_object`](crate::s3::client::Client::append_object) method.
#[derive(Clone, Debug, Default)]
pub struct AppendObject {
client: Client,
@ -107,9 +111,14 @@ impl ToS3Request for AppendObject {
// region: append-object-content
/// AppendObjectContent takes a `ObjectContent` stream and appends it to MinIO/S3.
/// Argument builder for the [`AppendObject`](https://docs.aws.amazon.com/AmazonS3/latest/userguide/directory-buckets-objects-append.html) S3 API operation.
///
/// It is a higher level API and handles multipart appends transparently.
/// This struct constructs the parameters required for the [`Client::append_object_content`](crate::s3::client::Client::append_object_content) method.
/// It is High-level API for appending content to an object using multipart uploads.
///
/// `AppendObjectContent` consumes an [`ObjectContent`] stream and transparently appends it to an existing object in MinIO or S3,
/// managing multipart upload details internally.
#[derive(Default)]
pub struct AppendObjectContent {
client: Client,
@ -284,12 +293,7 @@ impl AppendObjectContent {
part_number += 1;
let buffer_size = part_content.len() as u64;
assert!(
buffer_size <= part_size,
"{:?} <= {:?}",
buffer_size,
part_size
);
assert!(buffer_size <= part_size, "{buffer_size} <= {part_size}",);
if buffer_size == 0 && part_number > 1 {
// We are done as we appended at least 1 part and we have

View File

@ -18,7 +18,7 @@ use std::marker::PhantomData;
use crate::s3::client::Client;
use crate::s3::multimap::Multimap;
#[derive(Clone, Default)]
#[derive(Clone, Debug, Default)]
pub struct BucketCommon<A> {
pub(crate) client: Client,

View File

@ -20,10 +20,10 @@ use crate::s3::types::{S3Api, S3Request, ToS3Request};
use crate::s3::utils::check_bucket_name;
use http::Method;
/// Argument builder for [bucket_exists()](Client::bucket_exists) API
/// This struct constructs the parameters required for the [`Client::bucket_exists`](crate::s3::client::Client::bucket_exists) method.
pub type BucketExists = BucketCommon<BucketExistsPhantomData>;
#[derive(Default, Debug)]
#[derive(Clone, Debug, Default)]
pub struct BucketExistsPhantomData;
impl S3Api for BucketExists {

View File

@ -31,7 +31,9 @@ use http::Method;
use std::collections::HashMap;
use std::sync::Arc;
/// Argument builder for [UploadPartCopy](https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPartCopy.html) API
/// Argument builder for the [`UploadPartCopy`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPartCopy.html) S3 API operation.
///
/// This struct constructs the parameters required for the [`Client::upload_part_copy`](crate::s3::client::Client::upload_part_copy) method.
#[derive(Clone, Debug, Default)]
pub struct UploadPartCopy {
client: Client,
@ -98,8 +100,7 @@ impl ToS3Request for UploadPartCopy {
}
if !(1..=MAX_MULTIPART_COUNT).contains(&self.part_number) {
return Err(Error::InvalidPartNumber(format!(
"part number must be between 1 and {}",
MAX_MULTIPART_COUNT
"part number must be between 1 and {MAX_MULTIPART_COUNT}"
)));
}
}
@ -325,7 +326,7 @@ impl ToS3Request for CopyObjectInternal {
}
}
/// Argument builder for [copy_object()](Client::copy_object_old) API
/// Argument builder for [copy_object()](Client::copy_object) API
#[derive(Clone, Debug, Default)]
pub struct CopyObject {
client: Client,
@ -409,9 +410,7 @@ impl CopyObject {
self.tagging_directive = tagging_directive;
self
}
}
impl CopyObject {
pub async fn send(self) -> Result<CopyObjectResponse, Error> {
{
if let Some(v) = &self.sse {
@ -612,9 +611,7 @@ impl ComposeObjectInternal {
self.sources = sources;
self
}
}
impl ComposeObjectInternal {
#[async_recursion]
pub async fn send(self) -> (Result<ComposeObjectResponse, Error>, String) {
let mut upload_id = String::new();
@ -754,7 +751,7 @@ impl ComposeObjectInternal {
let mut headers_copy = headers.clone();
headers_copy.add(
"x-amz-copy-source-range",
format!("bytes={}-{}", offset, end_bytes),
format!("bytes={offset}-{end_bytes}"),
);
let resp: UploadPartCopyResponse = match self
@ -885,9 +882,7 @@ impl ComposeObject {
self.sources = sources;
self
}
}
impl ComposeObject {
pub async fn send(self) -> Result<ComposeObjectResponse, Error> {
{
if let Some(v) = &self.sse {
@ -934,7 +929,7 @@ impl ComposeObject {
// region: misc
#[derive(Clone, Debug, Default)]
/// Source object information for [compose object argument](ComposeObjectArgs)
/// Source object information for [compose_object](Client::compose_object)
pub struct ComposeSource {
pub extra_headers: Option<Multimap>,
pub extra_query_params: Option<Multimap>,
@ -963,35 +958,23 @@ impl ComposeSource {
/// use minio::s3::builders::ComposeSource;
/// let src = ComposeSource::new("my-src-bucket", "my-src-object").unwrap();
/// ```
pub fn new(bucket_name: &str, object_name: &str) -> Result<ComposeSource, Error> {
pub fn new(bucket_name: &str, object_name: &str) -> Result<Self, Error> {
check_bucket_name(bucket_name, true)?;
check_object_name(object_name)?;
Ok(ComposeSource {
extra_headers: None,
extra_query_params: None,
region: None,
Ok(Self {
bucket: bucket_name.to_owned(),
object: object_name.to_owned(),
version_id: None,
ssec: None,
offset: None,
length: None,
match_etag: None,
not_match_etag: None,
modified_since: None,
unmodified_since: None,
object_size: None,
headers: None,
..Default::default()
})
}
pub fn get_object_size(&self) -> u64 {
self.object_size.expect("A: ABORT: ComposeSource::build_headers() must be called prior to this method invocation. This shoud not happen.")
self.object_size.expect("A: ABORT: ComposeSource::build_headers() must be called prior to this method invocation. This should not happen.")
}
pub fn get_headers(&self) -> Multimap {
self.headers.as_ref().expect("B: ABORT: ComposeSource::build_headers() must be called prior to this method invocation. This shoud not happen.").clone()
self.headers.as_ref().expect("B: ABORT: ComposeSource::build_headers() must be called prior to this method invocation. This should not happen.").clone()
}
pub fn build_headers(&mut self, object_size: u64, etag: String) -> Result<(), Error> {
@ -1098,24 +1081,14 @@ pub struct CopySource {
}
impl CopySource {
pub fn new(bucket_name: &str, object_name: &str) -> Result<CopySource, Error> {
pub fn new(bucket_name: &str, object_name: &str) -> Result<Self, Error> {
check_bucket_name(bucket_name, true)?;
check_object_name(object_name)?;
Ok(CopySource {
extra_headers: None,
extra_query_params: None,
region: None,
Ok(Self {
bucket: bucket_name.to_owned(),
object: object_name.to_owned(),
version_id: None,
ssec: None,
offset: None,
length: None,
match_etag: None,
not_match_etag: None,
modified_since: None,
unmodified_since: None,
..Default::default()
})
}
@ -1178,20 +1151,20 @@ fn into_headers_copy_object(
}
if !tagging.is_empty() {
map.insert("x-amz-tagging".into(), tagging);
map.add("x-amz-tagging", tagging);
}
}
if let Some(v) = retention {
map.insert("x-amz-object-lock-mode".into(), v.mode.to_string());
map.insert(
"x-amz-object-lock-retain-until-date".into(),
map.add("x-amz-object-lock-mode", v.mode.to_string());
map.add(
"x-amz-object-lock-retain-until-date",
to_iso8601utc(v.retain_until_date),
);
}
if legal_hold {
map.insert("x-amz-object-lock-legal-hold".into(), "ON".into());
map.add("x-amz-object-lock-legal-hold", "ON");
}
map

View File

@ -17,15 +17,17 @@ use crate::s3::Client;
use crate::s3::client::DEFAULT_REGION;
use crate::s3::error::Error;
use crate::s3::multimap::{Multimap, MultimapExt};
use crate::s3::response::MakeBucketResponse;
use crate::s3::response::CreateBucketResponse;
use crate::s3::segmented_bytes::SegmentedBytes;
use crate::s3::types::{S3Api, S3Request, ToS3Request};
use crate::s3::utils::check_bucket_name;
use http::Method;
/// Argument builder for [make_bucket()](Client::make_bucket) API
/// Argument builder for the [`CreateBucket`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucket.html) S3 API operation.
///
/// This struct constructs the parameters required for the [`Client::create_bucket`](crate::s3::client::Client::create_bucket) method.
#[derive(Clone, Debug, Default)]
pub struct MakeBucket {
pub struct CreateBucket {
client: Client,
extra_headers: Option<Multimap>,
@ -36,7 +38,7 @@ pub struct MakeBucket {
object_lock: bool,
}
impl MakeBucket {
impl CreateBucket {
pub fn new(client: Client, bucket: String) -> Self {
Self {
client,
@ -66,11 +68,11 @@ impl MakeBucket {
}
}
impl S3Api for MakeBucket {
type S3Response = MakeBucketResponse;
impl S3Api for CreateBucket {
type S3Response = CreateBucketResponse;
}
impl ToS3Request for MakeBucket {
impl ToS3Request for CreateBucket {
fn to_s3request(self) -> Result<S3Request, Error> {
check_bucket_name(&self.bucket, true)?;
@ -95,8 +97,7 @@ impl ToS3Request for MakeBucket {
let data: String = match region_str.as_str() {
DEFAULT_REGION => String::new(),
_ => format!(
"<CreateBucketConfiguration><LocationConstraint>{}</LocationConstraint></CreateBucketConfiguration>",
region_str
"<CreateBucketConfiguration><LocationConstraint>{region_str}</LocationConstraint></CreateBucketConfiguration>",
),
};

View File

@ -15,22 +15,24 @@
use crate::s3::builders::BucketCommon;
use crate::s3::error::Error;
use crate::s3::response::RemoveBucketResponse;
use crate::s3::response::DeleteBucketResponse;
use crate::s3::types::{S3Api, S3Request, ToS3Request};
use crate::s3::utils::check_bucket_name;
use http::Method;
/// Argument builder for [remove_bucket()](Client::remove_bucket) API
pub type RemoveBucket = BucketCommon<RemoveBucketPhantomData>;
/// Argument builder for the [`GetBucketEncryption`](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.
pub type DeleteBucket = BucketCommon<DeleteBucketPhantomData>;
#[derive(Default, Debug)]
pub struct RemoveBucketPhantomData;
#[derive(Clone, Debug, Default)]
pub struct DeleteBucketPhantomData;
impl S3Api for RemoveBucket {
type S3Response = RemoveBucketResponse;
impl S3Api for DeleteBucket {
type S3Response = DeleteBucketResponse;
}
impl ToS3Request for RemoveBucket {
impl ToS3Request for DeleteBucket {
fn to_s3request(self) -> Result<S3Request, Error> {
check_bucket_name(&self.bucket, true)?;

View File

@ -20,10 +20,12 @@ use crate::s3::types::{S3Api, S3Request, ToS3Request};
use crate::s3::utils::{check_bucket_name, insert};
use http::Method;
/// Argument builder for [delete_bucket_encryption()](Client::delete_bucket_encryption) API
/// Argument builder for the [`DeleteBucketEncryption`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketEncryption.html) S3 API operation.
///
/// 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>;
#[derive(Default, Debug)]
#[derive(Clone, Debug, Default)]
pub struct DeleteBucketEncryptionPhantomData;
impl S3Api for DeleteBucketEncryption {

View File

@ -20,10 +20,12 @@ use crate::s3::types::{S3Api, S3Request, ToS3Request};
use crate::s3::utils::{check_bucket_name, insert};
use http::Method;
/// Argument builder for [delete_bucket_lifecycle()](Client::delete_bucket_lifecycle) API
/// Argument builder for the [`DeleteBucketLifecycle`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketLifecycle.html) S3 API operation.
///
/// 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>;
#[derive(Default, Debug)]
#[derive(Clone, Debug, Default)]
pub struct DeleteBucketLifecyclePhantomData;
impl S3Api for DeleteBucketLifecycle {

View File

@ -22,10 +22,10 @@ use crate::s3::utils::{check_bucket_name, insert};
use bytes::Bytes;
use http::Method;
/// Argument builder for [delete_bucket_notification()](Client::delete_bucket_notification) API
/// This struct constructs the parameters required for the [`Client::delete_bucket_notification`](crate::s3::client::Client::delete_bucket_notification) method.
pub type DeleteBucketNotification = BucketCommon<DeleteBucketNotificationPhantomData>;
#[derive(Default, Debug)]
#[derive(Clone, Debug, Default)]
pub struct DeleteBucketNotificationPhantomData;
impl S3Api for DeleteBucketNotification {

View File

@ -20,10 +20,12 @@ use crate::s3::types::{S3Api, S3Request, ToS3Request};
use crate::s3::utils::{check_bucket_name, insert};
use http::Method;
/// Argument builder for [delete_bucket_policy()](Client::delete_bucket_policy) API
/// Argument builder for the [`DeleteBucketPolicy`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketPolicy.html) S3 API operation.
///
/// 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>;
#[derive(Default, Debug)]
#[derive(Clone, Debug, Default)]
pub struct DeleteBucketPolicyPhantomData;
impl S3Api for DeleteBucketPolicy {

View File

@ -20,10 +20,12 @@ use crate::s3::types::{S3Api, S3Request, ToS3Request};
use crate::s3::utils::{check_bucket_name, insert};
use http::Method;
/// Argument builder for [delete_bucket_replication()](Client::delete_bucket_replication) API
/// Argument builder for the [`DeleteBucketReplication`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketReplication.html) S3 API operation.
///
/// 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>;
#[derive(Default, Debug)]
#[derive(Clone, Debug, Default)]
pub struct DeleteBucketReplicationPhantomData;
impl S3Api for DeleteBucketReplication {

View File

@ -15,22 +15,24 @@
use crate::s3::builders::BucketCommon;
use crate::s3::error::Error;
use crate::s3::response::DeleteBucketTagsResponse;
use crate::s3::response::DeleteBucketTaggingResponse;
use crate::s3::types::{S3Api, S3Request, ToS3Request};
use crate::s3::utils::{check_bucket_name, insert};
use http::Method;
/// Argument builder for [delete_bucket_tags()](Client::delete_bucket_tags) API
pub type DeleteBucketTags = BucketCommon<DeleteBucketTagsPhantomData>;
/// Argument builder for the [`DeleteBucketTagging`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketTagging.html) S3 API operation.
///
/// 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>;
#[derive(Default, Debug)]
pub struct DeleteBucketTagsPhantomData;
#[derive(Clone, Debug, Default)]
pub struct DeleteBucketTaggingPhantomData;
impl S3Api for DeleteBucketTags {
type S3Response = DeleteBucketTagsResponse;
impl S3Api for DeleteBucketTagging {
type S3Response = DeleteBucketTaggingResponse;
}
impl ToS3Request for DeleteBucketTags {
impl ToS3Request for DeleteBucketTagging {
fn to_s3request(self) -> Result<S3Request, Error> {
check_bucket_name(&self.bucket, true)?;

View File

@ -22,10 +22,10 @@ use crate::s3::utils::{check_bucket_name, insert};
use bytes::Bytes;
use http::Method;
/// Argument builder for [delete_object_lock_config()](Client::delete_object_lock_config) API
/// 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>;
#[derive(Default, Debug)]
#[derive(Clone, Debug, Default)]
pub struct DeleteObjectLockConfigPhantomData;
impl S3Api for DeleteObjectLockConfig {

View File

@ -16,14 +16,16 @@
use crate::s3::Client;
use crate::s3::error::Error;
use crate::s3::multimap::{Multimap, MultimapExt};
use crate::s3::response::DeleteObjectTagsResponse;
use crate::s3::response::DeleteObjectTaggingResponse;
use crate::s3::types::{S3Api, S3Request, ToS3Request};
use crate::s3::utils::{check_bucket_name, check_object_name, insert};
use http::Method;
/// Argument builder for [delete_object_tags()](Client::delete_object_tags) API
/// Argument builder for the [`DeleteObjectTagging`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObjectTagging.html) S3 API operation.
///
/// This struct constructs the parameters required for the [`Client::delete_object_tags`](crate::s3::client::Client::delete_object_tagging) method.
#[derive(Clone, Debug, Default)]
pub struct DeleteObjectTags {
pub struct DeleteObjectTagging {
client: Client,
extra_headers: Option<Multimap>,
@ -35,7 +37,7 @@ pub struct DeleteObjectTags {
version_id: Option<String>,
}
impl DeleteObjectTags {
impl DeleteObjectTagging {
pub fn new(client: Client, bucket: String, object: String) -> Self {
Self {
client,
@ -66,11 +68,11 @@ impl DeleteObjectTags {
}
}
impl S3Api for DeleteObjectTags {
type S3Response = DeleteObjectTagsResponse;
impl S3Api for DeleteObjectTagging {
type S3Response = DeleteObjectTaggingResponse;
}
impl ToS3Request for DeleteObjectTags {
impl ToS3Request for DeleteObjectTagging {
fn to_s3request(self) -> Result<S3Request, Error> {
check_bucket_name(&self.bucket, true)?;
check_object_name(&self.object)?;

View File

@ -1,5 +1,5 @@
// MinIO Rust Library for Amazon S3 Compatible Cloud Storage
// Copyright 2022-2024 MinIO, Inc.
// Copyright 2025 MinIO, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@ -273,7 +273,11 @@ impl ToS3Request for RemoveObjectsApi {
// endregion: remove-object-api
// region: delete-object
// region: delete-objects
/// Argument builder for the [`DeleteObjects`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObjects.html) S3 API operation.
///
/// 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>>,
}
@ -299,7 +303,7 @@ where
}
}
// endregion: delete-object
// endregion: delete-objects
// region: remove-objects

View File

@ -1,92 +0,0 @@
// MinIO Rust Library for Amazon S3 Compatible Cloud Storage
// Copyright 2025 MinIO, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use crate::s3::Client;
use crate::s3::error::Error;
use crate::s3::multimap::{Multimap, MultimapExt};
use crate::s3::response::DisableObjectLegalHoldResponse;
use crate::s3::segmented_bytes::SegmentedBytes;
use crate::s3::types::{S3Api, S3Request, ToS3Request};
use crate::s3::utils::{check_bucket_name, check_object_name, insert, md5sum_hash};
use bytes::Bytes;
use http::Method;
/// Argument builder for [disable_object_legal_hold()](Client::disable_object_legal_hold) API
#[derive(Clone, Debug, Default)]
pub struct DisableObjectLegalHold {
client: Client,
extra_headers: Option<Multimap>,
extra_query_params: Option<Multimap>,
region: Option<String>,
bucket: String,
object: String,
version_id: Option<String>,
}
impl DisableObjectLegalHold {
pub fn new(client: Client, bucket: String, object: String) -> Self {
Self {
client,
bucket,
object,
..Default::default()
}
}
pub fn extra_headers(mut self, extra_headers: Option<Multimap>) -> Self {
self.extra_headers = extra_headers;
self
}
pub fn extra_query_params(mut self, extra_query_params: Option<Multimap>) -> Self {
self.extra_query_params = extra_query_params;
self
}
pub fn version_id(mut self, version_id: Option<String>) -> Self {
self.version_id = version_id;
self
}
}
impl S3Api for DisableObjectLegalHold {
type S3Response = DisableObjectLegalHoldResponse;
}
impl ToS3Request for DisableObjectLegalHold {
fn to_s3request(self) -> Result<S3Request, Error> {
check_bucket_name(&self.bucket, true)?;
check_object_name(&self.object)?;
let mut headers: Multimap = self.extra_headers.unwrap_or_default();
let mut query_params: Multimap = insert(self.extra_query_params, "legal-hold");
query_params.add_version(self.version_id);
const PAYLOAD: &str = "<LegalHold><Status>OFF</Status></LegalHold>";
headers.add("Content-MD5", md5sum_hash(PAYLOAD.as_ref()));
let body: Option<SegmentedBytes> = Some(SegmentedBytes::from(Bytes::from(PAYLOAD)));
//TODO consider const body
Ok(S3Request::new(self.client, Method::PUT)
.region(self.region)
.bucket(Some(self.bucket))
.query_params(query_params)
.headers(headers)
.object(Some(self.object))
.body(body))
}
}

View File

@ -20,10 +20,12 @@ use crate::s3::types::{S3Api, S3Request, ToS3Request};
use crate::s3::utils::{check_bucket_name, insert};
use http::Method;
/// Argument builder for [get_bucket_encryption()](crate::s3::client::Client::get_bucket_encryption) API
/// Argument builder for the [`GetBucketEncryption`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketEncryption.html) S3 API operation.
///
/// 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>;
#[derive(Default, Debug)]
#[derive(Clone, Debug, Default)]
pub struct GetBucketEncryptionPhantomData;
impl S3Api for GetBucketEncryption {

View File

@ -20,10 +20,12 @@ use crate::s3::types::{S3Api, S3Request, ToS3Request};
use crate::s3::utils::{check_bucket_name, insert};
use http::Method;
/// Argument builder for [get_bucket_lifecycle()](Client::get_bucket_lifecycle) API
/// Argument builder for the [`GetBucketLifecycle`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketLifecycle.html) S3 API operation.
///
/// This struct constructs the parameters required for the [`Client::get_bucket_lifecycle`](crate::s3::client::Client::get_bucket_lifecycle) method.
pub type GetBucketLifecycle = BucketCommon<GetBucketLifecyclePhantomData>;
#[derive(Default, Debug)]
#[derive(Clone, Debug, Default)]
pub struct GetBucketLifecyclePhantomData;
impl S3Api for GetBucketLifecycle {

View File

@ -20,7 +20,9 @@ use crate::s3::types::{S3Api, S3Request, ToS3Request};
use crate::s3::utils::{check_bucket_name, insert};
use http::Method;
/// Argument builder for [get_bucket_notification()](Client::get_bucket_notification) API
/// Argument builder for the [`GetBucketNotification`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketNotification.html) S3 API operation.
///
/// 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>;
#[derive(Default, Debug)]

View File

@ -20,10 +20,12 @@ use crate::s3::types::{S3Api, S3Request, ToS3Request};
use crate::s3::utils::{check_bucket_name, insert};
use http::Method;
/// Argument builder for [get_bucket_policy()](Client::get_bucket_policy) API
/// Argument builder for the [`GetBucketPolicy`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketPolicy.html) S3 API operation.
///
/// 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>;
#[derive(Default, Debug)]
#[derive(Clone, Debug, Default)]
pub struct GetBucketPolicyPhantomData;
impl S3Api for GetBucketPolicy {

View File

@ -20,10 +20,12 @@ use crate::s3::types::{S3Api, S3Request, ToS3Request};
use crate::s3::utils::{check_bucket_name, insert};
use http::Method;
/// Argument builder for [get_bucket_replication()](Client::get_bucket_replication) API
/// Argument builder for the [`GetBucketReplication`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketReplication.html) S3 API operation.
///
/// 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>;
#[derive(Default, Debug)]
#[derive(Clone, Debug, Default)]
pub struct GetBucketReplicationPhantomData;
impl S3Api for GetBucketReplication {

View File

@ -16,15 +16,17 @@
use crate::s3::Client;
use crate::s3::error::Error;
use crate::s3::multimap::Multimap;
use crate::s3::response::GetBucketTagsResponse;
use crate::s3::response::GetBucketTaggingResponse;
use crate::s3::types::{S3Api, S3Request, ToS3Request};
use crate::s3::utils::{check_bucket_name, insert};
use http::Method;
use std::collections::HashMap;
/// Argument builder for [get_bucket_tags()](crate::s3::client::Client::get_bucket_tags) API
/// Argument builder for the [`GetBucketTagging`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketTagging.html) S3 API operation.
///
/// This struct constructs the parameters required for the [`Client::get_bucket_tagging`](crate::s3::client::Client::get_bucket_tagging) method.
#[derive(Clone, Debug, Default)]
pub struct GetBucketTags {
pub struct GetBucketTagging {
client: Client,
extra_headers: Option<Multimap>,
@ -35,7 +37,7 @@ pub struct GetBucketTags {
tags: HashMap<String, String>,
}
impl GetBucketTags {
impl GetBucketTagging {
pub fn new(client: Client, bucket: String) -> Self {
Self {
client,
@ -65,11 +67,11 @@ impl GetBucketTags {
}
}
impl S3Api for GetBucketTags {
type S3Response = GetBucketTagsResponse;
impl S3Api for GetBucketTagging {
type S3Response = GetBucketTaggingResponse;
}
impl ToS3Request for GetBucketTags {
impl ToS3Request for GetBucketTagging {
fn to_s3request(self) -> Result<S3Request, Error> {
check_bucket_name(&self.bucket, true)?;

View File

@ -20,10 +20,12 @@ use crate::s3::types::{S3Api, S3Request, ToS3Request};
use crate::s3::utils::{check_bucket_name, insert};
use http::Method;
/// Argument builder for [get_bucket_versioning()](crate::s3::client::Client::get_bucket_versioning) API
/// Argument builder for the [`GetBucketVersioning`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketVersioning.html) S3 API operation.
///
/// 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>;
#[derive(Default, Debug)]
#[derive(Clone, Debug, Default)]
pub struct GetBucketVersioningPhantomData;
impl S3Api for GetBucketVersioning {

View File

@ -26,7 +26,9 @@ use crate::s3::{
utils::{UtcTime, check_bucket_name, to_http_header_value},
};
/// Argument builder for [list_objects()](Client::get_object) API.
/// Argument builder for the [`GetObject`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html) S3 API operation.
///
/// This struct constructs the parameters required for the [`Client::get_object`](crate::s3::client::Client::get_object) method.
#[derive(Debug, Clone, Default)]
pub struct GetObject {
client: Client,

View File

@ -16,14 +16,16 @@
use crate::s3::Client;
use crate::s3::error::Error;
use crate::s3::multimap::{Multimap, MultimapExt};
use crate::s3::response::IsObjectLegalHoldEnabledResponse;
use crate::s3::response::GetObjectLegalHoldResponse;
use crate::s3::types::{S3Api, S3Request, ToS3Request};
use crate::s3::utils::{check_bucket_name, check_object_name, insert};
use http::Method;
/// Argument builder for [is_object_legal_hold_enabled()](Client::is_object_legal_hold_enabled) API
/// Argument builder for the [`GetObjectLegalHold`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectLegalHold.html) S3 API operation.
///
/// This struct constructs the parameters required for the [`Client::get_object_legal_hold`](crate::s3::client::Client::get_object_legal_hold) method.
#[derive(Clone, Debug, Default)]
pub struct IsObjectLegalHoldEnabled {
pub struct GetObjectLegalHold {
client: Client,
extra_headers: Option<Multimap>,
@ -35,7 +37,7 @@ pub struct IsObjectLegalHoldEnabled {
version_id: Option<String>,
}
impl IsObjectLegalHoldEnabled {
impl GetObjectLegalHold {
pub fn new(client: Client, bucket: String, object: String) -> Self {
Self {
client,
@ -61,11 +63,11 @@ impl IsObjectLegalHoldEnabled {
}
}
impl S3Api for IsObjectLegalHoldEnabled {
type S3Response = IsObjectLegalHoldEnabledResponse;
impl S3Api for GetObjectLegalHold {
type S3Response = GetObjectLegalHoldResponse;
}
impl ToS3Request for IsObjectLegalHoldEnabled {
impl ToS3Request for GetObjectLegalHold {
fn to_s3request(self) -> Result<S3Request, Error> {
check_bucket_name(&self.bucket, true)?;
check_object_name(&self.object)?;

View File

@ -20,10 +20,12 @@ use crate::s3::types::{S3Api, S3Request, ToS3Request};
use crate::s3::utils::{check_bucket_name, insert};
use http::Method;
/// Argument builder for [get_object_lock_config()](Client::get_object_lock_config) API
/// Argument builder for the [`GetObjectLockConfig`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectLockConfiguration.html) S3 API operation.
///
/// 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>;
#[derive(Default, Debug)]
#[derive(Clone, Debug, Default)]
pub struct GetObjectLockConfigPhantomData;
impl S3Api for GetObjectLockConfig {

View File

@ -20,7 +20,7 @@ use crate::s3::utils::{check_bucket_name, check_object_name};
use crate::s3::{
client::Client,
error::Error,
response::ObjectPromptResponse,
response::GetObjectPromptResponse,
types::{S3Api, S3Request, ToS3Request},
};
use bytes::Bytes;
@ -28,7 +28,7 @@ use http::Method;
use serde_json::json;
#[derive(Debug, Clone, Default)]
pub struct ObjectPrompt {
pub struct GetObjectPrompt {
client: Client,
bucket: String,
object: String,
@ -43,9 +43,9 @@ pub struct ObjectPrompt {
}
// builder interface
impl ObjectPrompt {
impl GetObjectPrompt {
pub fn new(client: Client, bucket: String, object: String, prompt: String) -> Self {
ObjectPrompt {
GetObjectPrompt {
client,
bucket,
object,
@ -85,11 +85,11 @@ impl ObjectPrompt {
}
}
impl S3Api for ObjectPrompt {
type S3Response = ObjectPromptResponse;
impl S3Api for GetObjectPrompt {
type S3Response = GetObjectPromptResponse;
}
impl ToS3Request for ObjectPrompt {
impl ToS3Request for GetObjectPrompt {
fn to_s3request(self) -> Result<S3Request, Error> {
{
check_bucket_name(&self.bucket, true)?;

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 http::Method;
/// Argument builder for [get_object_retention()](Client::get_object_retention) API
/// Argument builder for the [`GetObjectRetention`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectRetention.html) S3 API operation.
///
/// This struct constructs the parameters required for the [`Client::get_object_retention`](crate::s3::client::Client::get_object_retention) method.
#[derive(Clone, Debug, Default)]
pub struct GetObjectRetention {
client: Client,

View File

@ -16,14 +16,14 @@
use crate::s3::Client;
use crate::s3::error::Error;
use crate::s3::multimap::{Multimap, MultimapExt};
use crate::s3::response::GetObjectTagsResponse;
use crate::s3::response::GetObjectTaggingResponse;
use crate::s3::types::{S3Api, S3Request, ToS3Request};
use crate::s3::utils::{check_bucket_name, check_object_name, insert};
use http::Method;
/// Argument builder for [get_object_tags()](Client::get_object_tags) API
/// Argument builder for [get_object_tags()](crate::s3::client::Client::get_object_tagging) API
#[derive(Clone, Debug, Default)]
pub struct GetObjectTags {
pub struct GetObjectTagging {
client: Client,
extra_headers: Option<Multimap>,
@ -35,7 +35,7 @@ pub struct GetObjectTags {
version_id: Option<String>,
}
impl GetObjectTags {
impl GetObjectTagging {
pub fn new(client: Client, bucket: String, object: String) -> Self {
Self {
client,
@ -66,11 +66,11 @@ impl GetObjectTags {
}
}
impl S3Api for GetObjectTags {
type S3Response = GetObjectTagsResponse;
impl S3Api for GetObjectTagging {
type S3Response = GetObjectTaggingResponse;
}
impl ToS3Request for GetObjectTags {
impl ToS3Request for GetObjectTagging {
fn to_s3request(self) -> Result<S3Request, Error> {
check_bucket_name(&self.bucket, true)?;
check_object_name(&self.object)?;

View File

@ -23,7 +23,7 @@ use crate::s3::signer::presign_v4;
use crate::s3::utils::{UtcTime, check_bucket_name, check_object_name, utc_now};
use http::Method;
/// Argument for [get_presigned_object_url()](crate::s3::client::Client::get_presigned_object_url) API
/// 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)]
pub struct GetPresignedObjectUrl {
client: Client,

View File

@ -23,7 +23,7 @@ use crate::s3::utils::{
use serde_json::{Value, json};
use std::collections::HashMap;
/// Argument for [get_presigned_object_url()](crate::s3::client::Client::get_presigned_object_url) API
/// This struct constructs the parameters required for the [`Client::get_presigned_object_url`](crate::s3::client::Client::get_presigned_object_url) method.
pub struct GetPresignedPolicyFormData {
client: Client,
policy: PostPolicy,
@ -54,6 +54,7 @@ impl GetPresignedPolicyFormData {
///
/// Condition elements and respective condition for Post policy is available <a
/// href="https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-HTTPPOSTConstructPolicy.html#sigv4-PolicyConditions">here</a>.
#[derive(Clone, Debug, Default)]
pub struct PostPolicy {
pub region: Option<String>,
pub bucket: String,
@ -81,17 +82,13 @@ impl PostPolicy {
/// let expiration = utc_now() + Duration::days(7);
/// let policy = PostPolicy::new("bucket-name", expiration).unwrap();
/// ```
pub fn new(bucket_name: &str, expiration: UtcTime) -> Result<PostPolicy, Error> {
pub fn new(bucket_name: &str, expiration: UtcTime) -> Result<Self, Error> {
check_bucket_name(bucket_name, true)?;
Ok(PostPolicy {
region: None,
Ok(Self {
bucket: bucket_name.to_owned(),
expiration,
eq_conditions: HashMap::new(),
starts_with_conditions: HashMap::new(),
lower_limit: None,
upper_limit: None,
..Default::default()
})
}
@ -147,13 +144,12 @@ impl PostPolicy {
|| v.eq_ignore_ascii_case("content-length-range")
{
return Err(Error::PostPolicyError(format!(
"{} is unsupported for equals condition",
element
"{element} is unsupported for equals condition",
)));
}
if PostPolicy::is_reserved_element(v.as_str()) {
return Err(Error::PostPolicyError(format!("{} cannot set", element)));
return Err(Error::PostPolicyError(format!("{element} cannot set")));
}
self.eq_conditions.insert(v, value.to_string());
@ -203,13 +199,12 @@ impl PostPolicy {
|| (v.starts_with("x-amz-") && v.starts_with("x-amz-meta-"))
{
return Err(Error::PostPolicyError(format!(
"{} is unsupported for starts-with condition",
element
"{element} is unsupported for starts-with condition",
)));
}
if PostPolicy::is_reserved_element(v.as_str()) {
return Err(Error::PostPolicyError(format!("{} cannot set", element)));
return Err(Error::PostPolicyError(format!("{element} cannot set")));
}
self.starts_with_conditions.insert(v, value.to_string());

View File

@ -22,7 +22,7 @@ use crate::s3::types::{S3Api, S3Request, ToS3Request};
use crate::s3::utils::{check_bucket_name, insert};
use http::Method;
/// Argument builder for [get_region()](Client::get_region) API
/// This struct constructs the parameters required for the [`Client::get_region`](crate::s3::client::Client::get_region) method.
#[derive(Clone, Debug, Default)]
pub struct GetRegion {
client: Client,

View File

@ -1,5 +1,5 @@
// 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");
// you may not use this file except in compliance with the License.
@ -21,16 +21,16 @@ use crate::s3::multimap::{Multimap, MultimapExt};
use crate::s3::{
client::Client,
error::Error,
response::ListenBucketNotificationResponse,
response::ListBucketNotificationResponse,
types::{NotificationRecords, S3Api, S3Request, ToS3Request},
utils::check_bucket_name,
};
/// Argument builder for
/// [listen_bucket_notification()](crate::s3::client::Client::listen_bucket_notification)
/// [listen_bucket_notification()](crate::s3::client::Client::list_bucket_notification)
/// API.
#[derive(Clone, Debug, Default)]
pub struct ListenBucketNotification {
pub struct ListBucketNotification {
client: Client,
extra_headers: Option<Multimap>,
@ -42,7 +42,7 @@ pub struct ListenBucketNotification {
events: Option<Vec<String>>,
}
impl ListenBucketNotification {
impl ListBucketNotification {
pub fn new(client: Client, bucket: String) -> Self {
Self {
client,
@ -83,19 +83,19 @@ impl ListenBucketNotification {
}
#[async_trait]
impl S3Api for ListenBucketNotification {
impl S3Api for ListBucketNotification {
type S3Response = (
ListenBucketNotificationResponse,
ListBucketNotificationResponse,
Box<dyn Stream<Item = Result<NotificationRecords, Error>> + Unpin + Send>,
);
}
impl ToS3Request for ListenBucketNotification {
impl ToS3Request for ListBucketNotification {
fn to_s3request(self) -> Result<S3Request, Error> {
{
check_bucket_name(&self.bucket, true)?;
if self.client.is_aws_host() {
return Err(Error::UnsupportedApi("ListenBucketNotification".into()));
return Err(Error::UnsupportedApi("ListBucketNotification".into()));
}
}

View File

@ -23,7 +23,9 @@ use crate::s3::{
types::{S3Api, S3Request, ToS3Request},
};
/// Argument builder for [list_buckets()](Client::list_buckets) API.
/// Argument builder for the [`ListBuckets`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBuckets.html) S3 API operation.
///
/// This struct constructs the parameters required for the [`Client::list_buckets`](crate::s3::client::Client::list_buckets) method.
#[derive(Clone, Debug, Default)]
pub struct ListBuckets {
client: Client,

View File

@ -57,7 +57,9 @@ fn delim_helper(delim: Option<String>, recursive: bool) -> Option<String> {
// region: list-objects-v1
/// Argument for ListObjectsV1 S3 API.
/// Argument builder for the [`ListObjectsV1`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjects.html) S3 API operation.
///
/// This struct constructs the parameters required for the [`Client::list_objects`](crate::s3::client::Client::list_objects) method.
#[derive(Clone, Debug, Default)]
struct ListObjectsV1 {
client: Client,
@ -157,7 +159,9 @@ impl From<ListObjects> for ListObjectsV1 {
// region: list-objects-v2
/// Argument for ListObjectsV2 S3 API.
/// Argument builder for the [`ListObjectsV2`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectsV2.html) S3 API operation.
///
/// This struct constructs the parameters required for the [`Client::list_objects`](crate::s3::client::Client::list_objects) method.
#[derive(Clone, Debug, Default)]
struct ListObjectsV2 {
client: Client,
@ -174,7 +178,6 @@ struct ListObjectsV2 {
continuation_token: Option<String>,
fetch_owner: bool,
include_user_metadata: bool,
unsorted: bool,
}
#[async_trait]
@ -241,9 +244,6 @@ impl ToS3Request for ListObjectsV2 {
if self.include_user_metadata {
query_params.add("metadata", "true");
}
if self.unsorted {
query_params.add("unsorted", "true");
}
}
Ok(S3Request::new(self.client, Method::GET)
@ -270,7 +270,6 @@ impl From<ListObjects> for ListObjectsV2 {
continuation_token: value.continuation_token,
fetch_owner: value.fetch_owner,
include_user_metadata: value.include_user_metadata,
unsorted: value.unsorted,
}
}
}
@ -278,7 +277,9 @@ impl From<ListObjects> for ListObjectsV2 {
// region: list-object-versions
/// Argument for ListObjectVersions S3 API
/// Argument builder for the [`ListObjectVersions`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectVersions.html) S3 API operation.
///
/// This struct constructs the parameters required for the [`Client::list_objects`](crate::s3::client::Client::list_objects) method.
#[derive(Clone, Debug, Default)]
struct ListObjectVersions {
client: Client,
@ -294,7 +295,6 @@ struct ListObjectVersions {
key_marker: Option<String>,
version_id_marker: Option<String>,
include_user_metadata: bool,
unsorted: bool,
}
#[async_trait]
@ -361,9 +361,6 @@ impl ToS3Request for ListObjectVersions {
if self.include_user_metadata {
query_params.add("metadata", "true");
}
if self.unsorted {
query_params.add("unsorted", "true");
}
}
Ok(S3Request::new(self.client, Method::GET)
@ -389,7 +386,6 @@ impl From<ListObjects> for ListObjectVersions {
key_marker: value.key_marker,
version_id_marker: value.version_id_marker,
include_user_metadata: value.include_user_metadata,
unsorted: value.unsorted,
}
}
}
@ -401,8 +397,8 @@ impl From<ListObjects> for ListObjectVersions {
/// Argument builder for
/// [list_objects()](crate::s3::client::Client::list_objects) API.
///
/// Use the various builder methods to set parameters on the request. Finally to
/// send the request and consume the results use the `ToStream` instance to get
/// Use the various builder methods to set parameters on the request. Finally, to
/// send the request and consume the results. Use the `ToStream` instance to get
/// a stream of results. Pagination is automatically performed.
#[derive(Clone, Debug, Default)]
pub struct ListObjects {
@ -435,7 +431,6 @@ pub struct ListObjects {
recursive: bool,
use_api_v1: bool,
include_versions: bool,
unsorted: bool,
}
#[async_trait]
@ -486,7 +481,7 @@ impl ListObjects {
}
/// Disable setting the `EncodingType` parameter in the ListObjects request.
/// By default it is set to `url`.
/// By default, it is set to `url`.
pub fn disable_url_encoding(mut self, disable_url_encoding: bool) -> Self {
self.disable_url_encoding = disable_url_encoding;
self
@ -552,6 +547,10 @@ impl ListObjects {
}
/// Set this to use ListObjectsV1. Defaults to false.
/// * For general purpose buckets, ListObjectsV2 returns objects in
/// lexicographical order based on their key names.
/// * For directory buckets (S3-Express), ListObjectsV2 returns objects
/// in an unspecified order implementation-dependent order.
pub fn use_api_v1(mut self, use_api_v1: bool) -> Self {
self.use_api_v1 = use_api_v1;
self
@ -563,11 +562,5 @@ impl ListObjects {
self.include_versions = include_versions;
self
}
/// Set this to allow unsorted versions. Defaults to false
pub fn unsorted(mut self, unsorted: bool) -> Self {
self.unsorted = unsorted;
self
}
}
// endregion: list-objects

View File

@ -16,16 +16,16 @@
use crate::s3::Client;
use crate::s3::error::Error;
use crate::s3::multimap::Multimap;
use crate::s3::response::SetBucketEncryptionResponse;
use crate::s3::response::PutBucketEncryptionResponse;
use crate::s3::segmented_bytes::SegmentedBytes;
use crate::s3::types::{S3Api, S3Request, SseConfig, ToS3Request};
use crate::s3::utils::{check_bucket_name, insert};
use bytes::Bytes;
use http::Method;
/// Argument builder for [set_bucket_encryption()](Client::set_bucket_encryption) API
/// Argument builder for [put_bucket_encryption()](crate::s3::client::Client::put_bucket_encryption) API
#[derive(Clone, Debug, Default)]
pub struct SetBucketEncryption {
pub struct PutBucketEncryption {
client: Client,
extra_headers: Option<Multimap>,
@ -36,7 +36,7 @@ pub struct SetBucketEncryption {
config: SseConfig,
}
impl SetBucketEncryption {
impl PutBucketEncryption {
pub fn new(client: Client, bucket: String) -> Self {
Self {
client,
@ -66,11 +66,11 @@ impl SetBucketEncryption {
}
}
impl S3Api for SetBucketEncryption {
type S3Response = SetBucketEncryptionResponse;
impl S3Api for PutBucketEncryption {
type S3Response = PutBucketEncryptionResponse;
}
impl ToS3Request for SetBucketEncryption {
impl ToS3Request for PutBucketEncryption {
fn to_s3request(self) -> Result<S3Request, Error> {
check_bucket_name(&self.bucket, true)?;

View File

@ -16,16 +16,16 @@
use crate::s3::Client;
use crate::s3::error::Error;
use crate::s3::multimap::{Multimap, MultimapExt};
use crate::s3::response::SetBucketLifecycleResponse;
use crate::s3::response::PutBucketLifecycleResponse;
use crate::s3::segmented_bytes::SegmentedBytes;
use crate::s3::types::{LifecycleConfig, S3Api, S3Request, ToS3Request};
use crate::s3::utils::{check_bucket_name, insert, md5sum_hash};
use bytes::Bytes;
use http::Method;
/// Argument builder for [set_bucket_lifecycle()](crate::s3::client::Client::set_bucket_lifecycle) API
/// Argument builder for [put_bucket_lifecycle()](crate::s3::client::Client::put_bucket_lifecycle) API
#[derive(Clone, Debug, Default)]
pub struct SetBucketLifecycle {
pub struct PutBucketLifecycle {
client: Client,
extra_headers: Option<Multimap>,
@ -36,7 +36,7 @@ pub struct SetBucketLifecycle {
config: LifecycleConfig,
}
impl SetBucketLifecycle {
impl PutBucketLifecycle {
pub fn new(client: Client, bucket: String) -> Self {
Self {
client,
@ -66,11 +66,11 @@ impl SetBucketLifecycle {
}
}
impl S3Api for SetBucketLifecycle {
type S3Response = SetBucketLifecycleResponse;
impl S3Api for PutBucketLifecycle {
type S3Response = PutBucketLifecycleResponse;
}
impl ToS3Request for SetBucketLifecycle {
impl ToS3Request for PutBucketLifecycle {
fn to_s3request(self) -> Result<S3Request, Error> {
check_bucket_name(&self.bucket, true)?;

View File

@ -16,16 +16,18 @@
use crate::s3::Client;
use crate::s3::error::Error;
use crate::s3::multimap::Multimap;
use crate::s3::response::SetBucketNotificationResponse;
use crate::s3::response::PutBucketNotificationResponse;
use crate::s3::segmented_bytes::SegmentedBytes;
use crate::s3::types::{NotificationConfig, S3Api, S3Request, ToS3Request};
use crate::s3::utils::{check_bucket_name, insert};
use bytes::Bytes;
use http::Method;
/// Argument builder for [set_bucket_notification()](crate::s3::client::Client::set_bucket_notification) API
/// Argument builder for the [`PutBucketNotification`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketNotification.html) S3 API operation.
///
/// This struct constructs the parameters required for the [`Client::put_bucket_notification`](crate::s3::client::Client::put_bucket_notification) method.
#[derive(Clone, Debug, Default)]
pub struct SetBucketNotification {
pub struct PutBucketNotification {
client: Client,
extra_headers: Option<Multimap>,
@ -36,7 +38,7 @@ pub struct SetBucketNotification {
config: NotificationConfig,
}
impl SetBucketNotification {
impl PutBucketNotification {
pub fn new(client: Client, bucket: String) -> Self {
Self {
client,
@ -66,11 +68,11 @@ impl SetBucketNotification {
}
}
impl S3Api for SetBucketNotification {
type S3Response = SetBucketNotificationResponse;
impl S3Api for PutBucketNotification {
type S3Response = PutBucketNotificationResponse;
}
impl ToS3Request for SetBucketNotification {
impl ToS3Request for PutBucketNotification {
fn to_s3request(self) -> Result<S3Request, Error> {
check_bucket_name(&self.bucket, true)?;

View File

@ -16,16 +16,18 @@
use crate::s3::Client;
use crate::s3::error::Error;
use crate::s3::multimap::Multimap;
use crate::s3::response::SetBucketPolicyResponse;
use crate::s3::response::PutBucketPolicyResponse;
use crate::s3::segmented_bytes::SegmentedBytes;
use crate::s3::types::{S3Api, S3Request, ToS3Request};
use crate::s3::utils::{check_bucket_name, insert};
use bytes::Bytes;
use http::Method;
/// Argument builder for [set_bucket_policy()](crate::s3::client::Client::set_bucket_policy) API
/// Argument builder for the [`PutBucketPolicy`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketPolicy.html) S3 API operation.
///
/// This struct constructs the parameters required for the [`Client::put_bucket_policy`](crate::s3::client::Client::put_bucket_policy) method.
#[derive(Clone, Debug, Default)]
pub struct SetBucketPolicy {
pub struct PutBucketPolicy {
client: Client,
extra_headers: Option<Multimap>,
@ -36,7 +38,7 @@ pub struct SetBucketPolicy {
config: String, //TODO consider PolicyConfig struct
}
impl SetBucketPolicy {
impl PutBucketPolicy {
pub fn new(client: Client, bucket: String) -> Self {
Self {
client,
@ -66,11 +68,11 @@ impl SetBucketPolicy {
}
}
impl S3Api for SetBucketPolicy {
type S3Response = SetBucketPolicyResponse;
impl S3Api for PutBucketPolicy {
type S3Response = PutBucketPolicyResponse;
}
impl ToS3Request for SetBucketPolicy {
impl ToS3Request for PutBucketPolicy {
fn to_s3request(self) -> Result<S3Request, Error> {
check_bucket_name(&self.bucket, true)?;

View File

@ -16,16 +16,18 @@
use crate::s3::Client;
use crate::s3::error::Error;
use crate::s3::multimap::Multimap;
use crate::s3::response::SetBucketReplicationResponse;
use crate::s3::response::PutBucketReplicationResponse;
use crate::s3::segmented_bytes::SegmentedBytes;
use crate::s3::types::{ReplicationConfig, S3Api, S3Request, ToS3Request};
use crate::s3::utils::{check_bucket_name, insert};
use bytes::Bytes;
use http::Method;
/// Argument builder for [set_bucket_replication()](crate::s3::client::Client::set_bucket_replication) API
/// Argument builder for the [`PutBucketReplication`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketReplication.html) S3 API operation.
///
/// This struct constructs the parameters required for the [`Client::put_bucket_replication`](crate::s3::client::Client::put_bucket_replication) method.
#[derive(Clone, Debug, Default)]
pub struct SetBucketReplication {
pub struct PutBucketReplication {
client: Client,
extra_headers: Option<Multimap>,
@ -36,7 +38,7 @@ pub struct SetBucketReplication {
config: ReplicationConfig,
}
impl SetBucketReplication {
impl PutBucketReplication {
pub fn new(client: Client, bucket: String) -> Self {
Self {
client,
@ -66,11 +68,11 @@ impl SetBucketReplication {
}
}
impl S3Api for SetBucketReplication {
type S3Response = SetBucketReplicationResponse;
impl S3Api for PutBucketReplication {
type S3Response = PutBucketReplicationResponse;
}
impl ToS3Request for SetBucketReplication {
impl ToS3Request for PutBucketReplication {
fn to_s3request(self) -> Result<S3Request, Error> {
check_bucket_name(&self.bucket, true)?;

View File

@ -16,7 +16,7 @@
use crate::s3::Client;
use crate::s3::error::Error;
use crate::s3::multimap::Multimap;
use crate::s3::response::SetBucketTagsResponse;
use crate::s3::response::PutBucketTaggingResponse;
use crate::s3::segmented_bytes::SegmentedBytes;
use crate::s3::types::{S3Api, S3Request, ToS3Request};
use crate::s3::utils::{check_bucket_name, insert};
@ -24,9 +24,11 @@ use bytes::Bytes;
use http::Method;
use std::collections::HashMap;
/// Argument builder for [set_bucket_tags()](crate::s3::client::Client::set_bucket_tags) API
/// Argument builder for the [`PutBucketTagging`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketTagging.html) S3 API operation.
///
/// This struct constructs the parameters required for the [`Client::put_bucket_tagging`](crate::s3::client::Client::put_bucket_tagging) method.
#[derive(Clone, Debug, Default)]
pub struct SetBucketTags {
pub struct PutBucketTagging {
client: Client,
extra_headers: Option<Multimap>,
@ -37,7 +39,7 @@ pub struct SetBucketTags {
tags: HashMap<String, String>,
}
impl SetBucketTags {
impl PutBucketTagging {
pub fn new(client: Client, bucket: String) -> Self {
Self {
client,
@ -67,11 +69,11 @@ impl SetBucketTags {
}
}
impl S3Api for SetBucketTags {
type S3Response = SetBucketTagsResponse;
impl S3Api for PutBucketTagging {
type S3Response = PutBucketTaggingResponse;
}
impl ToS3Request for SetBucketTags {
impl ToS3Request for PutBucketTagging {
fn to_s3request(self) -> Result<S3Request, Error> {
check_bucket_name(&self.bucket, true)?;

View File

@ -16,7 +16,7 @@
use crate::s3::Client;
use crate::s3::error::Error;
use crate::s3::multimap::Multimap;
use crate::s3::response::SetBucketVersioningResponse;
use crate::s3::response::PutBucketVersioningResponse;
use crate::s3::segmented_bytes::SegmentedBytes;
use crate::s3::types::{S3Api, S3Request, ToS3Request};
use crate::s3::utils::{check_bucket_name, insert};
@ -24,11 +24,20 @@ use bytes::Bytes;
use http::Method;
use std::fmt;
/// Represents the versioning state of an S3 bucket.
///
/// This enum corresponds to the possible values returned by the
/// `GetBucketVersioning` API call in S3-compatible services.
///
/// # Variants
///
/// - `Enabled`: Object versioning is enabled for the bucket.
/// - `Suspended`: Object versioning is suspended for the bucket.
#[derive(Clone, Debug, PartialEq)]
pub enum VersioningStatus {
/// **Enable** object versioning in given bucket.
/// Object versioning is enabled for the bucket.
Enabled,
/// **Suspend** object versioning in given bucket.
/// Object versioning is suspended for the bucket.
Suspended,
}
@ -41,21 +50,42 @@ impl fmt::Display for VersioningStatus {
}
}
/// Argument builder for [set_bucket_encryption()](crate::s3::client::Client::set_bucket_encryption) API
/// Argument builder for the [`PutBucketVersioning`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketVersioning.html) S3 API operation.
///
/// This struct constructs the parameters required for the [`Client::put_bucket_versioning`](crate::s3::client::Client::put_bucket_versioning) method.
#[derive(Clone, Debug, Default)]
pub struct SetBucketVersioning {
pub struct PutBucketVersioning {
/// The S3 client instance used to send the request.
client: Client,
/// Optional additional HTTP headers to include in the request.
extra_headers: Option<Multimap>,
/// Optional additional query parameters to include in the request URL.
extra_query_params: Option<Multimap>,
/// Optional AWS region to override the client's default region.
region: Option<String>,
/// The name of the bucket for which to configure versioning.
bucket: String,
/// Desired versioning status for the bucket.
///
/// - `Some(VersioningStatus::Enabled)`: Enables versioning.
/// - `Some(VersioningStatus::Suspended)`: Suspends versioning.
/// - `None`: No change to the current versioning status.
status: Option<VersioningStatus>,
/// Specifies whether MFA delete is enabled for the bucket.
///
/// - `Some(true)`: Enables MFA delete.
/// - `Some(false)`: Disables MFA delete.
/// - `None`: No change to the current MFA delete setting.
mfa_delete: Option<bool>,
}
impl SetBucketVersioning {
impl PutBucketVersioning {
pub fn new(client: Client, bucket: String) -> Self {
Self {
client,
@ -90,11 +120,11 @@ impl SetBucketVersioning {
}
}
impl S3Api for SetBucketVersioning {
type S3Response = SetBucketVersioningResponse;
impl S3Api for PutBucketVersioning {
type S3Response = PutBucketVersioningResponse;
}
impl ToS3Request for SetBucketVersioning {
impl ToS3Request for PutBucketVersioning {
fn to_s3request(self) -> Result<S3Request, Error> {
check_bucket_name(&self.bucket, true)?;

View File

@ -36,7 +36,7 @@ use std::{collections::HashMap, sync::Arc};
// region: multipart-upload
/// Argument for
/// [create_multipart_upload()](Client::create_multipart_upload)
/// [create_multipart_upload()](crate::s3::client::Client::create_multipart_upload)
/// API
#[derive(Clone, Debug, Default)]
pub struct CreateMultipartUpload {
@ -145,7 +145,7 @@ impl ToS3Request for CreateMultipartUpload {
// region: abort-multipart-upload
/// Argument for
/// [abort_multipart_upload()](Client::abort_multipart_upload)
/// [abort_multipart_upload()](crate::s3::client::Client::abort_multipart_upload)
/// API
#[derive(Clone, Debug, Default)]
pub struct AbortMultipartUpload {
@ -214,7 +214,7 @@ impl ToS3Request for AbortMultipartUpload {
// region: complete-multipart-upload
/// Argument for
/// [complete_multipart_upload()](Client::complete_multipart_upload)
/// [complete_multipart_upload()](crate::s3::client::Client::complete_multipart_upload)
/// API
#[derive(Clone, Debug, Default)]
pub struct CompleteMultipartUpload {
@ -317,7 +317,7 @@ impl ToS3Request for CompleteMultipartUpload {
// region: upload-part
/// Argument for [upload_part()](Client::upload_part) S3 API
/// Argument for [upload_part()](crate::s3::client::Client::upload_part) S3 API
#[derive(Debug, Clone, Default)]
pub struct UploadPart {
client: Client,
@ -417,8 +417,7 @@ impl ToS3Request for UploadPart {
if let Some(part_number) = self.part_number {
if !(1..=MAX_MULTIPART_COUNT).contains(&part_number) {
return Err(Error::InvalidPartNumber(format!(
"part number must be between 1 and {}",
MAX_MULTIPART_COUNT
"part number must be between 1 and {MAX_MULTIPART_COUNT}"
)));
}
}
@ -530,6 +529,7 @@ impl ToS3Request for PutObject {
/// PutObjectContent takes a `ObjectContent` stream and uploads it to MinIO/S3.
///
/// It is a higher level API and handles multipart uploads transparently.
#[derive(Default)]
pub struct PutObjectContent {
client: Client,
@ -567,18 +567,7 @@ impl PutObjectContent {
bucket,
object,
input_content: content.into(),
extra_headers: None,
extra_query_params: None,
region: None,
user_metadata: None,
sse: None,
tags: None,
retention: None,
legal_hold: false,
part_size: Size::Unknown,
content_type: None,
content_stream: ContentStream::empty(),
part_count: None,
..Default::default()
}
}
@ -777,12 +766,7 @@ impl PutObjectContent {
let buffer_size = part_content.len() as u64;
total_read += buffer_size;
assert!(
buffer_size <= part_size,
"{:?} <= {:?}",
buffer_size,
part_size
);
assert!(buffer_size <= part_size, "{buffer_size} <= {part_size}",);
if (buffer_size == 0) && (part_number > 1) {
// We are done as we uploaded at least 1 part and we have reached the end of the stream.
@ -897,8 +881,7 @@ fn into_headers_put_object(
}
if !k.starts_with("x-amz-meta-") {
return Err(Error::InvalidUserMetadata(format!(
"user metadata key '{}' does not start with 'x-amz-meta-'",
k
"user metadata key '{k}' does not start with 'x-amz-meta-'",
)));
}
}
@ -941,10 +924,7 @@ fn into_headers_put_object(
if !map.contains_key("Content-Type") {
map.insert(
"Content-Type".into(),
match content_type {
Some(content_type) => content_type.clone(),
None => "application/octet-stream".into(),
},
content_type.unwrap_or_else(|| "application/octet-stream".into()),
);
}

View File

@ -16,16 +16,18 @@
use crate::s3::Client;
use crate::s3::error::Error;
use crate::s3::multimap::{Multimap, MultimapExt};
use crate::s3::response::EnableObjectLegalHoldResponse;
use crate::s3::response::PutObjectLegalHoldResponse;
use crate::s3::segmented_bytes::SegmentedBytes;
use crate::s3::types::{S3Api, S3Request, ToS3Request};
use crate::s3::utils::{check_bucket_name, check_object_name, insert, md5sum_hash};
use bytes::Bytes;
use http::Method;
/// Argument builder for [enable_object_legal_hold()](Client::enable_object_legal_hold) API
/// Argument builder for the [`PutObjectLegalHold`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObjectLegalHold.html) S3 API operation.
///
/// This struct constructs the parameters required for the [`Client::put_object_legal_hold`](crate::s3::client::Client::put_object_legal_hold) method.
#[derive(Clone, Debug, Default)]
pub struct EnableObjectLegalHold {
pub struct PutObjectLegalHold {
client: Client,
extra_headers: Option<Multimap>,
@ -35,9 +37,10 @@ pub struct EnableObjectLegalHold {
object: String,
version_id: Option<String>,
legal_hold: Option<bool>,
}
impl EnableObjectLegalHold {
impl PutObjectLegalHold {
pub fn new(client: Client, bucket: String, object: String) -> Self {
Self {
client,
@ -61,13 +64,18 @@ impl EnableObjectLegalHold {
self.version_id = version_id;
self
}
pub fn legal_hold(mut self, legal_hold: Option<bool>) -> Self {
self.legal_hold = legal_hold;
self
}
}
impl S3Api for EnableObjectLegalHold {
type S3Response = EnableObjectLegalHoldResponse;
impl S3Api for PutObjectLegalHold {
type S3Response = PutObjectLegalHoldResponse;
}
impl ToS3Request for EnableObjectLegalHold {
impl ToS3Request for PutObjectLegalHold {
fn to_s3request(self) -> Result<S3Request, Error> {
check_bucket_name(&self.bucket, true)?;
check_object_name(&self.object)?;
@ -76,10 +84,14 @@ impl ToS3Request for EnableObjectLegalHold {
let mut query_params: Multimap = insert(self.extra_query_params, "legal-hold");
query_params.add_version(self.version_id);
const PAYLOAD: &str = "<LegalHold><Status>ON</Status></LegalHold>";
headers.add("Content-MD5", md5sum_hash(PAYLOAD.as_ref()));
let body: Option<SegmentedBytes> = Some(SegmentedBytes::from(Bytes::from(PAYLOAD)));
//TODO consider const body
let payload: &str = match self.legal_hold {
Some(true) => "<LegalHold><Status>ON</Status></LegalHold>",
_ => "<LegalHold><Status>OFF</Status></LegalHold>",
};
// TODO consider const payload with precalculated md5
headers.add("Content-MD5", md5sum_hash(payload.as_ref()));
let body: Option<SegmentedBytes> = Some(SegmentedBytes::from(Bytes::from(payload)));
Ok(S3Request::new(self.client, Method::PUT)
.region(self.region)

View File

@ -16,17 +16,18 @@
use crate::s3::Client;
use crate::s3::error::Error;
use crate::s3::multimap::Multimap;
use crate::s3::response::SetObjectLockConfigResponse;
use crate::s3::response::PutObjectLockConfigResponse;
use crate::s3::segmented_bytes::SegmentedBytes;
use crate::s3::types::{ObjectLockConfig, S3Api, S3Request, ToS3Request};
use crate::s3::utils::{check_bucket_name, insert};
use bytes::Bytes;
use http::Method;
/// Argument builder for [set_object_lock_config()](Client::set_object_lock_config) API
/// Argument builder for the [`PutObjectLockConfig`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObjectLockConfiguration.html) S3 API operation.
///
/// This struct constructs the parameters required for the [`Client::put_object_lock_config`](crate::s3::client::Client::put_object_lock_config) method.
#[derive(Clone, Debug, Default)]
pub struct SetObjectLockConfig {
pub struct PutObjectLockConfig {
client: Client,
extra_headers: Option<Multimap>,
@ -37,7 +38,7 @@ pub struct SetObjectLockConfig {
config: ObjectLockConfig,
}
impl SetObjectLockConfig {
impl PutObjectLockConfig {
pub fn new(client: Client, bucket: String) -> Self {
Self {
client,
@ -67,11 +68,11 @@ impl SetObjectLockConfig {
}
}
impl S3Api for SetObjectLockConfig {
type S3Response = SetObjectLockConfigResponse;
impl S3Api for PutObjectLockConfig {
type S3Response = PutObjectLockConfigResponse;
}
impl ToS3Request for SetObjectLockConfig {
impl ToS3Request for PutObjectLockConfig {
fn to_s3request(self) -> Result<S3Request, Error> {
check_bucket_name(&self.bucket, true)?;

View File

@ -16,7 +16,7 @@
use crate::s3::Client;
use crate::s3::error::Error;
use crate::s3::multimap::{Multimap, MultimapExt};
use crate::s3::response::SetObjectRetentionResponse;
use crate::s3::response::PutObjectRetentionResponse;
use crate::s3::segmented_bytes::SegmentedBytes;
use crate::s3::types::{RetentionMode, S3Api, S3Request, ToS3Request};
use crate::s3::utils::{
@ -25,9 +25,11 @@ use crate::s3::utils::{
use bytes::Bytes;
use http::Method;
/// Argument builder for [set_object_retention()](Client::set_object_retention) API
/// Argument builder for the [`PutObjectRetention`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObjectRetention.html) S3 API operation.
///
/// This struct constructs the parameters required for the [`Client::put_object_retention`](crate::s3::client::Client::put_object_retention) method.
#[derive(Clone, Debug, Default)]
pub struct SetObjectRetention {
pub struct PutObjectRetention {
client: Client,
extra_headers: Option<Multimap>,
@ -42,7 +44,7 @@ pub struct SetObjectRetention {
retain_until_date: Option<UtcTime>,
}
impl SetObjectRetention {
impl PutObjectRetention {
pub fn new(client: Client, bucket: String, object: String) -> Self {
Self {
client,
@ -88,11 +90,11 @@ impl SetObjectRetention {
}
}
impl S3Api for SetObjectRetention {
type S3Response = SetObjectRetentionResponse;
impl S3Api for PutObjectRetention {
type S3Response = PutObjectRetentionResponse;
}
impl ToS3Request for SetObjectRetention {
impl ToS3Request for PutObjectRetention {
fn to_s3request(self) -> Result<S3Request, Error> {
{
check_bucket_name(&self.bucket, true)?;

View File

@ -16,7 +16,7 @@
use crate::s3::Client;
use crate::s3::error::Error;
use crate::s3::multimap::{Multimap, MultimapExt};
use crate::s3::response::SetObjectTagsResponse;
use crate::s3::response::PutObjectTaggingResponse;
use crate::s3::segmented_bytes::SegmentedBytes;
use crate::s3::types::{S3Api, S3Request, ToS3Request};
use crate::s3::utils::{check_bucket_name, check_object_name, insert};
@ -24,9 +24,9 @@ use bytes::Bytes;
use http::Method;
use std::collections::HashMap;
/// Argument builder for [set_object_tags()](Client::set_object_tags) API
/// Argument builder for [put_object_tagging()](crate::s3::client::Client::put_object_tagging) API
#[derive(Clone, Debug, Default)]
pub struct SetObjectTags {
pub struct PutObjectTagging {
client: Client,
extra_headers: Option<Multimap>,
@ -39,7 +39,7 @@ pub struct SetObjectTags {
tags: HashMap<String, String>,
}
impl SetObjectTags {
impl PutObjectTagging {
pub fn new(client: Client, bucket: String, object: String) -> Self {
Self {
client,
@ -75,11 +75,11 @@ impl SetObjectTags {
}
}
impl S3Api for SetObjectTags {
type S3Response = SetObjectTagsResponse;
impl S3Api for PutObjectTagging {
type S3Response = PutObjectTaggingResponse;
}
impl ToS3Request for SetObjectTags {
impl ToS3Request for PutObjectTagging {
fn to_s3request(self) -> Result<S3Request, Error> {
check_bucket_name(&self.bucket, true)?;
check_object_name(&self.object)?;

View File

@ -25,7 +25,9 @@ use async_trait::async_trait;
use bytes::Bytes;
use http::Method;
/// Argument builder for [bucket_exists()](Client::bucket_exists) API
/// Argument builder for the [`SelectObjectContent`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_SelectObjectContent.html) S3 API operation.
///
/// This struct constructs the parameters required for the [`Client::select_object_content`](crate::s3::client::Client::select_object_content) method.
#[derive(Default)]
pub struct SelectObjectContent {
client: Client,

View File

@ -27,7 +27,7 @@ use crate::s3::{
utils::{UtcTime, check_bucket_name, to_http_header_value},
};
/// Argument builder for [list_objects()](Client::get_object) API.
/// This struct constructs the parameters required for the [`Client::stat_object`](crate::s3::client::Client::stat_object) method.
#[derive(Debug, Clone, Default)]
pub struct StatObject {
client: Client,

View File

@ -43,50 +43,49 @@ use tokio::task;
mod append_object;
mod bucket_exists;
mod copy_object;
mod create_bucket;
mod delete_bucket;
mod delete_bucket_encryption;
mod delete_bucket_lifecycle;
mod delete_bucket_notification;
mod delete_bucket_policy;
mod delete_bucket_replication;
mod delete_bucket_tags;
mod delete_bucket_tagging;
mod delete_object_lock_config;
mod delete_object_tags;
mod disable_object_legal_hold;
mod enable_object_legal_hold;
mod delete_object_tagging;
mod delete_objects;
mod get_bucket_encryption;
mod get_bucket_lifecycle;
mod get_bucket_notification;
mod get_bucket_policy;
mod get_bucket_replication;
mod get_bucket_tags;
mod get_bucket_tagging;
mod get_bucket_versioning;
mod get_object;
mod get_object_legal_hold;
mod get_object_lock_config;
mod get_object_prompt;
mod get_object_retention;
mod get_object_tags;
mod get_object_tagging;
mod get_presigned_object_url;
mod get_presigned_post_form_data;
mod get_region;
mod is_object_legal_hold_enabled;
mod list_bucket_notification;
mod list_buckets;
mod list_objects;
mod listen_bucket_notification;
mod make_bucket;
mod object_prompt;
mod put_bucket_encryption;
mod put_bucket_lifecycle;
mod put_bucket_notification;
mod put_bucket_policy;
mod put_bucket_replication;
mod put_bucket_tagging;
mod put_bucket_versioning;
mod put_object;
mod remove_bucket;
mod remove_objects;
mod put_object_legal_hold;
mod put_object_lock_config;
mod put_object_retention;
mod put_object_tagging;
mod select_object_content;
mod set_bucket_encryption;
mod set_bucket_lifecycle;
mod set_bucket_notification;
mod set_bucket_policy;
mod set_bucket_replication;
mod set_bucket_tags;
mod set_bucket_versioning;
mod set_object_lock_config;
mod set_object_retention;
mod set_object_tags;
mod stat_object;
use super::types::S3Api;
@ -252,7 +251,7 @@ impl Client {
/// Returns whether this client is configured to use the express endpoint and is minio enterprise.
pub fn is_minio_express(&self) -> bool {
if self.shared.express.get().is_some() {
self.shared.express.get().unwrap().clone()
*self.shared.express.get().unwrap()
} else {
task::block_in_place(|| match tokio::runtime::Runtime::new() {
Ok(rt) => {
@ -483,12 +482,8 @@ impl Client {
// Sort headers alphabetically by name
header_strings.sort();
let body_str: String = String::from_utf8(
body.clone()
.unwrap_or(&SegmentedBytes::new())
.to_bytes()
.to_vec(),
)?;
let body_str: String =
String::from_utf8(body.unwrap_or(&SegmentedBytes::new()).to_bytes().to_vec())?;
println!(
"S3 request: {} url={:?}; headers={:?}; body={}\n",
@ -535,15 +530,12 @@ impl Client {
retry,
);
match e {
Error::S3Error(ref err) => {
if (err.code == ErrorCode::NoSuchBucket) || (err.code == ErrorCode::RetryHead) {
if let Some(v) = bucket_name {
self.shared.region_map.remove(v);
}
if let Error::S3Error(ref err) = e {
if (err.code == ErrorCode::NoSuchBucket) || (err.code == ErrorCode::RetryHead) {
if let Some(v) = bucket_name {
self.shared.region_map.remove(v);
}
}
_ => {}
};
Err(e)
@ -700,12 +692,12 @@ impl SharedClientItems {
409 => match bucket_name {
Some(_) => (ErrorCode::NoSuchBucket, "Bucket does not exist".into()),
_ => (
ErrorCode::ResourceConflict.into(),
ErrorCode::ResourceConflict,
"Request resource conflicts".into(),
),
},
501 => (
ErrorCode::MethodNotAllowed.into(),
ErrorCode::MethodNotAllowed,
"The specified method is not allowed against this resource".into(),
),
_ => return Error::ServerError(http_status_code),

View File

@ -21,14 +21,41 @@ use crate::s3::builders::{AppendObject, AppendObjectContent};
use crate::s3::segmented_bytes::SegmentedBytes;
impl Client {
/// Creates an AppendObject request builder to append data to the end of an (existing) object.
/// Creates a [`AppendObject`] request builder to append data to the end of an (existing) object.
/// This is a lower-level API that performs a non-multipart object upload.
///
/// To execute the request, call [`AppendObject::send()`](crate::s3::types::S3Api::send),
/// which returns a [`Result`] containing a [`AppendObjectResponse`](crate::s3::response::AppendObjectResponse).
///
/// 🛈 This operation is not supported for regular non-express buckets.
pub fn append_object<S1: Into<String>, S2: Into<String>>(
///
/// # Example
///
/// ```no_run
/// use minio::s3::Client;
/// use minio::s3::response::{AppendObjectResponse, PutObjectResponse};
/// use minio::s3::segmented_bytes::SegmentedBytes;
/// use minio::s3::types::S3Api;
///
/// #[tokio::main]
/// async fn main() {
/// let client: Client = Default::default(); // configure your client here
/// let data1: SegmentedBytes = SegmentedBytes::from("aaaa".to_string());
/// let data2: SegmentedBytes = SegmentedBytes::from("bbbb".to_string());
/// let resp: PutObjectResponse = client
/// .put_object("bucket-name", "object-name", data1)
/// .send().await.unwrap();
/// let offset_bytes = 4; // the offset at which to append the data
/// let resp: AppendObjectResponse = client
/// .append_object("bucket-name", "object-name", data2, offset_bytes)
/// .send().await.unwrap();
/// println!("size of the final object is {} bytes", resp.object_size);
/// }
/// ```
pub fn append_object<S: Into<String>>(
&self,
bucket: S1,
object: S2,
bucket: S,
object: S,
data: SegmentedBytes,
offset_bytes: u64,
) -> AppendObject {
@ -41,13 +68,42 @@ impl Client {
)
}
/// Creates an AppendObjectContent request builder to append data to the end of an existing
/// Creates an [`AppendObjectContent`] request builder to append data to the end of an (existing)
/// object. The content is streamed and appended to MinIO/S3. This is a higher-level API that
/// handles multipart appends transparently.
pub fn append_object_content<S1: Into<String>, S2: Into<String>, C: Into<ObjectContent>>(
///
/// To execute the request, call [`AppendObjectContent::send()`](crate::s3::types::S3Api::send),
/// which returns a [`Result`] containing a [`AppendObjectResponse`](crate::s3::response::AppendObjectResponse).
///
/// 🛈 This operation is not supported for regular non-express buckets.
///
/// # Example
///
/// ```no_run
/// use minio::s3::Client;
/// use minio::s3::response::{AppendObjectResponse, PutObjectResponse};
/// use minio::s3::builders::ObjectContent;
/// use minio::s3::segmented_bytes::SegmentedBytes;
/// use minio::s3::types::S3Api;
///
/// #[tokio::main]
/// async fn main() {
/// let client: Client = Default::default(); // configure your client here
/// let data1: SegmentedBytes = SegmentedBytes::from("aaaa".to_string());
/// let content2: String = "bbbb".to_string();
/// let resp: PutObjectResponse = client
/// .put_object("bucket-name", "object-name", data1)
/// .send().await.unwrap();
/// let resp: AppendObjectResponse = client
/// .append_object_content("bucket-name", "object-name", content2)
/// .send().await.unwrap();
/// println!("size of the final object is {} bytes", resp.object_size);
/// }
/// ```
pub fn append_object_content<S: Into<String>, C: Into<ObjectContent>>(
&self,
bucket: S1,
object: S2,
bucket: S,
object: S,
content: C,
) -> AppendObjectContent {
AppendObjectContent::new(self.clone(), bucket.into(), object.into(), content)

View File

@ -31,12 +31,12 @@ impl Client {
/// use minio::s3::response::BucketExistsResponse;
/// use minio::s3::types::S3Api;
///
///
/// #[tokio::main]
/// async fn main() {
/// let client: Client = Default::default(); // configure your client here
/// let resp: BucketExistsResponse =
/// client.bucket_exists("bucket-name").send().await.unwrap();
/// let resp: BucketExistsResponse = client
/// .bucket_exists("bucket-name")
/// .send().await.unwrap();
/// println!("bucket '{}' exists: {}", resp.bucket, resp.exists);
/// }
/// ```

View File

@ -22,7 +22,31 @@ use crate::s3::builders::{
};
impl Client {
/// Executes [UploadPartCopy](https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPartCopy.html) S3 API
/// Creates a [`UploadPartCopy`] request builder.
/// See [UploadPartCopy](https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPartCopy.html) S3 API
///
/// To execute the request, call [`UploadPartCopy::send()`](crate::s3::types::S3Api::send),
/// which returns a [`Result`] containing a [`UploadPartCopyResponse`](crate::s3::response::UploadPartCopyResponse).
///
/// # Example
///
/// ```no_run
/// use minio::s3::Client;
/// use minio::s3::response::{UploadPartCopyResponse};
/// use minio::s3::segmented_bytes::SegmentedBytes;
/// use minio::s3::types::S3Api;
///
/// #[tokio::main]
/// async fn main() {
/// let client: Client = Default::default(); // configure your client here
/// let data1: SegmentedBytes = SegmentedBytes::from("aaaa".to_string());
/// todo!();
/// let resp: UploadPartCopyResponse = client
/// .upload_part_copy("bucket-name", "object-name", "TODO")
/// .send().await.unwrap();
/// println!("uploaded {}", resp.object);
/// }
/// ```
pub fn upload_part_copy<S1: Into<String>, S2: Into<String>, S3: Into<String>>(
&self,
bucket: S1,
@ -34,7 +58,7 @@ impl Client {
/// Create a CopyObject request builder. This is a lower-level API that
/// performs a non-multipart object copy.
pub fn copy_object_internal<S1: Into<String>, S2: Into<String>>(
pub(crate) fn copy_object_internal<S1: Into<String>, S2: Into<String>>(
&self,
bucket: S1,
object: S2,
@ -42,8 +66,8 @@ impl Client {
CopyObjectInternal::new(self.clone(), bucket.into(), object.into())
}
/// copy object is a high-order API that calls [`stat_object`] and based on the results calls
/// either [`compose_object`] or [`copy_object_internal`] to copy the object.
/// copy object is a high-order 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.
pub fn copy_object<S1: Into<String>, S2: Into<String>>(
&self,
bucket: S1,
@ -60,8 +84,8 @@ impl Client {
ComposeObjectInternal::new(self.clone(), bucket.into(), object.into())
}
/// compose object is high-order API that calls [`compose_object_internal`] and if that call fails,
/// it calls ['abort_multipart_upload`].
/// compose object is high-order API that calls [`compose_object_internal`](Client::compose_object_internal) and if that call fails,
/// it calls ['abort_multipart_upload`](Client::abort_multipart_upload).
pub fn compose_object<S1: Into<String>, S2: Into<String>>(
&self,
bucket: S1,

View File

@ -16,31 +16,31 @@
//! S3 APIs for bucket objects.
use super::Client;
use crate::s3::builders::MakeBucket;
use crate::s3::builders::CreateBucket;
impl Client {
/// Creates a [`MakeBucket`] request builder.
/// Creates a [`CreateBucket`] request builder.
///
/// To execute the request, call [`MakeBucket::send()`](crate::s3::types::S3Api::send),
/// which returns a [`Result`] containing a [`MakeBucketResponse`](crate::s3::response::MakeBucketResponse).
/// To execute the request, call [`CreateBucket::send()`](crate::s3::types::S3Api::send),
/// which returns a [`Result`] containing a [`CreateBucketResponse`](crate::s3::response::CreateBucketResponse).
///
/// # Example
///
/// ```no_run
/// use minio::s3::Client;
/// use minio::s3::response::MakeBucketResponse;
/// use minio::s3::response::CreateBucketResponse;
/// use minio::s3::types::S3Api;
///
///
/// #[tokio::main]
/// async fn main() {
/// let client: Client = Default::default(); // configure your client here
/// let resp: MakeBucketResponse =
/// client.make_bucket("bucket-name").send().await.unwrap();
/// let resp: CreateBucketResponse = client
/// .create_bucket("bucket-name")
/// .send().await.unwrap();
/// println!("Made bucket '{}' in region '{}'", resp.bucket, resp.region);
/// }
/// ```
pub fn make_bucket<S: Into<String>>(&self, bucket: S) -> MakeBucket {
MakeBucket::new(self.clone(), bucket.into())
pub fn create_bucket<S: Into<String>>(&self, bucket: S) -> CreateBucket {
CreateBucket::new(self.clone(), bucket.into())
}
}

View File

@ -16,48 +16,46 @@
//! S3 APIs for bucket objects.
use super::Client;
use crate::s3::builders::{ObjectToDelete, RemoveBucket, RemoveObject};
use crate::s3::builders::{DeleteBucket, ObjectToDelete, RemoveObject};
use crate::s3::error::{Error, ErrorCode};
use crate::s3::response::DeleteResult;
use crate::s3::response::{
DisableObjectLegalHoldResponse, RemoveBucketResponse, RemoveObjectResponse,
RemoveObjectsResponse,
DeleteBucketResponse, PutObjectLegalHoldResponse, RemoveObjectResponse, RemoveObjectsResponse,
};
use crate::s3::types::{S3Api, ToStream};
use futures::StreamExt;
impl Client {
/// Creates a [`RemoveBucket`] request builder.
/// Creates a [`DeleteBucket`] request builder.
///
/// To execute the request, call [`RemoveBucket::send()`](crate::s3::types::S3Api::send),
/// which returns a [`Result`] containing a [`RemoveBucketResponse`](crate::s3::response::RemoveBucketResponse).
/// To execute the request, call [`DeleteBucket::send()`](crate::s3::types::S3Api::send),
/// which returns a [`Result`] containing a [`DeleteBucketResponse`].
///
/// # Example
///
/// ```no_run
/// use minio::s3::Client;
/// use minio::s3::response::RemoveBucketResponse;
/// use minio::s3::response::DeleteBucketResponse;
/// use minio::s3::types::S3Api;
///
///
/// #[tokio::main]
/// async fn main() {
/// let client: Client = Default::default(); // configure your client here
/// let resp: RemoveBucketResponse =
/// client.remove_bucket("bucket-name").send().await.unwrap();
/// let resp: DeleteBucketResponse =
/// client.delete_bucket("bucket-name").send().await.unwrap();
/// println!("bucket '{}' in region '{}' is removed", resp.bucket, resp.region);
/// }
/// ```
pub fn remove_bucket<S: Into<String>>(&self, bucket: S) -> RemoveBucket {
RemoveBucket::new(self.clone(), bucket.into())
pub fn delete_bucket<S: Into<String>>(&self, bucket: S) -> DeleteBucket {
DeleteBucket::new(self.clone(), bucket.into())
}
/// Removes a bucket and also removes non-empty buckets by first removing all objects before
/// Deletes a bucket and also deletes non-empty buckets by first removing all objects before
/// deleting the bucket. Bypasses governance mode and legal hold.
pub async fn remove_and_purge_bucket<S: Into<String>>(
pub async fn delete_and_purge_bucket<S: Into<String>>(
&self,
bucket: S,
) -> Result<RemoveBucketResponse, Error> {
) -> Result<DeleteBucketResponse, Error> {
let bucket: String = bucket.into();
if self.is_minio_express() {
let mut stream = self.list_objects(&bucket).to_stream().await;
@ -98,8 +96,8 @@ impl Client {
DeleteResult::Deleted(_) => {}
DeleteResult::Error(v) => {
// the object is not deleted. try to disable legal hold and try again.
let _resp: DisableObjectLegalHoldResponse = self
.disable_object_legal_hold(&bucket, &v.object_name)
let _resp: PutObjectLegalHoldResponse = self
.put_object_legal_hold(&bucket, &v.object_name, false)
.version_id(v.version_id.clone())
.send()
.await?;
@ -118,11 +116,11 @@ impl Client {
}
}
}
match self.remove_bucket(bucket).send().await {
match self.delete_bucket(bucket).send().await {
Ok(resp) => Ok(resp),
Err(Error::S3Error(e)) => {
if e.code == ErrorCode::NoSuchBucket {
Ok(RemoveBucketResponse {
Ok(DeleteBucketResponse {
headers: e.headers,
bucket: e.bucket_name,
region: String::new(),

View File

@ -31,12 +31,12 @@ impl Client {
/// use minio::s3::response::DeleteBucketEncryptionResponse;
/// use minio::s3::types::S3Api;
///
///
/// #[tokio::main]
/// async fn main() {
/// let client: Client = Default::default(); // configure your client here
/// let resp: DeleteBucketEncryptionResponse =
/// client.delete_bucket_encryption("bucket-name").send().await.unwrap();
/// let resp: DeleteBucketEncryptionResponse = client
/// .delete_bucket_encryption("bucket-name")
/// .send().await.unwrap();
/// println!("bucket '{}' is deleted", resp.bucket);
/// }
/// ```

View File

@ -31,12 +31,12 @@ impl Client {
/// use minio::s3::response::DeleteBucketLifecycleResponse;
/// use minio::s3::types::S3Api;
///
///
/// #[tokio::main]
/// async fn main() {
/// let client: Client = Default::default(); // configure your client here
/// let resp: DeleteBucketLifecycleResponse =
/// client.delete_bucket_lifecycle("bucket-name").send().await.unwrap();
/// let resp: DeleteBucketLifecycleResponse = client
/// .delete_bucket_lifecycle("bucket-name")
/// .send().await.unwrap();
/// println!("lifecycle of bucket '{}' is deleted", resp.bucket);
/// }
/// ```

View File

@ -31,12 +31,12 @@ impl Client {
/// use minio::s3::response::DeleteBucketNotificationResponse;
/// use minio::s3::types::S3Api;
///
///
/// #[tokio::main]
/// async fn main() {
/// let client: Client = Default::default(); // configure your client here
/// let resp: DeleteBucketNotificationResponse =
/// client.delete_bucket_notification("bucket-name").send().await.unwrap();
/// let resp: DeleteBucketNotificationResponse = client
/// .delete_bucket_notification("bucket-name")
/// .send().await.unwrap();
/// println!("notification of bucket '{}' is deleted", resp.bucket);
/// }
/// ```

View File

@ -19,7 +19,6 @@ use super::Client;
use crate::s3::builders::DeleteBucketPolicy;
impl Client {
/// Create a DeleteBucketPolicy request builder.
/// Creates a [`DeleteBucketPolicy`] request builder.
///
/// To execute the request, call [`DeleteBucketPolicy::send()`](crate::s3::types::S3Api::send),
@ -32,12 +31,12 @@ impl Client {
/// use minio::s3::response::DeleteBucketPolicyResponse;
/// use minio::s3::types::S3Api;
///
///
/// #[tokio::main]
/// async fn main() {
/// let client: Client = Default::default(); // configure your client here
/// let resp: DeleteBucketPolicyResponse =
/// client.delete_bucket_policy("bucket-name").send().await.unwrap();
/// let resp: DeleteBucketPolicyResponse = client
/// .delete_bucket_policy("bucket-name")
/// .send().await.unwrap();
/// println!("policy of bucket '{}' is deleted", resp.bucket);
/// }
/// ```

View File

@ -33,12 +33,12 @@ impl Client {
/// use minio::s3::response::DeleteBucketReplicationResponse;
/// use minio::s3::types::S3Api;
///
///
/// #[tokio::main]
/// async fn main() {
/// let client: Client = Default::default(); // configure your client here
/// let resp: DeleteBucketReplicationResponse =
/// client.delete_bucket_replication("bucket-name").send().await.unwrap();
/// let resp: DeleteBucketReplicationResponse = client
/// .delete_bucket_replication("bucket-name")
/// .send().await.unwrap();
/// println!("replication of bucket '{}' is deleted", resp.bucket);
/// }
/// ```

View File

@ -16,13 +16,13 @@
//! S3 APIs for bucket objects.
use super::Client;
use crate::s3::builders::DeleteBucketTags;
use crate::s3::builders::DeleteBucketTagging;
impl Client {
/// Creates a [`DeleteBucketTags`] request builder.
/// Creates a [`DeleteBucketTagging`] request builder.
///
/// To execute the request, call [`DeleteBucketTagsResponse::send()`](crate::s3::types::S3Api::send),
/// which returns a [`Result`] containing a [`DeleteBucketTagsResponse`](crate::s3::response::DeleteBucketTagsResponse).
/// To execute the request, call [`DeleteBucketTagging::send()`](crate::s3::types::S3Api::send),
/// which returns a [`Result`] containing a [`DeleteBucketTagsResponse`](crate::s3::response::DeleteBucketTaggingResponse).
///
/// 🛈 This operation is not supported for express buckets.
///
@ -30,19 +30,19 @@ impl Client {
///
/// ```no_run
/// use minio::s3::Client;
/// use minio::s3::response::DeleteBucketTagsResponse;
/// use minio::s3::response::DeleteBucketTaggingResponse;
/// use minio::s3::types::S3Api;
///
///
/// #[tokio::main]
/// async fn main() {
/// let client: Client = Default::default(); // configure your client here
/// let resp: DeleteBucketTagsResponse =
/// client.delete_bucket_tags("bucket-name").send().await.unwrap();
/// let resp: DeleteBucketTaggingResponse = client
/// .delete_bucket_tagging("bucket-name")
/// .send().await.unwrap();
/// println!("tags of bucket '{}' are deleted", resp.bucket);
/// }
/// ```
pub fn delete_bucket_tags<S: Into<String>>(&self, bucket: S) -> DeleteBucketTags {
DeleteBucketTags::new(self.clone(), bucket.into())
pub fn delete_bucket_tagging<S: Into<String>>(&self, bucket: S) -> DeleteBucketTagging {
DeleteBucketTagging::new(self.clone(), bucket.into())
}
}

View File

@ -30,24 +30,23 @@ impl Client {
///
/// ```no_run
/// use minio::s3::Client;
/// use minio::s3::response::{DeleteObjectLockConfigResponse, MakeBucketResponse, SetObjectLockConfigResponse};
/// use minio::s3::response::{DeleteObjectLockConfigResponse, CreateBucketResponse, PutObjectLockConfigResponse};
/// use minio::s3::types::{S3Api, ObjectLockConfig, RetentionMode};
///
///
/// #[tokio::main]
/// async fn main() {
/// let client: Client = Default::default(); // configure your client here
/// let bucket_name = "bucket-name";
///
/// let resp: MakeBucketResponse =
/// client.make_bucket(bucket_name).object_lock(true).send().await.unwrap();
/// let resp: CreateBucketResponse =
/// client.create_bucket(bucket_name).object_lock(true).send().await.unwrap();
/// println!("created bucket '{}' with object locking enabled", resp.bucket);
///
/// const DURATION_DAYS: i32 = 7;
/// let config = ObjectLockConfig::new(RetentionMode::GOVERNANCE, Some(DURATION_DAYS), None).unwrap();
///
/// let resp: SetObjectLockConfigResponse =
/// client.set_object_lock_config(bucket_name).config(config).send().await.unwrap();
/// let resp: PutObjectLockConfigResponse =
/// client.put_object_lock_config(bucket_name).config(config).send().await.unwrap();
/// println!("configured object locking for bucket '{}'", resp.bucket);
///
/// let resp: DeleteObjectLockConfigResponse =

View File

@ -16,13 +16,13 @@
//! S3 APIs for bucket objects.
use super::Client;
use crate::s3::builders::DeleteObjectTags;
use crate::s3::builders::DeleteObjectTagging;
impl Client {
/// Creates a [`DeleteObjectTags`] request builder.
/// Creates a [`DeleteObjectTagging`] request builder.
///
/// To execute the request, call [`DeleteObjectTags::send()`](crate::s3::types::S3Api::send),
/// which returns a [`Result`] containing a [`DeleteObjectTagsResponse`](crate::s3::response::DeleteObjectTagsResponse).
/// To execute the request, call [`DeleteObjectTagging::send()`](crate::s3::types::S3Api::send),
/// which returns a [`Result`] containing a [`DeleteObjectTagsResponse`](crate::s3::response::DeleteObjectTaggingResponse).
///
/// 🛈 This operation is not supported for express buckets.
///
@ -30,23 +30,23 @@ impl Client {
///
/// ```no_run
/// use minio::s3::Client;
/// use minio::s3::response::DeleteObjectTagsResponse;
/// use minio::s3::response::DeleteObjectTaggingResponse;
/// use minio::s3::types::S3Api;
///
///
/// #[tokio::main]
/// async fn main() {
/// let client: Client = Default::default(); // configure your client here
/// let resp: DeleteObjectTagsResponse =
/// client.delete_object_tags("bucket-name", "object_name").send().await.unwrap();
/// let resp: DeleteObjectTaggingResponse = client
/// .delete_object_tagging("bucket-name", "object_name")
/// .send().await.unwrap();
/// println!("legal hold of object '{}' in bucket '{}' is deleted", resp.object, resp.bucket);
/// }
/// ```
pub fn delete_object_tags<S1: Into<String>, S2: Into<String>>(
pub fn delete_object_tagging<S1: Into<String>, S2: Into<String>>(
&self,
bucket: S1,
object: S2,
) -> DeleteObjectTags {
DeleteObjectTags::new(self.clone(), bucket.into(), object.into())
) -> DeleteObjectTagging {
DeleteObjectTagging::new(self.clone(), bucket.into(), object.into())
}
}

View File

@ -35,7 +35,6 @@ impl Client {
/// use minio::s3::builders::ObjectToDelete;
/// use minio::s3::types::S3Api;
///
///
/// #[tokio::main]
/// async fn main() {
/// let client: Client = Default::default(); // configure your client here

View File

@ -31,13 +31,13 @@ impl Client {
/// use minio::s3::response::GetBucketEncryptionResponse;
/// use minio::s3::types::S3Api;
///
///
/// #[tokio::main]
/// async fn main() {
/// let client: Client = Default::default(); // configure your client here
/// let resp: GetBucketEncryptionResponse =
/// client.get_bucket_encryption("bucket-name").send().await.unwrap();
/// println!("retrieved SseConfig '{:?}' from bucket '{}' is enabled", resp.config, resp.bucket);
/// let resp: GetBucketEncryptionResponse = client
/// .get_bucket_encryption("bucket-name")
/// .send().await.unwrap();
/// println!("retrieved SseConfig '{:?}' from bucket '{}'", resp.config, resp.bucket);
/// }
/// ```
pub fn get_bucket_encryption<S: Into<String>>(&self, bucket: S) -> GetBucketEncryption {

View File

@ -33,13 +33,13 @@ impl Client {
/// use minio::s3::response::GetBucketLifecycleResponse;
/// use minio::s3::types::S3Api;
///
///
/// #[tokio::main]
/// async fn main() {
/// let client: Client = Default::default(); // configure your client here
/// let resp: GetBucketLifecycleResponse =
/// client.get_bucket_lifecycle("bucket-name").send().await.unwrap();
/// println!("retrieved bucket lifecycle config '{:?}' from bucket '{}' is enabled", resp.config, resp.bucket);
/// let resp: GetBucketLifecycleResponse = client
/// .get_bucket_lifecycle("bucket-name")
/// .send().await.unwrap();
/// println!("retrieved bucket lifecycle config '{:?}' from bucket '{}'", resp.config, resp.bucket);
/// }
/// ```
pub fn get_bucket_lifecycle<S: Into<String>>(&self, bucket: S) -> GetBucketLifecycle {

View File

@ -31,13 +31,13 @@ impl Client {
/// use minio::s3::response::GetBucketNotificationResponse;
/// use minio::s3::types::S3Api;
///
///
/// #[tokio::main]
/// async fn main() {
/// let client: Client = Default::default(); // configure your client here
/// let resp: GetBucketNotificationResponse =
/// client.get_bucket_notification("bucket-name").send().await.unwrap();
/// println!("retrieved bucket notification config '{:?}' from bucket '{}' is enabled", resp.config, resp.bucket);
/// let resp: GetBucketNotificationResponse = client
/// .get_bucket_notification("bucket-name")
/// .send().await.unwrap();
/// println!("retrieved bucket notification config '{:?}' from bucket '{}'", resp.config, resp.bucket);
/// }
/// ```
pub fn get_bucket_notification<S: Into<String>>(&self, bucket: S) -> GetBucketNotification {

View File

@ -31,13 +31,13 @@ impl Client {
/// use minio::s3::response::GetBucketPolicyResponse;
/// use minio::s3::types::S3Api;
///
///
/// #[tokio::main]
/// async fn main() {
/// let client: Client = Default::default(); // configure your client here
/// let resp: GetBucketPolicyResponse =
/// client.get_bucket_policy("bucket-name").send().await.unwrap();
/// println!("retrieved bucket policy config '{:?}' from bucket '{}' is enabled", resp.config, resp.bucket);
/// let resp: GetBucketPolicyResponse = client
/// .get_bucket_policy("bucket-name")
/// .send().await.unwrap();
/// println!("retrieved bucket policy config '{:?}' from bucket '{}'", resp.config, resp.bucket);
/// }
/// ```
pub fn get_bucket_policy<S: Into<String>>(&self, bucket: S) -> GetBucketPolicy {

View File

@ -33,13 +33,13 @@ impl Client {
/// use minio::s3::response::GetBucketReplicationResponse;
/// use minio::s3::types::S3Api;
///
///
/// #[tokio::main]
/// async fn main() {
/// let client: Client = Default::default(); // configure your client here
/// let resp: GetBucketReplicationResponse =
/// client.get_bucket_replication("bucket-name").send().await.unwrap();
/// println!("retrieved bucket replication config '{:?}' from bucket '{}' is enabled", resp.config, resp.bucket);
/// let resp: GetBucketReplicationResponse = client
/// .get_bucket_replication("bucket-name")
/// .send().await.unwrap();
/// println!("retrieved bucket replication config '{:?}' from bucket '{}'", resp.config, resp.bucket);
/// }
/// ```
pub fn get_bucket_replication<S: Into<String>>(&self, bucket: S) -> GetBucketReplication {

View File

@ -16,13 +16,13 @@
//! S3 APIs for bucket objects.
use super::Client;
use crate::s3::builders::GetBucketTags;
use crate::s3::builders::GetBucketTagging;
impl Client {
/// Creates a [`GetBucketTags`] request builder.
/// Creates a [`GetBucketTagging`] request builder.
///
/// To execute the request, call [`GetBucketTags::send()`](crate::s3::types::S3Api::send),
/// which returns a [`Result`] containing a [`GetBucketTagsResponse`](crate::s3::response::GetBucketTagsResponse).
/// which returns a [`Result`] containing a [`GetBucketTagsResponse`](crate::s3::response::GetBucketTaggingResponse).
///
/// 🛈 This operation is not supported for express buckets.
///
@ -30,19 +30,19 @@ impl Client {
///
/// ```no_run
/// use minio::s3::Client;
/// use minio::s3::response::GetBucketTagsResponse;
/// use minio::s3::response::GetBucketTaggingResponse;
/// use minio::s3::types::S3Api;
///
///
/// #[tokio::main]
/// async fn main() {
/// let client: Client = Default::default(); // configure your client here
/// let resp: GetBucketTagsResponse =
/// client.get_bucket_tags("bucket-name").send().await.unwrap();
/// println!("retrieved bucket tags '{:?}' from bucket '{}' is enabled", resp.tags, resp.bucket);
/// let resp: GetBucketTaggingResponse = client
/// .get_bucket_tagging("bucket-name")
/// .send().await.unwrap();
/// println!("retrieved bucket tags '{:?}' from bucket '{}'", resp.tags, resp.bucket);
/// }
/// ```
pub fn get_bucket_tags<S: Into<String>>(&self, bucket: S) -> GetBucketTags {
GetBucketTags::new(self.clone(), bucket.into())
pub fn get_bucket_tagging<S: Into<String>>(&self, bucket: S) -> GetBucketTagging {
GetBucketTagging::new(self.clone(), bucket.into())
}
}

View File

@ -33,13 +33,13 @@ impl Client {
/// use minio::s3::response::GetBucketVersioningResponse;
/// use minio::s3::types::S3Api;
///
///
/// #[tokio::main]
/// async fn main() {
/// let client: Client = Default::default(); // configure your client here
/// let resp: GetBucketVersioningResponse =
/// client.get_bucket_versioning("bucket-name").send().await.unwrap();
/// println!("retrieved versioning status '{:?}' from bucket '{}' is enabled", resp.status, resp.bucket);
/// let resp: GetBucketVersioningResponse = client
/// .get_bucket_versioning("bucket-name")
/// .send().await.unwrap();
/// println!("retrieved versioning status '{:?}' from bucket '{}'", resp.status, resp.bucket);
/// }
/// ```
pub fn get_bucket_versioning<S: Into<String>>(&self, bucket: S) -> GetBucketVersioning {

View File

@ -31,12 +31,12 @@ impl Client {
/// use minio::s3::response::GetObjectResponse;
/// use minio::s3::types::S3Api;
///
///
/// #[tokio::main]
/// async fn main() {
/// let client: Client = Default::default(); // configure your client here
/// let resp: GetObjectResponse =
/// client.get_object("bucket-name", "object-name").send().await.unwrap();
/// let resp: GetObjectResponse = client
/// .get_object("bucket-name", "object-name")
/// .send().await.unwrap();
/// let content_bytes = resp.content.to_segmented_bytes().await.unwrap().to_bytes();
/// let content_str = String::from_utf8(content_bytes.to_vec()).unwrap();
/// println!("retrieved content '{}'", content_str);

View File

@ -16,13 +16,13 @@
//! S3 APIs for bucket objects.
use super::Client;
use crate::s3::builders::EnableObjectLegalHold;
use crate::s3::builders::GetObjectLegalHold;
impl Client {
/// Creates a [`EnableObjectLegalHold`] request builder.
/// Creates a [`GetObjectLegalHold`] request builder.
///
/// To execute the request, call [`EnableObjectLegalHold::send()`](crate::s3::types::S3Api::send),
/// which returns a [`Result`] containing a [`EnableObjectLegalHoldResponse`](crate::s3::response::EnableObjectLegalHoldResponse).
/// To execute the request, call [`GetObjectLegalHold::send()`](crate::s3::types::S3Api::send),
/// which returns a [`Result`] containing a [`GetObjectLegalHoldResponse`](crate::s3::response::GetObjectLegalHoldResponse).
///
/// 🛈 This operation is not supported for express buckets.
///
@ -30,23 +30,23 @@ impl Client {
///
/// ```no_run
/// use minio::s3::Client;
/// use minio::s3::response::EnableObjectLegalHoldResponse;
/// use minio::s3::response::GetObjectLegalHoldResponse;
/// use minio::s3::types::S3Api;
///
///
/// #[tokio::main]
/// async fn main() {
/// let client: Client = Default::default(); // configure your client here
/// let resp: EnableObjectLegalHoldResponse =
/// client.enable_object_legal_hold("bucket-name", "object-name").send().await.unwrap();
/// println!("legal hold of object '{}' in bucket '{}' is enabled", resp.object, resp.bucket);
/// let resp: GetObjectLegalHoldResponse = client
/// .get_object_legal_hold("bucket-name", "object-name")
/// .send().await.unwrap();
/// println!("legal hold of object '{}' in bucket '{}' is enabled: {}", resp.object, resp.bucket, resp.enabled);
/// }
/// ```
pub fn enable_object_legal_hold<S1: Into<String>, S2: Into<String>>(
pub fn get_object_legal_hold<S1: Into<String>, S2: Into<String>>(
&self,
bucket: S1,
object: S2,
) -> EnableObjectLegalHold {
EnableObjectLegalHold::new(self.clone(), bucket.into(), object.into())
) -> GetObjectLegalHold {
GetObjectLegalHold::new(self.clone(), bucket.into(), object.into())
}
}

View File

@ -33,12 +33,12 @@ impl Client {
/// use minio::s3::response::GetObjectLockConfigResponse;
/// use minio::s3::types::S3Api;
///
///
/// #[tokio::main]
/// async fn main() {
/// let client: Client = Default::default(); // configure your client here
/// let resp: GetObjectLockConfigResponse =
/// client.get_object_lock_config("bucket-name").send().await.unwrap();
/// let resp: GetObjectLockConfigResponse = client
/// .get_object_lock_config("bucket-name")
/// .send().await.unwrap();
/// println!("retrieved object lock config '{:?}' from bucket '{}' is enabled", resp.config, resp.bucket);
/// }
/// ```

View File

@ -15,39 +15,38 @@
//! S3 APIs for downloading objects.
use crate::s3::builders::ObjectPrompt;
use crate::s3::builders::GetObjectPrompt;
use super::Client;
impl Client {
/// Creates a [`ObjectPrompt`] request builder. Prompt an object using natural language.
/// Creates a [`GetObjectPrompt`] request builder. Prompt an object using natural language.
///
/// To execute the request, call [`ObjectPrompt::send()`](crate::s3::types::S3Api::send),
/// which returns a [`Result`] containing a [`ObjectPromptResponse`](crate::s3::response::ObjectPromptResponse).
/// To execute the request, call [`GetObjectPrompt::send()`](crate::s3::types::S3Api::send),
/// which returns a [`Result`] containing a [`GetObjectPromptResponse`](crate::s3::response::GetObjectPromptResponse).
///
/// # Example
///
/// ```no_run
/// use minio::s3::Client;
/// use minio::s3::response::ObjectPromptResponse;
/// use minio::s3::response::GetObjectPromptResponse;
/// use minio::s3::types::S3Api;
///
///
/// #[tokio::main]
/// async fn main() {
/// let client: Client = Default::default(); // configure your client here
/// let resp: ObjectPromptResponse = client
/// .object_prompt("bucket-name", "object-name", "What is it about?")
/// let resp: GetObjectPromptResponse = client
/// .get_object_prompt("bucket-name", "object-name", "What is it about?")
/// .send().await.unwrap();
/// println!("the prompt response is: '{}'", resp.prompt_response);
/// }
/// ```
pub fn object_prompt<S1: Into<String>, S2: Into<String>, S3: Into<String>>(
pub fn get_object_prompt<S1: Into<String>, S2: Into<String>, S3: Into<String>>(
&self,
bucket: S1,
object: S2,
prompt: S3,
) -> ObjectPrompt {
ObjectPrompt::new(self.clone(), bucket.into(), object.into(), prompt.into())
) -> GetObjectPrompt {
GetObjectPrompt::new(self.clone(), bucket.into(), object.into(), prompt.into())
}
}

View File

@ -33,12 +33,12 @@ impl Client {
/// use minio::s3::response::GetObjectRetentionResponse;
/// use minio::s3::types::S3Api;
///
///
/// #[tokio::main]
/// async fn main() {
/// let client: Client = Default::default(); // configure your client here
/// let resp: GetObjectRetentionResponse =
/// client.get_object_retention("bucket-name", "object-name").send().await.unwrap();
/// let resp: GetObjectRetentionResponse = client
/// .get_object_retention("bucket-name", "object-name")
/// .send().await.unwrap();
/// println!("retrieved retention mode '{:?}' until '{:?}' from bucket '{}' is enabled", resp.retention_mode, resp.retain_until_date, resp.bucket);
/// }
/// ```

Some files were not shown because too many files have changed in this diff Show More