From f11fafdf7e2b1283418624dce896d539408e10fc Mon Sep 17 00:00:00 2001 From: Henk-Jan Lebbink Date: Fri, 11 Jul 2025 22:54:21 +0200 Subject: [PATCH 1/3] use crate TypedBuilder for builders bugfixes WIP doc updated --- .claude/settings.local.json | 9 + Cargo.toml | 61 +- README.md | 4 +- benches/s3/bench_bucket_exists.rs | 7 +- benches/s3/bench_bucket_lifecycle.rs | 20 +- benches/s3/bench_bucket_notification.rs | 20 +- benches/s3/bench_bucket_policy.rs | 25 +- benches/s3/bench_bucket_replication.rs | 25 +- benches/s3/bench_bucket_tagging.rs | 20 +- benches/s3/bench_bucket_versioning.rs | 12 +- benches/s3/bench_list_bucket.rs | 2 +- benches/s3/bench_object_append.rs | 22 +- benches/s3/bench_object_copy.rs | 13 +- benches/s3/bench_object_legal_hold.rs | 17 +- benches/s3/bench_object_lock_config.rs | 20 +- benches/s3/bench_object_put.rs | 14 +- benches/s3/bench_object_retention.rs | 31 +- benches/s3/bench_object_tagging.rs | 15 +- benches/s3/common_benches.rs | 7 +- common/src/cleanup_guard.rs | 8 +- common/src/test_context.rs | 9 +- examples/append_object.rs | 13 +- examples/bucket_encryption.rs | 19 +- examples/bucket_lifecycle.rs | 26 +- examples/bucket_versioning.rs | 35 +- examples/common.rs | 40 +- examples/file_downloader.rs | 11 +- examples/file_uploader.rs | 5 +- examples/object_prompt.rs | 6 +- examples/put_object.rs | 9 +- macros/src/test_attr.rs | 6 +- src/lib.rs | 7 +- src/s3/builders.rs | 2 +- src/s3/builders/append_object.rs | 175 +++-- src/s3/builders/bucket_common.rs | 47 +- src/s3/builders/bucket_exists.rs | 22 +- src/s3/builders/copy_object.rs | 567 +++++++--------- src/s3/builders/create_bucket.rs | 69 +- src/s3/builders/delete_bucket.rs | 22 +- src/s3/builders/delete_bucket_encryption.rs | 24 +- src/s3/builders/delete_bucket_lifecycle.rs | 24 +- src/s3/builders/delete_bucket_notification.rs | 27 +- src/s3/builders/delete_bucket_policy.rs | 22 +- src/s3/builders/delete_bucket_replication.rs | 24 +- src/s3/builders/delete_bucket_tagging.rs | 25 +- src/s3/builders/delete_object_lock_config.rs | 27 +- src/s3/builders/delete_object_tagging.rs | 67 +- src/s3/builders/delete_objects.rs | 175 +++-- src/s3/builders/get_bucket_encryption.rs | 24 +- src/s3/builders/get_bucket_lifecycle.rs | 57 +- src/s3/builders/get_bucket_notification.rs | 24 +- src/s3/builders/get_bucket_policy.rs | 22 +- src/s3/builders/get_bucket_replication.rs | 24 +- src/s3/builders/get_bucket_tagging.rs | 63 +- src/s3/builders/get_bucket_versioning.rs | 24 +- src/s3/builders/get_object.rs | 122 ++-- src/s3/builders/get_object_legal_hold.rs | 54 +- src/s3/builders/get_object_lock_config.rs | 21 +- src/s3/builders/get_object_prompt.rs | 95 ++- src/s3/builders/get_object_retention.rs | 65 +- src/s3/builders/get_object_tagging.rs | 62 +- src/s3/builders/get_presigned_object_url.rs | 58 +- .../get_presigned_policy_form_data.rs | 30 +- src/s3/builders/get_region.rs | 48 +- src/s3/builders/list_buckets.rs | 42 +- src/s3/builders/list_objects.rs | 239 +++---- src/s3/builders/listen_bucket_notification.rs | 72 +- src/s3/builders/put_bucket_encryption.rs | 69 +- src/s3/builders/put_bucket_lifecycle.rs | 69 +- src/s3/builders/put_bucket_notification.rs | 68 +- src/s3/builders/put_bucket_policy.rs | 63 +- src/s3/builders/put_bucket_replication.rs | 68 +- src/s3/builders/put_bucket_tagging.rs | 64 +- src/s3/builders/put_bucket_versioning.rs | 73 +-- src/s3/builders/put_object.rs | 615 +++++++----------- src/s3/builders/put_object_legal_hold.rs | 76 +-- src/s3/builders/put_object_lock_config.rs | 64 +- src/s3/builders/put_object_retention.rs | 97 ++- src/s3/builders/put_object_tagging.rs | 74 +-- src/s3/builders/select_object_content.rs | 91 ++- src/s3/builders/stat_object.rs | 121 ++-- src/s3/client.rs | 83 ++- src/s3/client/append_object.rs | 49 +- src/s3/client/bucket_exists.rs | 16 +- src/s3/client/copy_object.rs | 66 +- src/s3/client/create_bucket.rs | 16 +- src/s3/client/delete_bucket.rs | 58 +- src/s3/client/delete_bucket_encryption.rs | 21 +- src/s3/client/delete_bucket_lifecycle.rs | 18 +- src/s3/client/delete_bucket_notification.rs | 18 +- src/s3/client/delete_bucket_policy.rs | 18 +- src/s3/client/delete_bucket_replication.rs | 21 +- src/s3/client/delete_bucket_tagging.rs | 18 +- src/s3/client/delete_object_lock_config.rs | 34 +- src/s3/client/delete_object_tagging.rs | 19 +- src/s3/client/delete_objects.rs | 35 +- src/s3/client/get_bucket_encryption.rs | 18 +- src/s3/client/get_bucket_lifecycle.rs | 18 +- src/s3/client/get_bucket_notification.rs | 18 +- src/s3/client/get_bucket_policy.rs | 18 +- src/s3/client/get_bucket_replication.rs | 18 +- src/s3/client/get_bucket_tagging.rs | 18 +- src/s3/client/get_bucket_versioning.rs | 18 +- src/s3/client/get_object.rs | 19 +- src/s3/client/get_object_legal_hold.rs | 19 +- src/s3/client/get_object_lock_config.rs | 18 +- src/s3/client/get_object_prompt.rs | 20 +- src/s3/client/get_object_retention.rs | 19 +- src/s3/client/get_object_tagging.rs | 19 +- src/s3/client/get_presigned_object_url.rs | 20 +- src/s3/client/get_presigned_post_form_data.rs | 21 +- src/s3/client/get_region.rs | 24 +- src/s3/client/list_buckets.rs | 16 +- src/s3/client/list_objects.rs | 54 +- src/s3/client/listen_bucket_notification.rs | 18 +- src/s3/client/put_bucket_encryption.rs | 18 +- src/s3/client/put_bucket_lifecycle.rs | 18 +- src/s3/client/put_bucket_notification.rs | 18 +- src/s3/client/put_bucket_policy.rs | 18 +- src/s3/client/put_bucket_replication.rs | 19 +- src/s3/client/put_bucket_tagging.rs | 19 +- src/s3/client/put_bucket_versioning.rs | 18 +- src/s3/client/put_object.rs | 119 ++-- src/s3/client/put_object_legal_hold.rs | 21 +- src/s3/client/put_object_lock_config.rs | 26 +- src/s3/client/put_object_retention.rs | 19 +- src/s3/client/put_object_tagging.rs | 23 +- src/s3/client/select_object_content.rs | 21 +- src/s3/client/stat_object.rs | 19 +- src/s3/creds.rs | 2 +- src/s3/http.rs | 5 +- src/s3/minio_error_response.rs | 2 +- src/s3/mod.rs | 2 +- src/s3/response/bucket_exists.rs | 2 +- src/s3/response/copy_object.rs | 4 +- src/s3/response/create_bucket.rs | 2 +- src/s3/response/delete_bucket.rs | 2 +- src/s3/response/delete_bucket_encryption.rs | 2 +- src/s3/response/delete_bucket_lifecycle.rs | 2 +- src/s3/response/delete_bucket_notification.rs | 2 +- src/s3/response/delete_bucket_policy.rs | 2 +- src/s3/response/delete_bucket_replication.rs | 2 +- src/s3/response/delete_bucket_tagging.rs | 2 +- src/s3/response/delete_object.rs | 4 +- src/s3/response/delete_object_lock_config.rs | 2 +- src/s3/response/delete_object_tagging.rs | 2 +- src/s3/response/get_bucket_encryption.rs | 2 +- src/s3/response/get_bucket_lifecycle.rs | 2 +- src/s3/response/get_bucket_notification.rs | 2 +- src/s3/response/get_bucket_policy.rs | 2 +- src/s3/response/get_bucket_replication.rs | 2 +- src/s3/response/get_bucket_tagging.rs | 2 +- src/s3/response/get_bucket_versioning.rs | 2 +- src/s3/response/get_object_legal_hold.rs | 2 +- src/s3/response/get_object_lock_config.rs | 2 +- src/s3/response/get_object_retention.rs | 2 +- src/s3/response/get_object_tagging.rs | 2 +- src/s3/response/get_presigned_object_url.rs | 2 +- src/s3/response/get_region.rs | 2 +- src/s3/response/list_buckets.rs | 2 +- src/s3/response/list_objects.rs | 36 +- src/s3/response/listen_bucket_notification.rs | 2 +- src/s3/response/put_bucket_encryption.rs | 2 +- src/s3/response/put_bucket_lifecycle.rs | 2 +- src/s3/response/put_bucket_notification.rs | 2 +- src/s3/response/put_bucket_policy.rs | 2 +- src/s3/response/put_bucket_replication.rs | 2 +- src/s3/response/put_bucket_tagging.rs | 2 +- src/s3/response/put_bucket_versioning.rs | 2 +- src/s3/response/put_object.rs | 10 +- src/s3/response/put_object_legal_hold.rs | 2 +- src/s3/response/put_object_lock_config.rs | 2 +- src/s3/response/put_object_retention.rs | 2 +- src/s3/response/put_object_tagging.rs | 2 +- src/s3/response/select_object_content.rs | 4 +- src/s3/response/stat_object.rs | 2 +- src/s3/types.rs | 162 ++--- src/s3/utils.rs | 11 +- tests/test_append_object.rs | 25 +- tests/test_bucket_create_delete.rs | 55 +- tests/test_bucket_encryption.rs | 4 + tests/test_bucket_exists.rs | 24 +- tests/test_bucket_lifecycle.rs | 12 +- tests/test_bucket_notification.rs | 4 + tests/test_bucket_policy.rs | 4 + tests/test_bucket_replication.rs | 19 +- tests/test_bucket_tagging.rs | 21 +- tests/test_bucket_versioning.rs | 13 +- tests/test_get_object.rs | 2 + tests/test_get_presigned_object_url.rs | 1 + tests/test_get_presigned_post_form_data.rs | 1 + tests/test_list_buckets.rs | 2 +- tests/test_list_objects.rs | 4 + tests/test_listen_bucket_notification.rs | 2 + tests/test_object_compose.rs | 3 + tests/test_object_copy.rs | 10 +- tests/test_object_delete.rs | 5 +- tests/test_object_legal_hold.rs | 5 + tests/test_object_lock_config.rs | 4 + tests/test_object_put.rs | 14 +- tests/test_object_retention.rs | 9 +- tests/test_object_tagging.rs | 5 + tests/test_select_object_content.rs | 4 + tests/test_upload_download_object.rs | 2 + 204 files changed, 3243 insertions(+), 3203 deletions(-) create mode 100644 .claude/settings.local.json diff --git a/.claude/settings.local.json b/.claude/settings.local.json new file mode 100644 index 00000000..c994be3e --- /dev/null +++ b/.claude/settings.local.json @@ -0,0 +1,9 @@ +{ + "permissions": { + "allow": [ + "Bash(grep:*)" + ], + "deny": [] + }, + "$schema": "https://json.schemastore.org/claude-code-settings.json" +} \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index 38fc6046..ed269cfd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,41 +33,42 @@ bytes = { workspace = true } async-std = { workspace = true, features = ["attributes"] } reqwest = { workspace = true, features = ["stream"] } -async-recursion = "1.1.1" -async-stream = "0.3.6" -async-trait = "0.1.88" -base64 = "0.22.1" -chrono = "0.4.41" -crc = "3.3.0" +async-recursion = "1.1" +async-stream = "0.3" +async-trait = "0.1" +base64 = "0.22" +chrono = "0.4" +crc = "3.3" dashmap = "6.1.0" -env_logger = "0.11.8" -hmac = { version = "0.12.1", optional = true } -hyper = { version = "1.6.0", features = ["full"] } -lazy_static = "1.5.0" -log = "0.4.27" -md5 = "0.8.0" -multimap = "0.10.1" -percent-encoding = "2.3.1" -url = "2.5.4" -regex = "1.11.1" -ring = { version = "0.17.14", optional = true, default-features = false, features = ["alloc"] } -serde = { version = "1.0.219", features = ["derive"] } -serde_json = "1.0.142" -sha2 = { version = "0.10.9", optional = true } -urlencoding = "2.1.3" -xmltree = "0.11.0" -http = "1.3.1" -thiserror = "2.0.14" +env_logger = "0.11" +hmac = { version = "0.12", optional = true } +hyper = { version = "1.7", features = ["full"] } +lazy_static = "1.5" +log = "0.4" +md5 = "0.8" +multimap = "0.10" +percent-encoding = "2.3" +url = "2.5" +regex = "1.11" +ring = { version = "0.17", optional = true, default-features = false, features = ["alloc"] } +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" +sha2 = { version = "0.10", optional = true } +urlencoding = "2.1" +xmltree = "0.11" +http = "1.3" +thiserror = "2.0" +typed-builder = "0.21" [dev-dependencies] minio-common = { path = "./common" } minio-macros = { path = "./macros" } -tokio = { version = "1.47.1", features = ["full"] } -async-std = { version = "1.13.1", features = ["attributes", "tokio1"] } -clap = { version = "4.5.44", features = ["derive"] } -rand = { version = "0.9.2", features = ["small_rng"] } -quickcheck = "1.0.3" -criterion = "0.7.0" +tokio = { version = "1.47", features = ["full"] } +async-std = { version = "1.13", features = ["attributes", "tokio1"] } +clap = { version = "4.5", features = ["derive"] } +rand = { version = "0.9", features = ["small_rng"] } +quickcheck = "1.0" +criterion = "0.7" [lib] name = "minio" diff --git a/README.md b/README.md index e4350bab..38fad224 100644 --- a/README.md +++ b/README.md @@ -24,8 +24,8 @@ use minio::s3::response::BucketExistsResponse; #[tokio::main] async fn main() { - let client: Client = Default::default(); // configure your client - + let client = Client::create_client_on_localhost().unwrap(); // configure your client here + let exists: BucketExistsResponse = client .bucket_exists("my-bucket") .send() diff --git a/benches/s3/bench_bucket_exists.rs b/benches/s3/bench_bucket_exists.rs index fd946b3d..da6120a2 100644 --- a/benches/s3/bench_bucket_exists.rs +++ b/benches/s3/bench_bucket_exists.rs @@ -23,6 +23,11 @@ pub(crate) fn bench_bucket_exists(criterion: &mut Criterion) { "bucket_exists", criterion, || async { Ctx2::new().await }, - |ctx| BucketExists::new(ctx.client.clone(), ctx.bucket.clone()), + |ctx| { + BucketExists::builder() + .client(ctx.client.clone()) + .bucket(ctx.bucket.clone()) + .build() + }, ); } diff --git a/benches/s3/bench_bucket_lifecycle.rs b/benches/s3/bench_bucket_lifecycle.rs index 56bfb67b..d76dd1b4 100644 --- a/benches/s3/bench_bucket_lifecycle.rs +++ b/benches/s3/bench_bucket_lifecycle.rs @@ -27,8 +27,11 @@ pub(crate) fn bench_put_bucket_lifecycle(criterion: &mut Criterion) { || async { Ctx2::new().await }, |ctx| { let config = create_bucket_lifecycle_config_examples(); - PutBucketLifecycle::new(ctx.client.clone(), ctx.bucket.clone()) + PutBucketLifecycle::builder() + .client(ctx.client.clone()) + .bucket(ctx.bucket.clone()) .life_cycle_config(config) + .build() }, ) } @@ -42,12 +45,18 @@ pub(crate) fn bench_get_bucket_lifecycle(criterion: &mut Criterion) { ctx.client .put_bucket_lifecycle(&ctx.bucket) .life_cycle_config(config) + .build() .send() .await .unwrap(); ctx }, - |ctx| GetBucketLifecycle::new(ctx.client.clone(), ctx.bucket.clone()), + |ctx| { + GetBucketLifecycle::builder() + .client(ctx.client.clone()) + .bucket(ctx.bucket.clone()) + .build() + }, ) } pub(crate) fn bench_delete_bucket_lifecycle(criterion: &mut Criterion) { @@ -55,6 +64,11 @@ pub(crate) fn bench_delete_bucket_lifecycle(criterion: &mut Criterion) { "delete_bucket_lifecycle", criterion, || async { Ctx2::new().await }, - |ctx| DeleteBucketLifecycle::new(ctx.client.clone(), ctx.bucket.clone()), + |ctx| { + DeleteBucketLifecycle::builder() + .client(ctx.client.clone()) + .bucket(ctx.bucket.clone()) + .build() + }, ) } diff --git a/benches/s3/bench_bucket_notification.rs b/benches/s3/bench_bucket_notification.rs index 56da1512..228c678b 100644 --- a/benches/s3/bench_bucket_notification.rs +++ b/benches/s3/bench_bucket_notification.rs @@ -28,8 +28,11 @@ pub(crate) fn bench_put_bucket_notification(criterion: &mut Criterion) { || async { Ctx2::new().await }, |ctx| { let config = create_bucket_notification_config_example(); - PutBucketNotification::new(ctx.client.clone(), ctx.bucket.clone()) + PutBucketNotification::builder() + .client(ctx.client.clone()) + .bucket(ctx.bucket.clone()) .notification_config(config) + .build() }, ) } @@ -44,12 +47,18 @@ pub(crate) fn bench_get_bucket_notification(criterion: &mut Criterion) { ctx.client .put_bucket_notification(&ctx.bucket) .notification_config(config) + .build() .send() .await .unwrap(); ctx }, - |ctx| GetBucketNotification::new(ctx.client.clone(), ctx.bucket.clone()), + |ctx| { + GetBucketNotification::builder() + .client(ctx.client.clone()) + .bucket(ctx.bucket.clone()) + .build() + }, ) } #[allow(dead_code)] @@ -58,6 +67,11 @@ pub(crate) fn bench_delete_bucket_notification(criterion: &mut Criterion) { "delete_bucket_notification", criterion, || async { Ctx2::new().await }, - |ctx| DeleteBucketNotification::new(ctx.client.clone(), ctx.bucket.clone()), + |ctx| { + DeleteBucketNotification::builder() + .client(ctx.client.clone()) + .bucket(ctx.bucket.clone()) + .build() + }, ) } diff --git a/benches/s3/bench_bucket_policy.rs b/benches/s3/bench_bucket_policy.rs index d63a913d..0362ad00 100644 --- a/benches/s3/bench_bucket_policy.rs +++ b/benches/s3/bench_bucket_policy.rs @@ -27,7 +27,11 @@ pub(crate) fn bench_put_bucket_policy(criterion: &mut Criterion) { || async { Ctx2::new().await }, |ctx| { let config = create_bucket_policy_config_example(&ctx.bucket); - PutBucketPolicy::new(ctx.client.clone(), ctx.bucket.clone()).config(config) + PutBucketPolicy::builder() + .client(ctx.client.clone()) + .bucket(ctx.bucket.clone()) + .config(config) + .build() }, ) } @@ -38,14 +42,22 @@ 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); - PutBucketPolicy::new(ctx.client.clone(), ctx.bucket.clone()) + PutBucketPolicy::builder() + .client(ctx.client.clone()) + .bucket(ctx.bucket.clone()) .config(config) + .build() .send() .await .unwrap(); ctx }, - |ctx| GetBucketPolicy::new(ctx.client.clone(), ctx.bucket.clone()), + |ctx| { + GetBucketPolicy::builder() + .client(ctx.client.clone()) + .bucket(ctx.bucket.clone()) + .build() + }, ) } pub(crate) fn bench_delete_bucket_policy(criterion: &mut Criterion) { @@ -53,6 +65,11 @@ pub(crate) fn bench_delete_bucket_policy(criterion: &mut Criterion) { "delete_bucket_policy", criterion, || async { Ctx2::new().await }, - |ctx| DeleteBucketPolicy::new(ctx.client.clone(), ctx.bucket.clone()), + |ctx| { + DeleteBucketPolicy::builder() + .client(ctx.client.clone()) + .bucket(ctx.bucket.clone()) + .build() + }, ) } diff --git a/benches/s3/bench_bucket_replication.rs b/benches/s3/bench_bucket_replication.rs index 1ae70820..e2536b7d 100644 --- a/benches/s3/bench_bucket_replication.rs +++ b/benches/s3/bench_bucket_replication.rs @@ -36,6 +36,7 @@ pub(crate) fn bench_put_bucket_replication(criterion: &mut Criterion) { .client .put_bucket_versioning(&ctx.bucket) .versioning_status(VersioningStatus::Enabled) + .build() .send() .await .unwrap(); @@ -44,6 +45,7 @@ pub(crate) fn bench_put_bucket_replication(criterion: &mut Criterion) { .client .put_bucket_versioning(ctx.aux_bucket.clone().unwrap()) .versioning_status(VersioningStatus::Enabled) + .build() .send() .await .unwrap(); @@ -53,8 +55,11 @@ pub(crate) fn bench_put_bucket_replication(criterion: &mut Criterion) { |ctx| { let config = create_bucket_replication_config_example(ctx.aux_bucket.clone().unwrap().as_str()); - PutBucketReplication::new(ctx.client.clone(), ctx.bucket.clone()) + PutBucketReplication::builder() + .client(ctx.client.clone()) + .bucket(ctx.bucket.clone()) .replication_config(config) + .build() }, ) } @@ -71,6 +76,7 @@ pub(crate) fn bench_get_bucket_replication(criterion: &mut Criterion) { .client .put_bucket_versioning(&ctx.bucket) .versioning_status(VersioningStatus::Enabled) + .build() .send() .await .unwrap(); @@ -79,13 +85,19 @@ pub(crate) fn bench_get_bucket_replication(criterion: &mut Criterion) { .client .put_bucket_versioning(ctx.aux_bucket.clone().unwrap()) .versioning_status(VersioningStatus::Enabled) + .build() .send() .await .unwrap(); ctx }, - |ctx| GetBucketReplication::new(ctx.client.clone(), ctx.bucket.clone()), + |ctx| { + GetBucketReplication::builder() + .client(ctx.client.clone()) + .bucket(ctx.bucket.clone()) + .build() + }, ) } #[allow(dead_code)] @@ -101,6 +113,7 @@ pub(crate) fn bench_delete_bucket_replication(criterion: &mut Criterion) { .client .put_bucket_versioning(&ctx.bucket) .versioning_status(VersioningStatus::Enabled) + .build() .send() .await .unwrap(); @@ -109,12 +122,18 @@ pub(crate) fn bench_delete_bucket_replication(criterion: &mut Criterion) { .client .put_bucket_versioning(ctx.aux_bucket.clone().unwrap()) .versioning_status(VersioningStatus::Enabled) + .build() .send() .await .unwrap(); ctx }, - |ctx| DeleteBucketReplication::new(ctx.client.clone(), ctx.bucket.clone()), + |ctx| { + DeleteBucketReplication::builder() + .client(ctx.client.clone()) + .bucket(ctx.bucket.clone()) + .build() + }, ) } diff --git a/benches/s3/bench_bucket_tagging.rs b/benches/s3/bench_bucket_tagging.rs index 8f0ad00b..62785ce7 100644 --- a/benches/s3/bench_bucket_tagging.rs +++ b/benches/s3/bench_bucket_tagging.rs @@ -29,8 +29,11 @@ pub(crate) async fn bench_put_bucket_tagging(criterion: &mut Criterion) { criterion, || async { Ctx2::new().await }, |ctx| { - PutBucketTagging::new(ctx.client.clone(), ctx.bucket.clone()) + PutBucketTagging::builder() + .client(ctx.client.clone()) + .bucket(ctx.bucket.clone()) .tags(create_tags_example()) + .build() }, ) } @@ -46,12 +49,18 @@ pub(crate) async fn bench_get_bucket_tagging(criterion: &mut Criterion) { ctx.client .put_bucket_tagging(&ctx.bucket) .tags(create_tags_example()) + .build() .send() .await .unwrap(); ctx }, - |ctx| GetBucketTagging::new(ctx.client.clone(), ctx.bucket.clone()), + |ctx| { + GetBucketTagging::builder() + .client(ctx.client.clone()) + .bucket(ctx.bucket.clone()) + .build() + }, ) } pub(crate) async fn bench_delete_bucket_tagging(criterion: &mut Criterion) { @@ -62,6 +71,11 @@ pub(crate) async fn bench_delete_bucket_tagging(criterion: &mut Criterion) { "delete_bucket_tagging", criterion, || async { Ctx2::new().await }, - |ctx| DeleteBucketTagging::new(ctx.client.clone(), ctx.bucket.clone()), + |ctx| { + DeleteBucketTagging::builder() + .client(ctx.client.clone()) + .bucket(ctx.bucket.clone()) + .build() + }, ) } diff --git a/benches/s3/bench_bucket_versioning.rs b/benches/s3/bench_bucket_versioning.rs index 44394dfd..ccc64be9 100644 --- a/benches/s3/bench_bucket_versioning.rs +++ b/benches/s3/bench_bucket_versioning.rs @@ -26,7 +26,12 @@ pub(crate) async fn bench_get_bucket_versioning(criterion: &mut Criterion) { "get_bucket_versioning", criterion, || async { Ctx2::new().await }, - |ctx| GetBucketVersioning::new(ctx.client.clone(), ctx.bucket.clone()), + |ctx| { + GetBucketVersioning::builder() + .client(ctx.client.clone()) + .bucket(ctx.bucket.clone()) + .build() + }, ) } pub(crate) async fn bench_put_bucket_versioning(criterion: &mut Criterion) { @@ -38,8 +43,11 @@ pub(crate) async fn bench_put_bucket_versioning(criterion: &mut Criterion) { criterion, || async { Ctx2::new().await }, |ctx| { - PutBucketVersioning::new(ctx.client.clone(), ctx.bucket.clone()) + PutBucketVersioning::builder() + .client(ctx.client.clone()) + .bucket(ctx.bucket.clone()) .versioning_status(VersioningStatus::Enabled) + .build() }, ) } diff --git a/benches/s3/bench_list_bucket.rs b/benches/s3/bench_list_bucket.rs index 8709eebd..c1327846 100644 --- a/benches/s3/bench_list_bucket.rs +++ b/benches/s3/bench_list_bucket.rs @@ -23,6 +23,6 @@ pub(crate) fn bench_list_buckets(criterion: &mut Criterion) { "list_buckets", criterion, || async { Ctx2::new().await }, - |ctx| ListBuckets::new(ctx.client.clone()), + |ctx| ListBuckets::builder().client(ctx.client.clone()).build(), ) } diff --git a/benches/s3/bench_object_append.rs b/benches/s3/bench_object_append.rs index 309333d1..61be5c3b 100644 --- a/benches/s3/bench_object_append.rs +++ b/benches/s3/bench_object_append.rs @@ -14,6 +14,7 @@ // limitations under the License. use crate::common_benches::{Ctx2, benchmark_s3_api}; +use std::sync::Arc; use criterion::Criterion; use minio::s3::builders::AppendObject; @@ -41,18 +42,23 @@ pub(crate) async fn bench_object_append(criterion: &mut Criterion) { let resp: StatObjectResponse = task::block_in_place(|| { let runtime = tokio::runtime::Runtime::new().map_err(|e| Error::DriveIo(e.into()))?; - runtime.block_on(ctx.client.stat_object(&ctx.bucket, &ctx.object).send()) + runtime.block_on( + ctx.client + .stat_object(&ctx.bucket, &ctx.object) + .build() + .send(), + ) }) .unwrap(); let offset_bytes: u64 = resp.size().unwrap(); - AppendObject::new( - ctx.client.clone(), - ctx.bucket.clone(), - ctx.object.clone(), - data1, - offset_bytes, - ) + AppendObject::builder() + .client(ctx.client.clone()) + .bucket(ctx.bucket.clone()) + .object(ctx.object.clone()) + .data(Arc::new(data1)) + .offset_bytes(offset_bytes) + .build() }, ) } diff --git a/benches/s3/bench_object_copy.rs b/benches/s3/bench_object_copy.rs index eb76d261..13bd1fc0 100644 --- a/benches/s3/bench_object_copy.rs +++ b/benches/s3/bench_object_copy.rs @@ -27,8 +27,17 @@ pub(crate) fn bench_object_copy_internal(criterion: &mut Criterion) { |ctx| { let object_name_src = &ctx.object; let object_name_dst = rand_object_name(); - CopyObjectInternal::new(ctx.client.clone(), ctx.bucket.clone(), object_name_dst) - .source(CopySource::new(&ctx.bucket, object_name_src).unwrap()) + CopyObjectInternal::builder() + .client(ctx.client.clone()) + .bucket(ctx.bucket.clone()) + .object(object_name_dst) + .source( + CopySource::builder() + .bucket(ctx.bucket.clone()) + .object(object_name_src) + .build(), + ) + .build() }, ) } diff --git a/benches/s3/bench_object_legal_hold.rs b/benches/s3/bench_object_legal_hold.rs index dd139b45..2032e09d 100644 --- a/benches/s3/bench_object_legal_hold.rs +++ b/benches/s3/bench_object_legal_hold.rs @@ -28,8 +28,12 @@ pub(crate) async fn bench_put_object_legal_hold(criterion: &mut Criterion) { criterion, || async { Ctx2::new_with_object(true).await }, |ctx| { - PutObjectLegalHold::new(ctx.client.clone(), ctx.bucket.clone(), ctx.object.clone()) - .legal_hold(Some(true)) + PutObjectLegalHold::builder() + .client(ctx.client.clone()) + .bucket(ctx.bucket.clone()) + .object(ctx.object.clone()) + .legal_hold(true) + .build() }, ) } @@ -44,11 +48,18 @@ pub(crate) async fn bench_get_object_legal_hold(criterion: &mut Criterion) { let ctx = Ctx2::new_with_object(true).await; ctx.client .get_object_legal_hold(&ctx.bucket, &ctx.object) + .build() .send() .await .unwrap(); ctx }, - |ctx| GetObjectLegalHold::new(ctx.client.clone(), ctx.bucket.clone(), ctx.object.clone()), + |ctx| { + GetObjectLegalHold::builder() + .client(ctx.client.clone()) + .bucket(ctx.bucket.clone()) + .object(ctx.object.clone()) + .build() + }, ) } diff --git a/benches/s3/bench_object_lock_config.rs b/benches/s3/bench_object_lock_config.rs index 83e69495..29a23344 100644 --- a/benches/s3/bench_object_lock_config.rs +++ b/benches/s3/bench_object_lock_config.rs @@ -28,7 +28,11 @@ pub(crate) async fn bench_put_object_lock_config(criterion: &mut Criterion) { || async { Ctx2::new_with_object(true).await }, |ctx| { let config = create_object_lock_config_example(); - PutObjectLockConfig::new(ctx.client.clone(), ctx.bucket.clone()).config(config) + PutObjectLockConfig::builder() + .client(ctx.client.clone()) + .bucket(ctx.bucket.clone()) + .config(config) + .build() }, ) } @@ -40,7 +44,12 @@ pub(crate) async fn bench_get_object_lock_config(criterion: &mut Criterion) { "get_object_lock_config", criterion, || async { Ctx2::new_with_object(true).await }, - |ctx| GetObjectLockConfig::new(ctx.client.clone(), ctx.bucket.clone()), + |ctx| { + GetObjectLockConfig::builder() + .client(ctx.client.clone()) + .bucket(ctx.bucket.clone()) + .build() + }, ) } pub(crate) async fn bench_delete_object_lock_config(criterion: &mut Criterion) { @@ -51,6 +60,11 @@ pub(crate) async fn bench_delete_object_lock_config(criterion: &mut Criterion) { "delete_object_lock_config", criterion, || async { Ctx2::new_with_object(true).await }, - |ctx| DeleteObjectLockConfig::new(ctx.client.clone(), ctx.bucket.clone()), + |ctx| { + DeleteObjectLockConfig::builder() + .client(ctx.client.clone()) + .bucket(ctx.bucket.clone()) + .build() + }, ) } diff --git a/benches/s3/bench_object_put.rs b/benches/s3/bench_object_put.rs index 3d2cd493..e6bf1eb9 100644 --- a/benches/s3/bench_object_put.rs +++ b/benches/s3/bench_object_put.rs @@ -14,9 +14,10 @@ // limitations under the License. use crate::common_benches::{Ctx2, benchmark_s3_api}; +use std::sync::Arc; use criterion::Criterion; -use minio::s3::builders::{ObjectContent, PutObject}; +use minio::s3::builders::{ObjectContent, PutObject, UploadPart}; use minio::s3::segmented_bytes::SegmentedBytes; use minio_common::rand_src::RandSrc; use minio_common::utils::rand_object_name; @@ -37,7 +38,16 @@ pub(crate) fn bench_object_put(criterion: &mut Criterion) { }) .unwrap(); - PutObject::new(ctx.client.clone(), ctx.bucket.clone(), object_name, data) + PutObject::builder() + .inner( + UploadPart::builder() + .client(ctx.client.clone()) + .bucket(ctx.bucket.clone()) + .object(object_name) + .data(Arc::new(data)) + .build(), + ) + .build() }, ) } diff --git a/benches/s3/bench_object_retention.rs b/benches/s3/bench_object_retention.rs index 40c30546..07a27ead 100644 --- a/benches/s3/bench_object_retention.rs +++ b/benches/s3/bench_object_retention.rs @@ -30,9 +30,13 @@ pub(crate) async fn bench_put_object_retention(criterion: &mut Criterion) { criterion, || async { Ctx2::new_with_object(true).await }, |ctx| { - PutObjectRetention::new(ctx.client.clone(), ctx.bucket.clone(), ctx.object.clone()) + PutObjectRetention::builder() + .client(ctx.client.clone()) + .bucket(ctx.bucket.clone()) + .object(ctx.object.clone()) .retention_mode(Some(RetentionMode::GOVERNANCE)) .retain_until_date(Some(utc_now() + chrono::Duration::days(1))) + .build() }, ) } @@ -45,15 +49,24 @@ pub(crate) async fn bench_get_object_retention(criterion: &mut Criterion) { criterion, || async { let ctx = Ctx2::new_with_object(true).await; - 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() - .await - .unwrap(); + let _resp: PutObjectRetentionResponse = PutObjectRetention::builder() + .client(ctx.client.clone()) + .bucket(ctx.bucket.clone()) + .object(ctx.object.clone()) + .retention_mode(Some(RetentionMode::GOVERNANCE)) + .retain_until_date(Some(utc_now() + chrono::Duration::days(1))) + .build() + .send() + .await + .unwrap(); ctx }, - |ctx| GetObjectRetention::new(ctx.client.clone(), ctx.bucket.clone(), ctx.object.clone()), + |ctx| { + GetObjectRetention::builder() + .client(ctx.client.clone()) + .bucket(ctx.bucket.clone()) + .object(ctx.object.clone()) + .build() + }, ) } diff --git a/benches/s3/bench_object_tagging.rs b/benches/s3/bench_object_tagging.rs index e733ac1e..9edd117e 100644 --- a/benches/s3/bench_object_tagging.rs +++ b/benches/s3/bench_object_tagging.rs @@ -30,8 +30,12 @@ pub(crate) async fn bench_put_object_tagging(criterion: &mut Criterion) { criterion, || async { Ctx2::new_with_object(false).await }, |ctx| { - PutObjectTagging::new(ctx.client.clone(), ctx.bucket.clone(), ctx.object.clone()) + PutObjectTagging::builder() + .client(ctx.client.clone()) + .bucket(ctx.bucket.clone()) + .object(ctx.object.clone()) .tags(create_tags_example()) + .build() }, ) } @@ -49,11 +53,18 @@ pub(crate) async fn bench_get_object_tagging(criterion: &mut Criterion) { .client .put_object_tagging(&ctx.bucket, &ctx.object) .tags(create_tags_example()) + .build() .send() .await .unwrap(); ctx }, - |ctx| GetObjectTagging::new(ctx.client.clone(), ctx.bucket.clone(), ctx.object.clone()), + |ctx| { + GetObjectTagging::builder() + .client(ctx.client.clone()) + .bucket(ctx.bucket.clone()) + .object(ctx.object.clone()) + .build() + }, ) } diff --git a/benches/s3/common_benches.rs b/benches/s3/common_benches.rs index 89ad455a..b99f999d 100644 --- a/benches/s3/common_benches.rs +++ b/benches/s3/common_benches.rs @@ -14,7 +14,7 @@ // limitations under the License. use criterion::Criterion; -use minio::s3::Client; +use minio::s3::MinioClient; use minio::s3::error::Error; use minio::s3::response::{CreateBucketResponse, PutObjectContentResponse}; use minio::s3::types::{FromS3Response, S3Api, S3Request}; @@ -27,7 +27,7 @@ use std::env; use tokio::runtime::Runtime; pub(crate) struct Ctx2 { - pub client: Client, + pub client: MinioClient, pub bucket: String, pub object: String, _cleanup: CleanupGuard, @@ -64,6 +64,7 @@ impl Ctx2 { .client .create_bucket(&bucket_name) .object_lock(object_lock) + .build() .send() .await .unwrap(); @@ -73,6 +74,7 @@ impl Ctx2 { let _resp: PutObjectContentResponse = ctx .client .put_object_content(&bucket_name, &object_name, data) + .build() .send() .await .unwrap(); @@ -95,6 +97,7 @@ impl Ctx2 { .client .create_bucket(&bucket_name) .object_lock(false) + .build() .send() .await .unwrap(); diff --git a/common/src/cleanup_guard.rs b/common/src/cleanup_guard.rs index 2347b987..83c52238 100644 --- a/common/src/cleanup_guard.rs +++ b/common/src/cleanup_guard.rs @@ -13,17 +13,17 @@ // See the License for the specific language governing permissions and // limitations under the License. -use minio::s3::Client; +use minio::s3::MinioClient; /// Cleanup guard that removes the bucket when it is dropped pub struct CleanupGuard { - client: Client, + client: MinioClient, bucket_name: String, } impl CleanupGuard { #[allow(dead_code)] - pub fn new>(client: Client, bucket_name: S) -> Self { + pub fn new>(client: MinioClient, bucket_name: S) -> Self { Self { client, bucket_name: bucket_name.into(), @@ -35,7 +35,7 @@ impl CleanupGuard { } } -pub async fn cleanup(client: Client, bucket_name: &str) { +pub async fn cleanup(client: MinioClient, bucket_name: &str) { tokio::select!( _ = tokio::time::sleep(std::time::Duration::from_secs(60)) => { eprintln!("Cleanup timeout after 60s while removing bucket {bucket_name}"); diff --git a/common/src/test_context.rs b/common/src/test_context.rs index 291ffc51..de4d2217 100644 --- a/common/src/test_context.rs +++ b/common/src/test_context.rs @@ -15,7 +15,7 @@ use crate::cleanup_guard::CleanupGuard; use crate::utils::rand_bucket_name; -use minio::s3::Client; +use minio::s3::MinioClient; use minio::s3::creds::StaticProvider; use minio::s3::http::BaseUrl; use minio::s3::types::S3Api; @@ -23,7 +23,7 @@ use std::path::{Path, PathBuf}; #[derive(Clone)] pub struct TestContext { - pub client: Client, + pub client: MinioClient, pub base_url: BaseUrl, pub access_key: String, pub secret_key: String, @@ -57,7 +57,7 @@ impl TestContext { } let static_provider = StaticProvider::new(&access_key, &secret_key, None); - let client = Client::new( + let client = MinioClient::new( base_url.clone(), Some(static_provider), ssl_cert_file, @@ -114,7 +114,7 @@ impl TestContext { base_url.region = region; let static_provider = StaticProvider::new(&access_key, &secret_key, None); - let client = Client::new( + let client = MinioClient::new( base_url.clone(), Some(static_provider), Some(&*ssl_cert_file), @@ -154,6 +154,7 @@ impl TestContext { let _resp = self .client .create_bucket(&bucket_name) + .build() .send() .await .unwrap(); diff --git a/examples/append_object.rs b/examples/append_object.rs index c24e0079..a2d5fc08 100644 --- a/examples/append_object.rs +++ b/examples/append_object.rs @@ -15,8 +15,8 @@ mod common; -use crate::common::{create_bucket_if_not_exists, create_client_on_localhost}; -use minio::s3::Client; +use crate::common::create_bucket_if_not_exists; +use minio::s3::MinioClient; use minio::s3::response::a_response_traits::HasObjectSize; use minio::s3::response::{AppendObjectResponse, StatObjectResponse}; use minio::s3::segmented_bytes::SegmentedBytes; @@ -27,7 +27,7 @@ use rand::distr::Alphanumeric; #[tokio::main] async fn main() -> Result<(), Box> { env_logger::init(); // Note: set environment variable RUST_LOG="INFO" to log info and higher - let client: Client = create_client_on_localhost()?; + let client: MinioClient = MinioClient::create_client_on_localhost()?; if !client.is_minio_express().await { println!("Need (MinIO) Express mode to run this example"); @@ -51,6 +51,7 @@ async fn main() -> Result<(), Box> { let resp: AppendObjectResponse = client .append_object(bucket_name, object_name, data, offset_bytes) + .build() .send() .await?; @@ -63,7 +64,11 @@ async fn main() -> Result<(), Box> { } //println!("Append response: {resp:#?}"); - let resp: StatObjectResponse = client.stat_object(bucket_name, object_name).send().await?; + let resp: StatObjectResponse = client + .stat_object(bucket_name, object_name) + .build() + .send() + .await?; if resp.size()? != offset_bytes { panic!( "from the stat_Object: size mismatch: expected {}, got {offset_bytes}", diff --git a/examples/bucket_encryption.rs b/examples/bucket_encryption.rs index c36769dc..fead410a 100644 --- a/examples/bucket_encryption.rs +++ b/examples/bucket_encryption.rs @@ -16,20 +16,23 @@ mod common; use crate::common::{create_bucket_if_not_exists, create_client_on_play}; -use minio::s3::Client; +use minio::s3::MinioClient; use minio::s3::response::{GetBucketEncryptionResponse, PutBucketEncryptionResponse}; use minio::s3::types::{S3Api, SseConfig}; #[tokio::main] async fn main() -> Result<(), Box> { env_logger::init(); // Note: set environment variable RUST_LOG="INFO" to log info and higher - let client: Client = create_client_on_play()?; + let client: MinioClient = create_client_on_play()?; let bucket_name: &str = "encryption-rust-bucket"; create_bucket_if_not_exists(bucket_name, &client).await?; - let resp: GetBucketEncryptionResponse = - client.get_bucket_encryption(bucket_name).send().await?; + let resp: GetBucketEncryptionResponse = client + .get_bucket_encryption(bucket_name) + .build() + .send() + .await?; log::info!("encryption before: config={:?}", resp.config()); let config = SseConfig::default(); @@ -38,11 +41,15 @@ async fn main() -> Result<(), Box> { let _resp: PutBucketEncryptionResponse = client .put_bucket_encryption(bucket_name) .sse_config(config.clone()) + .build() .send() .await?; - let resp: GetBucketEncryptionResponse = - client.get_bucket_encryption(bucket_name).send().await?; + let resp: GetBucketEncryptionResponse = client + .get_bucket_encryption(bucket_name) + .build() + .send() + .await?; log::info!("encryption after: config={:?}", resp.config()); Ok(()) diff --git a/examples/bucket_lifecycle.rs b/examples/bucket_lifecycle.rs index 6c694003..245f13a7 100644 --- a/examples/bucket_lifecycle.rs +++ b/examples/bucket_lifecycle.rs @@ -16,7 +16,7 @@ mod common; use crate::common::{create_bucket_if_not_exists, create_client_on_play}; -use minio::s3::Client; +use minio::s3::MinioClient; use minio::s3::lifecycle_config::{LifecycleConfig, LifecycleRule}; use minio::s3::response::{ DeleteBucketLifecycleResponse, GetBucketLifecycleResponse, PutBucketLifecycleResponse, @@ -26,15 +26,18 @@ use minio::s3::types::{Filter, S3Api}; #[tokio::main] async fn main() -> Result<(), Box> { env_logger::init(); // Note: set environment variable RUST_LOG="INFO" to log info and higher - let client: Client = create_client_on_play()?; + let client: MinioClient = create_client_on_play()?; let bucket_name: &str = "lifecycle-rust-bucket"; create_bucket_if_not_exists(bucket_name, &client).await?; if false { // TODO - let resp: GetBucketLifecycleResponse = - client.get_bucket_lifecycle(bucket_name).send().await?; + let resp: GetBucketLifecycleResponse = client + .get_bucket_lifecycle(bucket_name) + .build() + .send() + .await?; log::info!("life cycle settings before setting: resp={resp:?}"); } @@ -52,21 +55,28 @@ async fn main() -> Result<(), Box> { let resp: PutBucketLifecycleResponse = client .put_bucket_lifecycle(bucket_name) .life_cycle_config(LifecycleConfig { rules }) + .build() .send() .await?; log::info!("response of setting life cycle config: resp={resp:?}"); if false { // TODO - let resp: GetBucketLifecycleResponse = - client.get_bucket_lifecycle(bucket_name).send().await?; + let resp: GetBucketLifecycleResponse = client + .get_bucket_lifecycle(bucket_name) + .build() + .send() + .await?; log::info!("life cycle settings after setting: resp={resp:?}"); } if false { // TODO - let resp: DeleteBucketLifecycleResponse = - client.delete_bucket_lifecycle(bucket_name).send().await?; + let resp: DeleteBucketLifecycleResponse = client + .delete_bucket_lifecycle(bucket_name) + .build() + .send() + .await?; log::info!("response of deleting lifecycle config: resp={resp:?}"); } Ok(()) diff --git a/examples/bucket_versioning.rs b/examples/bucket_versioning.rs index d11e2768..9c613378 100644 --- a/examples/bucket_versioning.rs +++ b/examples/bucket_versioning.rs @@ -16,7 +16,7 @@ mod common; use crate::common::{create_bucket_if_not_exists, create_client_on_play}; -use minio::s3::Client; +use minio::s3::MinioClient; use minio::s3::builders::VersioningStatus; use minio::s3::response::{GetBucketVersioningResponse, PutBucketVersioningResponse}; use minio::s3::types::S3Api; @@ -24,13 +24,16 @@ use minio::s3::types::S3Api; #[tokio::main] async fn main() -> Result<(), Box> { env_logger::init(); // Note: set environment variable RUST_LOG="INFO" to log info and higher - let client: Client = create_client_on_play()?; + let client: MinioClient = create_client_on_play()?; let bucket_name: &str = "versioning-rust-bucket"; create_bucket_if_not_exists(bucket_name, &client).await?; - let resp: GetBucketVersioningResponse = - client.get_bucket_versioning(bucket_name).send().await?; + let resp: GetBucketVersioningResponse = client + .get_bucket_versioning(bucket_name) + .build() + .send() + .await?; log::info!( "versioning before: status={:?}, mfa_delete={:?}", resp.status(), @@ -40,11 +43,15 @@ async fn main() -> Result<(), Box> { let _resp: PutBucketVersioningResponse = client .put_bucket_versioning(bucket_name) .versioning_status(VersioningStatus::Enabled) + .build() .send() .await?; - let resp: GetBucketVersioningResponse = - client.get_bucket_versioning(bucket_name).send().await?; + let resp: GetBucketVersioningResponse = client + .get_bucket_versioning(bucket_name) + .build() + .send() + .await?; log::info!( "versioning after setting to Enabled: status={:?}, mfa_delete={:?}", @@ -55,11 +62,15 @@ async fn main() -> Result<(), Box> { let _resp: PutBucketVersioningResponse = client .put_bucket_versioning(bucket_name) .versioning_status(VersioningStatus::Suspended) + .build() .send() .await?; - let resp: GetBucketVersioningResponse = - client.get_bucket_versioning(bucket_name).send().await?; + let resp: GetBucketVersioningResponse = client + .get_bucket_versioning(bucket_name) + .build() + .send() + .await?; log::info!( "versioning after setting to Suspended: status={:?}, mfa_delete={:?}", @@ -70,11 +81,15 @@ async fn main() -> Result<(), Box> { let _resp: PutBucketVersioningResponse = client .put_bucket_versioning(bucket_name) //.versioning_status(VersioningStatus::Suspended) + .build() .send() .await?; - let resp: GetBucketVersioningResponse = - client.get_bucket_versioning(bucket_name).send().await?; + let resp: GetBucketVersioningResponse = client + .get_bucket_versioning(bucket_name) + .build() + .send() + .await?; log::info!( "versioning after setting to None: status={:?}, mfa_delete={:?}", diff --git a/examples/common.rs b/examples/common.rs index d3624e01..8c49dfd1 100644 --- a/examples/common.rs +++ b/examples/common.rs @@ -1,11 +1,26 @@ +// 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 minio::s3::creds::StaticProvider; use minio::s3::http::BaseUrl; use minio::s3::response::BucketExistsResponse; use minio::s3::types::S3Api; -use minio::s3::{Client, ClientBuilder}; +use minio::s3::{MinioClient, MinioClientBuilder}; #[allow(dead_code)] -pub fn create_client_on_play() -> Result> { +pub fn create_client_on_play() -> Result> { let base_url = "https://play.min.io".parse::()?; log::info!("Trying to connect to MinIO at: `{base_url:?}`"); @@ -15,20 +30,7 @@ pub fn create_client_on_play() -> Result Result> { - let base_url = "http://localhost:9000/".parse::()?; - log::info!("Trying to connect to MinIO at: `{base_url:?}`"); - - let static_provider = StaticProvider::new("minioadmin", "minioadmin", None); - - let client = ClientBuilder::new(base_url.clone()) + let client = MinioClientBuilder::new(base_url.clone()) .provider(Some(static_provider)) .build()?; Ok(client) @@ -36,14 +38,14 @@ pub fn create_client_on_localhost() -> Result Result<(), Box> { // Check 'bucket_name' bucket exist or not. - let resp: BucketExistsResponse = client.bucket_exists(bucket_name).send().await?; + let resp: BucketExistsResponse = client.bucket_exists(bucket_name).build().send().await?; // Make 'bucket_name' bucket if not exist. if !resp.exists() { - client.create_bucket(bucket_name).send().await.unwrap(); + client.create_bucket(bucket_name).build().send().await?; }; Ok(()) } diff --git a/examples/file_downloader.rs b/examples/file_downloader.rs index f26f0be3..94b4ae64 100644 --- a/examples/file_downloader.rs +++ b/examples/file_downloader.rs @@ -16,7 +16,7 @@ mod common; use crate::common::{create_bucket_if_not_exists, create_client_on_play}; -use minio::s3::Client; +use minio::s3::MinioClient; use minio::s3::builders::ObjectContent; use minio::s3::types::S3Api; use std::path::Path; @@ -24,7 +24,7 @@ use std::path::Path; #[tokio::main] async fn main() -> Result<(), Box> { env_logger::init(); // Note: set environment variable RUST_LOG="INFO" to log info and higher - let client: Client = create_client_on_play()?; + let client: MinioClient = create_client_on_play()?; let bucket_name: &str = "file-download-rust-bucket"; let object_name: &str = "cat.png"; @@ -45,6 +45,7 @@ async fn main() -> Result<(), Box> { let content = ObjectContent::from(filename); client .put_object_content(bucket_name, object_name, content) + .build() .send() .await?; @@ -53,7 +54,11 @@ async fn main() -> Result<(), Box> { filename.display() ); - let get_object = client.get_object(bucket_name, object_name).send().await?; + let get_object = client + .get_object(bucket_name, object_name) + .build() + .send() + .await?; get_object .content()? diff --git a/examples/file_uploader.rs b/examples/file_uploader.rs index 37dfa76a..96a9c966 100644 --- a/examples/file_uploader.rs +++ b/examples/file_uploader.rs @@ -15,14 +15,14 @@ mod common; use crate::common::{create_bucket_if_not_exists, create_client_on_play}; -use minio::s3::Client; +use minio::s3::MinioClient; use minio::s3::builders::ObjectContent; use std::path::Path; #[tokio::main] async fn main() -> Result<(), Box> { env_logger::init(); // Note: set environment variable RUST_LOG="INFO" to log info and higher - let client: Client = create_client_on_play()?; + let client: MinioClient = create_client_on_play()?; let bucket_name: &str = "file-upload-rust-bucket"; create_bucket_if_not_exists(bucket_name, &client).await?; @@ -43,6 +43,7 @@ async fn main() -> Result<(), Box> { let content = ObjectContent::from(filename); client .put_object_content(bucket_name, object_name, content) + .build() .send() .await?; diff --git a/examples/object_prompt.rs b/examples/object_prompt.rs index ff84193f..3b38e8b4 100644 --- a/examples/object_prompt.rs +++ b/examples/object_prompt.rs @@ -16,8 +16,8 @@ mod common; use crate::common::create_bucket_if_not_exists; +use minio::s3::MinioClientBuilder; use minio::s3::builders::ObjectContent; -use minio::s3::client::ClientBuilder; use minio::s3::creds::StaticProvider; use minio::s3::http::BaseUrl; use minio::s3::response::GetObjectPromptResponse; @@ -34,7 +34,7 @@ async fn main() -> Result<(), Box> { let static_provider = StaticProvider::new("admin", "admin", None); - let client = ClientBuilder::new(base_url.clone()) + let client = MinioClientBuilder::new(base_url.clone()) .provider(Some(static_provider)) .ignore_cert_check(Some(true)) .build()?; @@ -58,6 +58,7 @@ async fn main() -> Result<(), Box> { let content = ObjectContent::from(filename); client .put_object_content(bucket_name, object_name, content) + .build() .send() .await?; @@ -69,6 +70,7 @@ async fn main() -> Result<(), Box> { 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 + .build() .send() .await?; diff --git a/examples/put_object.rs b/examples/put_object.rs index 56861f26..9eed4a29 100644 --- a/examples/put_object.rs +++ b/examples/put_object.rs @@ -17,7 +17,7 @@ use clap::Parser; use log::info; use minio::s3::response::BucketExistsResponse; use minio::s3::types::S3Api; -use minio::s3::{Client, builders::ObjectContent, client::ClientBuilder, creds::StaticProvider}; +use minio::s3::{MinioClient, MinioClientBuilder, builders::ObjectContent, creds::StaticProvider}; use std::path::PathBuf; /// Upload a file to the given bucket and object path on the MinIO Play server. @@ -41,20 +41,21 @@ async fn main() -> Result<(), Box> { None, ); - let client: Client = ClientBuilder::new("https://play.min.io".parse()?) + let client: MinioClient = MinioClientBuilder::new("https://play.min.io".parse()?) .provider(Some(static_provider)) .build()?; - let resp: BucketExistsResponse = client.bucket_exists(&args.bucket).send().await.unwrap(); + let resp: BucketExistsResponse = client.bucket_exists(&args.bucket).build().send().await?; if !resp.exists() { - client.create_bucket(&args.bucket).send().await.unwrap(); + client.create_bucket(&args.bucket).build().send().await?; } let content = ObjectContent::from(args.file.as_path()); // Put an object client .put_object_content(&args.bucket, &args.object, content) + .build() .send() .await?; diff --git a/macros/src/test_attr.rs b/macros/src/test_attr.rs index ef1e102a..d0f5d2ae 100644 --- a/macros/src/test_attr.rs +++ b/macros/src/test_attr.rs @@ -71,7 +71,7 @@ impl MacroArgs { if let Some(FnArg::Typed(pat_type)) = iter.next() { let type_str = pat_type.ty.to_token_stream().to_string(); if !type_str.contains("TestContext") { - let error_msg = "First argument must be of type TestContext"; + let error_msg = "The first argument must be of type TestContext"; return Err(proc_macro::TokenStream::from( Error::custom(error_msg) .with_span(&pat_type.span()) @@ -86,7 +86,7 @@ impl MacroArgs { { let type_str = pat_type.ty.to_token_stream().to_string(); if !type_str.contains("String") { - let error_msg = "Second argument must be of type String"; + let error_msg = "The second argument must be of type String"; return Err(proc_macro::TokenStream::from( Error::custom(error_msg) .with_span(&pat_type.span()) @@ -261,7 +261,7 @@ fn generate_with_bucket_body( let client_clone = ctx.client.clone(); let bucket_name = #bucket_name; - let resp = client_clone.create_bucket(bucket_name)#maybe_lock.send().await.expect("Failed to create bucket"); + let resp = client_clone.create_bucket(bucket_name)#maybe_lock.build().send().await.expect("Failed to create bucket"); assert_eq!(resp.bucket(), bucket_name); let res = AssertUnwindSafe(#inner_fn_name(ctx, resp.bucket().to_string())).catch_unwind().await; #maybe_cleanup diff --git a/src/lib.rs b/src/lib.rs index 88952ee5..16808ef3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -26,16 +26,17 @@ //! ## Basic Usage //! //! ```no_run -//! use minio::s3::Client; +//! use minio::s3::MinioClient; //! use minio::s3::types::S3Api; //! use minio::s3::response::BucketExistsResponse; //! //! #[tokio::main] //! async fn main() { -//! let client: Client = Default::default(); // configure your client +//! let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here //! //! let exists: BucketExistsResponse = client //! .bucket_exists("my-bucket") +//! .build() //! .send() //! .await //! .expect("request failed"); @@ -51,7 +52,7 @@ //! - Transparent error handling via `Result` //! //! ## Design -//! - Each API method on the [`s3::client::Client`] returns a builder struct +//! - Each API method on the [`s3::client::MinioClient`] returns a builder struct //! - Builders implement [`s3::types::ToS3Request`] for request conversion and [`s3::types::S3Api`] for execution //! - Responses implement [`s3::types::FromS3Response`] for consistent deserialization diff --git a/src/s3/builders.rs b/src/s3/builders.rs index 8a06fe96..6a83738d 100644 --- a/src/s3/builders.rs +++ b/src/s3/builders.rs @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Argument builders for [minio::s3::client::Client](crate::s3::client::Client) APIs +//! Argument builders for [minio::s3::client::Client](crate::s3::client::MinioClient) APIs mod append_object; mod bucket_common; diff --git a/src/s3/builders/append_object.rs b/src/s3/builders/append_object.rs index 75631ba0..de23022c 100644 --- a/src/s3/builders/append_object.rs +++ b/src/s3/builders/append_object.rs @@ -13,10 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::s3::Client; use crate::s3::builders::{ ContentStream, MAX_MULTIPART_COUNT, ObjectContent, Size, calc_part_info, }; +use crate::s3::client::MinioClient; use crate::s3::error::ValidationErr; use crate::s3::error::{Error, IoError}; use crate::s3::header_constants::*; @@ -29,61 +29,62 @@ use crate::s3::types::{S3Api, S3Request, ToS3Request}; use crate::s3::utils::{check_bucket_name, check_object_name, check_sse}; use http::Method; use std::sync::Arc; +use typed_builder::TypedBuilder; // region: append-object /// 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)] +/// This struct constructs the parameters required for the [`Client::append_object`](crate::s3::client::MinioClient::append_object) method. +#[derive(Clone, Debug, TypedBuilder)] pub struct AppendObject { - client: Client, + #[builder(!default)] // force required + client: MinioClient, + #[builder(default, setter(into))] extra_headers: Option, + + #[builder(default, setter(into))] extra_query_params: Option, + + #[builder(setter(into))] // force required + accept Into bucket: String, + + #[builder(setter(into))] // force required + accept Into object: String, + #[builder(default, setter(into))] region: Option, + + #[builder(default, setter(into))] sse: Option>, - data: SegmentedBytes, + #[builder(!default)] // force required + data: Arc, + + #[builder(!default)] // force required /// value of x-amz-write-offset-bytes offset_bytes: u64, } -impl AppendObject { - pub fn new( - client: Client, - bucket: String, - object: String, - data: SegmentedBytes, - offset_bytes: u64, - ) -> Self { - Self { - client, - bucket, - object, - offset_bytes, - data, - ..Default::default() - } - } - - pub fn extra_headers(mut self, extra_headers: Option) -> Self { - self.extra_headers = extra_headers; - self - } - - pub fn extra_query_params(mut self, extra_query_params: Option) -> Self { - self.extra_query_params = extra_query_params; - self - } -} - impl S3Api for AppendObject { type S3Response = AppendObjectResponse; } +/// Builder type for [`AppendObject`] that is returned by [`MinioClient::append_object`](crate::s3::client::MinioClient::append_object). +/// +/// This type alias simplifies the complex generic signature generated by the `typed_builder` crate. +pub type AppendObjectBldr = AppendObjectBuilder<( + (MinioClient,), + (), + (), + (String,), + (String,), + (), + (), + (Arc,), + (u64,), +)>; + impl ToS3Request for AppendObject { fn to_s3request(self) -> Result { check_bucket_name(&self.bucket, true)?; @@ -93,13 +94,16 @@ impl ToS3Request for AppendObject { let mut headers: Multimap = self.extra_headers.unwrap_or_default(); headers.add(X_AMZ_WRITE_OFFSET_BYTES, self.offset_bytes.to_string()); - Ok(S3Request::new(self.client, Method::PUT) + Ok(S3Request::builder() + .client(self.client) + .method(Method::PUT) .region(self.region) - .bucket(Some(self.bucket)) + .bucket(self.bucket) .query_params(self.extra_query_params.unwrap_or_default()) - .object(Some(self.object)) + .object(self.object) .headers(headers) - .body(Some(self.data))) + .body(self.data) + .build()) } } // endregion: append-object @@ -108,83 +112,59 @@ impl ToS3Request for AppendObject { /// 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_content`](crate::s3::client::Client::append_object_content) method. +/// This struct constructs the parameters required for the [`Client::append_object_content`](crate::s3::client::MinioClient::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)] +#[derive(TypedBuilder)] pub struct AppendObjectContent { - client: Client, - + #[builder(!default)] // force required + client: MinioClient, + #[builder(default, setter(into))] extra_headers: Option, + #[builder(default, setter(into))] extra_query_params: Option, + #[builder(default, setter(into))] region: Option, + #[builder(setter(into))] // force required + accept Into bucket: String, + #[builder(setter(into))] // force required + accept Into object: String, + #[builder(default)] sse: Option>, + #[builder(default = Size::Unknown)] part_size: Size, - - // source data + #[builder(!default, setter(into))] input_content: ObjectContent, - - // Computed. + #[builder(default = ContentStream::empty())] content_stream: ContentStream, + #[builder(default)] part_count: Option, - /// Value of x-amz-write-offset-bytes + #[builder(default)] offset_bytes: u64, } -impl AppendObjectContent { - pub fn new( - client: Client, - bucket: String, - object: String, - content: impl Into, - ) -> Self { - Self { - client, - bucket, - object, - input_content: content.into(), - extra_headers: None, - extra_query_params: None, - region: None, - sse: None, - part_size: Size::Unknown, - content_stream: ContentStream::empty(), - part_count: None, - offset_bytes: 0, - } - } - - pub fn extra_headers(mut self, extra_headers: Option) -> Self { - self.extra_headers = extra_headers; - self - } - - pub fn extra_query_params(mut self, extra_query_params: Option) -> Self { - self.extra_query_params = extra_query_params; - self - } - - /// Sets the region for the request - pub fn region(mut self, region: Option) -> Self { - self.region = region; - self - } - - pub fn part_size(mut self, part_size: impl Into) -> Self { - self.part_size = part_size.into(); - self - } - - pub fn offset_bytes(mut self, offset_bytes: u64) -> Self { - self.offset_bytes = offset_bytes; - self - } +/// Builder type for [`AppendObjectContent`] that is returned by [`MinioClient::append_object_content`](crate::s3::client::MinioClient::append_object_content). +/// +/// This type alias simplifies the complex generic signature generated by the `typed_builder` crate. +pub type AppendObjectContentBldr = AppendObjectContentBuilder<( + (MinioClient,), + (), + (), + (), + (String,), + (String,), + (), + (), + (ObjectContent,), + (), + (), + (), +)>; +impl AppendObjectContent { pub async fn send(mut self) -> Result { check_bucket_name(&self.bucket, true)?; check_object_name(&self.object)?; @@ -223,6 +203,7 @@ impl AppendObjectContent { let resp: StatObjectResponse = self .client .stat_object(&self.bucket, &self.object) + .build() .send() .await?; //println!("statObjectResponse={:#?}", resp); @@ -247,7 +228,7 @@ impl AppendObjectContent { region: self.region, offset_bytes: current_file_size, sse: self.sse, - data: seg_bytes, + data: Arc::new(seg_bytes), }; ao.send().await } else if object_size.is_known() && (seg_bytes.len() as u64) < part_size { @@ -312,7 +293,7 @@ impl AppendObjectContent { object: self.object.clone(), region: self.region.clone(), sse: self.sse.clone(), - data: part_content, + data: Arc::new(part_content), offset_bytes: next_offset_bytes, }; let resp: AppendObjectResponse = append_object.send().await?; diff --git a/src/s3/builders/bucket_common.rs b/src/s3/builders/bucket_common.rs index d83a18df..9fa7f7f2 100644 --- a/src/s3/builders/bucket_common.rs +++ b/src/s3/builders/bucket_common.rs @@ -13,49 +13,26 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::s3::client::Client; +use crate::s3::client::MinioClient; use crate::s3::multimap_ext::Multimap; use std::marker::PhantomData; +use typed_builder::TypedBuilder; /// Common parameters for bucket operations -/// -/// See [Amazon S3 Buckets](https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingBucket.html) for more information. -#[derive(Clone, Debug, Default)] -pub struct BucketCommon { - pub(crate) client: Client, +#[derive(Clone, Debug, TypedBuilder)] +pub struct BucketCommon { + #[builder(!default)] // force required + pub(crate) client: MinioClient, + #[builder(default, setter(into))] pub(crate) extra_headers: Option, + #[builder(default, setter(into))] pub(crate) extra_query_params: Option, + #[builder(default, setter(into))] pub(crate) region: Option, + #[builder(setter(into))] // force required + accept Into pub(crate) bucket: String, - _operation: PhantomData, -} - -impl BucketCommon { - pub fn new(client: Client, bucket: String) -> BucketCommon { - BucketCommon { - client, - bucket, - ..Default::default() - } - } - - /// Sets extra headers for the request - pub fn extra_headers(mut self, extra_headers: Option) -> Self { - self.extra_headers = extra_headers; - self - } - - /// Sets extra query parameters for the request - pub fn extra_query_params(mut self, extra_query_params: Option) -> Self { - self.extra_query_params = extra_query_params; - self - } - - /// Sets the region for the request - pub fn region(mut self, region: Option) -> Self { - self.region = region; - self - } + #[builder(default)] + _operation: PhantomData, } diff --git a/src/s3/builders/bucket_exists.rs b/src/s3/builders/bucket_exists.rs index 9df54152..cc47ee95 100644 --- a/src/s3/builders/bucket_exists.rs +++ b/src/s3/builders/bucket_exists.rs @@ -13,35 +13,45 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::s3::builders::BucketCommon; +use crate::s3::MinioClient; +use crate::s3::builders::{BucketCommon, BucketCommonBuilder}; use crate::s3::error::ValidationErr; use crate::s3::response::BucketExistsResponse; use crate::s3::types::{S3Api, S3Request, ToS3Request}; use crate::s3::utils::check_bucket_name; use http::Method; -/// This struct constructs the parameters required for the [`Client::bucket_exists`](crate::s3::client::Client::bucket_exists) method. +/// This struct constructs the parameters required for the [`Client::bucket_exists`](crate::s3::client::MinioClient::bucket_exists) method. /// /// See [Amazon S3: Working with Buckets](https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingBucket.html) /// for more information about checking if a bucket exists. pub type BucketExists = BucketCommon; #[doc(hidden)] -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug)] pub struct BucketExistsPhantomData; impl S3Api for BucketExists { type S3Response = BucketExistsResponse; } +/// Builder type for [`BucketExists`] that is returned by [`MinioClient::bucket_exists`](crate::s3::client::MinioClient::bucket_exists). +/// +/// This type alias simplifies the complex generic signature generated by the `typed_builder` crate. +pub type BucketExistsBldr = + BucketCommonBuilder; + impl ToS3Request for BucketExists { fn to_s3request(self) -> Result { check_bucket_name(&self.bucket, true)?; - Ok(S3Request::new(self.client, Method::HEAD) + Ok(S3Request::builder() + .client(self.client) + .method(Method::HEAD) .region(self.region) - .bucket(Some(self.bucket)) + .bucket(self.bucket) .query_params(self.extra_query_params.unwrap_or_default()) - .headers(self.extra_headers.unwrap_or_default())) + .headers(self.extra_headers.unwrap_or_default()) + .build()) } } diff --git a/src/s3/builders/copy_object.rs b/src/s3/builders/copy_object.rs index ecdd5e24..f8553b7c 100644 --- a/src/s3/builders/copy_object.rs +++ b/src/s3/builders/copy_object.rs @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::s3::Client; +use crate::s3::client::MinioClient; use crate::s3::client::{MAX_MULTIPART_COUNT, MAX_PART_SIZE}; use crate::s3::error::{Error, ValidationErr}; use crate::s3::header_constants::*; @@ -34,67 +34,52 @@ use async_recursion::async_recursion; use http::Method; use std::collections::HashMap; use std::sync::Arc; +use typed_builder::TypedBuilder; /// 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)] +/// This struct constructs the parameters required for the [`Client::upload_part_copy`](crate::s3::client::MinioClient::upload_part_copy) method. +#[derive(Clone, Debug, TypedBuilder)] pub struct UploadPartCopy { - client: Client, - + #[builder(!default)] // force required + client: MinioClient, + #[builder(default, setter(into))] extra_headers: Option, + #[builder(default, setter(into))] extra_query_params: Option, + #[builder(default, setter(into))] region: Option, + #[builder(setter(into))] // force required + accept Into bucket: String, - + #[builder(setter(into))] // force required + accept Into object: String, + #[builder(setter(into))] // force required + accept Into upload_id: String, + #[builder(default = 0)] part_number: u16, + #[builder(default)] headers: Multimap, } -impl UploadPartCopy { - pub fn new(client: Client, bucket: String, object: String, upload_id: String) -> Self { - Self { - client, - bucket, - object, - upload_id, - ..Default::default() - } - } - - pub fn extra_headers(mut self, extra_headers: Option) -> Self { - self.extra_headers = extra_headers; - self - } - - pub fn extra_query_params(mut self, extra_query_params: Option) -> Self { - self.extra_query_params = extra_query_params; - self - } - - /// Sets the region for the request - pub fn region(mut self, region: Option) -> Self { - self.region = region; - self - } - - pub fn part_number(mut self, part_number: u16) -> Self { - self.part_number = part_number; - self - } - - pub fn headers(mut self, headers: Multimap) -> Self { - self.headers = headers; - self - } -} - impl S3Api for UploadPartCopy { type S3Response = UploadPartCopyResponse; } +/// Builder type for [`UploadPartCopy`] that is returned by [`MinioClient::upload_part_copy`](crate::s3::client::MinioClient::upload_part_copy). +/// +/// This type alias simplifies the complex generic signature generated by the `typed_builder` crate. +pub type UploadPartCopyBldr = UploadPartCopyBuilder<( + (MinioClient,), + (), + (), + (), + (String,), + (String,), + (String,), + (), + (), +)>; + impl ToS3Request for UploadPartCopy { fn to_s3request(self) -> Result { { @@ -121,113 +106,77 @@ impl ToS3Request for UploadPartCopy { query_params.add("uploadId", self.upload_id); } - Ok(S3Request::new(self.client, Method::PUT) + Ok(S3Request::builder() + .client(self.client) + .method(Method::PUT) .region(self.region) - .bucket(Some(self.bucket)) - .object(Some(self.object)) + .bucket(self.bucket) + .object(self.object) .query_params(query_params) - .headers(headers)) + .headers(headers) + .build()) } } -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug, TypedBuilder)] pub struct CopyObjectInternal { - client: Client, - + #[builder(!default)] // force required + client: MinioClient, + #[builder(default, setter(into))] extra_headers: Option, + #[builder(default, setter(into))] extra_query_params: Option, - region: Option, + #[builder(default, setter(into))] + pub(crate) region: Option, + #[builder(setter(into))] // force required + accept Into bucket: String, - + #[builder(setter(into))] // force required + accept Into object: String, + #[builder(default)] headers: Multimap, + #[builder(default, setter(into))] user_metadata: Option, + #[builder(default, setter(into))] sse: Option>, + #[builder(default, setter(into))] tags: Option>, + #[builder(default, setter(into))] retention: Option, + #[builder(default)] legal_hold: bool, + #[builder(!default)] // force required source: CopySource, - + #[builder(default, setter(into))] metadata_directive: Option, + #[builder(default, setter(into))] tagging_directive: Option, } -impl CopyObjectInternal { - 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) -> Self { - self.extra_headers = extra_headers; - self - } - - pub fn extra_query_params(mut self, extra_query_params: Option) -> Self { - self.extra_query_params = extra_query_params; - self - } - - /// Sets the region for the request - pub fn region(mut self, region: Option) -> Self { - self.region = region; - self - } - - pub fn headers(mut self, headers: Multimap) -> Self { - self.headers = headers; - self - } - - pub fn user_metadata(mut self, user_metadata: Option) -> Self { - self.user_metadata = user_metadata; - self - } - - pub fn sse(mut self, sse: Option>) -> Self { - self.sse = sse; - self - } - - pub fn tags(mut self, tags: Option>) -> Self { - self.tags = tags; - self - } - - pub fn retention(mut self, retention: Option) -> Self { - self.retention = retention; - self - } - - pub fn legal_hold(mut self, legal_hold: bool) -> Self { - self.legal_hold = legal_hold; - self - } - - pub fn source(mut self, source: CopySource) -> Self { - self.source = source; - self - } - - pub fn metadata_directive(mut self, metadata_directive: Option) -> Self { - self.metadata_directive = metadata_directive; - self - } - - pub fn tagging_directive(mut self, tagging_directive: Option) -> Self { - self.tagging_directive = tagging_directive; - self - } -} - impl S3Api for CopyObjectInternal { type S3Response = CopyObjectInternalResponse; } +/// Builder type for [`CopyObjectInternal`] that is returned by [`MinioClient::copy_object_internal`](crate::s3::client::MinioClient::copy_object_internal). +/// +/// This type alias simplifies the complex generic signature generated by the `typed_builder` crate. +pub type CopyObjectInternalBldr = CopyObjectInternalBuilder<( + (MinioClient,), + (), + (), + (), + (String,), + (String,), + (), + (), + (), + (), + (), + (), + (), + (), + (), +)>; + impl ToS3Request for CopyObjectInternal { fn to_s3request(self) -> Result { check_sse(&self.sse, &self.client)?; @@ -314,105 +263,77 @@ impl ToS3Request for CopyObjectInternal { } }; - Ok(S3Request::new(self.client, Method::PUT) + Ok(S3Request::builder() + .client(self.client) + .method(Method::PUT) .region(self.region) - .bucket(Some(self.bucket)) - .object(Some(self.object)) + .bucket(self.bucket) + .object(self.object) .query_params(self.extra_query_params.unwrap_or_default()) - .headers(headers)) + .headers(headers) + .build()) } } /// Argument builder for [`CopyObject`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html) S3 API operation. /// -/// This struct constructs the parameters required for the [`Client::copy_object`](crate::s3::client::Client::copy_object) method. -#[derive(Clone, Debug, Default)] +/// This struct constructs the parameters required for the [`Client::copy_object`](crate::s3::client::MinioClient::copy_object) method. +#[derive(Clone, Debug, TypedBuilder)] pub struct CopyObject { - client: Client, - + #[builder(!default)] // force required + client: MinioClient, + #[builder(default, setter(into))] extra_headers: Option, + #[builder(default, setter(into))] extra_query_params: Option, - region: Option, + #[builder(default, setter(into))] + pub(crate) region: Option, + #[builder(setter(into))] // force required + accept Into bucket: String, - + #[builder(setter(into))] // force required + accept Into object: String, + #[builder(default, setter(into))] headers: Option, + #[builder(default, setter(into))] user_metadata: Option, + #[builder(default, setter(into))] sse: Option>, + #[builder(default, setter(into))] tags: Option>, + #[builder(default, setter(into))] retention: Option, + #[builder(default = false)] legal_hold: bool, + #[builder(!default)] // force required source: CopySource, + #[builder(default, setter(into))] metadata_directive: Option, + #[builder(default, setter(into))] tagging_directive: Option, } -impl CopyObject { - 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) -> Self { - self.extra_headers = extra_headers; - self - } - - pub fn extra_query_params(mut self, extra_query_params: Option) -> Self { - self.extra_query_params = extra_query_params; - self - } - - /// Sets the region for the request - pub fn region(mut self, region: Option) -> Self { - self.region = region; - self - } - - pub fn headers(mut self, headers: Option) -> Self { - self.headers = headers; - self - } - - pub fn user_metadata(mut self, user_metadata: Option) -> Self { - self.user_metadata = user_metadata; - self - } - pub fn sse(mut self, sse: Option>) -> Self { - self.sse = sse; - self - } - pub fn tags(mut self, tags: Option>) -> Self { - self.tags = tags; - self - } - pub fn retention(mut self, retention: Option) -> Self { - self.retention = retention; - self - } - pub fn legal_hold(mut self, legal_hold: bool) -> Self { - self.legal_hold = legal_hold; - self - } - - /// Sets the source for the copy operation. - pub fn source(mut self, source: CopySource) -> Self { - self.source = source; - self - } - pub fn metadata_directive(mut self, metadata_directive: Option) -> Self { - self.metadata_directive = metadata_directive; - self - } - pub fn tagging_directive(mut self, tagging_directive: Option) -> Self { - self.tagging_directive = tagging_directive; - self - } +/// Builder type for [`CopyObject`] that is returned by [`MinioClient::copy_object`](crate::s3::client::MinioClient::copy_object). +/// +/// This type alias simplifies the complex generic signature generated by the `typed_builder` crate. +pub type CopyObjectBldr = CopyObjectBuilder<( + (MinioClient,), + (), + (), + (), + (String,), + (String,), + (), + (), + (), + (), + (), + (), + (), + (), + (), +)>; +impl CopyObject { /// Sends the copy object request. /// /// Functionally related to the [S3Api::send()](crate::s3::types::S3Api::send) method, but @@ -434,6 +355,7 @@ impl CopyObject { .not_match_etag(source.not_match_etag) .modified_since(source.modified_since) .unmodified_since(source.unmodified_since) + .build() .send() .await?; @@ -490,6 +412,7 @@ impl CopyObject { .tags(self.tags) .retention(self.retention) .legal_hold(self.legal_hold) + .build() .send() .await?; @@ -511,6 +434,7 @@ impl CopyObject { .source(self.source) .metadata_directive(self.metadata_directive) .tagging_directive(self.tagging_directive) + .build() .send() .await?; @@ -520,86 +444,56 @@ impl CopyObject { } } -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug, TypedBuilder)] pub struct ComposeObjectInternal { - client: Client, - + #[builder(!default)] // force required + client: MinioClient, + #[builder(default, setter(into))] extra_headers: Option, + #[builder(default, setter(into))] extra_query_params: Option, - region: Option, + #[builder(default, setter(into))] + pub(crate) region: Option, + #[builder(setter(into))] // force required + accept Into bucket: String, - + #[builder(setter(into))] // force required + accept Into object: String, + #[builder(default, setter(into))] headers: Option, + #[builder(default, setter(into))] user_metadata: Option, + #[builder(default, setter(into))] sse: Option>, + #[builder(default, setter(into))] tags: Option>, + #[builder(default, setter(into))] retention: Option, + #[builder(default)] legal_hold: bool, + #[builder(default)] sources: Vec, } -impl ComposeObjectInternal { - 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) -> Self { - self.extra_headers = extra_headers; - self - } - - pub fn extra_query_params(mut self, extra_query_params: Option) -> Self { - self.extra_query_params = extra_query_params; - self - } - - /// Sets the region for the request - pub fn region(mut self, region: Option) -> Self { - self.region = region; - self - } - - pub fn headers(mut self, headers: Option) -> Self { - self.headers = headers; - self - } - - pub fn user_metadata(mut self, user_metadata: Option) -> Self { - self.user_metadata = user_metadata; - self - } - - pub fn sse(mut self, sse: Option>) -> Self { - self.sse = sse; - self - } - - pub fn tags(mut self, tags: Option>) -> Self { - self.tags = tags; - self - } - - pub fn retention(mut self, retention: Option) -> Self { - self.retention = retention; - self - } - - pub fn legal_hold(mut self, legal_hold: bool) -> Self { - self.legal_hold = legal_hold; - self - } - - pub fn sources(mut self, sources: Vec) -> Self { - self.sources = sources; - self - } +/// Builder type for [`ComposeObjectInternal`] that is returned by [`MinioClient::compose_object_internal`](crate::s3::client::MinioClient::compose_object_internal). +/// +/// This type alias simplifies the complex generic signature generated by the `typed_builder` crate. +pub type ComposeObjectInternalBldr = ComposeObjectInternalBuilder<( + (MinioClient,), + (), + (), + (), + (String,), + (String,), + (), + (), + (), + (), + (), + (), + (), +)>; +impl ComposeObjectInternal { #[async_recursion] pub async fn send(self) -> (Result, String) { let mut upload_id = String::new(); @@ -627,6 +521,13 @@ impl ComposeObjectInternal { .tags(self.tags) .retention(self.retention) .legal_hold(self.legal_hold) + .source( + CopySource::builder() + .bucket(&self.bucket) + .object(&self.object) + .build(), + ) // TODO redundant use of bucket and object + .build() .send() .await { @@ -653,6 +554,7 @@ impl ComposeObjectInternal { .extra_query_params(self.extra_query_params.clone()) .region(self.region.clone()) .extra_headers(Some(headers)) + .build() .send() .await { @@ -710,6 +612,7 @@ impl ComposeObjectInternal { .region(self.region.clone()) .part_number(part_number) .headers(headers) + .build() .send() .await { @@ -749,6 +652,7 @@ impl ComposeObjectInternal { .region(self.region.clone()) .part_number(part_number) .headers(headers_copy) + .build() .send() .await { @@ -777,6 +681,7 @@ impl ComposeObjectInternal { .client .complete_multipart_upload(&self.bucket, &self.object, &upload_id, parts) .region(self.region) + .build() .send() .await; @@ -798,87 +703,57 @@ impl ComposeObjectInternal { /// Argument builder for [`CopyObject`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html) S3 API operation. /// /// See [Amazon S3 Multipart Upload](https://docs.aws.amazon.com/AmazonS3/latest/userguide/mpuoverview.html) -/// This struct constructs the parameters required for the [`Client::copy_object`](crate::s3::client::Client::copy_object) method. -#[derive(Clone, Debug, Default)] +/// This struct constructs the parameters required for the [`Client::copy_object`](crate::s3::client::MinioClient::copy_object) method. +#[derive(Clone, Debug, TypedBuilder)] pub struct ComposeObject { - client: Client, - + //#[builder(!default)] // force required + client: MinioClient, + #[builder(default)] extra_headers: Option, + #[builder(default, setter(into))] extra_query_params: Option, + #[builder(default, setter(into))] region: Option, + #[builder(setter(into))] // force required + accept Into bucket: String, - + #[builder(setter(into))] // force required + accept Into object: String, + #[builder(default, setter(into))] headers: Option, + #[builder(default, setter(into))] user_metadata: Option, + #[builder(default, setter(into))] sse: Option>, + #[builder(default, setter(into))] tags: Option>, + #[builder(default, setter(into))] retention: Option, + #[builder(default)] legal_hold: bool, + #[builder(default)] sources: Vec, } -impl ComposeObject { - 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) -> Self { - self.extra_headers = extra_headers; - self - } - - pub fn extra_query_params(mut self, extra_query_params: Option) -> Self { - self.extra_query_params = extra_query_params; - self - } - - /// Sets the region for the request - pub fn region(mut self, region: Option) -> Self { - self.region = region; - self - } - - pub fn headers(mut self, headers: Option) -> Self { - self.headers = headers; - self - } - - pub fn user_metadata(mut self, user_metadata: Option) -> Self { - self.user_metadata = user_metadata; - self - } - - pub fn sse(mut self, sse: Option>) -> Self { - self.sse = sse; - self - } - - pub fn tags(mut self, tags: Option>) -> Self { - self.tags = tags; - self - } - - pub fn retention(mut self, retention: Option) -> Self { - self.retention = retention; - self - } - - pub fn legal_hold(mut self, legal_hold: bool) -> Self { - self.legal_hold = legal_hold; - self - } - - pub fn sources(mut self, sources: Vec) -> Self { - self.sources = sources; - self - } +/// Builder type for [`ComposeObject`] that is returned by [`MinioClient::compose_object`](crate::s3::client::MinioClient::compose_object). +/// +/// This type alias simplifies the complex generic signature generated by the `typed_builder` crate. +pub type ComposeObjectBldr = ComposeObjectBuilder<( + (MinioClient,), + (), + (), + (), + (String,), + (String,), + (), + (), + (), + (), + (), + (), + (Vec,), +)>; +impl ComposeObject { pub async fn send(self) -> Result { check_sse(&self.sse, &self.client)?; @@ -898,6 +773,7 @@ impl ComposeObject { .retention(self.retention) .legal_hold(self.legal_hold) .sources(self.sources) + .build() .send() .await; @@ -908,6 +784,7 @@ impl ComposeObject { let _resp: AbortMultipartUploadResponse = self .client .abort_multipart_upload(&bucket, &object, &upload_id) + .build() .send() .await?; } @@ -920,7 +797,7 @@ impl ComposeObject { // region: misc #[derive(Clone, Debug, Default)] -/// Source object information for [compose_object](Client::compose_object) +/// Source object information for [compose_object](MinioClient::compose_object) pub struct ComposeSource { pub extra_headers: Option, pub extra_query_params: Option, @@ -1050,36 +927,38 @@ impl ComposeSource { } } -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug, TypedBuilder)] /// Base argument for object conditional read APIs pub struct CopySource { + #[builder(default, setter(into))] pub extra_headers: Option, + #[builder(default, setter(into))] pub extra_query_params: Option, + #[builder(default, setter(into))] pub region: Option, + #[builder(setter(into))] // force required + accept Into pub bucket: String, + #[builder(setter(into))] // force required + accept Into pub object: String, + #[builder(default, setter(into))] pub version_id: Option, + #[builder(default, setter(into))] pub ssec: Option, + #[builder(default, setter(into))] pub offset: Option, + #[builder(default, setter(into))] pub length: Option, + #[builder(default, setter(into))] pub match_etag: Option, + #[builder(default, setter(into))] pub not_match_etag: Option, + #[builder(default, setter(into))] pub modified_since: Option, + #[builder(default, setter(into))] pub unmodified_since: Option, } impl CopySource { - pub fn new(bucket_name: &str, object_name: &str) -> Result { - check_bucket_name(bucket_name, true)?; - check_object_name(object_name)?; - - Ok(Self { - bucket: bucket_name.to_owned(), - object: object_name.to_owned(), - ..Default::default() - }) - } - fn get_range_value(&self) -> String { let (offset, length) = match self.length { Some(_) => (Some(self.offset.unwrap_or(0_u64)), self.length), diff --git a/src/s3/builders/create_bucket.rs b/src/s3/builders/create_bucket.rs index a69455fa..e31e7880 100644 --- a/src/s3/builders/create_bucket.rs +++ b/src/s3/builders/create_bucket.rs @@ -13,8 +13,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::s3::Client; use crate::s3::client::DEFAULT_REGION; +use crate::s3::client::MinioClient; use crate::s3::error::ValidationErr; use crate::s3::header_constants::*; use crate::s3::multimap_ext::{Multimap, MultimapExt}; @@ -23,57 +23,37 @@ use crate::s3::segmented_bytes::SegmentedBytes; use crate::s3::types::{S3Api, S3Request, ToS3Request}; use crate::s3::utils::check_bucket_name; use http::Method; +use std::sync::Arc; +use typed_builder::TypedBuilder; /// 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)] +/// This struct constructs the parameters required for the [`Client::create_bucket`](crate::s3::client::MinioClient::create_bucket) method. +#[derive(Clone, Debug, TypedBuilder)] pub struct CreateBucket { - client: Client, - + #[builder(!default)] // force required + client: MinioClient, + #[builder(default, setter(into))] extra_headers: Option, + #[builder(default, setter(into))] extra_query_params: Option, + #[builder(default, setter(into))] region: Option, + #[builder(!default, setter(into))] // force required + accept Into bucket: String, - + #[builder(default = false)] object_lock: bool, } -impl CreateBucket { - pub fn new(client: Client, bucket: String) -> Self { - Self { - client, - bucket, - ..Default::default() - } - } - - pub fn extra_headers(mut self, extra_headers: Option) -> Self { - self.extra_headers = extra_headers; - self - } - - pub fn extra_query_params(mut self, extra_query_params: Option) -> Self { - self.extra_query_params = extra_query_params; - self - } - - /// Sets the region for the request - pub fn region(mut self, region: Option) -> Self { - self.region = region; - self - } - - pub fn object_lock(mut self, object_lock: bool) -> Self { - self.object_lock = object_lock; - self - } -} - impl S3Api for CreateBucket { type S3Response = CreateBucketResponse; } +/// Builder type for [`CreateBucket`] that is returned by [`MinioClient::create_bucket`](crate::s3::client::MinioClient::create_bucket). +/// +/// This type alias simplifies the complex generic signature generated by the `typed_builder` crate. +pub type CreateBucketBldr = CreateBucketBuilder<((MinioClient,), (), (), (), (String,), ())>; + impl ToS3Request for CreateBucket { fn to_s3request(self) -> Result { check_bucket_name(&self.bucket, true)?; @@ -106,16 +86,19 @@ impl ToS3Request for CreateBucket { ), }; - let body: Option = match data.is_empty() { + let body: Option> = match data.is_empty() { true => None, - false => Some(SegmentedBytes::from(data)), + false => Some(Arc::new(SegmentedBytes::from(data))), }; - Ok(S3Request::new(self.client, Method::PUT) - .region(Some(region_str)) - .bucket(Some(self.bucket)) + Ok(S3Request::builder() + .client(self.client) + .method(Method::PUT) + .region(region_str) + .bucket(self.bucket) .query_params(self.extra_query_params.unwrap_or_default()) .headers(headers) - .body(body)) + .body(body) + .build()) } } diff --git a/src/s3/builders/delete_bucket.rs b/src/s3/builders/delete_bucket.rs index 6c67e91a..b01fcbfa 100644 --- a/src/s3/builders/delete_bucket.rs +++ b/src/s3/builders/delete_bucket.rs @@ -13,7 +13,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::s3::builders::BucketCommon; +use crate::s3::MinioClient; +use crate::s3::builders::{BucketCommon, BucketCommonBuilder}; use crate::s3::error::ValidationErr; use crate::s3::response::DeleteBucketResponse; use crate::s3::types::{S3Api, S3Request, ToS3Request}; @@ -22,26 +23,35 @@ use http::Method; /// Argument builder for the [`DeleteBucket`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucket.html) S3 API operation. /// -/// This struct constructs the parameters required for the [`Client::delete_bucket`](crate::s3::client::Client::delete_bucket) method. +/// This struct constructs the parameters required for the [`Client::delete_bucket`](crate::s3::client::MinioClient::delete_bucket) method. /// See [Amazon S3: Deleting Buckets](https://docs.aws.amazon.com/AmazonS3/latest/userguide/delete-bucket.html) for more information. pub type DeleteBucket = BucketCommon; #[doc(hidden)] -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug)] pub struct DeleteBucketPhantomData; impl S3Api for DeleteBucket { type S3Response = DeleteBucketResponse; } +/// Builder type for [`DeleteBucket`] that is returned by [`MinioClient::delete_bucket`](crate::s3::client::MinioClient::delete_bucket). +/// +/// This type alias simplifies the complex generic signature generated by the `typed_builder` crate. +pub type DeleteBucketBldr = + BucketCommonBuilder; + impl ToS3Request for DeleteBucket { fn to_s3request(self) -> Result { check_bucket_name(&self.bucket, true)?; - Ok(S3Request::new(self.client, Method::DELETE) + Ok(S3Request::builder() + .client(self.client) + .method(Method::DELETE) .region(self.region) - .bucket(Some(self.bucket)) + .bucket(self.bucket) .query_params(self.extra_query_params.unwrap_or_default()) - .headers(self.extra_headers.unwrap_or_default())) + .headers(self.extra_headers.unwrap_or_default()) + .build()) } } diff --git a/src/s3/builders/delete_bucket_encryption.rs b/src/s3/builders/delete_bucket_encryption.rs index 7a851064..be4121df 100644 --- a/src/s3/builders/delete_bucket_encryption.rs +++ b/src/s3/builders/delete_bucket_encryption.rs @@ -13,7 +13,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::s3::builders::BucketCommon; +use crate::s3::MinioClient; +use crate::s3::builders::{BucketCommon, BucketCommonBuilder}; use crate::s3::error::ValidationErr; use crate::s3::response::DeleteBucketEncryptionResponse; use crate::s3::types::{S3Api, S3Request, ToS3Request}; @@ -22,25 +23,36 @@ use http::Method; /// 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. +/// This struct constructs the parameters required for the [`Client::delete_bucket_encryption`](crate::s3::client::MinioClient::delete_bucket_encryption) method. pub type DeleteBucketEncryption = BucketCommon; #[doc(hidden)] -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug)] pub struct DeleteBucketEncryptionPhantomData; impl S3Api for DeleteBucketEncryption { type S3Response = DeleteBucketEncryptionResponse; } +/// Builder type for [`DeleteBucketEncryption`] that is returned by [`MinioClient::delete_bucket_encryption`](crate::s3::client::MinioClient::delete_bucket_encryption). +/// +/// This type alias simplifies the complex generic signature generated by the `typed_builder` crate. +pub type DeleteBucketEncryptionBldr = BucketCommonBuilder< + DeleteBucketEncryptionPhantomData, + ((MinioClient,), (), (), (), (String,), ()), +>; + impl ToS3Request for DeleteBucketEncryption { fn to_s3request(self) -> Result { check_bucket_name(&self.bucket, true)?; - Ok(S3Request::new(self.client, Method::DELETE) + Ok(S3Request::builder() + .client(self.client) + .method(Method::DELETE) .region(self.region) - .bucket(Some(self.bucket)) + .bucket(self.bucket) .query_params(insert(self.extra_query_params, "encryption")) - .headers(self.extra_headers.unwrap_or_default())) + .headers(self.extra_headers.unwrap_or_default()) + .build()) } } diff --git a/src/s3/builders/delete_bucket_lifecycle.rs b/src/s3/builders/delete_bucket_lifecycle.rs index 339458df..f63b205c 100644 --- a/src/s3/builders/delete_bucket_lifecycle.rs +++ b/src/s3/builders/delete_bucket_lifecycle.rs @@ -13,7 +13,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::s3::builders::BucketCommon; +use crate::s3::MinioClient; +use crate::s3::builders::{BucketCommon, BucketCommonBuilder}; use crate::s3::error::ValidationErr; use crate::s3::response::DeleteBucketLifecycleResponse; use crate::s3::types::{S3Api, S3Request, ToS3Request}; @@ -22,25 +23,36 @@ use http::Method; /// 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. +/// This struct constructs the parameters required for the [`Client::delete_bucket_lifecycle`](crate::s3::client::MinioClient::delete_bucket_lifecycle) method. pub type DeleteBucketLifecycle = BucketCommon; #[doc(hidden)] -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug)] pub struct DeleteBucketLifecyclePhantomData; impl S3Api for DeleteBucketLifecycle { type S3Response = DeleteBucketLifecycleResponse; } +/// Builder type for [`DeleteBucketLifecycle`] that is returned by [`MinioClient::delete_bucket_lifecycle`](crate::s3::client::MinioClient::delete_bucket_lifecycle). +/// +/// This type alias simplifies the complex generic signature generated by the `typed_builder` crate. +pub type DeleteBucketLifecycleBldr = BucketCommonBuilder< + DeleteBucketLifecyclePhantomData, + ((MinioClient,), (), (), (), (String,), ()), +>; + impl ToS3Request for DeleteBucketLifecycle { fn to_s3request(self) -> Result { check_bucket_name(&self.bucket, true)?; - Ok(S3Request::new(self.client, Method::DELETE) + Ok(S3Request::builder() + .client(self.client) + .method(Method::DELETE) .region(self.region) - .bucket(Some(self.bucket)) + .bucket(self.bucket) .query_params(insert(self.extra_query_params, "lifecycle")) - .headers(self.extra_headers.unwrap_or_default())) + .headers(self.extra_headers.unwrap_or_default()) + .build()) } } diff --git a/src/s3/builders/delete_bucket_notification.rs b/src/s3/builders/delete_bucket_notification.rs index 7235ec02..79fb9168 100644 --- a/src/s3/builders/delete_bucket_notification.rs +++ b/src/s3/builders/delete_bucket_notification.rs @@ -13,7 +13,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::s3::builders::BucketCommon; +use crate::s3::MinioClient; +use crate::s3::builders::{BucketCommon, BucketCommonBuilder}; use crate::s3::error::ValidationErr; use crate::s3::response::DeleteBucketNotificationResponse; use crate::s3::segmented_bytes::SegmentedBytes; @@ -21,22 +22,31 @@ use crate::s3::types::{NotificationConfig, S3Api, S3Request, ToS3Request}; use crate::s3::utils::{check_bucket_name, insert}; use bytes::Bytes; use http::Method; +use std::sync::Arc; /// Argument builder for the [`DeleteBucketNotification`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketNotificationConfiguration.html) S3 API operation. /// Note: on Amazon S3, a bucket notification is deleted by setting its configuration to empty. /// -/// This struct constructs the parameters required for the [`Client::delete_bucket_notification`](crate::s3::client::Client::delete_bucket_notification) method. +/// This struct constructs the parameters required for the [`Client::delete_bucket_notification`](crate::s3::client::MinioClient::delete_bucket_notification) method. /// See [Amazon S3: Managing Bucket Notifications](https://docs.aws.amazon.com/AmazonS3/latest/userguide/NotificationHowTo.html) for more information. pub type DeleteBucketNotification = BucketCommon; #[doc(hidden)] -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug)] pub struct DeleteBucketNotificationPhantomData; impl S3Api for DeleteBucketNotification { type S3Response = DeleteBucketNotificationResponse; } +/// Builder type for [`DeleteBucketNotification`] that is returned by [`MinioClient::delete_bucket_notification`](crate::s3::client::MinioClient::delete_bucket_notification). +/// +/// This type alias simplifies the complex generic signature generated by the `typed_builder` crate. +pub type DeleteBucketNotificationBldr = BucketCommonBuilder< + DeleteBucketNotificationPhantomData, + ((MinioClient,), (), (), (), (String,), ()), +>; + impl ToS3Request for DeleteBucketNotification { fn to_s3request(self) -> Result { check_bucket_name(&self.bucket, true)?; @@ -47,14 +57,17 @@ impl ToS3Request for DeleteBucketNotification { topic_config_list: None, }; let bytes: Bytes = CONFIG.to_xml().into(); - let body: Option = Some(SegmentedBytes::from(bytes)); + let body: Arc = Arc::new(SegmentedBytes::from(bytes)); //TODO consider const body - Ok(S3Request::new(self.client, Method::PUT) + Ok(S3Request::builder() + .client(self.client) + .method(Method::PUT) .region(self.region) - .bucket(Some(self.bucket)) + .bucket(self.bucket) .query_params(insert(self.extra_query_params, "notification")) .headers(self.extra_headers.unwrap_or_default()) - .body(body)) + .body(body) + .build()) } } diff --git a/src/s3/builders/delete_bucket_policy.rs b/src/s3/builders/delete_bucket_policy.rs index 7f70fce8..c30cf206 100644 --- a/src/s3/builders/delete_bucket_policy.rs +++ b/src/s3/builders/delete_bucket_policy.rs @@ -13,7 +13,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::s3::builders::BucketCommon; +use crate::s3::MinioClient; +use crate::s3::builders::{BucketCommon, BucketCommonBuilder}; use crate::s3::error::ValidationErr; use crate::s3::response::DeleteBucketPolicyResponse; use crate::s3::types::{S3Api, S3Request, ToS3Request}; @@ -22,25 +23,34 @@ use http::Method; /// 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. +/// This struct constructs the parameters required for the [`Client::delete_bucket_policy`](crate::s3::client::MinioClient::delete_bucket_policy) method. pub type DeleteBucketPolicy = BucketCommon; #[doc(hidden)] -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug)] pub struct DeleteBucketPolicyPhantomData; impl S3Api for DeleteBucketPolicy { type S3Response = DeleteBucketPolicyResponse; } +/// Builder type for [`DeleteBucketPolicy`] that is returned by [`MinioClient::delete_bucket_policy`](crate::s3::client::MinioClient::delete_bucket_policy). +/// +/// This type alias simplifies the complex generic signature generated by the `typed_builder` crate. +pub type DeleteBucketPolicyBldr = + BucketCommonBuilder; + impl ToS3Request for DeleteBucketPolicy { fn to_s3request(self) -> Result { check_bucket_name(&self.bucket, true)?; - Ok(S3Request::new(self.client, Method::DELETE) + Ok(S3Request::builder() + .client(self.client) + .method(Method::DELETE) .region(self.region) - .bucket(Some(self.bucket)) + .bucket(self.bucket) .query_params(insert(self.extra_query_params, "policy")) - .headers(self.extra_headers.unwrap_or_default())) + .headers(self.extra_headers.unwrap_or_default()) + .build()) } } diff --git a/src/s3/builders/delete_bucket_replication.rs b/src/s3/builders/delete_bucket_replication.rs index 9ef55249..2f56a5a2 100644 --- a/src/s3/builders/delete_bucket_replication.rs +++ b/src/s3/builders/delete_bucket_replication.rs @@ -13,7 +13,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::s3::builders::BucketCommon; +use crate::s3::MinioClient; +use crate::s3::builders::{BucketCommon, BucketCommonBuilder}; use crate::s3::error::ValidationErr; use crate::s3::response::DeleteBucketReplicationResponse; use crate::s3::types::{S3Api, S3Request, ToS3Request}; @@ -22,25 +23,36 @@ use http::Method; /// 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. +/// This struct constructs the parameters required for the [`Client::delete_bucket_replication`](crate::s3::client::MinioClient::delete_bucket_replication) method. pub type DeleteBucketReplication = BucketCommon; #[doc(hidden)] -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug)] pub struct DeleteBucketReplicationPhantomData; impl S3Api for DeleteBucketReplication { type S3Response = DeleteBucketReplicationResponse; } +/// Builder type for [`DeleteBucketReplication`] that is returned by [`MinioClient::delete_bucket_replication`](crate::s3::client::MinioClient::delete_bucket_replication). +/// +/// This type alias simplifies the complex generic signature generated by the `typed_builder` crate. +pub type DeleteBucketReplicationBldr = BucketCommonBuilder< + DeleteBucketReplicationPhantomData, + ((MinioClient,), (), (), (), (String,), ()), +>; + impl ToS3Request for DeleteBucketReplication { fn to_s3request(self) -> Result { check_bucket_name(&self.bucket, true)?; - Ok(S3Request::new(self.client, Method::DELETE) + Ok(S3Request::builder() + .client(self.client) + .method(Method::DELETE) .region(self.region) - .bucket(Some(self.bucket)) + .bucket(self.bucket) .query_params(insert(self.extra_query_params, "replication")) - .headers(self.extra_headers.unwrap_or_default())) + .headers(self.extra_headers.unwrap_or_default()) + .build()) } } diff --git a/src/s3/builders/delete_bucket_tagging.rs b/src/s3/builders/delete_bucket_tagging.rs index fd32752c..223cc8c5 100644 --- a/src/s3/builders/delete_bucket_tagging.rs +++ b/src/s3/builders/delete_bucket_tagging.rs @@ -13,7 +13,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::s3::builders::BucketCommon; +use crate::s3::MinioClient; +use crate::s3::builders::{BucketCommon, BucketCommonBuilder}; use crate::s3::error::ValidationErr; use crate::s3::response::DeleteBucketTaggingResponse; use crate::s3::types::{S3Api, S3Request, ToS3Request}; @@ -22,25 +23,35 @@ use http::Method; /// 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. +/// This struct constructs the parameters required for the [`Client::delete_bucket_tags`](crate::s3::client::MinioClient::delete_bucket_tagging) method. pub type DeleteBucketTagging = BucketCommon; #[doc(hidden)] -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug)] pub struct DeleteBucketTaggingPhantomData; impl S3Api for DeleteBucketTagging { type S3Response = DeleteBucketTaggingResponse; } +/// Builder type for [`DeleteBucketTagging`] that is returned by [`MinioClient::delete_bucket_tagging`](crate::s3::client::MinioClient::delete_bucket_tagging). +/// +/// This type alias simplifies the complex generic signature generated by the `typed_builder` crate. +pub type DeleteBucketTaggingBldr = BucketCommonBuilder< + DeleteBucketTaggingPhantomData, + ((MinioClient,), (), (), (), (String,), ()), +>; + impl ToS3Request for DeleteBucketTagging { fn to_s3request(self) -> Result { check_bucket_name(&self.bucket, true)?; - Ok(S3Request::new(self.client, Method::DELETE) - .region(self.region) - .bucket(Some(self.bucket)) + Ok(S3Request::builder() + .client(self.client) + .method(Method::DELETE) + .bucket(self.bucket) .query_params(insert(self.extra_query_params, "tagging")) - .headers(self.extra_headers.unwrap_or_default())) + .headers(self.extra_headers.unwrap_or_default()) + .build()) } } diff --git a/src/s3/builders/delete_object_lock_config.rs b/src/s3/builders/delete_object_lock_config.rs index 2e0f1e64..cf3a030f 100644 --- a/src/s3/builders/delete_object_lock_config.rs +++ b/src/s3/builders/delete_object_lock_config.rs @@ -13,7 +13,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::s3::builders::BucketCommon; +use crate::s3::MinioClient; +use crate::s3::builders::{BucketCommon, BucketCommonBuilder}; use crate::s3::error::ValidationErr; use crate::s3::response::DeleteObjectLockConfigResponse; use crate::s3::segmented_bytes::SegmentedBytes; @@ -21,18 +22,27 @@ use crate::s3::types::{ObjectLockConfig, S3Api, S3Request, ToS3Request}; use crate::s3::utils::{check_bucket_name, insert}; use bytes::Bytes; use http::Method; +use std::sync::Arc; -/// This struct constructs the parameters required for the [`Client::delete_object_lock_config`](crate::s3::client::Client::delete_object_lock_config) method. +/// This struct constructs the parameters required for the [`Client::delete_object_lock_config`](crate::s3::client::MinioClient::delete_object_lock_config) method. pub type DeleteObjectLockConfig = BucketCommon; #[doc(hidden)] -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug)] pub struct DeleteObjectLockConfigPhantomData; impl S3Api for DeleteObjectLockConfig { type S3Response = DeleteObjectLockConfigResponse; } +/// Builder type for [`DeleteObjectLockConfig`] that is returned by [`MinioClient::delete_object_lock_config`](crate::s3::client::MinioClient::delete_object_lock_config). +/// +/// This type alias simplifies the complex generic signature generated by the `typed_builder` crate. +pub type DeleteObjectLockConfigBldr = BucketCommonBuilder< + DeleteObjectLockConfigPhantomData, + ((MinioClient,), (), (), (), (String,), ()), +>; + impl ToS3Request for DeleteObjectLockConfig { fn to_s3request(self) -> Result { check_bucket_name(&self.bucket, true)?; @@ -43,14 +53,17 @@ impl ToS3Request for DeleteObjectLockConfig { retention_duration_years: None, }; let bytes: Bytes = config.to_xml().into(); - let body: Option = Some(SegmentedBytes::from(bytes)); + let body: Arc = Arc::new(SegmentedBytes::from(bytes)); //TODO consider const body - Ok(S3Request::new(self.client, Method::PUT) + Ok(S3Request::builder() + .client(self.client) + .method(Method::PUT) .region(self.region) - .bucket(Some(self.bucket)) + .bucket(self.bucket) .query_params(insert(self.extra_query_params, "object-lock")) .headers(self.extra_headers.unwrap_or_default()) - .body(body)) + .body(body) + .build()) } } diff --git a/src/s3/builders/delete_object_tagging.rs b/src/s3/builders/delete_object_tagging.rs index 3e9711d2..77439a8c 100644 --- a/src/s3/builders/delete_object_tagging.rs +++ b/src/s3/builders/delete_object_tagging.rs @@ -13,66 +13,46 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::s3::Client; +use crate::s3::client::MinioClient; use crate::s3::error::ValidationErr; use crate::s3::multimap_ext::{Multimap, MultimapExt}; 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; +use typed_builder::TypedBuilder; /// 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)] +/// This struct constructs the parameters required for the [`Client::delete_object_tags`](crate::s3::client::MinioClient::delete_object_tagging) method. +#[derive(Clone, Debug, TypedBuilder)] pub struct DeleteObjectTagging { - client: Client, - + #[builder(!default)] // force required + client: MinioClient, + #[builder(default, setter(into))] extra_headers: Option, + #[builder(default, setter(into))] extra_query_params: Option, + #[builder(default, setter(into))] region: Option, + #[builder(setter(into))] // force required + accept Into bucket: String, - + #[builder(setter(into))] // force required + accept Into object: String, + #[builder(default, setter(into))] version_id: Option, } -impl DeleteObjectTagging { - 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) -> Self { - self.extra_headers = extra_headers; - self - } - - pub fn extra_query_params(mut self, extra_query_params: Option) -> Self { - self.extra_query_params = extra_query_params; - self - } - - /// Sets the region for the request - pub fn region(mut self, region: Option) -> Self { - self.region = region; - self - } - - pub fn version_id(mut self, version_id: Option) -> Self { - self.version_id = version_id; - self - } -} - impl S3Api for DeleteObjectTagging { type S3Response = DeleteObjectTaggingResponse; } +/// Builder type for [`DeleteObjectTagging`] that is returned by [`MinioClient::delete_object_tagging`](crate::s3::client::MinioClient::delete_object_tagging). +/// +/// This type alias simplifies the complex generic signature generated by the `typed_builder` crate. +pub type DeleteObjectTaggingBldr = + DeleteObjectTaggingBuilder<((MinioClient,), (), (), (), (String,), (String,), ())>; + impl ToS3Request for DeleteObjectTagging { fn to_s3request(self) -> Result { check_bucket_name(&self.bucket, true)?; @@ -81,11 +61,14 @@ impl ToS3Request for DeleteObjectTagging { let mut query_params: Multimap = insert(self.extra_query_params, "tagging"); query_params.add_version(self.version_id); - Ok(S3Request::new(self.client, Method::DELETE) + Ok(S3Request::builder() + .client(self.client) + .method(Method::DELETE) .region(self.region) - .bucket(Some(self.bucket)) + .bucket(self.bucket) .query_params(query_params) - .object(Some(self.object)) - .headers(self.extra_headers.unwrap_or_default())) + .object(self.object) + .headers(self.extra_headers.unwrap_or_default()) + .build()) } } diff --git a/src/s3/builders/delete_objects.rs b/src/s3/builders/delete_objects.rs index c7cbe8fb..a6a4d592 100644 --- a/src/s3/builders/delete_objects.rs +++ b/src/s3/builders/delete_objects.rs @@ -13,12 +13,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::s3::Client; use crate::s3::client::MAX_MULTIPART_COUNT; +use crate::s3::client::MinioClient; use crate::s3::error::{Error, ValidationErr}; use crate::s3::header_constants::*; use crate::s3::multimap_ext::{Multimap, MultimapExt}; use crate::s3::response::{DeleteError, DeleteObjectResponse, DeleteObjectsResponse}; +use crate::s3::segmented_bytes::SegmentedBytes; use crate::s3::types::{ListEntry, S3Api, S3Request, ToS3Request, ToStream}; use crate::s3::utils::{check_bucket_name, check_object_name, insert, md5sum_hash}; use async_trait::async_trait; @@ -27,6 +28,8 @@ use futures_util::stream::iter; use futures_util::{Stream, StreamExt, stream as futures_stream}; use http::Method; use std::pin::Pin; +use std::sync::Arc; +use typed_builder::TypedBuilder; // region: object-to-delete pub trait ValidKey: Into {} @@ -94,58 +97,37 @@ impl From for ObjectToDelete { // region: delete-object -/// Argument builder for the [`RemoveObject`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObject.html) S3 API operation. +/// Argument builder for the [`DeleteObject`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObject.html) S3 API operation. /// -/// This struct constructs the parameters required for the [`Client::remove_object`](crate::s3::client::Client::delete_object) method. -#[derive(Debug, Clone, Default)] +/// This struct constructs the parameters required for the [`Client::delete_object`](crate::s3::client::Client::delete_object) method. +#[derive(Debug, Clone, TypedBuilder)] pub struct DeleteObject { - client: Client, - + #[builder(!default)] // force required + client: MinioClient, + #[builder(default, setter(into))] extra_headers: Option, + #[builder(default, setter(into))] extra_query_params: Option, + #[builder(default, setter(into))] region: Option, + #[builder(setter(into))] // force required + accept Into bucket: String, - + #[builder(default, setter(into))] object: ObjectToDelete, + #[builder(default)] bypass_governance_mode: bool, } -impl DeleteObject { - pub fn new(client: Client, bucket: String, object: impl Into) -> Self { - Self { - client, - bucket, - object: object.into(), - ..Default::default() - } - } - - pub fn bypass_governance_mode(mut self, bypass_governance_mode: bool) -> Self { - self.bypass_governance_mode = bypass_governance_mode; - self - } - - pub fn extra_headers(mut self, extra_headers: Option) -> Self { - self.extra_headers = extra_headers; - self - } - - pub fn extra_query_params(mut self, extra_query_params: Option) -> Self { - self.extra_query_params = extra_query_params; - self - } - - /// Sets the region for the request - pub fn region(mut self, region: Option) -> Self { - self.region = region; - self - } -} - impl S3Api for DeleteObject { type S3Response = DeleteObjectResponse; } +/// Builder type for [`DeleteObject`] that is returned by [`MinioClient::delete_object`](crate::s3::client::MinioClient::delete_object). +/// +/// This type alias simplifies the complex generic signature generated by the `typed_builder` crate. +pub type DeleteObjectBldr = + DeleteObjectBuilder<((MinioClient,), (), (), (), (String,), (ObjectToDelete,), ())>; + impl ToS3Request for DeleteObject { fn to_s3request(self) -> Result { check_bucket_name(&self.bucket, true)?; @@ -159,77 +141,68 @@ impl ToS3Request for DeleteObject { headers.add(X_AMZ_BYPASS_GOVERNANCE_RETENTION, "true"); } - Ok(S3Request::new(self.client, Method::DELETE) + Ok(S3Request::builder() + .client(self.client) + .method(Method::DELETE) .region(self.region) - .bucket(Some(self.bucket)) - .object(Some(self.object.key)) + .bucket(self.bucket) + .object(self.object.key) .query_params(query_params) - .headers(headers)) + .headers(headers) + .build()) } } // endregion: delete-object // region: delete-objects -#[derive(Debug, Clone, Default)] -pub struct DeleteObjects { - client: Client, - - bucket: String, - objects: Vec, - - bypass_governance_mode: bool, - verbose_mode: bool, +/// 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_objects`](crate::s3::client::Client::delete_objects) method. +#[derive(Clone, Debug, TypedBuilder)] +pub struct DeleteObjects { + #[builder(!default)] // force required + client: MinioClient, + #[builder(default, setter(into))] extra_headers: Option, + #[builder(default, setter(into))] extra_query_params: Option, + #[builder(default, setter(into))] region: Option, -} - -impl DeleteObjects { - pub fn new(client: Client, bucket: String, objects: Vec) -> Self { - DeleteObjects { - client, - bucket, - objects, - ..Default::default() - } - } + #[builder(setter(into))] // force required + accept Into + bucket: String, - pub fn bypass_governance_mode(mut self, bypass_governance_mode: bool) -> Self { - self.bypass_governance_mode = bypass_governance_mode; - self - } + #[builder(!default)] + objects: Vec, + #[builder(default)] + bypass_governance_mode: bool, /// Enable verbose mode (defaults to false). If enabled, the response will /// include the keys of objects that were successfully deleted. Otherwise, /// only objects that encountered an error are returned. - pub fn verbose_mode(mut self, verbose_mode: bool) -> Self { - self.verbose_mode = verbose_mode; - self - } - - pub fn extra_headers(mut self, extra_headers: Option) -> Self { - self.extra_headers = extra_headers; - self - } - - pub fn extra_query_params(mut self, extra_query_params: Option) -> Self { - self.extra_query_params = extra_query_params; - self - } - - /// Sets the region for the request - pub fn region(mut self, region: Option) -> Self { - self.region = region; - self - } + #[builder(default)] + verbose_mode: bool, } impl S3Api for DeleteObjects { type S3Response = DeleteObjectsResponse; } +/// Builder type for [`DeleteObjects`] that is returned by [`MinioClient::delete_objects`](crate::s3::client::MinioClient::delete_objects). +/// +/// This type alias simplifies the complex generic signature generated by the `typed_builder` crate. +pub type DeleteObjectsBldr = DeleteObjectsBuilder<( + (MinioClient,), + (), + (), + (), + (String,), + (Vec,), + (), + (), +)>; + impl ToS3Request for DeleteObjects { fn to_s3request(self) -> Result { check_bucket_name(&self.bucket, true)?; @@ -261,13 +234,17 @@ impl ToS3Request for DeleteObjects { headers.add(CONTENT_TYPE, "application/xml"); headers.add(CONTENT_MD5, md5sum_hash(bytes.as_ref())); } + let body = Arc::new(SegmentedBytes::from(bytes)); - Ok(S3Request::new(self.client, Method::POST) + Ok(S3Request::builder() + .client(self.client) + .method(Method::POST) .region(self.region) - .bucket(Some(self.bucket)) + .bucket(self.bucket) .query_params(insert(self.extra_query_params, "delete")) .headers(headers) - .body(Some(bytes.into()))) + .body(body) + .build()) } } @@ -304,12 +281,12 @@ where // region: delete-objects-streaming -/// Argument builder for the [`DeleteObjectsStreaming`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObjects.html) S3 API operation. -/// Note that this API is not part of the official S3 API, but is a MinIO extension for streaming deletion of multiple objects. +/// Argument builder for streaming multiple object deletions using 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::`](crate::s3::client::Client::get_bucket_encryption) method. +/// This struct constructs the parameters required for the [`Client::delete_objects_streaming`](crate::s3::client::Client::delete_objects_streaming) method. pub struct DeleteObjectsStreaming { - client: Client, + //TODO + client: MinioClient, bucket: String, objects: ObjectsStream, @@ -323,7 +300,7 @@ pub struct DeleteObjectsStreaming { } impl DeleteObjectsStreaming { - pub fn new(client: Client, bucket: String, objects: impl Into) -> Self { + pub fn new(client: MinioClient, bucket: String, objects: impl Into) -> Self { Self { client, bucket, @@ -380,12 +357,16 @@ impl DeleteObjectsStreaming { } Ok(Some( - DeleteObjects::new(self.client.clone(), self.bucket.clone(), objects) + DeleteObjects::builder() + .client(self.client.clone()) + .bucket(self.bucket.clone()) + .objects(objects) .bypass_governance_mode(self.bypass_governance_mode) .verbose_mode(self.verbose_mode) .extra_headers(self.extra_headers.clone()) .extra_query_params(self.extra_query_params.clone()) - .region(self.region.clone()), + .region(self.region.clone()) + .build(), )) } } diff --git a/src/s3/builders/get_bucket_encryption.rs b/src/s3/builders/get_bucket_encryption.rs index fa978341..92976fa1 100644 --- a/src/s3/builders/get_bucket_encryption.rs +++ b/src/s3/builders/get_bucket_encryption.rs @@ -13,7 +13,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::s3::builders::BucketCommon; +use crate::s3::MinioClient; +use crate::s3::builders::{BucketCommon, BucketCommonBuilder}; use crate::s3::error::ValidationErr; use crate::s3::response::GetBucketEncryptionResponse; use crate::s3::types::{S3Api, S3Request, ToS3Request}; @@ -22,25 +23,36 @@ use http::Method; /// 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. +/// This struct constructs the parameters required for the [`Client::get_bucket_encryption`](crate::s3::client::MinioClient::get_bucket_encryption) method. pub type GetBucketEncryption = BucketCommon; #[doc(hidden)] -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug)] pub struct GetBucketEncryptionPhantomData; impl S3Api for GetBucketEncryption { type S3Response = GetBucketEncryptionResponse; } +/// Builder type for [`GetBucketEncryption`] that is returned by [`MinioClient::get_bucket_encryption`](crate::s3::client::MinioClient::get_bucket_encryption). +/// +/// This type alias simplifies the complex generic signature generated by the `typed_builder` crate. +pub type GetBucketEncryptionBldr = BucketCommonBuilder< + GetBucketEncryptionPhantomData, + ((MinioClient,), (), (), (), (String,), ()), +>; + impl ToS3Request for GetBucketEncryption { fn to_s3request(self) -> Result { check_bucket_name(&self.bucket, true)?; - Ok(S3Request::new(self.client, Method::GET) + Ok(S3Request::builder() + .client(self.client) + .method(Method::GET) .region(self.region) - .bucket(Some(self.bucket)) + .bucket(self.bucket) .query_params(insert(self.extra_query_params, "encryption")) - .headers(self.extra_headers.unwrap_or_default())) + .headers(self.extra_headers.unwrap_or_default()) + .build()) } } diff --git a/src/s3/builders/get_bucket_lifecycle.rs b/src/s3/builders/get_bucket_lifecycle.rs index 516533f7..c9610a53 100644 --- a/src/s3/builders/get_bucket_lifecycle.rs +++ b/src/s3/builders/get_bucket_lifecycle.rs @@ -13,58 +13,44 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::s3::Client; +use crate::s3::client::MinioClient; use crate::s3::error::ValidationErr; use crate::s3::multimap_ext::{Multimap, MultimapExt}; use crate::s3::response::GetBucketLifecycleResponse; use crate::s3::types::{S3Api, S3Request, ToS3Request}; use crate::s3::utils::{check_bucket_name, insert}; use http::Method; +use typed_builder::TypedBuilder; /// 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. -#[derive(Clone, Debug, Default)] +/// This struct constructs the parameters required for the [`Client::get_bucket_lifecycle`](crate::s3::client::MinioClient::get_bucket_lifecycle) method. +#[derive(Clone, Debug, TypedBuilder)] pub struct GetBucketLifecycle { - client: Client, - + #[builder(!default)] // force required + client: MinioClient, + #[builder(default, setter(into))] extra_headers: Option, + #[builder(default, setter(into))] extra_query_params: Option, + #[builder(default, setter(into))] region: Option, + #[builder(setter(into))] // force required + accept Into bucket: String, - + #[builder(default)] with_updated_at: bool, } -impl GetBucketLifecycle { - pub fn new(client: Client, bucket: String) -> Self { - Self { - client, - bucket, - ..Default::default() - } - } - - pub fn extra_headers(mut self, extra_headers: Option) -> Self { - self.extra_headers = extra_headers; - self - } - - pub fn extra_query_params(mut self, extra_query_params: Option) -> Self { - self.extra_query_params = extra_query_params; - self - } - - pub fn with_updated_at(mut self, with_updated_at: bool) -> Self { - self.with_updated_at = with_updated_at; - self - } -} - impl S3Api for GetBucketLifecycle { type S3Response = GetBucketLifecycleResponse; } +/// Builder type for [`GetBucketLifecycle`] that is returned by [`MinioClient::get_bucket_lifecycle`](crate::s3::client::MinioClient::get_bucket_lifecycle). +/// +/// This type alias simplifies the complex generic signature generated by the `typed_builder` crate. +pub type GetBucketLifecycleBldr = + GetBucketLifecycleBuilder<((MinioClient,), (), (), (), (String,), ())>; + impl ToS3Request for GetBucketLifecycle { fn to_s3request(self) -> Result { check_bucket_name(&self.bucket, true)?; @@ -74,10 +60,13 @@ impl ToS3Request for GetBucketLifecycle { query_params.add("withUpdatedAt", "true"); } - Ok(S3Request::new(self.client, Method::GET) + Ok(S3Request::builder() + .client(self.client) + .method(Method::GET) .region(self.region) - .bucket(Some(self.bucket)) + .bucket(self.bucket) .query_params(query_params) - .headers(self.extra_headers.unwrap_or_default())) + .headers(self.extra_headers.unwrap_or_default()) + .build()) } } diff --git a/src/s3/builders/get_bucket_notification.rs b/src/s3/builders/get_bucket_notification.rs index 7cb5921a..8cb53eae 100644 --- a/src/s3/builders/get_bucket_notification.rs +++ b/src/s3/builders/get_bucket_notification.rs @@ -13,7 +13,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::s3::builders::BucketCommon; +use crate::s3::MinioClient; +use crate::s3::builders::{BucketCommon, BucketCommonBuilder}; use crate::s3::error::ValidationErr; use crate::s3::response::GetBucketNotificationResponse; use crate::s3::types::{S3Api, S3Request, ToS3Request}; @@ -22,25 +23,36 @@ use http::Method; /// 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. +/// This struct constructs the parameters required for the [`Client::get_bucket_notification`](crate::s3::client::MinioClient::get_bucket_notification) method. pub type GetBucketNotification = BucketCommon; #[doc(hidden)] -#[derive(Default, Debug)] +#[derive(Clone, Debug)] pub struct GetBucketNotificationPhantomData; impl S3Api for GetBucketNotification { type S3Response = GetBucketNotificationResponse; } +/// Builder type for [`GetBucketNotification`] that is returned by [`MinioClient::get_bucket_notification`](crate::s3::client::MinioClient::get_bucket_notification). +/// +/// This type alias simplifies the complex generic signature generated by the `typed_builder` crate. +pub type GetBucketNotificationBldr = BucketCommonBuilder< + GetBucketNotificationPhantomData, + ((MinioClient,), (), (), (), (String,), ()), +>; + impl ToS3Request for GetBucketNotification { fn to_s3request(self) -> Result { check_bucket_name(&self.bucket, true)?; - Ok(S3Request::new(self.client, Method::GET) + Ok(S3Request::builder() + .client(self.client) + .method(Method::GET) .region(self.region) - .bucket(Some(self.bucket)) + .bucket(self.bucket) .query_params(insert(self.extra_query_params, "notification")) - .headers(self.extra_headers.unwrap_or_default())) + .headers(self.extra_headers.unwrap_or_default()) + .build()) } } diff --git a/src/s3/builders/get_bucket_policy.rs b/src/s3/builders/get_bucket_policy.rs index 18d6f102..b4a25465 100644 --- a/src/s3/builders/get_bucket_policy.rs +++ b/src/s3/builders/get_bucket_policy.rs @@ -13,7 +13,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::s3::builders::BucketCommon; +use crate::s3::MinioClient; +use crate::s3::builders::{BucketCommon, BucketCommonBuilder}; use crate::s3::error::ValidationErr; use crate::s3::response::GetBucketPolicyResponse; use crate::s3::types::{S3Api, S3Request, ToS3Request}; @@ -22,25 +23,34 @@ use http::Method; /// 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. +/// This struct constructs the parameters required for the [`Client::get_bucket_policy`](crate::s3::client::MinioClient::get_bucket_policy) method. pub type GetBucketPolicy = BucketCommon; #[doc(hidden)] -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug)] pub struct GetBucketPolicyPhantomData; impl S3Api for GetBucketPolicy { type S3Response = GetBucketPolicyResponse; } +/// Builder type for [`GetBucketPolicy`] that is returned by [`MinioClient::get_bucket_policy`](crate::s3::client::MinioClient::get_bucket_policy). +/// +/// This type alias simplifies the complex generic signature generated by the `typed_builder` crate. +pub type GetBucketPolicyBldr = + BucketCommonBuilder; + impl ToS3Request for GetBucketPolicy { fn to_s3request(self) -> Result { check_bucket_name(&self.bucket, true)?; - Ok(S3Request::new(self.client, Method::GET) + Ok(S3Request::builder() + .client(self.client) + .method(Method::GET) .region(self.region) - .bucket(Some(self.bucket)) + .bucket(self.bucket) .query_params(insert(self.extra_query_params, "policy")) - .headers(self.extra_headers.unwrap_or_default())) + .headers(self.extra_headers.unwrap_or_default()) + .build()) } } diff --git a/src/s3/builders/get_bucket_replication.rs b/src/s3/builders/get_bucket_replication.rs index 2c4d2954..b3593422 100644 --- a/src/s3/builders/get_bucket_replication.rs +++ b/src/s3/builders/get_bucket_replication.rs @@ -13,7 +13,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::s3::builders::BucketCommon; +use crate::s3::MinioClient; +use crate::s3::builders::{BucketCommon, BucketCommonBuilder}; use crate::s3::error::ValidationErr; use crate::s3::response::GetBucketReplicationResponse; use crate::s3::types::{S3Api, S3Request, ToS3Request}; @@ -22,25 +23,36 @@ use http::Method; /// 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. +/// This struct constructs the parameters required for the [`Client::get_bucket_replication`](crate::s3::client::MinioClient::get_bucket_replication) method. pub type GetBucketReplication = BucketCommon; #[doc(hidden)] -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug)] pub struct GetBucketReplicationPhantomData; impl S3Api for GetBucketReplication { type S3Response = GetBucketReplicationResponse; } +/// Builder type for [`GetBucketReplication`] that is returned by [`MinioClient::get_bucket_replication`](crate::s3::client::MinioClient::get_bucket_replication). +/// +/// This type alias simplifies the complex generic signature generated by the `typed_builder` crate. +pub type GetBucketReplicationBldr = BucketCommonBuilder< + GetBucketReplicationPhantomData, + ((MinioClient,), (), (), (), (String,), ()), +>; + impl ToS3Request for GetBucketReplication { fn to_s3request(self) -> Result { check_bucket_name(&self.bucket, true)?; - Ok(S3Request::new(self.client, Method::GET) + Ok(S3Request::builder() + .client(self.client) + .method(Method::GET) .region(self.region) - .bucket(Some(self.bucket)) + .bucket(self.bucket) .query_params(insert(self.extra_query_params, "replication")) - .headers(self.extra_headers.unwrap_or_default())) + .headers(self.extra_headers.unwrap_or_default()) + .build()) } } diff --git a/src/s3/builders/get_bucket_tagging.rs b/src/s3/builders/get_bucket_tagging.rs index 9f8e1ee5..e9f34068 100644 --- a/src/s3/builders/get_bucket_tagging.rs +++ b/src/s3/builders/get_bucket_tagging.rs @@ -13,73 +13,52 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::s3::Client; +use crate::s3::client::MinioClient; use crate::s3::error::ValidationErr; use crate::s3::multimap_ext::Multimap; 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; +use typed_builder::TypedBuilder; /// 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)] +/// This struct constructs the parameters required for the [`Client::get_bucket_tagging`](crate::s3::client::MinioClient::get_bucket_tagging) method. +#[derive(Clone, Debug, TypedBuilder)] pub struct GetBucketTagging { - client: Client, - + #[builder(!default)] // force required + client: MinioClient, + #[builder(default, setter(into))] extra_headers: Option, + #[builder(default, setter(into))] extra_query_params: Option, + #[builder(default, setter(into))] region: Option, + #[builder(setter(into))] // force required + accept Into bucket: String, - - tags: HashMap, -} - -impl GetBucketTagging { - pub fn new(client: Client, bucket: String) -> Self { - Self { - client, - bucket, - ..Default::default() - } - } - - pub fn extra_headers(mut self, extra_headers: Option) -> Self { - self.extra_headers = extra_headers; - self - } - - pub fn extra_query_params(mut self, extra_query_params: Option) -> Self { - self.extra_query_params = extra_query_params; - self - } - - /// Sets the region for the request - pub fn region(mut self, region: Option) -> Self { - self.region = region; - self - } - - pub fn tags(mut self, tags: HashMap) -> Self { - self.tags = tags; - self - } } impl S3Api for GetBucketTagging { type S3Response = GetBucketTaggingResponse; } +/// Builder type for [`GetBucketTagging`] that is returned by [`MinioClient::get_bucket_tagging`](crate::s3::client::MinioClient::get_bucket_tagging). +/// +/// This type alias simplifies the complex generic signature generated by the `typed_builder` crate. +pub type GetBucketTaggingBldr = GetBucketTaggingBuilder<((MinioClient,), (), (), (), (String,))>; + impl ToS3Request for GetBucketTagging { fn to_s3request(self) -> Result { check_bucket_name(&self.bucket, true)?; - Ok(S3Request::new(self.client, Method::GET) + Ok(S3Request::builder() + .client(self.client) + .method(Method::GET) .region(self.region) - .bucket(Some(self.bucket)) + .bucket(self.bucket) .query_params(insert(self.extra_query_params, "tagging")) - .headers(self.extra_headers.unwrap_or_default())) + .headers(self.extra_headers.unwrap_or_default()) + .build()) } } diff --git a/src/s3/builders/get_bucket_versioning.rs b/src/s3/builders/get_bucket_versioning.rs index 60ae0147..d53fda90 100644 --- a/src/s3/builders/get_bucket_versioning.rs +++ b/src/s3/builders/get_bucket_versioning.rs @@ -13,7 +13,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::s3::builders::BucketCommon; +use crate::s3::MinioClient; +use crate::s3::builders::{BucketCommon, BucketCommonBuilder}; use crate::s3::error::ValidationErr; use crate::s3::response::GetBucketVersioningResponse; use crate::s3::types::{S3Api, S3Request, ToS3Request}; @@ -22,25 +23,36 @@ use http::Method; /// 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. +/// This struct constructs the parameters required for the [`Client::get_bucket_versioning`](crate::s3::client::MinioClient::get_bucket_versioning) method. pub type GetBucketVersioning = BucketCommon; #[doc(hidden)] -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug)] pub struct GetBucketVersioningPhantomData; impl S3Api for GetBucketVersioning { type S3Response = GetBucketVersioningResponse; } +/// Builder type for [`GetBucketVersioning`] that is returned by [`MinioClient::get_bucket_versioning`](crate::s3::client::MinioClient::get_bucket_versioning). +/// +/// This type alias simplifies the complex generic signature generated by the `typed_builder` crate. +pub type GetBucketVersioningBldr = BucketCommonBuilder< + GetBucketVersioningPhantomData, + ((MinioClient,), (), (), (), (String,), ()), +>; + impl ToS3Request for GetBucketVersioning { fn to_s3request(self) -> Result { check_bucket_name(&self.bucket, true)?; - Ok(S3Request::new(self.client, Method::GET) + Ok(S3Request::builder() + .client(self.client) + .method(Method::GET) .region(self.region) - .bucket(Some(self.bucket)) + .bucket(self.bucket) .query_params(insert(self.extra_query_params, "versioning")) - .headers(self.extra_headers.unwrap_or_default())) + .headers(self.extra_headers.unwrap_or_default()) + .build()) } } diff --git a/src/s3/builders/get_object.rs b/src/s3/builders/get_object.rs index 4383cc97..28d01b37 100644 --- a/src/s3/builders/get_object.rs +++ b/src/s3/builders/get_object.rs @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::s3::client::Client; +use crate::s3::client::MinioClient; use crate::s3::error::ValidationErr; use crate::s3::header_constants::*; use crate::s3::multimap_ext::{Multimap, MultimapExt}; @@ -24,97 +24,64 @@ use crate::s3::utils::{ UtcTime, check_bucket_name, check_object_name, check_ssec, to_http_header_value, }; use http::Method; +use typed_builder::TypedBuilder; /// 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)] +/// This struct constructs the parameters required for the [`Client::get_object`](crate::s3::client::MinioClient::get_object) method. +#[derive(Debug, Clone, TypedBuilder)] pub struct GetObject { - client: Client, - + #[builder(!default)] // force required + client: MinioClient, + #[builder(default, setter(into))] extra_headers: Option, + #[builder(default, setter(into))] extra_query_params: Option, + #[builder(default, setter(into))] + region: Option, + #[builder(setter(into))] // force required + accept Into bucket: String, + #[builder(setter(into))] // force required + accept Into object: String, + #[builder(default, setter(into))] version_id: Option, + #[builder(default, setter(into))] offset: Option, + #[builder(default, setter(into))] length: Option, - region: Option, + #[builder(default, setter(into))] ssec: Option, // Conditionals + #[builder(default, setter(into))] match_etag: Option, + #[builder(default, setter(into))] not_match_etag: Option, + #[builder(default, setter(into))] modified_since: Option, + #[builder(default, setter(into))] unmodified_since: Option, } -impl GetObject { - 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) -> Self { - self.extra_headers = extra_headers; - self - } - - pub fn extra_query_params(mut self, extra_query_params: Option) -> Self { - self.extra_query_params = extra_query_params; - self - } - - pub fn version_id(mut self, version_id: Option) -> Self { - self.version_id = version_id; - self - } - - pub fn offset(mut self, offset: Option) -> Self { - self.offset = offset; - self - } - - pub fn length(mut self, length: Option) -> Self { - self.length = length; - self - } - - /// Sets the region for the request - pub fn region(mut self, region: Option) -> Self { - self.region = region; - self - } - - pub fn ssec(mut self, ssec: Option) -> Self { - self.ssec = ssec; - self - } - - pub fn match_etag(mut self, etag: Option) -> Self { - self.match_etag = etag; - self - } - - pub fn not_match_etag(mut self, etag: Option) -> Self { - self.not_match_etag = etag; - self - } - - pub fn modified_since(mut self, time: Option) -> Self { - self.modified_since = time; - self - } - - pub fn unmodified_since(mut self, time: Option) -> Self { - self.unmodified_since = time; - self - } -} +/// Builder type alias for [`GetObject`]. +/// +/// Constructed via [`GetObject::builder()`](GetObject::builder) and used to build a [`GetObject`] instance. +pub type GetObjectBldr = GetObjectBuilder<( + (MinioClient,), + (), + (), + (), + (String,), + (String,), + (), + (), + (), + (), + (), + (), + (), + (), +)>; impl S3Api for GetObject { type S3Response = GetObjectResponse; @@ -170,11 +137,14 @@ impl ToS3Request for GetObject { let mut query_params: Multimap = self.extra_query_params.unwrap_or_default(); query_params.add_version(self.version_id); - Ok(S3Request::new(self.client, Method::GET) + Ok(S3Request::builder() + .client(self.client) + .method(Method::GET) .region(self.region) - .bucket(Some(self.bucket)) - .object(Some(self.object)) + .bucket(self.bucket) + .object(self.object) .query_params(query_params) - .headers(headers)) + .headers(headers) + .build()) } } diff --git a/src/s3/builders/get_object_legal_hold.rs b/src/s3/builders/get_object_legal_hold.rs index cf474f4a..279aa0f7 100644 --- a/src/s3/builders/get_object_legal_hold.rs +++ b/src/s3/builders/get_object_legal_hold.rs @@ -13,55 +13,38 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::s3::Client; +use crate::s3::client::MinioClient; use crate::s3::error::ValidationErr; use crate::s3::multimap_ext::{Multimap, MultimapExt}; 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; +use typed_builder::TypedBuilder; /// 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)] +/// This struct constructs the parameters required for the [`Client::get_object_legal_hold`](crate::s3::client::MinioClient::get_object_legal_hold) method. +#[derive(Clone, Debug, TypedBuilder)] pub struct GetObjectLegalHold { - client: Client, - + #[builder(!default)] // force required + client: MinioClient, + #[builder(default, setter(into))] extra_headers: Option, + #[builder(default, setter(into))] extra_query_params: Option, + #[builder(default, setter(into))] region: Option, + #[builder(setter(into))] // force required + accept Into bucket: String, - + #[builder(setter(into))] // force required + accept Into object: String, + #[builder(default, setter(into))] version_id: Option, } -impl GetObjectLegalHold { - 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) -> Self { - self.extra_headers = extra_headers; - self - } - - pub fn extra_query_params(mut self, extra_query_params: Option) -> Self { - self.extra_query_params = extra_query_params; - self - } - - pub fn version_id(mut self, version_id: Option) -> Self { - self.version_id = version_id; - self - } -} +pub type GetObjectLegalHoldBldr = + GetObjectLegalHoldBuilder<((MinioClient,), (), (), (), (String,), (String,), ())>; impl S3Api for GetObjectLegalHold { type S3Response = GetObjectLegalHoldResponse; @@ -75,11 +58,14 @@ impl ToS3Request for GetObjectLegalHold { let mut query_params: Multimap = insert(self.extra_query_params, "legal-hold"); query_params.add_version(self.version_id); - Ok(S3Request::new(self.client, Method::GET) + Ok(S3Request::builder() + .client(self.client) + .method(Method::GET) .region(self.region) - .bucket(Some(self.bucket)) + .bucket(self.bucket) .query_params(query_params) .headers(self.extra_headers.unwrap_or_default()) - .object(Some(self.object))) + .object(self.object) + .build()) } } diff --git a/src/s3/builders/get_object_lock_config.rs b/src/s3/builders/get_object_lock_config.rs index d56a3de3..3957b299 100644 --- a/src/s3/builders/get_object_lock_config.rs +++ b/src/s3/builders/get_object_lock_config.rs @@ -13,7 +13,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::s3::builders::BucketCommon; +use crate::s3::MinioClient; +use crate::s3::builders::{BucketCommon, BucketCommonBuilder}; use crate::s3::error::ValidationErr; use crate::s3::response::GetObjectLockConfigResponse; use crate::s3::types::{S3Api, S3Request, ToS3Request}; @@ -22,13 +23,18 @@ use http::Method; /// 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. +/// This struct constructs the parameters required for the [`Client::get_object_lock_config`](crate::s3::client::MinioClient::get_object_lock_config) method. pub type GetObjectLockConfig = BucketCommon; #[doc(hidden)] -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug)] pub struct GetObjectLockConfigPhantomData; +pub type GetObjectLockConfigBldr = BucketCommonBuilder< + GetObjectLockConfigPhantomData, + ((MinioClient,), (), (), (), (String,), ()), +>; + impl S3Api for GetObjectLockConfig { type S3Response = GetObjectLockConfigResponse; } @@ -37,10 +43,13 @@ impl ToS3Request for GetObjectLockConfig { fn to_s3request(self) -> Result { check_bucket_name(&self.bucket, true)?; - Ok(S3Request::new(self.client, Method::GET) + Ok(S3Request::builder() + .client(self.client) + .method(Method::GET) .region(self.region) - .bucket(Some(self.bucket)) + .bucket(self.bucket) .query_params(insert(self.extra_query_params, "object-lock")) - .headers(self.extra_headers.unwrap_or_default())) + .headers(self.extra_headers.unwrap_or_default()) + .build()) } } diff --git a/src/s3/builders/get_object_prompt.rs b/src/s3/builders/get_object_prompt.rs index 185e4984..bc572d68 100644 --- a/src/s3/builders/get_object_prompt.rs +++ b/src/s3/builders/get_object_prompt.rs @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::s3::client::Client; +use crate::s3::client::MinioClient; use crate::s3::error::ValidationErr; use crate::s3::multimap_ext::{Multimap, MultimapExt}; use crate::s3::response::GetObjectPromptResponse; @@ -24,68 +24,48 @@ use crate::s3::utils::{check_bucket_name, check_object_name, check_ssec}; use bytes::Bytes; use http::Method; use serde_json::json; +use std::sync::Arc; +use typed_builder::TypedBuilder; /// Argument builder for the `GetObjectPrompt` operation. /// -/// This struct constructs the parameters required for the [`Client::get_object_prompt`](crate::s3::client::Client::get_object_prompt) method. -#[derive(Debug, Clone, Default)] +/// This struct constructs the parameters required for the [`Client::get_object_prompt`](crate::s3::client::MinioClient::get_object_prompt) method. +#[derive(Debug, Clone, TypedBuilder)] pub struct GetObjectPrompt { - client: Client, + #[builder(!default)] // force required + client: MinioClient, + #[builder(default, setter(into))] + extra_headers: Option, + #[builder(default, setter(into))] + extra_query_params: Option, + #[builder(default, setter(into))] + region: Option, + #[builder(setter(into))] // force required + accept Into bucket: String, + #[builder(setter(into))] // force required + accept Into object: String, + #[builder(setter(into))] // force required + accept Into prompt: String, + #[builder(default, setter(into))] lambda_arn: Option, - + #[builder(default, setter(into))] version_id: Option, - region: Option, + #[builder(default, setter(into))] ssec: Option, - extra_headers: Option, - extra_query_params: Option, } -// builder interface -impl GetObjectPrompt { - pub fn new(client: Client, bucket: String, object: String, prompt: String) -> Self { - GetObjectPrompt { - client, - bucket, - object, - prompt, - ..Default::default() - } - } - - pub fn lambda_arn(mut self, lambda_arn: &str) -> Self { - self.lambda_arn = Some(lambda_arn.to_string()); - self - } - - pub fn extra_headers(mut self, extra_headers: Option) -> Self { - self.extra_headers = extra_headers; - self - } - - pub fn extra_query_params(mut self, extra_query_params: Option) -> Self { - self.extra_query_params = extra_query_params; - self - } - - pub fn version_id(mut self, version_id: Option) -> Self { - self.version_id = version_id; - self - } - - /// Sets the region for the request - pub fn region(mut self, region: Option) -> Self { - self.region = region; - self - } - - pub fn ssec(mut self, ssec: Option) -> Self { - self.ssec = ssec; - self - } -} +pub type GetObjectPromptBldr = GetObjectPromptBuilder<( + (MinioClient,), + (), + (), + (), + (String,), + (String,), + (String,), + (), + (), + (), +)>; impl S3Api for GetObjectPrompt { type S3Response = GetObjectPromptResponse; @@ -113,14 +93,17 @@ impl ToS3Request for GetObjectPrompt { ); let prompt_body = json!({ "prompt": self.prompt }); - let body: SegmentedBytes = SegmentedBytes::from(Bytes::from(prompt_body.to_string())); + let body = Arc::new(SegmentedBytes::from(Bytes::from(prompt_body.to_string()))); - Ok(S3Request::new(self.client, Method::POST) + Ok(S3Request::builder() + .client(self.client) + .method(Method::POST) .region(self.region) - .bucket(Some(self.bucket)) - .object(Some(self.object)) + .bucket(self.bucket) + .object(self.object) .query_params(query_params) .headers(self.extra_headers.unwrap_or_default()) - .body(Some(body))) + .body(body) + .build()) } } diff --git a/src/s3/builders/get_object_retention.rs b/src/s3/builders/get_object_retention.rs index ad02f66c..a1ea1742 100644 --- a/src/s3/builders/get_object_retention.rs +++ b/src/s3/builders/get_object_retention.rs @@ -13,61 +13,41 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::s3::Client; +use crate::s3::client::MinioClient; use crate::s3::error::ValidationErr; use crate::s3::multimap_ext::{Multimap, MultimapExt}; use crate::s3::response::GetObjectRetentionResponse; use crate::s3::types::{S3Api, S3Request, ToS3Request}; use crate::s3::utils::{check_bucket_name, check_object_name, insert}; use http::Method; +use typed_builder::TypedBuilder; /// 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)] +/// This struct constructs the parameters required for the [`Client::get_object_retention`](crate::s3::client::MinioClient::get_object_retention) method. +#[derive(Clone, Debug, TypedBuilder)] pub struct GetObjectRetention { - client: Client, - + #[builder(!default)] // force required + client: MinioClient, + #[builder(default, setter(into))] extra_headers: Option, + #[builder(default, setter(into))] extra_query_params: Option, + #[builder(default, setter(into))] region: Option, + #[builder(setter(into))] // force required + accept Into bucket: String, - + #[builder(setter(into))] // force required + accept Into object: String, + #[builder(default, setter(into))] version_id: Option, } -impl GetObjectRetention { - 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) -> Self { - self.extra_headers = extra_headers; - self - } - - pub fn extra_query_params(mut self, extra_query_params: Option) -> Self { - self.extra_query_params = extra_query_params; - self - } - - /// Sets the region for the request - pub fn region(mut self, region: Option) -> Self { - self.region = region; - self - } - - pub fn version_id(mut self, version_id: Option) -> Self { - self.version_id = version_id; - self - } -} +/// Builder type alias for [`GetObjectRetention`]. +/// +/// Constructed via [`GetObjectRetention::builder()`](GetObjectRetention::builder) and used to build a [`GetObjectRetention`] instance. +pub type GetObjectRetentionBldr = + GetObjectRetentionBuilder<((MinioClient,), (), (), (), (String,), (String,), ())>; impl S3Api for GetObjectRetention { type S3Response = GetObjectRetentionResponse; @@ -81,11 +61,14 @@ impl ToS3Request for GetObjectRetention { let mut query_params: Multimap = insert(self.extra_query_params, "retention"); query_params.add_version(self.version_id); - Ok(S3Request::new(self.client, Method::GET) + Ok(S3Request::builder() + .client(self.client) + .method(Method::GET) .region(self.region) - .bucket(Some(self.bucket)) + .bucket(self.bucket) .query_params(query_params) - .object(Some(self.object)) - .headers(self.extra_headers.unwrap_or_default())) + .object(self.object) + .headers(self.extra_headers.unwrap_or_default()) + .build()) } } diff --git a/src/s3/builders/get_object_tagging.rs b/src/s3/builders/get_object_tagging.rs index 3b557758..7e01a1c1 100644 --- a/src/s3/builders/get_object_tagging.rs +++ b/src/s3/builders/get_object_tagging.rs @@ -13,61 +13,38 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::s3::Client; +use crate::s3::client::MinioClient; use crate::s3::error::ValidationErr; use crate::s3::multimap_ext::{Multimap, MultimapExt}; 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; +use typed_builder::TypedBuilder; /// Argument builder for the [`GetObjectTagging`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectTagging.html) S3 API operation. /// -/// This struct constructs the parameters required for the [`Client::get_object_tagging`](crate::s3::client::Client::get_object_tagging) method. -#[derive(Clone, Debug, Default)] +/// This struct constructs the parameters required for the [`Client::get_object_tagging`](crate::s3::client::MinioClient::get_object_tagging) method. +#[derive(Clone, Debug, TypedBuilder)] pub struct GetObjectTagging { - client: Client, - + #[builder(!default)] // force required + client: MinioClient, + #[builder(default, setter(into))] extra_headers: Option, + #[builder(default, setter(into))] extra_query_params: Option, + #[builder(default, setter(into))] region: Option, + #[builder(setter(into))] // force required + accept Into bucket: String, - + #[builder(setter(into))] // force required + accept Into object: String, + #[builder(default, setter(into))] version_id: Option, } -impl GetObjectTagging { - 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) -> Self { - self.extra_headers = extra_headers; - self - } - - pub fn extra_query_params(mut self, extra_query_params: Option) -> Self { - self.extra_query_params = extra_query_params; - self - } - - /// Sets the region for the request - pub fn region(mut self, region: Option) -> Self { - self.region = region; - self - } - - pub fn version_id(mut self, version_id: Option) -> Self { - self.version_id = version_id; - self - } -} +pub type GetObjectTaggingBldr = + GetObjectTaggingBuilder<((MinioClient,), (), (), (), (String,), (String,), ())>; impl S3Api for GetObjectTagging { type S3Response = GetObjectTaggingResponse; @@ -81,11 +58,14 @@ impl ToS3Request for GetObjectTagging { let mut query_params: Multimap = insert(self.extra_query_params, "tagging"); query_params.add_version(self.version_id); - Ok(S3Request::new(self.client, Method::GET) + Ok(S3Request::builder() + .client(self.client) + .method(Method::GET) .region(self.region) - .bucket(Some(self.bucket)) + .bucket(self.bucket) .query_params(query_params) - .object(Some(self.object)) - .headers(self.extra_headers.unwrap_or_default())) + .object(self.object) + .headers(self.extra_headers.unwrap_or_default()) + .build()) } } diff --git a/src/s3/builders/get_presigned_object_url.rs b/src/s3/builders/get_presigned_object_url.rs index 62960ff4..5a533757 100644 --- a/src/s3/builders/get_presigned_object_url.rs +++ b/src/s3/builders/get_presigned_object_url.rs @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::s3::Client; +use crate::s3::client::MinioClient; use crate::s3::creds::Credentials; use crate::s3::error::Error; use crate::s3::header_constants::*; @@ -22,51 +22,51 @@ use crate::s3::response::GetPresignedObjectUrlResponse; use crate::s3::signer::presign_v4; use crate::s3::utils::{UtcTime, check_bucket_name, check_object_name, utc_now}; use http::Method; +use typed_builder::TypedBuilder; /// The default expiry time in seconds for a [`GetPresignedObjectUrl`]. pub const DEFAULT_EXPIRY_SECONDS: u32 = 604_800; // 7 days -/// This struct constructs the parameters required for the [`Client::get_presigned_object_url`](crate::s3::client::Client::get_presigned_object_url) method. -#[derive(Clone, Debug, Default)] +/// This struct constructs the parameters required for the [`Client::get_presigned_object_url`](crate::s3::client::MinioClient::get_presigned_object_url) method. +#[derive(Clone, Debug, TypedBuilder)] pub struct GetPresignedObjectUrl { - client: Client, - + #[builder(!default)] // force required + client: MinioClient, + #[builder(default, setter(into))] extra_query_params: Option, + #[builder(default, setter(into))] region: Option, + #[builder(setter(into))] // force required + accept Into bucket: String, - + #[builder(setter(into))] // force required + accept Into object: String, + #[builder(default, setter(into))] version_id: Option, + #[builder(!default)] method: Method, + #[builder(default=Some(DEFAULT_EXPIRY_SECONDS), setter(into))] expiry_seconds: Option, + #[builder(default, setter(into))] request_time: Option, } -impl GetPresignedObjectUrl { - pub fn new(client: Client, bucket: String, object: String, method: Method) -> Self { - Self { - client, - bucket, - object, - method, - expiry_seconds: Some(DEFAULT_EXPIRY_SECONDS), - ..Default::default() - } - } - - /// Sets the expiry time for the presigned URL, defaulting to 7 days if not specified. - pub fn expiry_seconds(mut self, seconds: u32) -> Self { - self.expiry_seconds = Some(seconds); - self - } - - /// Sets the request time for the presigned URL, defaulting to the current time if not specified. - pub fn request_time(mut self, time: UtcTime) -> Self { - self.request_time = Some(time); - self - } +/// Builder type alias for [`GetPresignedObjectUrl`]. +/// +/// Constructed via [`GetPresignedObjectUrl::builder()`](GetPresignedObjectUrl::builder) and used to build a [`GetPresignedObjectUrl`] instance. +pub type GetPresignedObjectUrlBldr = GetPresignedObjectUrlBuilder<( + (MinioClient,), + (), + (), + (String,), + (String,), + (), + (Method,), + (), + (), +)>; +impl GetPresignedObjectUrl { /// Sends the request to generate a presigned URL for an S3 object. pub async fn send(self) -> Result { check_bucket_name(&self.bucket, true)?; diff --git a/src/s3/builders/get_presigned_policy_form_data.rs b/src/s3/builders/get_presigned_policy_form_data.rs index ec769ae9..e52492e9 100644 --- a/src/s3/builders/get_presigned_policy_form_data.rs +++ b/src/s3/builders/get_presigned_policy_form_data.rs @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::s3::Client; +use crate::s3::client::MinioClient; use crate::s3::creds::Credentials; use crate::s3::error::{Error, ValidationErr}; use crate::s3::header_constants::*; @@ -23,18 +23,20 @@ use crate::s3::utils::{ }; use serde_json::{Value, json}; use std::collections::HashMap; +use typed_builder::TypedBuilder; -/// This struct constructs the parameters required for the [`Client::get_presigned_object_url`](crate::s3::client::Client::get_presigned_object_url) method. +/// Argument builder for generating presigned POST policy for the [`POST Object`](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPOST.html) S3 API operation. +/// +/// This struct constructs the parameters required for the [`Client::get_presigned_policy_form_data`](crate::s3::client::Client::get_presigned_policy_form_data) method. +#[derive(Debug, Clone, TypedBuilder)] pub struct GetPresignedPolicyFormData { - client: Client, + #[builder(!default)] // force required + client: MinioClient, + #[builder(!default)] // force required policy: PostPolicy, } impl GetPresignedPolicyFormData { - pub fn new(client: Client, policy: PostPolicy) -> Self { - Self { client, policy } - } - pub async fn send(self) -> Result, Error> { let region: String = self .client @@ -53,11 +55,17 @@ impl GetPresignedPolicyFormData { } } +/// Builder type alias for [`GetPresignedPolicyFormData`]. +/// +/// Constructed via [`GetPresignedPolicyFormData::builder()`](GetPresignedPolicyFormData::builder) and used to build a [`GetPresignedPolicyFormData`] instance. +pub type GetPresignedPolicyFormDataBldr = + GetPresignedPolicyFormDataBuilder<((MinioClient,), (PostPolicy,))>; + /// Post policy information for presigned post policy form-data /// /// Condition elements and respective condition for Post policy is available here. -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug)] pub struct PostPolicy { pub region: Option, pub bucket: String, @@ -89,9 +97,13 @@ impl PostPolicy { check_bucket_name(bucket_name, true)?; Ok(Self { + region: None, bucket: bucket_name.to_owned(), expiration, - ..Default::default() + eq_conditions: Default::default(), + starts_with_conditions: Default::default(), + lower_limit: None, + upper_limit: None, }) } diff --git a/src/s3/builders/get_region.rs b/src/s3/builders/get_region.rs index 7932ec35..7a8b5320 100644 --- a/src/s3/builders/get_region.rs +++ b/src/s3/builders/get_region.rs @@ -13,46 +13,35 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::s3::Client; use crate::s3::client::DEFAULT_REGION; +use crate::s3::client::MinioClient; use crate::s3::error::ValidationErr; use crate::s3::multimap_ext::Multimap; use crate::s3::response::GetRegionResponse; use crate::s3::types::{S3Api, S3Request, ToS3Request}; use crate::s3::utils::{check_bucket_name, insert}; use http::Method; +use typed_builder::TypedBuilder; /// Argument builder for the [`GetRegion`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_HeadBucket.html) S3 API operation. /// -/// This struct constructs the parameters required for the [`Client::get_region`](crate::s3::client::Client::get_region) method. -#[derive(Clone, Debug, Default)] +/// This struct constructs the parameters required for the [`Client::get_region`](crate::s3::client::MinioClient::get_region) method. +#[derive(Clone, Debug, TypedBuilder)] pub struct GetRegion { - client: Client, - + #[builder(!default)] // force required + client: MinioClient, + #[builder(default, setter(into))] extra_headers: Option, + #[builder(default, setter(into))] extra_query_params: Option, + #[builder(setter(into))] // force required + accept Into bucket: String, } -impl GetRegion { - pub fn new(client: Client, bucket: String) -> Self { - Self { - client, - bucket, - ..Default::default() - } - } - - pub fn extra_headers(mut self, extra_headers: Option) -> Self { - self.extra_headers = extra_headers; - self - } - - pub fn extra_query_params(mut self, extra_query_params: Option) -> Self { - self.extra_query_params = extra_query_params; - self - } -} +/// Builder type alias for [`GetRegion`]. +/// +/// Constructed via [`GetRegion::builder()`](GetRegion::builder) and used to build a [`GetRegion`] instance. +pub type GetRegionBldr = GetRegionBuilder<((MinioClient,), (), (), (String,))>; #[doc(hidden)] #[derive(Default, Debug)] @@ -66,10 +55,13 @@ impl ToS3Request for GetRegion { fn to_s3request(self) -> Result { check_bucket_name(&self.bucket, true)?; - Ok(S3Request::new(self.client, Method::GET) - .region(Some(DEFAULT_REGION.to_string())) - .bucket(Some(self.bucket)) + Ok(S3Request::builder() + .client(self.client) + .method(Method::GET) + .region(DEFAULT_REGION.to_string()) + .bucket(self.bucket) .query_params(insert(self.extra_query_params, "location")) - .headers(self.extra_headers.unwrap_or_default())) + .headers(self.extra_headers.unwrap_or_default()) + .build()) } } diff --git a/src/s3/builders/list_buckets.rs b/src/s3/builders/list_buckets.rs index a00a4b0f..7c38a826 100644 --- a/src/s3/builders/list_buckets.rs +++ b/src/s3/builders/list_buckets.rs @@ -13,42 +13,31 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::s3::Client; +use crate::s3::client::MinioClient; use crate::s3::error::ValidationErr; use crate::s3::multimap_ext::Multimap; use crate::s3::response::ListBucketsResponse; use crate::s3::types::{S3Api, S3Request, ToS3Request}; use http::Method; +use typed_builder::TypedBuilder; /// 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)] +/// This struct constructs the parameters required for the [`Client::list_buckets`](crate::s3::client::MinioClient::list_buckets) method. +#[derive(Clone, Debug, TypedBuilder)] pub struct ListBuckets { - client: Client, - + #[builder(!default)] // force required + client: MinioClient, + #[builder(default, setter(into))] extra_headers: Option, + #[builder(default, setter(into))] extra_query_params: Option, } -impl ListBuckets { - pub fn new(client: Client) -> Self { - Self { - client, - ..Default::default() - } - } - - pub fn extra_headers(mut self, extra_headers: Option) -> Self { - self.extra_headers = extra_headers; - self - } - - pub fn extra_query_params(mut self, extra_query_params: Option) -> Self { - self.extra_query_params = extra_query_params; - self - } -} +/// Builder type alias for [`ListBuckets`]. +/// +/// Constructed via [`ListBuckets::builder()`](ListBuckets::builder) and used to build a [`ListBuckets`] instance. +pub type ListBucketsBldr = ListBucketsBuilder<((MinioClient,), (), ())>; impl S3Api for ListBuckets { type S3Response = ListBucketsResponse; @@ -56,8 +45,11 @@ impl S3Api for ListBuckets { impl ToS3Request for ListBuckets { fn to_s3request(self) -> Result { - Ok(S3Request::new(self.client, Method::GET) + Ok(S3Request::builder() + .client(self.client) + .method(Method::GET) .query_params(self.extra_query_params.unwrap_or_default()) - .headers(self.extra_headers.unwrap_or_default())) + .headers(self.extra_headers.unwrap_or_default()) + .build()) } } diff --git a/src/s3/builders/list_objects.rs b/src/s3/builders/list_objects.rs index a3e08e26..3ac051c6 100644 --- a/src/s3/builders/list_objects.rs +++ b/src/s3/builders/list_objects.rs @@ -12,7 +12,7 @@ //! Argument builders for ListObject APIs. -use crate::s3::client::Client; +use crate::s3::client::MinioClient; use crate::s3::error::{Error, ValidationErr}; use crate::s3::multimap_ext::{Multimap, MultimapExt}; use crate::s3::response::ListObjectsResponse; @@ -24,6 +24,7 @@ use crate::s3::utils::{check_bucket_name, insert}; use async_trait::async_trait; use futures_util::{Stream, StreamExt, stream as futures_stream}; use http::Method; +use typed_builder::TypedBuilder; fn add_common_list_objects_query_params( query_params: &mut Multimap, @@ -55,10 +56,10 @@ fn delim_helper(delim: Option, recursive: bool) -> Option { /// 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)] +/// This struct constructs the parameters required for the [`Client::list_objects`](crate::s3::client::MinioClient::list_objects) method. +#[derive(Clone, Debug)] struct ListObjectsV1 { - client: Client, + client: MinioClient, extra_headers: Option, extra_query_params: Option, @@ -127,11 +128,14 @@ impl ToS3Request for ListObjectsV1 { } } - Ok(S3Request::new(self.client, Method::GET) + Ok(S3Request::builder() + .client(self.client) + .method(Method::GET) .region(self.region) - .bucket(Some(self.bucket)) + .bucket(self.bucket) .query_params(query_params) - .headers(self.extra_headers.unwrap_or_default())) + .headers(self.extra_headers.unwrap_or_default()) + .build()) } } @@ -157,10 +161,10 @@ impl From for ListObjectsV1 { /// 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)] +/// This struct constructs the parameters required for the [`Client::list_objects`](crate::s3::client::MinioClient::list_objects) method. +#[derive(Clone, Debug)] struct ListObjectsV2 { - client: Client, + client: MinioClient, extra_headers: Option, extra_query_params: Option, @@ -242,11 +246,14 @@ impl ToS3Request for ListObjectsV2 { } } - Ok(S3Request::new(self.client, Method::GET) + Ok(S3Request::builder() + .client(self.client) + .method(Method::GET) .region(self.region) - .bucket(Some(self.bucket)) + .bucket(self.bucket) .query_params(query_params) - .headers(self.extra_headers.unwrap_or_default())) + .headers(self.extra_headers.unwrap_or_default()) + .build()) } } @@ -275,10 +282,10 @@ impl From for ListObjectsV2 { /// 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)] +/// This struct constructs the parameters required for the [`Client::list_objects`](crate::s3::client::MinioClient::list_objects) method. +#[derive(Clone, Debug)] struct ListObjectVersions { - client: Client, + client: MinioClient, extra_headers: Option, extra_query_params: Option, @@ -359,11 +366,14 @@ impl ToS3Request for ListObjectVersions { } } - Ok(S3Request::new(self.client, Method::GET) + Ok(S3Request::builder() + .client(self.client) + .method(Method::GET) .region(self.region) - .bucket(Some(self.bucket)) + .bucket(self.bucket) .query_params(query_params) - .headers(self.extra_headers.unwrap_or_default())) + .headers(self.extra_headers.unwrap_or_default()) + .build()) } } @@ -391,44 +401,115 @@ impl From for ListObjectVersions { // region: list-objects /// Argument builder for -/// [list_objects()](crate::s3::client::Client::list_objects) API. +/// [list_objects()](crate::s3::client::MinioClient::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 /// a stream of results. Pagination is automatically performed. -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug, TypedBuilder)] pub struct ListObjects { - client: Client, + #[builder(!default)] // force required + client: MinioClient, // Parameters common to all ListObjects APIs. + #[builder(default, setter(into))] extra_headers: Option, + #[builder(default, setter(into))] extra_query_params: Option, + /// Sets the region for the request + #[builder(default, setter(into))] region: Option, + #[builder(setter(into))] // force required + accept Into bucket: String, + + /// Delimiter to roll up common prefixes on. + #[builder(default, setter(into))] delimiter: Option, + /// Disable setting the `EncodingType` parameter in the ListObjects request. + /// By default, it is set to `url`. + #[builder(default)] disable_url_encoding: bool, + #[builder(default, setter(into))] max_keys: Option, + #[builder(default, setter(into))] prefix: Option, // Options specific to ListObjectsV1. + /// Used only with ListObjectsV1. + #[builder(default, setter(into))] marker: Option, // Options specific to ListObjectsV2. + /// Used only with ListObjectsV2 + #[builder(default, setter(into))] start_after: Option, + + /// Used only with ListObjectsV2 + #[builder(default, setter(into))] continuation_token: Option, + + /// Used only with ListObjectsV2 + #[builder(default)] fetch_owner: bool, + + /// Used only with ListObjectsV2. MinIO extension. + #[builder(default)] include_user_metadata: bool, // Options specific to ListObjectVersions. + /// Used only with GetObjectVersions. + #[builder(default, setter(into))] key_marker: Option, + + /// Used only with GetObjectVersions. + #[builder(default, setter(into))] version_id_marker: Option, // Higher level options. + /// This parameter takes effect only when delimiter is None. Enables + /// recursive traversal for listing of the bucket and prefix. + #[builder(default)] recursive: bool, + + /// 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. + #[builder(default)] use_api_v1: bool, + + /// Set this to include versions. Defaults to false. Has no effect when + /// `use_api_v1` is set. + #[builder(default)] include_versions: bool, } +/// Builder type alias for [`ListObjects`]. +/// +/// Constructed via [`ListObjects::builder()`](ListObjects::builder) and used to build a [`ListObjects`] instance. +pub type ListObjectBldr = ListObjectsBuilder<( + (MinioClient,), + (), + (), + (), + (String,), + (), + (), + (), + (), + (), + (), + (), + (), + (), + (), + (), + (), + (), + (), +)>; + #[async_trait] impl ToStream for ListObjects { type Item = ListObjectsResponse; @@ -446,118 +527,4 @@ impl ToStream for ListObjects { } } } - -impl ListObjects { - pub fn new(client: Client, bucket: String) -> Self { - Self { - client, - bucket, - ..Default::default() - } - } - pub fn extra_headers(mut self, extra_headers: Option) -> Self { - self.extra_headers = extra_headers; - self - } - - pub fn extra_query_params(mut self, extra_query_params: Option) -> Self { - self.extra_query_params = extra_query_params; - self - } - - /// Sets the region for the request - pub fn region(mut self, region: Option) -> Self { - self.region = region; - self - } - - /// Delimiter to roll up common prefixes on. - pub fn delimiter(mut self, delimiter: Option) -> Self { - self.delimiter = delimiter; - self - } - - /// Disable setting the `EncodingType` parameter in the ListObjects request. - /// 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 - } - - pub fn max_keys(mut self, max_keys: Option) -> Self { - self.max_keys = max_keys; - self - } - - pub fn prefix(mut self, prefix: Option) -> Self { - self.prefix = prefix; - self - } - - /// Used only with ListObjectsV1. - pub fn marker(mut self, marker: Option) -> Self { - self.marker = marker; - self - } - - /// Used only with ListObjectsV2 - pub fn start_after(mut self, start_after: Option) -> Self { - self.start_after = start_after; - self - } - - /// Used only with ListObjectsV2 - pub fn continuation_token(mut self, continuation_token: Option) -> Self { - self.continuation_token = continuation_token; - self - } - - /// Used only with ListObjectsV2 - pub fn fetch_owner(mut self, fetch_owner: bool) -> Self { - self.fetch_owner = fetch_owner; - self - } - - /// Used only with ListObjectsV2. MinIO extension. - pub fn include_user_metadata(mut self, include_user_metadata: bool) -> Self { - self.include_user_metadata = include_user_metadata; - self - } - - /// Used only with GetObjectVersions. - pub fn key_marker(mut self, key_marker: Option) -> Self { - self.key_marker = key_marker; - self - } - - /// Used only with GetObjectVersions. - pub fn version_id_marker(mut self, version_id_marker: Option) -> Self { - self.version_id_marker = version_id_marker; - self - } - - /// This parameter takes effect only when delimiter is None. Enables - /// recursive traversal for listing of the bucket and prefix. - pub fn recursive(mut self, recursive: bool) -> Self { - self.recursive = recursive; - self - } - - /// 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 - } - - /// Set this to include versions. Defaults to false. Has no effect when - /// `use_api_v1` is set. - pub fn include_versions(mut self, include_versions: bool) -> Self { - self.include_versions = include_versions; - self - } -} // endregion: list-objects diff --git a/src/s3/builders/listen_bucket_notification.rs b/src/s3/builders/listen_bucket_notification.rs index 50f21ece..7a3c26dd 100644 --- a/src/s3/builders/listen_bucket_notification.rs +++ b/src/s3/builders/listen_bucket_notification.rs @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::s3::client::Client; +use crate::s3::client::MinioClient; use crate::s3::error::{Error, ValidationErr}; use crate::s3::multimap_ext::{Multimap, MultimapExt}; use crate::s3::response::ListenBucketNotificationResponse; @@ -22,63 +22,36 @@ use crate::s3::utils::check_bucket_name; use async_trait::async_trait; use futures_util::Stream; use http::Method; +use typed_builder::TypedBuilder; /// Argument builder for the [`ListenBucketNotification`](https://min.io/docs/minio/linux/developers/go/API.html#ListenBucketNotification) /// -/// This struct constructs the parameters required for the [`Client::listen_bucket_notification`](crate::s3::client::Client::listen_bucket_notification) method. -#[derive(Clone, Debug, Default)] +/// This struct constructs the parameters required for the [`Client::listen_bucket_notification`](crate::s3::client::MinioClient::listen_bucket_notification) method. +#[derive(Clone, Debug, TypedBuilder)] pub struct ListenBucketNotification { - client: Client, - + #[builder(!default)] // force required + client: MinioClient, + #[builder(default, setter(into))] extra_headers: Option, + #[builder(default, setter(into))] extra_query_params: Option, + #[builder(default, setter(into))] region: Option, + #[builder(setter(into))] // force required + accept Into bucket: String, + #[builder(default, setter(into))] prefix: Option, + #[builder(default, setter(into))] suffix: Option, + #[builder(default, setter(into))] events: Option>, } -impl ListenBucketNotification { - pub fn new(client: Client, bucket: String) -> Self { - Self { - client, - bucket, - ..Default::default() - } - } - - pub fn extra_headers(mut self, extra_headers: Option) -> Self { - self.extra_headers = extra_headers; - self - } - - pub fn extra_query_params(mut self, extra_query_params: Option) -> Self { - self.extra_query_params = extra_query_params; - self - } - - /// Sets the region for the request - pub fn region(mut self, region: Option) -> Self { - self.region = region; - self - } - - pub fn prefix(mut self, prefix: Option) -> Self { - self.prefix = prefix; - self - } - - pub fn suffix(mut self, suffix: Option) -> Self { - self.suffix = suffix; - self - } - - pub fn events(mut self, events: Option>) -> Self { - self.events = events; - self - } -} +/// Builder type alias for [`ListenBucketNotification`]. +/// +/// Constructed via [`ListenBucketNotification::builder()`](ListenBucketNotification::builder) and used to build a [`ListenBucketNotification`] instance. +pub type ListenBucketNotificationBldr = + ListenBucketNotificationBuilder<((MinioClient,), (), (), (), (String,), (), (), ())>; #[async_trait] impl S3Api for ListenBucketNotification { @@ -118,10 +91,13 @@ impl ToS3Request for ListenBucketNotification { } } - Ok(S3Request::new(self.client, Method::GET) + Ok(S3Request::builder() + .client(self.client) + .method(Method::GET) .region(self.region) - .bucket(Some(self.bucket)) + .bucket(self.bucket) .query_params(query_params) - .headers(self.extra_headers.unwrap_or_default())) + .headers(self.extra_headers.unwrap_or_default()) + .build()) } } diff --git a/src/s3/builders/put_bucket_encryption.rs b/src/s3/builders/put_bucket_encryption.rs index 2c37ad5a..bfd54be6 100644 --- a/src/s3/builders/put_bucket_encryption.rs +++ b/src/s3/builders/put_bucket_encryption.rs @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::s3::Client; +use crate::s3::client::MinioClient; use crate::s3::error::ValidationErr; use crate::s3::multimap_ext::Multimap; use crate::s3::response::PutBucketEncryptionResponse; @@ -22,53 +22,33 @@ use crate::s3::types::{S3Api, S3Request, SseConfig, ToS3Request}; use crate::s3::utils::{check_bucket_name, insert}; use bytes::Bytes; use http::Method; +use std::sync::Arc; +use typed_builder::TypedBuilder; /// Argument builder for the [`PutBucketEncryption`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketEncryption.html) S3 API operation. /// -/// This struct constructs the parameters required for the [`Client::put_bucket_encryption`](crate::s3::client::Client::put_bucket_encryption) method. -#[derive(Clone, Debug, Default)] +/// This struct constructs the parameters required for the [`Client::put_bucket_encryption`](crate::s3::client::MinioClient::put_bucket_encryption) method. +#[derive(Clone, Debug, TypedBuilder)] pub struct PutBucketEncryption { - client: Client, - + #[builder(!default)] // force required + client: MinioClient, + #[builder(default, setter(into))] extra_headers: Option, + #[builder(default, setter(into))] extra_query_params: Option, + #[builder(default, setter(into))] region: Option, + #[builder(!default, setter(into))] // force required + accept Into bucket: String, - - config: SseConfig, + #[builder(default)] + sse_config: SseConfig, } -impl PutBucketEncryption { - pub fn new(client: Client, bucket: String) -> Self { - Self { - client, - bucket, - ..Default::default() - } - } - - pub fn extra_headers(mut self, extra_headers: Option) -> Self { - self.extra_headers = extra_headers; - self - } - - pub fn extra_query_params(mut self, extra_query_params: Option) -> Self { - self.extra_query_params = extra_query_params; - self - } - - /// Sets the region for the request - pub fn region(mut self, region: Option) -> Self { - self.region = region; - self - } - - /// Sets the server-side encryption configuration for the bucket. - pub fn sse_config(mut self, config: SseConfig) -> Self { - self.config = config; - self - } -} +/// Builder type alias for [`PutBucketEncryption`]. +/// +/// Constructed via [`PutBucketEncryption::builder()`](PutBucketEncryption::builder) and used to build a [`PutBucketEncryption`] instance. +pub type PutBucketEncryptionBldr = + PutBucketEncryptionBuilder<((MinioClient,), (), (), (), (String,), ())>; impl S3Api for PutBucketEncryption { type S3Response = PutBucketEncryptionResponse; @@ -78,14 +58,17 @@ impl ToS3Request for PutBucketEncryption { fn to_s3request(self) -> Result { check_bucket_name(&self.bucket, true)?; - let bytes: Bytes = self.config.to_xml().into(); - let body: Option = Some(SegmentedBytes::from(bytes)); + let bytes: Bytes = self.sse_config.to_xml().into(); + let body = Arc::new(SegmentedBytes::from(bytes)); - Ok(S3Request::new(self.client, Method::GET) + Ok(S3Request::builder() + .client(self.client) + .method(Method::GET) .region(self.region) - .bucket(Some(self.bucket)) + .bucket(self.bucket) .query_params(insert(self.extra_query_params, "encryption")) .headers(self.extra_headers.unwrap_or_default()) - .body(body)) + .body(body) + .build()) } } diff --git a/src/s3/builders/put_bucket_lifecycle.rs b/src/s3/builders/put_bucket_lifecycle.rs index e9662871..5bdc71da 100644 --- a/src/s3/builders/put_bucket_lifecycle.rs +++ b/src/s3/builders/put_bucket_lifecycle.rs @@ -13,62 +13,44 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::s3::Client; +use crate::s3::client::MinioClient; use crate::s3::error::ValidationErr; use crate::s3::header_constants::*; use crate::s3::lifecycle_config::LifecycleConfig; use crate::s3::multimap_ext::{Multimap, MultimapExt}; use crate::s3::response::PutBucketLifecycleResponse; +use crate::s3::segmented_bytes::SegmentedBytes; use crate::s3::types::{S3Api, S3Request, ToS3Request}; use crate::s3::utils::{check_bucket_name, insert, md5sum_hash}; use bytes::Bytes; use http::Method; +use std::sync::Arc; +use typed_builder::TypedBuilder; /// Argument builder for the [`PutBucketLifecycle`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketLifecycle.html) S3 API operation. /// -/// This struct constructs the parameters required for the [`Client::put_bucket_lifecycle`](crate::s3::client::Client::put_bucket_lifecycle) method. -#[derive(Clone, Debug, Default)] +/// This struct constructs the parameters required for the [`Client::put_bucket_lifecycle`](crate::s3::client::MinioClient::put_bucket_lifecycle) method. +#[derive(Clone, Debug, TypedBuilder)] pub struct PutBucketLifecycle { - client: Client, - + #[builder(!default)] // force required + client: MinioClient, + #[builder(default, setter(into))] extra_headers: Option, + #[builder(default, setter(into))] extra_query_params: Option, + #[builder(default, setter(into))] region: Option, + #[builder(!default, setter(into))] // force required + accept Into bucket: String, - - config: LifecycleConfig, + #[builder(default)] + life_cycle_config: LifecycleConfig, } -impl PutBucketLifecycle { - pub fn new(client: Client, bucket: String) -> Self { - Self { - client, - bucket, - ..Default::default() - } - } - - pub fn extra_headers(mut self, extra_headers: Option) -> Self { - self.extra_headers = extra_headers; - self - } - - pub fn extra_query_params(mut self, extra_query_params: Option) -> Self { - self.extra_query_params = extra_query_params; - self - } - - /// Sets the region for the request - pub fn region(mut self, region: Option) -> Self { - self.region = region; - self - } - - pub fn life_cycle_config(mut self, config: LifecycleConfig) -> Self { - self.config = config; - self - } -} +/// Builder type alias for [`PutBucketLifecycle`]. +/// +/// Constructed via [`PutBucketLifecycle::builder()`](PutBucketLifecycle::builder) and used to build a [`PutBucketLifecycle`] instance. +pub type PutBucketLifecycleBldr = + PutBucketLifecycleBuilder<((MinioClient,), (), (), (), (String,), ())>; impl S3Api for PutBucketLifecycle { type S3Response = PutBucketLifecycleResponse; @@ -80,14 +62,19 @@ impl ToS3Request for PutBucketLifecycle { let mut headers: Multimap = self.extra_headers.unwrap_or_default(); - let bytes: Bytes = self.config.to_xml().into(); + let bytes: Bytes = self.life_cycle_config.to_xml().into(); headers.add(CONTENT_MD5, md5sum_hash(bytes.as_ref())); - Ok(S3Request::new(self.client, Method::PUT) + let body = Arc::new(SegmentedBytes::from(bytes)); + + Ok(S3Request::builder() + .client(self.client) + .method(Method::PUT) .region(self.region) - .bucket(Some(self.bucket)) + .bucket(self.bucket) .query_params(insert(self.extra_query_params, "lifecycle")) .headers(headers) - .body(Some(bytes.into()))) + .body(body) + .build()) } } diff --git a/src/s3/builders/put_bucket_notification.rs b/src/s3/builders/put_bucket_notification.rs index cc5ffce3..9dd812c1 100644 --- a/src/s3/builders/put_bucket_notification.rs +++ b/src/s3/builders/put_bucket_notification.rs @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::s3::Client; +use crate::s3::client::MinioClient; use crate::s3::error::ValidationErr; use crate::s3::multimap_ext::Multimap; use crate::s3::response::PutBucketNotificationResponse; @@ -22,52 +22,33 @@ use crate::s3::types::{NotificationConfig, S3Api, S3Request, ToS3Request}; use crate::s3::utils::{check_bucket_name, insert}; use bytes::Bytes; use http::Method; +use std::sync::Arc; +use typed_builder::TypedBuilder; /// 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)] +/// This struct constructs the parameters required for the [`Client::put_bucket_notification`](crate::s3::client::MinioClient::put_bucket_notification) method. +#[derive(Clone, Debug, TypedBuilder)] pub struct PutBucketNotification { - client: Client, - + #[builder(!default)] // force required + client: MinioClient, + #[builder(default, setter(into))] extra_headers: Option, + #[builder(default, setter(into))] extra_query_params: Option, + #[builder(default, setter(into))] region: Option, + #[builder(setter(into))] // force required + accept Into bucket: String, - - config: NotificationConfig, + #[builder(default)] + notification_config: NotificationConfig, } -impl PutBucketNotification { - pub fn new(client: Client, bucket: String) -> Self { - Self { - client, - bucket, - ..Default::default() - } - } - - pub fn extra_headers(mut self, extra_headers: Option) -> Self { - self.extra_headers = extra_headers; - self - } - - pub fn extra_query_params(mut self, extra_query_params: Option) -> Self { - self.extra_query_params = extra_query_params; - self - } - - /// Sets the region for the request - pub fn region(mut self, region: Option) -> Self { - self.region = region; - self - } - - pub fn notification_config(mut self, config: NotificationConfig) -> Self { - self.config = config; - self - } -} +/// Builder type alias for [`PutBucketNotification`]. +/// +/// Constructed via [`PutBucketNotification::builder()`](PutBucketNotification::builder) and used to build a [`PutBucketNotification`] instance. +pub type PutBucketNotificationBldr = + PutBucketNotificationBuilder<((MinioClient,), (), (), (), (String,), ())>; impl S3Api for PutBucketNotification { type S3Response = PutBucketNotificationResponse; @@ -77,14 +58,17 @@ impl ToS3Request for PutBucketNotification { fn to_s3request(self) -> Result { check_bucket_name(&self.bucket, true)?; - let bytes: Bytes = self.config.to_xml().into(); - let body: Option = Some(SegmentedBytes::from(bytes)); + let bytes: Bytes = self.notification_config.to_xml().into(); + let body = Arc::new(SegmentedBytes::from(bytes)); - Ok(S3Request::new(self.client, Method::PUT) + Ok(S3Request::builder() + .client(self.client) + .method(Method::PUT) .region(self.region) - .bucket(Some(self.bucket)) + .bucket(self.bucket) .query_params(insert(self.extra_query_params, "notification")) .headers(self.extra_headers.unwrap_or_default()) - .body(body)) + .body(body) + .build()) } } diff --git a/src/s3/builders/put_bucket_policy.rs b/src/s3/builders/put_bucket_policy.rs index 186fdd50..07c33d1d 100644 --- a/src/s3/builders/put_bucket_policy.rs +++ b/src/s3/builders/put_bucket_policy.rs @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::s3::Client; +use crate::s3::client::MinioClient; use crate::s3::error::ValidationErr; use crate::s3::multimap_ext::Multimap; use crate::s3::response::PutBucketPolicyResponse; @@ -22,52 +22,32 @@ use crate::s3::types::{S3Api, S3Request, ToS3Request}; use crate::s3::utils::{check_bucket_name, insert}; use bytes::Bytes; use http::Method; +use std::sync::Arc; +use typed_builder::TypedBuilder; /// 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)] +/// This struct constructs the parameters required for the [`Client::put_bucket_policy`](crate::s3::client::MinioClient::put_bucket_policy) method. +#[derive(Clone, Debug, TypedBuilder)] pub struct PutBucketPolicy { - client: Client, - + #[builder(!default)] // force required + client: MinioClient, + #[builder(default, setter(into))] extra_headers: Option, + #[builder(default, setter(into))] extra_query_params: Option, + #[builder(default, setter(into))] region: Option, + #[builder(setter(into))] // force required + accept Into bucket: String, - + #[builder(default)] config: String, //TODO consider PolicyConfig struct } -impl PutBucketPolicy { - pub fn new(client: Client, bucket: String) -> Self { - Self { - client, - bucket, - ..Default::default() - } - } - - pub fn extra_headers(mut self, extra_headers: Option) -> Self { - self.extra_headers = extra_headers; - self - } - - pub fn extra_query_params(mut self, extra_query_params: Option) -> Self { - self.extra_query_params = extra_query_params; - self - } - - /// Sets the region for the request - pub fn region(mut self, region: Option) -> Self { - self.region = region; - self - } - - pub fn config(mut self, config: String) -> Self { - self.config = config; - self - } -} +/// Builder type for [`PutBucketPolicy`] that is returned by [`MinioClient::put_bucket_policy`](crate::s3::client::MinioClient::put_bucket_policy). +/// +/// This type alias simplifies the complex generic signature generated by the `typed_builder` crate. +pub type PutBucketPolicyBldr = PutBucketPolicyBuilder<((MinioClient,), (), (), (), (String,), ())>; impl S3Api for PutBucketPolicy { type S3Response = PutBucketPolicyResponse; @@ -78,13 +58,16 @@ impl ToS3Request for PutBucketPolicy { check_bucket_name(&self.bucket, true)?; let bytes: Bytes = self.config.into(); - let body: Option = Some(SegmentedBytes::from(bytes)); + let body = Arc::new(SegmentedBytes::from(bytes)); - Ok(S3Request::new(self.client, Method::PUT) + Ok(S3Request::builder() + .client(self.client) + .method(Method::PUT) .region(self.region) - .bucket(Some(self.bucket)) + .bucket(self.bucket) .query_params(insert(self.extra_query_params, "policy")) .headers(self.extra_headers.unwrap_or_default()) - .body(body)) + .body(body) + .build()) } } diff --git a/src/s3/builders/put_bucket_replication.rs b/src/s3/builders/put_bucket_replication.rs index 40e2859c..860cdd22 100644 --- a/src/s3/builders/put_bucket_replication.rs +++ b/src/s3/builders/put_bucket_replication.rs @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::s3::Client; +use crate::s3::client::MinioClient; use crate::s3::error::ValidationErr; use crate::s3::multimap_ext::Multimap; use crate::s3::response::PutBucketReplicationResponse; @@ -22,52 +22,33 @@ use crate::s3::types::{ReplicationConfig, S3Api, S3Request, ToS3Request}; use crate::s3::utils::{check_bucket_name, insert}; use bytes::Bytes; use http::Method; +use std::sync::Arc; +use typed_builder::TypedBuilder; /// 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)] +/// This struct constructs the parameters required for the [`Client::put_bucket_replication`](crate::s3::client::MinioClient::put_bucket_replication) method. +#[derive(Clone, Debug, TypedBuilder)] pub struct PutBucketReplication { - client: Client, - + #[builder(!default)] // force required + client: MinioClient, + #[builder(default, setter(into))] extra_headers: Option, + #[builder(default, setter(into))] extra_query_params: Option, + #[builder(default, setter(into))] region: Option, + #[builder(setter(into))] // force required + accept Into bucket: String, - - config: ReplicationConfig, + #[builder(default)] + replication_config: ReplicationConfig, } -impl PutBucketReplication { - pub fn new(client: Client, bucket: String) -> Self { - Self { - client, - bucket, - ..Default::default() - } - } - - pub fn extra_headers(mut self, extra_headers: Option) -> Self { - self.extra_headers = extra_headers; - self - } - - pub fn extra_query_params(mut self, extra_query_params: Option) -> Self { - self.extra_query_params = extra_query_params; - self - } - - /// Sets the region for the request - pub fn region(mut self, region: Option) -> Self { - self.region = region; - self - } - - pub fn replication_config(mut self, config: ReplicationConfig) -> Self { - self.config = config; - self - } -} +/// Builder type for [`PutBucketReplication`] that is returned by [`MinioClient::put_bucket_replication`](crate::s3::client::MinioClient::put_bucket_replication). +/// +/// This type alias simplifies the complex generic signature generated by the `typed_builder` crate. +pub type PutBucketReplicationBldr = + PutBucketReplicationBuilder<((MinioClient,), (), (), (), (String,), ())>; impl S3Api for PutBucketReplication { type S3Response = PutBucketReplicationResponse; @@ -77,14 +58,17 @@ impl ToS3Request for PutBucketReplication { fn to_s3request(self) -> Result { check_bucket_name(&self.bucket, true)?; - let bytes: Bytes = self.config.to_xml().into(); - let body: Option = Some(SegmentedBytes::from(bytes)); + let bytes: Bytes = self.replication_config.to_xml().into(); + let body = Arc::new(SegmentedBytes::from(bytes)); - Ok(S3Request::new(self.client, Method::PUT) + Ok(S3Request::builder() + .client(self.client) + .method(Method::PUT) .region(self.region) - .bucket(Some(self.bucket)) + .bucket(self.bucket) .query_params(insert(self.extra_query_params, "replication")) .headers(self.extra_headers.unwrap_or_default()) - .body(body)) + .body(body) + .build()) } } diff --git a/src/s3/builders/put_bucket_tagging.rs b/src/s3/builders/put_bucket_tagging.rs index cc15f58a..6b255bad 100644 --- a/src/s3/builders/put_bucket_tagging.rs +++ b/src/s3/builders/put_bucket_tagging.rs @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::s3::Client; +use crate::s3::client::MinioClient; use crate::s3::error::ValidationErr; use crate::s3::multimap_ext::Multimap; use crate::s3::response::PutBucketTaggingResponse; @@ -23,52 +23,33 @@ use crate::s3::utils::{check_bucket_name, insert}; use bytes::Bytes; use http::Method; use std::collections::HashMap; +use std::sync::Arc; +use typed_builder::TypedBuilder; /// 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)] +/// This struct constructs the parameters required for the [`Client::put_bucket_tagging`](crate::s3::client::MinioClient::put_bucket_tagging) method. +#[derive(Clone, Debug, TypedBuilder)] pub struct PutBucketTagging { - client: Client, - + #[builder(!default)] // force required + client: MinioClient, + #[builder(default, setter(into))] extra_headers: Option, + #[builder(default, setter(into))] extra_query_params: Option, + #[builder(default, setter(into))] region: Option, + #[builder(setter(into))] // force required + accept Into bucket: String, - + #[builder(default)] tags: HashMap, } -impl PutBucketTagging { - pub fn new(client: Client, bucket: String) -> Self { - Self { - client, - bucket, - ..Default::default() - } - } - - pub fn extra_headers(mut self, extra_headers: Option) -> Self { - self.extra_headers = extra_headers; - self - } - - pub fn extra_query_params(mut self, extra_query_params: Option) -> Self { - self.extra_query_params = extra_query_params; - self - } - - /// Sets the region for the request - pub fn region(mut self, region: Option) -> Self { - self.region = region; - self - } - - pub fn tags(mut self, tags: HashMap) -> Self { - self.tags = tags; - self - } -} +/// Builder type for [`PutBucketTagging`] that is returned by [`MinioClient::put_bucket_tagging`](crate::s3::client::MinioClient::put_bucket_tagging). +/// +/// This type alias simplifies the complex generic signature generated by the `typed_builder` crate. +pub type PutBucketTaggingBldr = + PutBucketTaggingBuilder<((MinioClient,), (), (), (), (String,), ())>; impl S3Api for PutBucketTagging { type S3Response = PutBucketTaggingResponse; @@ -97,13 +78,16 @@ impl ToS3Request for PutBucketTagging { data.push_str(""); data }; - let body: Option = Some(SegmentedBytes::from(Bytes::from(data))); + let body = Arc::new(SegmentedBytes::from(Bytes::from(data))); - Ok(S3Request::new(self.client, Method::PUT) + Ok(S3Request::builder() + .client(self.client) + .method(Method::PUT) .region(self.region) - .bucket(Some(self.bucket)) + .bucket(self.bucket) .query_params(insert(self.extra_query_params, "tagging")) .headers(self.extra_headers.unwrap_or_default()) - .body(body)) + .body(body) + .build()) } } diff --git a/src/s3/builders/put_bucket_versioning.rs b/src/s3/builders/put_bucket_versioning.rs index c5a711b4..8b6ef1fe 100644 --- a/src/s3/builders/put_bucket_versioning.rs +++ b/src/s3/builders/put_bucket_versioning.rs @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::s3::Client; +use crate::s3::client::MinioClient; use crate::s3::error::ValidationErr; use crate::s3::multimap_ext::Multimap; use crate::s3::response::PutBucketVersioningResponse; @@ -23,6 +23,8 @@ use crate::s3::utils::{check_bucket_name, insert}; use bytes::Bytes; use http::Method; use std::fmt; +use std::sync::Arc; +use typed_builder::TypedBuilder; /// Represents the versioning state of an S3 bucket. /// @@ -52,22 +54,27 @@ impl fmt::Display for VersioningStatus { /// 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)] +/// This struct constructs the parameters required for the [`Client::put_bucket_versioning`](crate::s3::client::MinioClient::put_bucket_versioning) method. +#[derive(Clone, Debug, TypedBuilder)] pub struct PutBucketVersioning { /// The S3 client instance used to send the request. - client: Client, + #[builder(!default)] // force required + client: MinioClient, /// Optional additional HTTP headers to include in the request. + #[builder(default, setter(into))] extra_headers: Option, /// Optional additional query parameters to include in the request URL. + #[builder(default, setter(into))] extra_query_params: Option, /// Optional AWS region to override the client's default region. + #[builder(default, setter(into))] region: Option, /// The name of the bucket for which to configure versioning. + #[builder(setter(into))] // force required + accept Into bucket: String, /// Desired versioning status for the bucket. @@ -75,51 +82,23 @@ pub struct PutBucketVersioning { /// - `Some(VersioningStatus::Enabled)`: Enables versioning. /// - `Some(VersioningStatus::Suspended)`: Suspends versioning. /// - `None`: No change to the current versioning status. - status: Option, + #[builder(default, setter(into))] + versioning_status: Option, /// 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. + #[builder(default)] mfa_delete: Option, } -impl PutBucketVersioning { - pub fn new(client: Client, bucket: String) -> Self { - Self { - client, - bucket, - ..Default::default() - } - } - - pub fn extra_headers(mut self, extra_headers: Option) -> Self { - self.extra_headers = extra_headers; - self - } - - pub fn extra_query_params(mut self, extra_query_params: Option) -> Self { - self.extra_query_params = extra_query_params; - self - } - - /// Sets the region for the request - pub fn region(mut self, region: Option) -> Self { - self.region = region; - self - } - - pub fn versioning_status(mut self, status: VersioningStatus) -> Self { - self.status = Some(status); - self - } - - pub fn mfa_delete(mut self, mfa_delete: Option) -> Self { - self.mfa_delete = mfa_delete; - self - } -} +/// Builder type for [`PutBucketVersioning`] that is returned by [`MinioClient::put_bucket_versioning`](crate::s3::client::MinioClient::put_bucket_versioning). +/// +/// This type alias simplifies the complex generic signature generated by the `typed_builder` crate. +pub type PutBucketVersioningBldr = + PutBucketVersioningBuilder<((MinioClient,), (), (), (), (String,), (), ())>; impl S3Api for PutBucketVersioning { type S3Response = PutBucketVersioningResponse; @@ -138,10 +117,11 @@ impl ToS3Request for PutBucketVersioning { data.push_str(""); } - match self.status { + match self.versioning_status { Some(VersioningStatus::Enabled) => data.push_str("Enabled"), Some(VersioningStatus::Suspended) => data.push_str("Suspended"), None => { + // TODO this seem inconsistent: `None`: No change to the current versioning status. return Err(ValidationErr::InvalidVersioningStatus( "Missing VersioningStatus".into(), )); @@ -151,13 +131,16 @@ impl ToS3Request for PutBucketVersioning { data.push_str(""); data }; - let body: Option = Some(SegmentedBytes::from(Bytes::from(data))); + let body = Arc::new(SegmentedBytes::from(Bytes::from(data))); - Ok(S3Request::new(self.client, Method::PUT) + Ok(S3Request::builder() + .client(self.client) + .method(Method::PUT) .region(self.region) - .bucket(Some(self.bucket)) + .bucket(self.bucket) .query_params(insert(self.extra_query_params, "versioning")) .headers(self.extra_headers.unwrap_or_default()) - .body(body)) + .body(body) + .build()) } } diff --git a/src/s3/builders/put_object.rs b/src/s3/builders/put_object.rs index 9fff2323..f01afbbb 100644 --- a/src/s3/builders/put_object.rs +++ b/src/s3/builders/put_object.rs @@ -15,7 +15,7 @@ use super::ObjectContent; use crate::s3::builders::{ContentStream, Size}; -use crate::s3::client::Client; +use crate::s3::client::MinioClient; use crate::s3::error::{Error, IoError, ValidationErr}; use crate::s3::header_constants::*; use crate::s3::multimap_ext::{Multimap, MultimapExt}; @@ -32,85 +32,58 @@ use crate::s3::utils::{check_object_name, check_sse, insert}; use bytes::{Bytes, BytesMut}; use http::Method; use std::{collections::HashMap, sync::Arc}; +use typed_builder::TypedBuilder; // region: multipart-upload -/// Argument for -/// [create_multipart_upload()](crate::s3::client::Client::create_multipart_upload) -/// API -#[derive(Clone, Debug, Default)] +/// Argument builder for the [`CreateMultipartUpload`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html) S3 API operation. +/// +/// This struct constructs the parameters required for the [`Client::create_multipart_upload`](crate::s3::client::MinioClient::create_multipart_upload) method. +#[derive(Clone, Debug, TypedBuilder)] pub struct CreateMultipartUpload { - client: Client, - + #[builder(!default)] // force required + client: MinioClient, + #[builder(default, setter(into))] extra_headers: Option, + #[builder(default, setter(into))] extra_query_params: Option, + #[builder(default, setter(into))] region: Option, + #[builder(setter(into))] // force required + accept Into bucket: String, + #[builder(setter(into))] // force required + accept Into object: String, + #[builder(default, setter(into))] user_metadata: Option, + #[builder(default, setter(into))] sse: Option>, + #[builder(default, setter(into))] tags: Option>, + #[builder(default, setter(into))] retention: Option, + #[builder(default = false)] legal_hold: bool, + #[builder(default, setter(into))] content_type: Option, } -impl CreateMultipartUpload { - pub fn new(client: Client, bucket: String, object: String) -> Self { - CreateMultipartUpload { - client, - bucket, - object, - ..Default::default() - } - } - - pub fn extra_headers(mut self, extra_headers: Option) -> Self { - self.extra_headers = extra_headers; - self - } - - pub fn extra_query_params(mut self, extra_query_params: Option) -> Self { - self.extra_query_params = extra_query_params; - self - } - - /// Sets the region for the request - pub fn region(mut self, region: Option) -> Self { - self.region = region; - self - } - - pub fn user_metadata(mut self, user_metadata: Option) -> Self { - self.user_metadata = user_metadata; - self - } - - pub fn sse(mut self, sse: Option>) -> Self { - self.sse = sse; - self - } - - pub fn tags(mut self, tags: Option>) -> Self { - self.tags = tags; - self - } - - pub fn retention(mut self, retention: Option) -> Self { - self.retention = retention; - self - } - - pub fn legal_hold(mut self, legal_hold: bool) -> Self { - self.legal_hold = legal_hold; - self - } - - pub fn content_type(mut self, content_type: Option) -> Self { - self.content_type = content_type; - self - } -} +/// Builder type for [`CreateMultipartUpload`] that is returned by [`MinioClient::create_multipart_upload`](crate::s3::client::MinioClient::create_multipart_upload). +/// +/// This type alias simplifies the complex generic signature generated by the `typed_builder` crate. +pub type CreateMultipartUploadBldr = CreateMultipartUploadBuilder<( + (MinioClient,), + (), + (), + (), + (String,), + (String,), + (), + (), + (), + (), + (), + (), +)>; impl S3Api for CreateMultipartUpload { type S3Response = CreateMultipartUploadResponse; @@ -131,12 +104,15 @@ impl ToS3Request for CreateMultipartUpload { self.content_type, )?; - Ok(S3Request::new(self.client, Method::POST) + Ok(S3Request::builder() + .client(self.client) + .method(Method::POST) .region(self.region) - .bucket(Some(self.bucket)) - .object(Some(self.object)) + .bucket(self.bucket) + .object(self.object) .query_params(insert(self.extra_query_params, "uploads")) - .headers(headers)) + .headers(headers) + .build()) } } @@ -145,48 +121,31 @@ impl ToS3Request for CreateMultipartUpload { // region: abort-multipart-upload /// Argument for -/// [abort_multipart_upload()](crate::s3::client::Client::abort_multipart_upload) +/// [abort_multipart_upload()](crate::s3::client::MinioClient::abort_multipart_upload) /// API -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug, TypedBuilder)] pub struct AbortMultipartUpload { - client: Client, - + #[builder(!default)] // force required + client: MinioClient, + #[builder(default, setter(into))] extra_headers: Option, + #[builder(default, setter(into))] extra_query_params: Option, + #[builder(default, setter(into))] region: Option, + #[builder(setter(into))] // force required + accept Into bucket: String, - + #[builder(setter(into))] // force required + accept Into object: String, + #[builder(setter(into))] // force required + accept Into upload_id: String, } -impl AbortMultipartUpload { - pub fn new(client: Client, bucket: String, object: String, upload_id: String) -> Self { - Self { - client, - bucket, - object, - upload_id, - ..Default::default() - } - } - - pub fn extra_headers(mut self, extra_headers: Option) -> Self { - self.extra_headers = extra_headers; - self - } - - pub fn extra_query_params(mut self, extra_query_params: Option) -> Self { - self.extra_query_params = extra_query_params; - self - } - - /// Sets the region for the request - pub fn region(mut self, region: Option) -> Self { - self.region = region; - self - } -} +/// Builder type for [`AbortMultipartUpload`] that is returned by [`MinioClient::abort_multipart_upload`](crate::s3::client::MinioClient::abort_multipart_upload). +/// +/// This type alias simplifies the complex generic signature generated by the `typed_builder` crate. +pub type AbortMultipartUploadBldr = + AbortMultipartUploadBuilder<((MinioClient,), (), (), (), (String,), (String,), (String,))>; impl S3Api for AbortMultipartUpload { type S3Response = AbortMultipartUploadResponse; @@ -201,12 +160,15 @@ impl ToS3Request for AbortMultipartUpload { let mut query_params: Multimap = self.extra_query_params.unwrap_or_default(); query_params.add("uploadId", url_encode(&self.upload_id).to_string()); - Ok(S3Request::new(self.client, Method::DELETE) + Ok(S3Request::builder() + .client(self.client) + .method(Method::DELETE) .region(self.region) - .bucket(Some(self.bucket)) - .object(Some(self.object)) + .bucket(self.bucket) + .object(self.object) .query_params(query_params) - .headers(headers)) + .headers(headers) + .build()) } } @@ -215,60 +177,46 @@ impl ToS3Request for AbortMultipartUpload { // region: complete-multipart-upload /// Argument for -/// [complete_multipart_upload()](crate::s3::client::Client::complete_multipart_upload) +/// [complete_multipart_upload()](crate::s3::client::MinioClient::complete_multipart_upload) /// API -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug, TypedBuilder)] pub struct CompleteMultipartUpload { - client: Client, - + #[builder(!default)] // force required + client: MinioClient, + #[builder(default, setter(into))] extra_headers: Option, + #[builder(default, setter(into))] extra_query_params: Option, + #[builder(default, setter(into))] region: Option, + #[builder(setter(into))] // force required + accept Into bucket: String, + #[builder(setter(into))] // force required + accept Into object: String, + #[builder(setter(into))] // force required + accept Into upload_id: String, + #[builder(!default)] // force required parts: Vec, } +/// Builder type for [`CompleteMultipartUpload`] that is returned by [`MinioClient::complete_multipart_upload`](crate::s3::client::MinioClient::complete_multipart_upload). +/// +/// This type alias simplifies the complex generic signature generated by the `typed_builder` crate. +pub type CompleteMultipartUploadBldr = CompleteMultipartUploadBuilder<( + (MinioClient,), + (), + (), + (), + (String,), + (String,), + (String,), + (Vec,), +)>; + impl S3Api for CompleteMultipartUpload { type S3Response = CompleteMultipartUploadResponse; } -impl CompleteMultipartUpload { - pub fn new( - client: Client, - bucket: String, - object: String, - upload_id: String, - parts: Vec, - ) -> Self { - Self { - client, - bucket, - object, - upload_id, - parts, - ..Default::default() - } - } - - pub fn extra_headers(mut self, extra_headers: Option) -> Self { - self.extra_headers = extra_headers; - self - } - - pub fn extra_query_params(mut self, extra_query_params: Option) -> Self { - self.extra_query_params = extra_query_params; - self - } - - /// Sets the region for the request - pub fn region(mut self, region: Option) -> Self { - self.region = region; - self - } -} - impl ToS3Request for CompleteMultipartUpload { fn to_s3request(self) -> Result { { @@ -307,102 +255,84 @@ impl ToS3Request for CompleteMultipartUpload { } let mut query_params: Multimap = self.extra_query_params.unwrap_or_default(); query_params.add("uploadId", self.upload_id); + let body = Arc::new(SegmentedBytes::from(bytes)); - Ok(S3Request::new(self.client, Method::POST) + Ok(S3Request::builder() + .client(self.client) + .method(Method::POST) .region(self.region) - .bucket(Some(self.bucket)) - .object(Some(self.object)) + .bucket(self.bucket) + .object(self.object) .query_params(query_params) .headers(headers) - .body(Some(bytes.into()))) + .body(body) + .build()) } } // endregion: complete-multipart-upload // region: upload-part -/// Argument for [upload_part()](crate::s3::client::Client::upload_part) S3 API -#[derive(Debug, Clone, Default)] +/// Argument for [upload_part()](crate::s3::client::MinioClient::upload_part) S3 API +#[derive(Debug, Clone, TypedBuilder)] pub struct UploadPart { - client: Client, - + #[builder(!default)] // force required + client: MinioClient, + #[builder(default, setter(into))] extra_headers: Option, + #[builder(default, setter(into))] extra_query_params: Option, + #[builder(setter(into))] // force required + accept Into bucket: String, + #[builder(setter(into))] // force required + accept Into object: String, + #[builder(default, setter(into))] region: Option, + #[builder(default, setter(into))] sse: Option>, + #[builder(default, setter(into))] tags: Option>, + #[builder(default, setter(into))] retention: Option, + #[builder(default = false)] legal_hold: bool, - data: SegmentedBytes, + #[builder(!default)] // force required + data: Arc, + #[builder(default, setter(into))] content_type: Option, // This is used only when this struct is used for PutObject. + #[builder(default, setter(into))] user_metadata: Option, // These are only used for multipart UploadPart but not for PutObject, so // they are optional. + #[builder(default, setter(into))] // force required upload_id: Option, + #[builder(default, setter(into))] // force required part_number: Option, } -impl UploadPart { - pub fn new( - client: Client, - bucket: String, - object: String, - upload_id: String, - part_number: u16, - data: SegmentedBytes, - ) -> Self { - Self { - client, - bucket, - object, - upload_id: Some(upload_id), - part_number: Some(part_number), - data, - ..Default::default() - } - } - - pub fn extra_headers(mut self, extra_headers: Option) -> Self { - self.extra_headers = extra_headers; - self - } - - pub fn extra_query_params(mut self, extra_query_params: Option) -> Self { - self.extra_query_params = extra_query_params; - self - } - - /// Sets the region for the request - pub fn region(mut self, region: Option) -> Self { - self.region = region; - self - } - - pub fn sse(mut self, sse: Option>) -> Self { - self.sse = sse; - self - } - - pub fn tags(mut self, tags: Option>) -> Self { - self.tags = tags; - self - } - - pub fn retention(mut self, retention: Option) -> Self { - self.retention = retention; - self - } - - pub fn legal_hold(mut self, legal_hold: bool) -> Self { - self.legal_hold = legal_hold; - self - } -} +/// Builder type for [`UploadPart`] that is returned by [`MinioClient::upload_part`](crate::s3::client::MinioClient::upload_part). +/// +/// This type alias simplifies the complex generic signature generated by the `typed_builder` crate. +pub type UploadPartBldr = UploadPartBuilder<( + (MinioClient,), + (), + (), + (String,), + (String,), + (), + (), + (), + (), + (), + (Arc,), + (), + (), + (Option,), + (Option,), +)>; impl S3Api for UploadPart { type S3Response = UploadPartResponse; @@ -449,13 +379,16 @@ impl ToS3Request for UploadPart { query_params.add("partNumber", part_number.to_string()); } - Ok(S3Request::new(self.client, Method::PUT) + Ok(S3Request::builder() + .client(self.client) + .method(Method::PUT) .region(self.region) - .bucket(Some(self.bucket)) + .bucket(self.bucket) .query_params(query_params) - .object(Some(self.object)) + .object(self.object) .headers(headers) - .body(Some(self.data))) + .body(self.data) + .build()) } } @@ -463,70 +396,26 @@ impl ToS3Request for UploadPart { // region: put-object -/// Argument builder for PutObject S3 API. This is a lower-level API. -#[derive(Debug, Clone, Default)] -pub struct PutObject(UploadPart); - -impl PutObject { - pub fn new(client: Client, bucket: String, object: String, data: SegmentedBytes) -> Self { - PutObject(UploadPart { - client, - bucket, - object, - data, - ..Default::default() - }) - } - - pub fn extra_headers(mut self, extra_headers: Option) -> Self { - self.0.extra_headers = extra_headers; - self - } - - pub fn extra_query_params(mut self, extra_query_params: Option) -> Self { - self.0.extra_query_params = extra_query_params; - self - } - - /// Sets the region for the request - pub fn region(mut self, region: Option) -> Self { - self.0.region = region; - self - } - - pub fn user_metadata(mut self, user_metadata: Option) -> Self { - self.0.user_metadata = user_metadata; - self - } - - pub fn sse(mut self, sse: Option>) -> Self { - self.0.sse = sse; - self - } - - pub fn tags(mut self, tags: Option>) -> Self { - self.0.tags = tags; - self - } - - pub fn retention(mut self, retention: Option) -> Self { - self.0.retention = retention; - self - } - - pub fn legal_hold(mut self, legal_hold: bool) -> Self { - self.0.legal_hold = legal_hold; - self - } +/// Argument builder for the [`PutObject`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html) S3 API operation. +/// +/// This struct constructs the parameters required for the [`Client::put_object`](crate::s3::client::Client::put_object) method. +#[derive(Debug, Clone, TypedBuilder)] +pub struct PutObject { + pub(crate) inner: UploadPart, } +/// Builder type for [`PutObject`] that is returned by [`MinioClient::put_object`](crate::s3::client::MinioClient::put_object). +/// +/// This type alias simplifies the complex generic signature generated by the `typed_builder` crate. +pub type PutObjectBldr = PutObjectBuilder<((UploadPart,),)>; + impl S3Api for PutObject { type S3Response = PutObjectResponse; } impl ToS3Request for PutObject { fn to_s3request(self) -> Result { - self.0.to_s3request() + self.inner.to_s3request() } } @@ -534,102 +423,71 @@ impl ToS3Request for PutObject { // region: put-object-content -/// PutObjectContent takes an `ObjectContent` stream and uploads it to MinIO/S3. +/// Argument builder for the [`PutObject`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html) S3 API operation with streaming content. /// -/// It is a higher level API and handles multipart uploads transparently. -#[derive(Default)] +/// This struct constructs the parameters required for the [`Client::put_object_content`](crate::s3::client::Client::put_object_content) method. +#[derive(TypedBuilder)] pub struct PutObjectContent { - client: Client, - + #[builder(!default)] // force required + client: MinioClient, + #[builder(default, setter(into))] extra_headers: Option, + #[builder(default, setter(into))] extra_query_params: Option, + #[builder(default, setter(into))] region: Option, + #[builder(setter(into))] // force required + accept Into bucket: String, + #[builder(setter(into))] // force required + accept Into object: String, + #[builder(default, setter(into))] user_metadata: Option, + #[builder(default, setter(into))] sse: Option>, + #[builder(default, setter(into))] tags: Option>, + #[builder(default, setter(into))] retention: Option, + #[builder(default = false)] legal_hold: bool, + #[builder(default)] part_size: Size, + #[builder(default, setter(into))] content_type: Option, // source data + #[builder(!default, setter(into))] // force required + accept Into input_content: ObjectContent, // Computed. // expected_parts: Option, + #[builder(default, setter(skip))] content_stream: ContentStream, + #[builder(default, setter(skip))] part_count: Option, } -impl PutObjectContent { - pub fn new( - client: Client, - bucket: String, - object: String, - content: impl Into, - ) -> Self { - Self { - client, - bucket, - object, - input_content: content.into(), - ..Default::default() - } - } - - pub fn extra_headers(mut self, extra_headers: Option) -> Self { - self.extra_headers = extra_headers; - self - } - - pub fn extra_query_params(mut self, extra_query_params: Option) -> Self { - self.extra_query_params = extra_query_params; - self - } - - /// Sets the region for the request - pub fn region(mut self, region: Option) -> Self { - self.region = region; - self - } - - pub fn user_metadata(mut self, user_metadata: Option) -> Self { - self.user_metadata = user_metadata; - self - } - - pub fn sse(mut self, sse: Option>) -> Self { - self.sse = sse; - self - } - - pub fn tags(mut self, tags: Option>) -> Self { - self.tags = tags; - self - } - - pub fn retention(mut self, retention: Option) -> Self { - self.retention = retention; - self - } - - pub fn legal_hold(mut self, legal_hold: bool) -> Self { - self.legal_hold = legal_hold; - self - } - - pub fn part_size(mut self, part_size: impl Into) -> Self { - self.part_size = part_size.into(); - self - } - - pub fn content_type(mut self, content_type: String) -> Self { - self.content_type = Some(content_type); - self - } +/// Builder type for [`PutObjectContent`] that is returned by [`MinioClient::put_object_content`](crate::s3::client::MinioClient::put_object_content). +/// +/// This type alias simplifies the complex generic signature generated by the `typed_builder` crate. +pub type PutObjectContentBldr = PutObjectContentBuilder<( + (MinioClient,), + (), + (), + (), + (String,), + (String,), + (), + (), + (), + (), + (), + (), + (), + (ObjectContent,), +)>; +impl PutObjectContent { pub async fn send(mut self) -> Result { check_bucket_name(&self.bucket, true)?; check_object_name(&self.object)?; @@ -667,25 +525,27 @@ impl PutObjectContent { { let size = seg_bytes.len() as u64; - let resp: PutObjectResponse = PutObject(UploadPart { - client: self.client.clone(), - extra_headers: self.extra_headers.clone(), - extra_query_params: self.extra_query_params.clone(), - bucket: self.bucket.clone(), - object: self.object.clone(), - region: self.region.clone(), - user_metadata: self.user_metadata.clone(), - sse: self.sse.clone(), - tags: self.tags.clone(), - retention: self.retention.clone(), - legal_hold: self.legal_hold, - part_number: None, - upload_id: None, - data: seg_bytes, - content_type: self.content_type.clone(), - }) - .send() - .await?; + let resp: PutObjectResponse = PutObject::builder() + .inner(UploadPart { + client: self.client.clone(), + extra_headers: self.extra_headers.clone(), + extra_query_params: self.extra_query_params.clone(), + bucket: self.bucket.clone(), + object: self.object.clone(), + region: self.region.clone(), + user_metadata: self.user_metadata.clone(), + sse: self.sse.clone(), + tags: self.tags.clone(), + retention: self.retention.clone(), + legal_hold: self.legal_hold, + part_number: None, + upload_id: None, + data: Arc::new(seg_bytes), + content_type: self.content_type.clone(), + }) + .build() + .send() + .await?; Ok(PutObjectContentResponse::new(resp, size)) } else if object_size.is_known() && (seg_bytes.len() as u64) < part_size { @@ -698,22 +558,22 @@ impl PutObjectContent { let object: String = self.object.clone(); // Otherwise, we start a multipart upload. - let create_mpu_resp: CreateMultipartUploadResponse = CreateMultipartUpload { - client: self.client.clone(), - extra_headers: self.extra_headers.clone(), - extra_query_params: self.extra_query_params.clone(), - region: self.region.clone(), - bucket: self.bucket.clone(), - object: self.object.clone(), - user_metadata: self.user_metadata.clone(), - sse: self.sse.clone(), - tags: self.tags.clone(), - retention: self.retention.clone(), - legal_hold: self.legal_hold, - content_type: self.content_type.clone(), - } - .send() - .await?; + let create_mpu_resp: CreateMultipartUploadResponse = CreateMultipartUpload::builder() + .client(self.client.clone()) + .extra_headers(self.extra_headers.clone()) + .extra_query_params(self.extra_query_params.clone()) + .region(self.region.clone()) + .bucket(self.bucket.clone()) + .object(self.object.clone()) + .user_metadata(self.user_metadata.clone()) + .sse(self.sse.clone()) + .tags(self.tags.clone()) + .retention(self.retention.clone()) + .legal_hold(self.legal_hold) + .content_type(self.content_type.clone()) + .build() + .send() + .await?; let client = self.client.clone(); let upload_id: String = create_mpu_resp.upload_id().await?; @@ -724,7 +584,12 @@ impl PutObjectContent { if mpu_res.is_err() { // If we failed to complete the multipart upload, we should abort it. - let _ = AbortMultipartUpload::new(client, bucket, object, upload_id) + let _ = AbortMultipartUpload::builder() + .client(client) + .bucket(bucket) + .object(object) + .upload_id(upload_id) + .build() .send() .await; } @@ -800,7 +665,7 @@ impl PutObjectContent { legal_hold: self.legal_hold, part_number: Some(part_number), upload_id: Some(upload_id.to_string()), - data: part_content, + data: Arc::new(part_content), content_type: self.content_type.clone(), } .send() diff --git a/src/s3/builders/put_object_legal_hold.rs b/src/s3/builders/put_object_legal_hold.rs index af50c40a..140a0668 100644 --- a/src/s3/builders/put_object_legal_hold.rs +++ b/src/s3/builders/put_object_legal_hold.rs @@ -13,63 +13,55 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::s3::Client; +use crate::s3::client::MinioClient; use crate::s3::error::ValidationErr; use crate::s3::header_constants::*; use crate::s3::multimap_ext::{Multimap, MultimapExt}; 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; +use std::sync::Arc; +use typed_builder::TypedBuilder; /// 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)] +/// This struct constructs the parameters required for the [`Client::put_object_legal_hold`](crate::s3::client::MinioClient::put_object_legal_hold) method. +#[derive(Clone, Debug, TypedBuilder)] pub struct PutObjectLegalHold { - client: Client, - + #[builder(!default)] // force required + client: MinioClient, + #[builder(default, setter(into))] extra_headers: Option, + #[builder(default, setter(into))] extra_query_params: Option, + #[builder(default, setter(into))] region: Option, + #[builder(setter(into))] // force required + accept Into bucket: String, - + #[builder(setter(into))] // force required + accept Into object: String, + #[builder(default, setter(into))] version_id: Option, + #[builder(default, setter(into))] legal_hold: Option, } -impl PutObjectLegalHold { - 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) -> Self { - self.extra_headers = extra_headers; - self - } - - pub fn extra_query_params(mut self, extra_query_params: Option) -> Self { - self.extra_query_params = extra_query_params; - self - } - - pub fn version_id(mut self, version_id: Option) -> Self { - self.version_id = version_id; - self - } - - pub fn legal_hold(mut self, legal_hold: Option) -> Self { - self.legal_hold = legal_hold; - self - } -} +/// Builder type for [`PutObjectLegalHold`] that is returned by [`MinioClient::put_object_legal_hold`](crate::s3::client::MinioClient::put_object_legal_hold). +/// +/// This type alias simplifies the complex generic signature generated by the `typed_builder` crate. +pub type PutObjectLegalHoldBldr = PutObjectLegalHoldBuilder<( + (MinioClient,), + (), + (), + (), + (String,), + (String,), + (), + (Option,), +)>; impl S3Api for PutObjectLegalHold { type S3Response = PutObjectLegalHoldResponse; @@ -92,13 +84,17 @@ impl ToS3Request for PutObjectLegalHold { // TODO consider const payload with precalculated md5 headers.add(CONTENT_MD5, md5sum_hash(bytes.as_ref())); + let body = Arc::new(SegmentedBytes::from(bytes)); - Ok(S3Request::new(self.client, Method::PUT) + Ok(S3Request::builder() + .client(self.client) + .method(Method::PUT) .region(self.region) - .bucket(Some(self.bucket)) + .bucket(self.bucket) .query_params(query_params) .headers(headers) - .object(Some(self.object)) - .body(Some(bytes.into()))) + .object(self.object) + .body(body) + .build()) } } diff --git a/src/s3/builders/put_object_lock_config.rs b/src/s3/builders/put_object_lock_config.rs index e713ae29..2558d97a 100644 --- a/src/s3/builders/put_object_lock_config.rs +++ b/src/s3/builders/put_object_lock_config.rs @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::s3::Client; +use crate::s3::client::MinioClient; use crate::s3::error::ValidationErr; use crate::s3::multimap_ext::Multimap; use crate::s3::response::PutObjectLockConfigResponse; @@ -22,52 +22,33 @@ use crate::s3::types::{ObjectLockConfig, S3Api, S3Request, ToS3Request}; use crate::s3::utils::{check_bucket_name, insert}; use bytes::Bytes; use http::Method; +use std::sync::Arc; +use typed_builder::TypedBuilder; /// 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)] +/// This struct constructs the parameters required for the [`Client::put_object_lock_config`](crate::s3::client::MinioClient::put_object_lock_config) method. +#[derive(Clone, Debug, TypedBuilder)] pub struct PutObjectLockConfig { - client: Client, - + #[builder(!default)] // force required + client: MinioClient, + #[builder(default, setter(into))] extra_headers: Option, + #[builder(default, setter(into))] extra_query_params: Option, + #[builder(default, setter(into))] region: Option, + #[builder(setter(into))] // force required + accept Into bucket: String, - + #[builder(default)] config: ObjectLockConfig, } -impl PutObjectLockConfig { - pub fn new(client: Client, bucket: String) -> Self { - Self { - client, - bucket, - ..Default::default() - } - } - - pub fn extra_headers(mut self, extra_headers: Option) -> Self { - self.extra_headers = extra_headers; - self - } - - pub fn extra_query_params(mut self, extra_query_params: Option) -> Self { - self.extra_query_params = extra_query_params; - self - } - - /// Sets the region for the request - pub fn region(mut self, region: Option) -> Self { - self.region = region; - self - } - - pub fn config(mut self, config: ObjectLockConfig) -> Self { - self.config = config; - self - } -} +/// Builder type for [`PutObjectLockConfig`] that is returned by [`MinioClient::put_object_lock_config`](crate::s3::client::MinioClient::put_object_lock_config). +/// +/// This type alias simplifies the complex generic signature generated by the `typed_builder` crate. +pub type PutObjectLockConfigBldr = + PutObjectLockConfigBuilder<((MinioClient,), (), (), (), (String,), ())>; impl S3Api for PutObjectLockConfig { type S3Response = PutObjectLockConfigResponse; @@ -78,13 +59,16 @@ impl ToS3Request for PutObjectLockConfig { check_bucket_name(&self.bucket, true)?; let bytes: Bytes = self.config.to_xml().into(); - let body: Option = Some(SegmentedBytes::from(bytes)); + let body = Arc::new(SegmentedBytes::from(bytes)); - Ok(S3Request::new(self.client, Method::PUT) + Ok(S3Request::builder() + .client(self.client) + .method(Method::PUT) .region(self.region) - .bucket(Some(self.bucket)) + .bucket(self.bucket) .query_params(insert(self.extra_query_params, "object-lock")) .headers(self.extra_headers.unwrap_or_default()) - .body(body)) + .body(body) + .build()) } } diff --git a/src/s3/builders/put_object_retention.rs b/src/s3/builders/put_object_retention.rs index e4fe8b6f..11120a0c 100644 --- a/src/s3/builders/put_object_retention.rs +++ b/src/s3/builders/put_object_retention.rs @@ -13,83 +13,63 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::s3::Client; +use crate::s3::client::MinioClient; use crate::s3::error::ValidationErr; use crate::s3::header_constants::*; use crate::s3::multimap_ext::{Multimap, MultimapExt}; use crate::s3::response::PutObjectRetentionResponse; +use crate::s3::segmented_bytes::SegmentedBytes; use crate::s3::types::{RetentionMode, S3Api, S3Request, ToS3Request}; use crate::s3::utils::{ UtcTime, check_bucket_name, check_object_name, insert, md5sum_hash, to_iso8601utc, }; use bytes::Bytes; use http::Method; +use std::sync::Arc; +use typed_builder::TypedBuilder; /// 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)] +/// This struct constructs the parameters required for the [`Client::put_object_retention`](crate::s3::client::MinioClient::put_object_retention) method. +#[derive(Clone, Debug, TypedBuilder)] pub struct PutObjectRetention { - client: Client, - + #[builder(!default)] // force required + client: MinioClient, + #[builder(default, setter(into))] extra_headers: Option, + #[builder(default, setter(into))] extra_query_params: Option, + #[builder(default, setter(into))] region: Option, + #[builder(setter(into))] // force required + accept Into bucket: String, - + #[builder(setter(into))] // force required + accept Into object: String, + #[builder(default, setter(into))] version_id: Option, + #[builder(default = false)] bypass_governance_mode: bool, + #[builder(default, setter(into))] retention_mode: Option, + #[builder(default, setter(into))] retain_until_date: Option, } -impl PutObjectRetention { - 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) -> Self { - self.extra_headers = extra_headers; - self - } - - pub fn extra_query_params(mut self, extra_query_params: Option) -> Self { - self.extra_query_params = extra_query_params; - self - } - - /// Sets the region for the request - pub fn region(mut self, region: Option) -> Self { - self.region = region; - self - } - - pub fn version_id(mut self, version_id: Option) -> Self { - self.version_id = version_id; - self - } - - pub fn bypass_governance_mode(mut self, bypass_governance_mode: bool) -> Self { - self.bypass_governance_mode = bypass_governance_mode; - self - } - - pub fn retention_mode(mut self, retention_mode: Option) -> Self { - self.retention_mode = retention_mode; - self - } - - pub fn retain_until_date(mut self, retain_until_date: Option) -> Self { - self.retain_until_date = retain_until_date; - self - } -} +/// Builder type for [`PutObjectRetention`] that is returned by [`MinioClient::put_object_retention`](crate::s3::client::MinioClient::put_object_retention). +/// +/// This type alias simplifies the complex generic signature generated by the `typed_builder` crate. +pub type PutObjectRetentionBldr = PutObjectRetentionBuilder<( + (MinioClient,), + (), + (), + (), + (String,), + (String,), + (), + (), + (), + (), +)>; impl S3Api for PutObjectRetention { type S3Response = PutObjectRetentionResponse; @@ -133,12 +113,17 @@ impl ToS3Request for PutObjectRetention { let mut query_params: Multimap = insert(self.extra_query_params, "retention"); query_params.add_version(self.version_id); - Ok(S3Request::new(self.client, Method::PUT) + let body = Arc::new(SegmentedBytes::from(bytes)); + + Ok(S3Request::builder() + .client(self.client) + .method(Method::PUT) .region(self.region) - .bucket(Some(self.bucket)) + .bucket(self.bucket) .query_params(query_params) .headers(headers) - .object(Some(self.object)) - .body(Some(bytes.into()))) + .object(self.object) + .body(body) + .build()) } } diff --git a/src/s3/builders/put_object_tagging.rs b/src/s3/builders/put_object_tagging.rs index ad093e52..6415688c 100644 --- a/src/s3/builders/put_object_tagging.rs +++ b/src/s3/builders/put_object_tagging.rs @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::s3::Client; +use crate::s3::client::MinioClient; use crate::s3::error::ValidationErr; use crate::s3::multimap_ext::{Multimap, MultimapExt}; use crate::s3::response::PutObjectTaggingResponse; @@ -23,60 +23,37 @@ use crate::s3::utils::{check_bucket_name, check_object_name, insert}; use bytes::Bytes; use http::Method; use std::collections::HashMap; +use std::sync::Arc; +use typed_builder::TypedBuilder; /// Argument builder for the [`PutObjectTagging`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObjectTagging.html) S3 API operation. /// -/// This struct constructs the parameters required for the [`Client::put_object_tagging`](crate::s3::client::Client::put_object_tagging) method. -#[derive(Clone, Debug, Default)] +/// This struct constructs the parameters required for the [`Client::put_object_tagging`](crate::s3::client::MinioClient::put_object_tagging) method. +#[derive(Clone, Debug, TypedBuilder)] pub struct PutObjectTagging { - client: Client, - + #[builder(!default)] // force required + client: MinioClient, + #[builder(default, setter(into))] extra_headers: Option, + #[builder(default, setter(into))] extra_query_params: Option, + #[builder(default, setter(into))] region: Option, + #[builder(setter(into))] // force required + accept Into bucket: String, - + #[builder(setter(into))] // force required + accept Into object: String, + #[builder(default, setter(into))] version_id: Option, + #[builder(default)] tags: HashMap, } -impl PutObjectTagging { - 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) -> Self { - self.extra_headers = extra_headers; - self - } - - pub fn extra_query_params(mut self, extra_query_params: Option) -> Self { - self.extra_query_params = extra_query_params; - self - } - - /// Sets the region for the request - pub fn region(mut self, region: Option) -> Self { - self.region = region; - self - } - - pub fn version_id(mut self, version_id: Option) -> Self { - self.version_id = version_id; - self - } - - pub fn tags(mut self, tags: HashMap) -> Self { - self.tags = tags; - self - } -} +/// Builder type for [`PutObjectTagging`] that is returned by [`MinioClient::put_object_tagging`](crate::s3::client::MinioClient::put_object_tagging). +/// +/// This type alias simplifies the complex generic signature generated by the `typed_builder` crate. +pub type PutObjectTaggingBldr = + PutObjectTaggingBuilder<((MinioClient,), (), (), (), (String,), (String,), (), ())>; impl S3Api for PutObjectTagging { type S3Response = PutObjectTaggingResponse; @@ -109,14 +86,17 @@ impl ToS3Request for PutObjectTagging { data.push_str(""); data }; - let body: Option = Some(SegmentedBytes::from(Bytes::from(data))); + let body = Arc::new(SegmentedBytes::from(Bytes::from(data))); - Ok(S3Request::new(self.client, Method::PUT) + Ok(S3Request::builder() + .client(self.client) + .method(Method::PUT) .region(self.region) - .bucket(Some(self.bucket)) + .bucket(self.bucket) .query_params(query_params) - .object(Some(self.object)) + .object(self.object) .headers(self.extra_headers.unwrap_or_default()) - .body(body)) + .body(body) + .build()) } } diff --git a/src/s3/builders/select_object_content.rs b/src/s3/builders/select_object_content.rs index ab2fac38..efe6496f 100644 --- a/src/s3/builders/select_object_content.rs +++ b/src/s3/builders/select_object_content.rs @@ -13,77 +13,62 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::s3::Client; +use crate::s3::client::MinioClient; use crate::s3::error::ValidationErr; use crate::s3::header_constants::*; use crate::s3::multimap_ext::{Multimap, MultimapExt}; use crate::s3::response::SelectObjectContentResponse; +use crate::s3::segmented_bytes::SegmentedBytes; use crate::s3::sse::SseCustomerKey; use crate::s3::types::{S3Api, S3Request, SelectRequest, ToS3Request}; use crate::s3::utils::{check_bucket_name, check_object_name, check_ssec, insert, md5sum_hash}; use async_trait::async_trait; use bytes::Bytes; use http::Method; +use std::sync::Arc; +use typed_builder::TypedBuilder; /// 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)] +/// This struct constructs the parameters required for the [`Client::select_object_content`](crate::s3::client::MinioClient::select_object_content) method. +#[derive(TypedBuilder)] pub struct SelectObjectContent { - client: Client, + #[builder(!default)] // force required + client: MinioClient, + #[builder(default, setter(into))] extra_headers: Option, + #[builder(default, setter(into))] extra_query_params: Option, + #[builder(default, setter(into))] region: Option, + #[builder(setter(into))] // force required + accept Into bucket: String, - + #[builder(setter(into))] // force required + accept Into object: String, + + #[builder(default, setter(into))] version_id: Option, + #[builder(default, setter(into))] ssec: Option, + #[builder(default)] request: SelectRequest, } -impl SelectObjectContent { - 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) -> Self { - self.extra_headers = extra_headers; - self - } - - pub fn extra_query_params(mut self, extra_query_params: Option) -> Self { - self.extra_query_params = extra_query_params; - self - } - - /// Sets the region for the request - pub fn region(mut self, region: Option) -> Self { - self.region = region; - self - } - - pub fn version_id(mut self, version_id: Option) -> Self { - self.version_id = version_id; - self - } - - pub fn ssec(mut self, ssec: Option) -> Self { - self.ssec = ssec; - self - } - - pub fn request(mut self, request: SelectRequest) -> Self { - self.request = request; - self - } -} +/// Builder type for [`SelectObjectContent`] that is returned by [`MinioClient::select_object_content`](crate::s3::client::MinioClient::select_object_content). +/// +/// This type alias simplifies the complex generic signature generated by the `typed_builder` crate. +pub type SelectObjectContentBldr = SelectObjectContentBuilder<( + (MinioClient,), + (), + (), + (), + (String,), + (String,), + (), + (), + (SelectRequest,), +)>; impl S3Api for SelectObjectContent { type S3Response = SelectObjectContentResponse; @@ -103,13 +88,19 @@ impl ToS3Request for SelectObjectContent { let mut query_params: Multimap = insert(self.extra_query_params, "select"); query_params.add("select-type", "2"); + query_params.add_version(self.version_id); + + let body = Arc::new(SegmentedBytes::from(bytes)); - Ok(S3Request::new(self.client, Method::POST) + Ok(S3Request::builder() + .client(self.client) + .method(Method::POST) .region(self.region) - .bucket(Some(self.bucket)) + .bucket(self.bucket) .query_params(query_params) .headers(headers) - .object(Some(self.object)) - .body(Some(bytes.into()))) + .object(self.object) + .body(body) + .build()) } } diff --git a/src/s3/builders/stat_object.rs b/src/s3/builders/stat_object.rs index 63e5b9d4..f1ee0ee5 100644 --- a/src/s3/builders/stat_object.rs +++ b/src/s3/builders/stat_object.rs @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::s3::client::Client; +use crate::s3::client::MinioClient; use crate::s3::error::ValidationErr; use crate::s3::header_constants::*; use crate::s3::multimap_ext::{Multimap, MultimapExt}; @@ -25,98 +25,60 @@ use crate::s3::utils::{ }; use async_trait::async_trait; use http::Method; +use typed_builder::TypedBuilder; -/// Argument builder for the [`StatObject`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectAttributes.html) S3 API operation. -/// Retrieves all of the metadata from an object without returning the object itself. +/// Argument builder for the [`HeadObject`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_HeadObject.html) S3 API operation. /// -/// This struct constructs the parameters required for the [`Client::stat_object`](crate::s3::client::Client::stat_object) method. -#[derive(Debug, Clone, Default)] +/// This struct constructs the parameters required for the [`Client::stat_object`](crate::s3::client::MinioClient::stat_object) method. +#[derive(Debug, Clone, TypedBuilder)] pub struct StatObject { - client: Client, + #[builder(!default)] // force required + client: MinioClient, + #[builder(default, setter(into))] extra_headers: Option, + #[builder(default, setter(into))] extra_query_params: Option, + #[builder(setter(into))] // force required + accept Into bucket: String, + #[builder(setter(into))] // force required + accept Into object: String, + + #[builder(default, setter(into))] version_id: Option, - offset: Option, - length: Option, + #[builder(default, setter(into))] region: Option, + #[builder(default, setter(into))] ssec: Option, // Conditionals + #[builder(default, setter(into))] match_etag: Option, + #[builder(default, setter(into))] not_match_etag: Option, + #[builder(default, setter(into))] modified_since: Option, + #[builder(default, setter(into))] unmodified_since: Option, } -impl StatObject { - 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) -> Self { - self.extra_headers = extra_headers; - self - } - - pub fn extra_query_params(mut self, extra_query_params: Option) -> Self { - self.extra_query_params = extra_query_params; - self - } - - pub fn version_id(mut self, version_id: Option) -> Self { - self.version_id = version_id; - self - } - - pub fn offset(mut self, offset: Option) -> Self { - self.offset = offset; - self - } - - pub fn length(mut self, length: Option) -> Self { - self.length = length; - self - } - - /// Sets the region for the request - pub fn region(mut self, region: Option) -> Self { - self.region = region; - self - } - - pub fn ssec(mut self, ssec: Option) -> Self { - self.ssec = ssec; - self - } - - pub fn match_etag(mut self, etag: Option) -> Self { - self.match_etag = etag; - self - } - - pub fn not_match_etag(mut self, etag: Option) -> Self { - self.not_match_etag = etag; - self - } - - pub fn modified_since(mut self, time: Option) -> Self { - self.modified_since = time; - self - } - - pub fn unmodified_since(mut self, time: Option) -> Self { - self.unmodified_since = time; - self - } -} +/// Builder type for [`StatObject`] that is returned by [`MinioClient::stat_object`](crate::s3::client::MinioClient::stat_object). +/// +/// This type alias simplifies the complex generic signature generated by the `typed_builder` crate. +pub type StatObjectBldr = StatObjectBuilder<( + (MinioClient,), + (), + (), + (String,), + (String,), + (), + (), + (), + (), + (), + (), + (), +)>; impl S3Api for StatObject { type S3Response = StatObjectResponse; @@ -151,11 +113,14 @@ impl ToS3Request for StatObject { let mut query_params: Multimap = self.extra_query_params.unwrap_or_default(); query_params.add_version(self.version_id); - Ok(S3Request::new(self.client, Method::GET) + Ok(S3Request::builder() + .client(self.client) + .method(Method::GET) .region(self.region) - .bucket(Some(self.bucket)) - .object(Some(self.object)) + .bucket(self.bucket) + .object(self.object) .query_params(query_params) - .headers(headers)) + .headers(headers) + .build()) } } diff --git a/src/s3/client.rs b/src/s3/client.rs index 29bde11d..fffe0355 100644 --- a/src/s3/client.rs +++ b/src/s3/client.rs @@ -19,7 +19,7 @@ use bytes::Bytes; use dashmap::DashMap; use http::HeaderMap; use hyper::http::Method; -use reqwest::{Body, Response}; +use reqwest::Body; use std::fs::File; use std::io::prelude::*; use std::mem; @@ -28,7 +28,7 @@ use std::sync::{Arc, OnceLock}; use uuid::Uuid; use crate::s3::builders::{BucketExists, ComposeSource}; -use crate::s3::creds::Provider; +use crate::s3::creds::{Provider, StaticProvider}; use crate::s3::error::{Error, IoError, NetworkError, S3ServerError, ValidationErr}; use crate::s3::header_constants::*; use crate::s3::http::BaseUrl; @@ -120,22 +120,32 @@ pub const MAX_OBJECT_SIZE: u64 = 5_497_558_138_880; // 5 TiB pub const MAX_MULTIPART_COUNT: u16 = 10_000; /// Client Builder manufactures a Client using given parameters. -#[derive(Debug, Default)] -pub struct ClientBuilder { +/// Creates a builder given a base URL for the MinIO service or other AWS S3 +/// compatible object storage service. +#[derive(Debug)] +pub struct MinioClientBuilder { + //#[builder(!default)] // force required base_url: BaseUrl, + //#[builder(default, setter(into, doc = "Set the credential provider. If not, set anonymous access is used."))] provider: Option>, + //#[builder(default, setter(into, doc = "Set file for loading CAs certs to trust. This is in addition to the system trust store. The file must contain PEM encoded certificates."))] ssl_cert_file: Option, + //#[builder(default, setter(into, doc = "Set flag to ignore certificate check. This is insecure and should only be used for testing."))] ignore_cert_check: Option, + //#[builder(default, setter(into, doc = "Set the app info as an Option of (app_name, app_version) pair. This will show up in the client's user-agent."))] app_info: Option<(String, String)>, } -impl ClientBuilder { +impl MinioClientBuilder { /// Creates a builder given a base URL for the MinIO service or other AWS S3 /// compatible object storage service. pub fn new(base_url: BaseUrl) -> Self { Self { base_url, - ..Default::default() + provider: None, + ssl_cert_file: None, + ignore_cert_check: None, + app_info: None, } } @@ -167,7 +177,7 @@ impl ClientBuilder { } /// Build the Client. - pub fn build(self) -> Result { + pub fn build(self) -> Result { let mut builder = reqwest::Client::builder().no_gzip(); let mut user_agent = String::from("MinIO (") @@ -207,12 +217,13 @@ impl ClientBuilder { } } - Ok(Client { + Ok(MinioClient { http_client: builder.build().map_err(ValidationErr::from)?, shared: Arc::new(SharedClientItems { base_url: self.base_url, provider: self.provider, - ..Default::default() + region_map: Default::default(), + express: Default::default(), }), }) } @@ -222,19 +233,19 @@ impl ClientBuilder { /// /// If credential provider is passed, all S3 operation requests are signed using /// AWS Signature Version 4; else they are performed anonymously. -#[derive(Clone, Default, Debug)] -pub struct Client { +#[derive(Clone, Debug)] +pub struct MinioClient { http_client: reqwest::Client, pub(crate) shared: Arc, } -impl Client { +impl MinioClient { /// Returns a S3 client with given base URL. /// /// # Examples /// /// ``` - /// use minio::s3::client::Client; + /// use minio::s3::client::MinioClient; /// use minio::s3::creds::StaticProvider; /// use minio::s3::http::BaseUrl; /// @@ -244,7 +255,7 @@ impl Client { /// "zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG", /// None, /// ); - /// let client = Client::new(base_url, Some(static_provider), None, None).unwrap(); + /// let client = MinioClient::new(base_url, Some(static_provider), None, None).unwrap(); /// ``` pub fn new( base_url: BaseUrl, @@ -252,7 +263,7 @@ impl Client { ssl_cert_file: Option<&Path>, ignore_cert_check: Option, ) -> Result { - ClientBuilder::new(base_url) + MinioClientBuilder::new(base_url) .provider(provider) .ssl_cert_file(ssl_cert_file) .ignore_cert_check(ignore_cert_check) @@ -274,10 +285,12 @@ impl Client { if let Some(val) = self.shared.express.get() { *val } else { - // Create a random bucket name - let bucket_name: String = Uuid::new_v4().to_string(); + let be = BucketExists::builder() + .client(self.clone()) + .bucket(Uuid::new_v4().to_string()) + .build(); - let express = match BucketExists::new(self.clone(), bucket_name).send().await { + let express = match be.send().await { Ok(v) => { if let Some(server) = v.headers().get("server") { if let Ok(s) = server.to_str() { @@ -299,6 +312,7 @@ impl Client { express } } + /// Add a bucket-region pair to the region cache if it does not exist. pub(crate) fn add_bucket_region(&mut self, bucket: &str, region: impl Into) { self.shared @@ -351,6 +365,7 @@ impl Client { .not_match_etag(source.not_match_etag.clone()) .modified_since(source.modified_since) .unmodified_since(source.unmodified_since) + .build() .send() .await?; @@ -491,13 +506,17 @@ impl Client { // Sort headers alphabetically by name header_strings.sort(); - println!( - "S3 request: {} url={:?}; headers={:?}; body={}\n", - method, + let debug_str = format!( + "S3 request: {method} url={:?}; headers={:?}; body={body:?}", url.path, - header_strings.join("; "), - body.as_ref().unwrap() + header_strings.join("; ") ); + let truncated = if debug_str.len() > 1000 { + format!("{}...", &debug_str[..997]) + } else { + debug_str + }; + println!("{truncated}"); } if (*method == Method::PUT) || (*method == Method::POST) { @@ -512,7 +531,7 @@ impl Client { req = req.body(Body::wrap_stream(stream)); } - let resp: Response = req.send().await.map_err(ValidationErr::from)?; //TODO request error handled by network error layer + let resp: reqwest::Response = req.send().await.map_err(ValidationErr::from)?; //TODO request error handled by network error layer if resp.status().is_success() { return Ok(resp); } @@ -591,9 +610,23 @@ impl Client { ) .await } + + /// create an example client for testing on localhost + pub fn create_client_on_localhost() + -> Result> { + let base_url = "http://localhost:9000/".parse::()?; + log::info!("Trying to connect to MinIO at: `{base_url:?}`"); + + let static_provider = StaticProvider::new("minioadmin", "minioadmin", None); + + let client = MinioClientBuilder::new(base_url.clone()) + .provider(Some(static_provider)) + .build()?; + Ok(client) + } } -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug)] pub(crate) struct SharedClientItems { pub(crate) base_url: BaseUrl, pub(crate) provider: Option>, diff --git a/src/s3/client/append_object.rs b/src/s3/client/append_object.rs index 92f9a021..db7cea71 100644 --- a/src/s3/client/append_object.rs +++ b/src/s3/client/append_object.rs @@ -15,12 +15,14 @@ // ! S3 APIs for appending objects. -use super::Client; -use crate::s3::builders::ObjectContent; -use crate::s3::builders::{AppendObject, AppendObjectContent}; +use super::MinioClient; +use crate::s3::builders::{ + AppendObject, AppendObjectBldr, AppendObjectContent, AppendObjectContentBldr, ObjectContent, +}; use crate::s3::segmented_bytes::SegmentedBytes; +use std::sync::Arc; -impl Client { +impl MinioClient { /// 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. /// @@ -32,7 +34,7 @@ impl Client { /// # Example /// /// ```no_run - /// use minio::s3::Client; + /// use minio::s3::MinioClient; /// use minio::s3::response::{AppendObjectResponse, PutObjectResponse}; /// use minio::s3::segmented_bytes::SegmentedBytes; /// use minio::s3::types::S3Api; @@ -40,16 +42,16 @@ impl Client { /// /// #[tokio::main] /// async fn main() { - /// let client: Client = Default::default(); // configure your client here + /// let client = MinioClient::create_client_on_localhost().unwrap(); // 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(); + /// .build().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(); + /// .build().send().await.unwrap(); /// println!("size of the final object is {} bytes", resp.object_size()); /// } /// ``` @@ -59,14 +61,13 @@ impl Client { object: S2, data: SegmentedBytes, offset_bytes: u64, - ) -> AppendObject { - AppendObject::new( - self.clone(), - bucket.into(), - object.into(), - data, - offset_bytes, - ) + ) -> AppendObjectBldr { + AppendObject::builder() + .client(self.clone()) + .bucket(bucket.into()) + .object(object.into()) + .data(Arc::new(data)) + .offset_bytes(offset_bytes) } /// Creates an [`AppendObjectContent`] request builder to append data to the end of an (existing) @@ -81,7 +82,7 @@ impl Client { /// # Example /// /// ```no_run - /// use minio::s3::Client; + /// use minio::s3::MinioClient; /// use minio::s3::response::{AppendObjectResponse, PutObjectResponse}; /// use minio::s3::builders::ObjectContent; /// use minio::s3::segmented_bytes::SegmentedBytes; @@ -90,15 +91,15 @@ impl Client { /// /// #[tokio::main] /// async fn main() { - /// let client: Client = Default::default(); // configure your client here + /// let client = MinioClient::create_client_on_localhost().unwrap(); // 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(); + /// .build().send().await.unwrap(); /// let resp: AppendObjectResponse = client /// .append_object_content("bucket-name", "object-name", content2) - /// .send().await.unwrap(); + /// .build().send().await.unwrap(); /// println!("size of the final object is {} bytes", resp.object_size()); /// } /// ``` @@ -107,7 +108,11 @@ impl Client { bucket: S1, object: S2, content: C, - ) -> AppendObjectContent { - AppendObjectContent::new(self.clone(), bucket.into(), object.into(), content) + ) -> AppendObjectContentBldr { + AppendObjectContent::builder() + .client(self.clone()) + .bucket(bucket) + .object(object) + .input_content(content) } } diff --git a/src/s3/client/bucket_exists.rs b/src/s3/client/bucket_exists.rs index 09277919..c42a6071 100644 --- a/src/s3/client/bucket_exists.rs +++ b/src/s3/client/bucket_exists.rs @@ -13,10 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::Client; -use crate::s3::builders::BucketExists; +use crate::s3::builders::{BucketExists, BucketExistsBldr}; +use crate::s3::client::MinioClient; -impl Client { +impl MinioClient { /// Creates a [`BucketExists`] request builder to check if a bucket exists in S3. /// /// To execute the request, call [`BucketExists::send()`](crate::s3::types::S3Api::send), @@ -25,21 +25,21 @@ impl Client { /// # Example /// /// ```no_run - /// use minio::s3::Client; + /// use minio::s3::MinioClient; /// use minio::s3::response::BucketExistsResponse; /// use minio::s3::types::S3Api; /// use minio::s3::response::a_response_traits::HasBucket; /// /// #[tokio::main] /// async fn main() { - /// let client: Client = Default::default(); // configure your client here + /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here /// let resp: BucketExistsResponse = client /// .bucket_exists("bucket-name") - /// .send().await.unwrap(); + /// .build().send().await.unwrap(); /// println!("bucket '{}' exists: {}", resp.bucket(), resp.exists()); /// } /// ``` - pub fn bucket_exists>(&self, bucket: S) -> BucketExists { - BucketExists::new(self.clone(), bucket.into()) + pub fn bucket_exists>(&self, bucket: S) -> BucketExistsBldr { + BucketExists::builder().client(self.clone()).bucket(bucket) } } diff --git a/src/s3/client/copy_object.rs b/src/s3/client/copy_object.rs index a34b906b..97dfef7d 100644 --- a/src/s3/client/copy_object.rs +++ b/src/s3/client/copy_object.rs @@ -13,13 +13,14 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::Client; use crate::s3::builders::{ - ComposeObject, ComposeObjectInternal, ComposeSource, CopyObject, CopyObjectInternal, - UploadPartCopy, + ComposeObject, ComposeObjectBldr, ComposeObjectInternal, ComposeObjectInternalBldr, + ComposeSource, CopyObject, CopyObjectBldr, CopyObjectInternal, CopyObjectInternalBldr, + UploadPartCopy, UploadPartCopyBldr, }; +use crate::s3::client::MinioClient; -impl Client { +impl MinioClient { /// Creates a [`UploadPartCopy`] request builder. /// See [UploadPartCopy](https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPartCopy.html) S3 API /// @@ -29,7 +30,7 @@ impl Client { /// # Example /// /// ```no_run - /// use minio::s3::Client; + /// use minio::s3::MinioClient; /// use minio::s3::response::UploadPartCopyResponse; /// use minio::s3::segmented_bytes::SegmentedBytes; /// use minio::s3::types::S3Api; @@ -37,12 +38,12 @@ impl Client { /// /// #[tokio::main] /// async fn main() { - /// let client: Client = Default::default(); // configure your client here + /// let client = MinioClient::create_client_on_localhost().unwrap(); // 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(); + /// .build().send().await.unwrap(); /// println!("uploaded {}", resp.object()); /// } /// ``` @@ -51,8 +52,12 @@ impl Client { bucket: S1, object: S2, upload_id: S3, - ) -> UploadPartCopy { - UploadPartCopy::new(self.clone(), bucket.into(), object.into(), upload_id.into()) + ) -> UploadPartCopyBldr { + UploadPartCopy::builder() + .client(self.clone()) + .bucket(bucket) + .object(object) + .upload_id(upload_id) } /// Create a CopyObject request builder. This is a lower-level API that @@ -61,8 +66,11 @@ impl Client { &self, bucket: S1, object: S2, - ) -> CopyObjectInternal { - CopyObjectInternal::new(self.clone(), bucket.into(), object.into()) + ) -> CopyObjectInternalBldr { + CopyObjectInternal::builder() + .client(self.clone()) + .bucket(bucket) + .object(object) } /// Create a CopyObject request builder. @@ -74,9 +82,9 @@ impl Client { /// The destination of the copy is specified via the `bucket` and `object` parameters of this function. /// To specify the source object to be copied, call `.source(...)` on the returned [`CopyObject`] builder. /// - /// Internally, this function first performs a [`stat_object`](Client::stat_object) call + /// Internally, this function first performs a [`stat_object`](MinioClient::stat_object) call /// to retrieve metadata about the source object. It then constructs a - /// [`compose_object`](Client::compose_object) request to perform the actual copy. + /// [`compose_object`](MinioClient::compose_object) request to perform the actual copy. /// /// # Arguments /// @@ -86,7 +94,7 @@ impl Client { /// # Example /// /// ```no_run - /// use minio::s3::Client; + /// use minio::s3::MinioClient; /// use minio::s3::response::CopyObjectResponse; /// use minio::s3::builders::CopySource; /// use minio::s3::types::S3Api; @@ -94,11 +102,11 @@ impl Client { /// #[tokio::main] /// async fn main() { /// use minio::s3::response::a_response_traits::HasVersion; - /// let client: Client = Default::default(); // configure your client here + /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here /// let resp: CopyObjectResponse = client /// .copy_object("bucket-name-dst", "object-name-dst") - /// .source(CopySource::new("bucket-name-src", "object-name-src").unwrap()) - /// .send().await.unwrap(); + /// .source(CopySource::builder().bucket("bucket-name-src").object("object-name-src").build()) + /// .build().send().await.unwrap(); /// println!("copied the file from src to dst. New version: {:?}", resp.version_id()); /// } /// ``` @@ -106,8 +114,11 @@ impl Client { &self, bucket: S1, object: S2, - ) -> CopyObject { - CopyObject::new(self.clone(), bucket.into(), object.into()) + ) -> CopyObjectBldr { + CopyObject::builder() + .client(self.clone()) + .bucket(bucket) + .object(object) } /// Create a ComposeObjectInternal request builder. This is a higher-level API that @@ -116,18 +127,25 @@ impl Client { &self, bucket: S1, object: S2, - ) -> ComposeObjectInternal { - ComposeObjectInternal::new(self.clone(), bucket.into(), object.into()) + ) -> ComposeObjectInternalBldr { + ComposeObjectInternal::builder() + .client(self.clone()) + .bucket(bucket) + .object(object) } /// compose object is higher-level API that calls an internal compose object, and if that call fails, - /// it calls ['abort_multipart_upload`](Client::abort_multipart_upload). + /// it calls ['abort_multipart_upload`](MinioClient::abort_multipart_upload). pub fn compose_object, S2: Into>( &self, bucket: S1, object: S2, sources: Vec, - ) -> ComposeObject { - ComposeObject::new(self.clone(), bucket.into(), object.into()).sources(sources) + ) -> ComposeObjectBldr { + ComposeObject::builder() + .client(self.clone()) + .bucket(bucket) + .object(object) + .sources(sources) } } diff --git a/src/s3/client/create_bucket.rs b/src/s3/client/create_bucket.rs index 8740adfa..566ce027 100644 --- a/src/s3/client/create_bucket.rs +++ b/src/s3/client/create_bucket.rs @@ -13,10 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::Client; -use crate::s3::builders::CreateBucket; +use crate::s3::builders::{CreateBucket, CreateBucketBldr}; +use crate::s3::client::MinioClient; -impl Client { +impl MinioClient { /// Creates a [`CreateBucket`] request builder. /// /// To execute the request, call [`CreateBucket::send()`](crate::s3::types::S3Api::send), @@ -25,21 +25,21 @@ impl Client { /// # Example /// /// ```no_run - /// use minio::s3::Client; + /// use minio::s3::MinioClient; /// use minio::s3::response::CreateBucketResponse; /// use minio::s3::types::S3Api; /// use minio::s3::response::a_response_traits::{HasBucket, HasRegion}; /// /// #[tokio::main] /// async fn main() { - /// let client: Client = Default::default(); // configure your client here + /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here /// let resp: CreateBucketResponse = client /// .create_bucket("bucket-name") - /// .send().await.unwrap(); + /// .build().send().await.unwrap(); /// println!("Made bucket '{}' in region '{}'", resp.bucket(), resp.region()); /// } /// ``` - pub fn create_bucket>(&self, bucket: S) -> CreateBucket { - CreateBucket::new(self.clone(), bucket.into()) + pub fn create_bucket>(&self, bucket: S) -> CreateBucketBldr { + CreateBucket::builder().client(self.clone()).bucket(bucket) } } diff --git a/src/s3/client/delete_bucket.rs b/src/s3/client/delete_bucket.rs index 7f09a7cb..0e1bbea7 100644 --- a/src/s3/client/delete_bucket.rs +++ b/src/s3/client/delete_bucket.rs @@ -13,20 +13,22 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::Client; -use crate::s3::builders::{DeleteBucket, DeleteObject, ObjectToDelete}; +use crate::s3::builders::{DeleteBucket, DeleteBucketBldr, DeleteObject, ObjectToDelete}; +use crate::s3::client::MinioClient; use crate::s3::error::Error; use crate::s3::error::S3ServerError::S3Error; use crate::s3::minio_error_response::MinioErrorCode; -use crate::s3::response::{BucketExistsResponse, DeleteResult}; use crate::s3::response::{ - DeleteBucketResponse, DeleteObjectResponse, DeleteObjectsResponse, PutObjectLegalHoldResponse, + BucketExistsResponse, DeleteBucketResponse, DeleteObjectResponse, DeleteObjectsResponse, + DeleteResult, PutObjectLegalHoldResponse, }; -use crate::s3::types::{S3Api, ToStream}; +use crate::s3::types::{S3Api, S3Request, ToStream}; use bytes::Bytes; use futures_util::StreamExt; +use http::Method; +use multimap::MultiMap; -impl Client { +impl MinioClient { /// Creates a [`DeleteBucket`] request builder. /// /// To execute the request, call [`DeleteBucket::send()`](crate::s3::types::S3Api::send), @@ -35,21 +37,22 @@ impl Client { /// # Example /// /// ```no_run - /// use minio::s3::Client; + /// use minio::s3::MinioClient; /// use minio::s3::response::DeleteBucketResponse; /// use minio::s3::types::S3Api; /// use minio::s3::response::a_response_traits::{HasBucket, HasRegion}; /// /// #[tokio::main] /// async fn main() { - /// let client: Client = Default::default(); // configure your client here - /// let resp: DeleteBucketResponse = - /// client.delete_bucket("bucket-name").send().await.unwrap(); + /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here + /// let resp: DeleteBucketResponse = client + /// .delete_bucket("bucket-name") + /// .build().send().await.unwrap(); /// println!("bucket '{}' in region '{}' is removed", resp.bucket(), resp.region()); /// } /// ``` - pub fn delete_bucket>(&self, bucket: S) -> DeleteBucket { - DeleteBucket::new(self.clone(), bucket.into()) + pub fn delete_bucket>(&self, bucket: S) -> DeleteBucketBldr { + DeleteBucket::builder().client(self.clone()).bucket(bucket) } /// Deletes a bucket and also deletes non-empty buckets by first removing all objects before @@ -60,11 +63,13 @@ impl Client { ) -> Result { let bucket: String = bucket.into(); - let resp: BucketExistsResponse = self.bucket_exists(&bucket).send().await?; + let resp: BucketExistsResponse = self.bucket_exists(&bucket).build().send().await?; if !resp.exists { // if the bucket does not exist, we can return early + let dummy: S3Request = S3Request::builder().client(self.clone()).method(Method::DELETE).bucket(bucket).headers(MultiMap::default()).build(/* S3RequestBuilder_Error_Missing_required_field_headers */); + return Ok(DeleteBucketResponse { - request: Default::default(), //TODO consider how to handle this + request: dummy, //TODO consider how to handle this body: Bytes::new(), headers: Default::default(), }); @@ -76,6 +81,7 @@ impl Client { .list_objects(&bucket) .include_versions(!is_express) .recursive(true) + .build() .to_stream() .await; @@ -111,17 +117,18 @@ impl Client { let _resp: PutObjectLegalHoldResponse = self .put_object_legal_hold(&bucket, &v.object_name, false) .version_id(v.version_id.clone()) + .build() .send() .await?; - let _resp: DeleteObjectResponse = DeleteObject::new( - self.clone(), - bucket.clone(), - ObjectToDelete::from(v), - ) - .bypass_governance_mode(true) - .send() - .await?; + let _resp: DeleteObjectResponse = DeleteObject::builder() + .client(self.clone()) + .bucket(bucket.clone()) + .object(v) + .bypass_governance_mode(true) + .build() + .send() + .await?; } } } @@ -129,13 +136,15 @@ impl Client { } } - let request: DeleteBucket = self.delete_bucket(&bucket); + let request: DeleteBucket = self.delete_bucket(&bucket).build(); match request.send().await { Ok(resp) => Ok(resp), Err(Error::S3Server(S3Error(mut e))) => { if matches!(e.code(), MinioErrorCode::NoSuchBucket) { + let dummy: S3Request = S3Request::builder().client(self.clone()).method(Method::DELETE).bucket(bucket).headers(MultiMap::default()).build(/* S3RequestBuilder_Error_Missing_required_field_headers */); + Ok(DeleteBucketResponse { - request: Default::default(), //TODO consider how to handle this + request: dummy, //TODO consider how to handle this body: Bytes::new(), headers: e.take_headers(), }) @@ -146,6 +155,7 @@ impl Client { .list_objects(&bucket) .include_versions(!is_express) .recursive(true) + .build() .to_stream() .await; diff --git a/src/s3/client/delete_bucket_encryption.rs b/src/s3/client/delete_bucket_encryption.rs index 9c692cdd..a25e11e1 100644 --- a/src/s3/client/delete_bucket_encryption.rs +++ b/src/s3/client/delete_bucket_encryption.rs @@ -13,10 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::Client; -use crate::s3::builders::DeleteBucketEncryption; +use crate::s3::builders::{DeleteBucketEncryption, DeleteBucketEncryptionBldr}; +use crate::s3::client::MinioClient; -impl Client { +impl MinioClient { /// Creates a [`DeleteBucketEncryption`] request builder. /// /// To execute the request, call [`DeleteBucketEncryption::send()`](crate::s3::types::S3Api::send), @@ -25,21 +25,26 @@ impl Client { /// # Example /// /// ```no_run - /// use minio::s3::Client; + /// use minio::s3::MinioClient; /// use minio::s3::response::DeleteBucketEncryptionResponse; /// use minio::s3::types::S3Api; /// use minio::s3::response::a_response_traits::HasBucket; /// /// #[tokio::main] /// async fn main() { - /// let client: Client = Default::default(); // configure your client here + /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here /// let resp: DeleteBucketEncryptionResponse = client /// .delete_bucket_encryption("bucket-name") - /// .send().await.unwrap(); + /// .build().send().await.unwrap(); /// println!("bucket '{}' is deleted", resp.bucket()); /// } /// ``` - pub fn delete_bucket_encryption>(&self, bucket: S) -> DeleteBucketEncryption { - DeleteBucketEncryption::new(self.clone(), bucket.into()) + pub fn delete_bucket_encryption>( + &self, + bucket: S, + ) -> DeleteBucketEncryptionBldr { + DeleteBucketEncryption::builder() + .client(self.clone()) + .bucket(bucket) } } diff --git a/src/s3/client/delete_bucket_lifecycle.rs b/src/s3/client/delete_bucket_lifecycle.rs index bcfe64f4..4489e434 100644 --- a/src/s3/client/delete_bucket_lifecycle.rs +++ b/src/s3/client/delete_bucket_lifecycle.rs @@ -13,10 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::Client; -use crate::s3::builders::DeleteBucketLifecycle; +use crate::s3::builders::{DeleteBucketLifecycle, DeleteBucketLifecycleBldr}; +use crate::s3::client::MinioClient; -impl Client { +impl MinioClient { /// Creates a [`DeleteBucketLifecycle`] request builder. /// /// To execute the request, call [`DeleteBucketLifecycle::send()`](crate::s3::types::S3Api::send), @@ -25,21 +25,23 @@ impl Client { /// # Example /// /// ```no_run - /// use minio::s3::Client; + /// use minio::s3::MinioClient; /// use minio::s3::response::DeleteBucketLifecycleResponse; /// use minio::s3::types::S3Api; /// use minio::s3::response::a_response_traits::HasBucket; /// /// #[tokio::main] /// async fn main() { - /// let client: Client = Default::default(); // configure your client here + /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here /// let resp: DeleteBucketLifecycleResponse = client /// .delete_bucket_lifecycle("bucket-name") - /// .send().await.unwrap(); + /// .build().send().await.unwrap(); /// println!("lifecycle of bucket '{}' is deleted", resp.bucket()); /// } /// ``` - pub fn delete_bucket_lifecycle>(&self, bucket: S) -> DeleteBucketLifecycle { - DeleteBucketLifecycle::new(self.clone(), bucket.into()) + pub fn delete_bucket_lifecycle>(&self, bucket: S) -> DeleteBucketLifecycleBldr { + DeleteBucketLifecycle::builder() + .client(self.clone()) + .bucket(bucket) } } diff --git a/src/s3/client/delete_bucket_notification.rs b/src/s3/client/delete_bucket_notification.rs index f311c59e..a9c2df90 100644 --- a/src/s3/client/delete_bucket_notification.rs +++ b/src/s3/client/delete_bucket_notification.rs @@ -13,10 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::Client; -use crate::s3::builders::DeleteBucketNotification; +use crate::s3::builders::{DeleteBucketNotification, DeleteBucketNotificationBldr}; +use crate::s3::client::MinioClient; -impl Client { +impl MinioClient { /// Creates a [`DeleteBucketNotification`] request builder. /// /// To execute the request, call [`DeleteBucketNotification::send()`](crate::s3::types::S3Api::send), @@ -25,24 +25,26 @@ impl Client { /// # Example /// /// ```no_run - /// use minio::s3::Client; + /// use minio::s3::MinioClient; /// use minio::s3::response::DeleteBucketNotificationResponse; /// use minio::s3::types::S3Api; /// use minio::s3::response::a_response_traits::HasBucket; /// /// #[tokio::main] /// async fn main() { - /// let client: Client = Default::default(); // configure your client here + /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here /// let resp: DeleteBucketNotificationResponse = client /// .delete_bucket_notification("bucket-name") - /// .send().await.unwrap(); + /// .build().send().await.unwrap(); /// println!("notification of bucket '{}' is deleted", resp.bucket()); /// } /// ``` pub fn delete_bucket_notification>( &self, bucket: S, - ) -> DeleteBucketNotification { - DeleteBucketNotification::new(self.clone(), bucket.into()) + ) -> DeleteBucketNotificationBldr { + DeleteBucketNotification::builder() + .client(self.clone()) + .bucket(bucket) } } diff --git a/src/s3/client/delete_bucket_policy.rs b/src/s3/client/delete_bucket_policy.rs index 61ce6cfe..1f3676eb 100644 --- a/src/s3/client/delete_bucket_policy.rs +++ b/src/s3/client/delete_bucket_policy.rs @@ -13,10 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::Client; -use crate::s3::builders::DeleteBucketPolicy; +use crate::s3::builders::{DeleteBucketPolicy, DeleteBucketPolicyBldr}; +use crate::s3::client::MinioClient; -impl Client { +impl MinioClient { /// Creates a [`DeleteBucketPolicy`] request builder. /// /// To execute the request, call [`DeleteBucketPolicy::send()`](crate::s3::types::S3Api::send), @@ -25,21 +25,23 @@ impl Client { /// # Example /// /// ```no_run - /// use minio::s3::Client; + /// use minio::s3::MinioClient; /// use minio::s3::response::DeleteBucketPolicyResponse; /// use minio::s3::types::S3Api; /// use minio::s3::response::a_response_traits::HasBucket; /// /// #[tokio::main] /// async fn main() { - /// let client: Client = Default::default(); // configure your client here + /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here /// let resp: DeleteBucketPolicyResponse = client /// .delete_bucket_policy("bucket-name") - /// .send().await.unwrap(); + /// .build().send().await.unwrap(); /// println!("policy of bucket '{}' is deleted", resp.bucket()); /// } /// ``` - pub fn delete_bucket_policy>(&self, bucket: S) -> DeleteBucketPolicy { - DeleteBucketPolicy::new(self.clone(), bucket.into()) + pub fn delete_bucket_policy>(&self, bucket: S) -> DeleteBucketPolicyBldr { + DeleteBucketPolicy::builder() + .client(self.clone()) + .bucket(bucket) } } diff --git a/src/s3/client/delete_bucket_replication.rs b/src/s3/client/delete_bucket_replication.rs index d5f45c0f..9f52ca5e 100644 --- a/src/s3/client/delete_bucket_replication.rs +++ b/src/s3/client/delete_bucket_replication.rs @@ -13,10 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::Client; -use crate::s3::builders::DeleteBucketReplication; +use crate::s3::builders::{DeleteBucketReplication, DeleteBucketReplicationBldr}; +use crate::s3::client::MinioClient; -impl Client { +impl MinioClient { /// Creates a [`DeleteBucketReplication`] request builder. /// /// To execute the request, call [`DeleteBucketReplication::send()`](crate::s3::types::S3Api::send), @@ -27,21 +27,26 @@ impl Client { /// # Example /// /// ```no_run - /// use minio::s3::Client; + /// use minio::s3::MinioClient; /// use minio::s3::response::DeleteBucketReplicationResponse; /// use minio::s3::types::S3Api; /// use minio::s3::response::a_response_traits::HasBucket; /// /// #[tokio::main] /// async fn main() { - /// let client: Client = Default::default(); // configure your client here + /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here /// let resp: DeleteBucketReplicationResponse = client /// .delete_bucket_replication("bucket-name") - /// .send().await.unwrap(); + /// .build().send().await.unwrap(); /// println!("replication of bucket '{}' is deleted", resp.bucket()); /// } /// ``` - pub fn delete_bucket_replication>(&self, bucket: S) -> DeleteBucketReplication { - DeleteBucketReplication::new(self.clone(), bucket.into()) + pub fn delete_bucket_replication>( + &self, + bucket: S, + ) -> DeleteBucketReplicationBldr { + DeleteBucketReplication::builder() + .client(self.clone()) + .bucket(bucket) } } diff --git a/src/s3/client/delete_bucket_tagging.rs b/src/s3/client/delete_bucket_tagging.rs index 30b74d21..e35a2dc2 100644 --- a/src/s3/client/delete_bucket_tagging.rs +++ b/src/s3/client/delete_bucket_tagging.rs @@ -13,10 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::Client; -use crate::s3::builders::DeleteBucketTagging; +use crate::s3::builders::{DeleteBucketTagging, DeleteBucketTaggingBldr}; +use crate::s3::client::MinioClient; -impl Client { +impl MinioClient { /// Creates a [`DeleteBucketTagging`] request builder. /// /// To execute the request, call [`DeleteBucketTagging::send()`](crate::s3::types::S3Api::send), @@ -27,21 +27,23 @@ impl Client { /// # Example /// /// ```no_run - /// use minio::s3::Client; + /// use minio::s3::MinioClient; /// use minio::s3::response::DeleteBucketTaggingResponse; /// use minio::s3::types::S3Api; /// use minio::s3::response::a_response_traits::HasBucket; /// /// #[tokio::main] /// async fn main() { - /// let client: Client = Default::default(); // configure your client here + /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here /// let resp: DeleteBucketTaggingResponse = client /// .delete_bucket_tagging("bucket-name") - /// .send().await.unwrap(); + /// .build().send().await.unwrap(); /// println!("tags of bucket '{}' are deleted", resp.bucket()); /// } /// ``` - pub fn delete_bucket_tagging>(&self, bucket: S) -> DeleteBucketTagging { - DeleteBucketTagging::new(self.clone(), bucket.into()) + pub fn delete_bucket_tagging>(&self, bucket: S) -> DeleteBucketTaggingBldr { + DeleteBucketTagging::builder() + .client(self.clone()) + .bucket(bucket) } } diff --git a/src/s3/client/delete_object_lock_config.rs b/src/s3/client/delete_object_lock_config.rs index 49657129..15f286fd 100644 --- a/src/s3/client/delete_object_lock_config.rs +++ b/src/s3/client/delete_object_lock_config.rs @@ -13,10 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::Client; -use crate::s3::builders::DeleteObjectLockConfig; +use crate::s3::builders::{DeleteObjectLockConfig, DeleteObjectLockConfigBldr}; +use crate::s3::client::MinioClient; -impl Client { +impl MinioClient { /// Creates a [`DeleteObjectLockConfig`] request builder. /// /// To execute the request, call [`DeleteObjectLockConfig::send()`](crate::s3::types::S3Api::send), @@ -27,34 +27,42 @@ impl Client { /// # Example /// /// ```no_run - /// use minio::s3::Client; + /// use minio::s3::MinioClient; /// use minio::s3::response::{DeleteObjectLockConfigResponse, CreateBucketResponse, PutObjectLockConfigResponse}; /// use minio::s3::types::{S3Api, ObjectLockConfig, RetentionMode}; /// use minio::s3::response::a_response_traits::HasBucket; /// /// #[tokio::main] /// async fn main() { - /// let client: Client = Default::default(); // configure your client here + /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here /// let bucket_name = "bucket-name"; /// - /// let resp: CreateBucketResponse = - /// client.create_bucket(bucket_name).object_lock(true).send().await.unwrap(); + /// let resp: CreateBucketResponse = client + /// .create_bucket(bucket_name).object_lock(true) + /// .build().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: PutObjectLockConfigResponse = - /// client.put_object_lock_config(bucket_name).config(config).send().await.unwrap(); + /// let resp: PutObjectLockConfigResponse = client + /// .put_object_lock_config(bucket_name).config(config) + /// .build().send().await.unwrap(); /// println!("configured object locking for bucket '{}'", resp.bucket()); /// - /// let resp: DeleteObjectLockConfigResponse = - /// client.delete_object_lock_config(bucket_name).send().await.unwrap(); + /// let resp: DeleteObjectLockConfigResponse = client + /// .delete_object_lock_config(bucket_name) + /// .build().send().await.unwrap(); /// println!("object locking of bucket '{}' is deleted", resp.bucket()); /// } /// ``` - pub fn delete_object_lock_config>(&self, bucket: S) -> DeleteObjectLockConfig { - DeleteObjectLockConfig::new(self.clone(), bucket.into()) + pub fn delete_object_lock_config>( + &self, + bucket: S, + ) -> DeleteObjectLockConfigBldr { + DeleteObjectLockConfig::builder() + .client(self.clone()) + .bucket(bucket) } } diff --git a/src/s3/client/delete_object_tagging.rs b/src/s3/client/delete_object_tagging.rs index 4a40b05d..b80119fa 100644 --- a/src/s3/client/delete_object_tagging.rs +++ b/src/s3/client/delete_object_tagging.rs @@ -13,10 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::Client; -use crate::s3::builders::DeleteObjectTagging; +use crate::s3::builders::{DeleteObjectTagging, DeleteObjectTaggingBldr}; +use crate::s3::client::MinioClient; -impl Client { +impl MinioClient { /// Creates a [`DeleteObjectTagging`] request builder. /// /// To execute the request, call [`DeleteObjectTagging::send()`](crate::s3::types::S3Api::send), @@ -27,17 +27,17 @@ impl Client { /// # Example /// /// ```no_run - /// use minio::s3::Client; + /// use minio::s3::MinioClient; /// use minio::s3::response::DeleteObjectTaggingResponse; /// use minio::s3::types::S3Api; /// use minio::s3::response::a_response_traits::{HasBucket, HasObject}; /// /// #[tokio::main] /// async fn main() { - /// let client: Client = Default::default(); // configure your client here + /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here /// let resp: DeleteObjectTaggingResponse = client /// .delete_object_tagging("bucket-name", "object_name") - /// .send().await.unwrap(); + /// .build().send().await.unwrap(); /// println!("legal hold of object '{}' in bucket '{}' is deleted", resp.object(), resp.bucket()); /// } /// ``` @@ -45,7 +45,10 @@ impl Client { &self, bucket: S1, object: S2, - ) -> DeleteObjectTagging { - DeleteObjectTagging::new(self.clone(), bucket.into(), object.into()) + ) -> DeleteObjectTaggingBldr { + DeleteObjectTagging::builder() + .client(self.clone()) + .bucket(bucket) + .object(object) } } diff --git a/src/s3/client/delete_objects.rs b/src/s3/client/delete_objects.rs index 7d6f421b..b2f3f152 100644 --- a/src/s3/client/delete_objects.rs +++ b/src/s3/client/delete_objects.rs @@ -13,14 +13,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::s3::{ - builders::{ - DeleteObject, DeleteObjects, DeleteObjectsStreaming, ObjectToDelete, ObjectsStream, - }, - client::Client, +use crate::s3::builders::{ + DeleteObject, DeleteObjectBldr, DeleteObjects, DeleteObjectsBldr, DeleteObjectsStreaming, + ObjectToDelete, ObjectsStream, }; +use crate::s3::client::MinioClient; -impl Client { +impl MinioClient { /// Creates a [`DeleteObject`] request builder to delete a single object from an S3 bucket. /// /// To execute the request, call [`DeleteObject::send()`](crate::s3::types::S3Api::send), @@ -29,7 +28,7 @@ impl Client { /// # Example /// /// ```no_run - /// use minio::s3::Client; + /// use minio::s3::MinioClient; /// use minio::s3::response::DeleteObjectResponse; /// use minio::s3::builders::ObjectToDelete; /// use minio::s3::types::S3Api; @@ -37,10 +36,10 @@ impl Client { /// /// #[tokio::main] /// async fn main() { - /// let client: Client = Default::default(); // configure your client here + /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here /// let resp: DeleteObjectResponse = client /// .delete_object("bucket-name", ObjectToDelete::from("object-name")) - /// .send().await.unwrap(); + /// .build().send().await.unwrap(); /// println!("the object is deleted. The delete marker has version '{:?}'", resp.version_id()); /// } /// ``` @@ -48,20 +47,26 @@ impl Client { &self, bucket: S, object: D, - ) -> DeleteObject { - DeleteObject::new(self.clone(), bucket.into(), object) + ) -> DeleteObjectBldr { + DeleteObject::builder() + .client(self.clone()) + .bucket(bucket) + .object(object) } /// Creates a [`DeleteObjects`] request builder to delete multiple objects from an S3 bucket. /// /// To execute the request, call [`DeleteObjects::send()`](crate::s3::types::S3Api::send), /// which returns a [`Result`] containing a [`DeleteObjectsResponse`](crate::s3::response::DeleteObjectsResponse). - pub fn delete_objects, D: Into>( + pub fn delete_objects>( &self, bucket: S, - object: Vec, - ) -> DeleteObjects { - DeleteObjects::new(self.clone(), bucket.into(), object) + objects: Vec, + ) -> DeleteObjectsBldr { + DeleteObjects::builder() + .client(self.clone()) + .bucket(bucket) + .objects(objects) } /// Creates a [`DeleteObjectsStreaming`] request builder to delete a stream of objects from an S3 bucket. diff --git a/src/s3/client/get_bucket_encryption.rs b/src/s3/client/get_bucket_encryption.rs index e1c91893..242eed5c 100644 --- a/src/s3/client/get_bucket_encryption.rs +++ b/src/s3/client/get_bucket_encryption.rs @@ -13,10 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::Client; -use crate::s3::builders::GetBucketEncryption; +use crate::s3::builders::{GetBucketEncryption, GetBucketEncryptionBldr}; +use crate::s3::client::MinioClient; -impl Client { +impl MinioClient { /// Creates a [`GetBucketEncryption`] request builder. /// /// To execute the request, call [`GetBucketEncryption::send()`](crate::s3::types::S3Api::send), @@ -25,21 +25,23 @@ impl Client { /// # Example /// /// ```no_run - /// use minio::s3::Client; + /// use minio::s3::MinioClient; /// use minio::s3::response::GetBucketEncryptionResponse; /// use minio::s3::types::S3Api; /// use minio::s3::response::a_response_traits::HasBucket; /// /// #[tokio::main] /// async fn main() { - /// let client: Client = Default::default(); // configure your client here + /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here /// let resp: GetBucketEncryptionResponse = client /// .get_bucket_encryption("bucket-name") - /// .send().await.unwrap(); + /// .build().send().await.unwrap(); /// println!("retrieved SseConfig '{:?}' from bucket '{}'", resp.config(), resp.bucket()); /// } /// ``` - pub fn get_bucket_encryption>(&self, bucket: S) -> GetBucketEncryption { - GetBucketEncryption::new(self.clone(), bucket.into()) + pub fn get_bucket_encryption>(&self, bucket: S) -> GetBucketEncryptionBldr { + GetBucketEncryption::builder() + .client(self.clone()) + .bucket(bucket) } } diff --git a/src/s3/client/get_bucket_lifecycle.rs b/src/s3/client/get_bucket_lifecycle.rs index 39b3a475..ecf31ed4 100644 --- a/src/s3/client/get_bucket_lifecycle.rs +++ b/src/s3/client/get_bucket_lifecycle.rs @@ -13,10 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::Client; -use crate::s3::builders::GetBucketLifecycle; +use crate::s3::builders::{GetBucketLifecycle, GetBucketLifecycleBldr}; +use crate::s3::client::MinioClient; -impl Client { +impl MinioClient { /// Creates a [`GetBucketLifecycle`] request builder. /// /// To execute the request, call [`GetBucketLifecycle::send()`](crate::s3::types::S3Api::send), @@ -25,21 +25,23 @@ impl Client { /// # Example /// /// ```no_run - /// use minio::s3::Client; + /// use minio::s3::MinioClient; /// use minio::s3::response::GetBucketLifecycleResponse; /// use minio::s3::types::S3Api; /// use minio::s3::response::a_response_traits::HasBucket; /// /// #[tokio::main] /// async fn main() { - /// let client: Client = Default::default(); // configure your client here + /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here /// let resp: GetBucketLifecycleResponse = client /// .get_bucket_lifecycle("bucket-name") - /// .send().await.unwrap(); + /// .build().send().await.unwrap(); /// println!("retrieved bucket lifecycle config '{:?}' from bucket '{}'", resp.config(), resp.bucket()); /// } /// ``` - pub fn get_bucket_lifecycle>(&self, bucket: S) -> GetBucketLifecycle { - GetBucketLifecycle::new(self.clone(), bucket.into()) + pub fn get_bucket_lifecycle>(&self, bucket: S) -> GetBucketLifecycleBldr { + GetBucketLifecycle::builder() + .client(self.clone()) + .bucket(bucket) } } diff --git a/src/s3/client/get_bucket_notification.rs b/src/s3/client/get_bucket_notification.rs index 66c0ffee..f41073b9 100644 --- a/src/s3/client/get_bucket_notification.rs +++ b/src/s3/client/get_bucket_notification.rs @@ -13,10 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::Client; -use crate::s3::builders::GetBucketNotification; +use crate::s3::builders::{GetBucketNotification, GetBucketNotificationBldr}; +use crate::s3::client::MinioClient; -impl Client { +impl MinioClient { /// Creates a [`GetBucketNotification`] request builder. /// /// To execute the request, call [`GetBucketNotification::send()`](crate::s3::types::S3Api::send), @@ -25,21 +25,23 @@ impl Client { /// # Example /// /// ```no_run - /// use minio::s3::Client; + /// use minio::s3::MinioClient; /// use minio::s3::response::GetBucketNotificationResponse; /// use minio::s3::types::S3Api; /// use minio::s3::response::a_response_traits::HasBucket; /// /// #[tokio::main] /// async fn main() { - /// let client: Client = Default::default(); // configure your client here + /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here /// let resp: GetBucketNotificationResponse = client /// .get_bucket_notification("bucket-name") - /// .send().await.unwrap(); + /// .build().send().await.unwrap(); /// println!("retrieved bucket notification config '{:?}' from bucket '{}'", resp.config(), resp.bucket()); /// } /// ``` - pub fn get_bucket_notification>(&self, bucket: S) -> GetBucketNotification { - GetBucketNotification::new(self.clone(), bucket.into()) + pub fn get_bucket_notification>(&self, bucket: S) -> GetBucketNotificationBldr { + GetBucketNotification::builder() + .client(self.clone()) + .bucket(bucket) } } diff --git a/src/s3/client/get_bucket_policy.rs b/src/s3/client/get_bucket_policy.rs index 4d7fb7ea..6952dead 100644 --- a/src/s3/client/get_bucket_policy.rs +++ b/src/s3/client/get_bucket_policy.rs @@ -13,10 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::Client; -use crate::s3::builders::GetBucketPolicy; +use crate::s3::builders::{GetBucketPolicy, GetBucketPolicyBldr}; +use crate::s3::client::MinioClient; -impl Client { +impl MinioClient { /// Creates a [`GetBucketPolicy`] request builder. /// /// To execute the request, call [`GetBucketPolicy::send()`](crate::s3::types::S3Api::send), @@ -25,21 +25,23 @@ impl Client { /// # Example /// /// ```no_run - /// use minio::s3::Client; + /// use minio::s3::MinioClient; /// use minio::s3::response::GetBucketPolicyResponse; /// use minio::s3::types::S3Api; /// use minio::s3::response::a_response_traits::HasBucket; /// /// #[tokio::main] /// async fn main() { - /// let client: Client = Default::default(); // configure your client here + /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here /// let resp: GetBucketPolicyResponse = client /// .get_bucket_policy("bucket-name") - /// .send().await.unwrap(); + /// .build().send().await.unwrap(); /// println!("retrieved bucket policy config '{:?}' from bucket '{}'", resp.config(), resp.bucket()); /// } /// ``` - pub fn get_bucket_policy>(&self, bucket: S) -> GetBucketPolicy { - GetBucketPolicy::new(self.clone(), bucket.into()) + pub fn get_bucket_policy>(&self, bucket: S) -> GetBucketPolicyBldr { + GetBucketPolicy::builder() + .client(self.clone()) + .bucket(bucket) } } diff --git a/src/s3/client/get_bucket_replication.rs b/src/s3/client/get_bucket_replication.rs index 6eddf41a..a3f3af70 100644 --- a/src/s3/client/get_bucket_replication.rs +++ b/src/s3/client/get_bucket_replication.rs @@ -13,10 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::Client; -use crate::s3::builders::GetBucketReplication; +use crate::s3::builders::{GetBucketReplication, GetBucketReplicationBldr}; +use crate::s3::client::MinioClient; -impl Client { +impl MinioClient { /// Creates a [`GetBucketReplication`] request builder. /// /// To execute the request, call [`GetBucketReplication::send()`](crate::s3::types::S3Api::send), @@ -27,21 +27,23 @@ impl Client { /// # Example /// /// ```no_run - /// use minio::s3::Client; + /// use minio::s3::MinioClient; /// use minio::s3::response::GetBucketReplicationResponse; /// use minio::s3::types::S3Api; /// use minio::s3::response::a_response_traits::HasBucket; /// /// #[tokio::main] /// async fn main() { - /// let client: Client = Default::default(); // configure your client here + /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here /// let resp: GetBucketReplicationResponse = client /// .get_bucket_replication("bucket-name") - /// .send().await.unwrap(); + /// .build().send().await.unwrap(); /// println!("retrieved bucket replication config '{:?}' from bucket '{}'", resp.config(), resp.bucket()); /// } /// ``` - pub fn get_bucket_replication>(&self, bucket: S) -> GetBucketReplication { - GetBucketReplication::new(self.clone(), bucket.into()) + pub fn get_bucket_replication>(&self, bucket: S) -> GetBucketReplicationBldr { + GetBucketReplication::builder() + .client(self.clone()) + .bucket(bucket) } } diff --git a/src/s3/client/get_bucket_tagging.rs b/src/s3/client/get_bucket_tagging.rs index 2bb0237e..4d1bde96 100644 --- a/src/s3/client/get_bucket_tagging.rs +++ b/src/s3/client/get_bucket_tagging.rs @@ -13,10 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::Client; -use crate::s3::builders::GetBucketTagging; +use crate::s3::builders::{GetBucketTagging, GetBucketTaggingBldr}; +use crate::s3::client::MinioClient; -impl Client { +impl MinioClient { /// Creates a [`GetBucketTagging`] request builder. /// /// To execute the request, call [`GetBucketTags::send()`](crate::s3::types::S3Api::send), @@ -27,21 +27,23 @@ impl Client { /// # Example /// /// ```no_run - /// use minio::s3::Client; + /// use minio::s3::MinioClient; /// use minio::s3::response::GetBucketTaggingResponse; /// use minio::s3::types::S3Api; /// use minio::s3::response::a_response_traits::{HasBucket, HasTagging}; /// /// #[tokio::main] /// async fn main() { - /// let client: Client = Default::default(); // configure your client here + /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here /// let resp: GetBucketTaggingResponse = client /// .get_bucket_tagging("bucket-name") - /// .send().await.unwrap(); + /// .build().send().await.unwrap(); /// println!("retrieved bucket tags '{:?}' from bucket '{}'", resp.tags(), resp.bucket()); /// } /// ``` - pub fn get_bucket_tagging>(&self, bucket: S) -> GetBucketTagging { - GetBucketTagging::new(self.clone(), bucket.into()) + pub fn get_bucket_tagging>(&self, bucket: S) -> GetBucketTaggingBldr { + GetBucketTagging::builder() + .client(self.clone()) + .bucket(bucket) } } diff --git a/src/s3/client/get_bucket_versioning.rs b/src/s3/client/get_bucket_versioning.rs index b1de3e37..ac808fb7 100644 --- a/src/s3/client/get_bucket_versioning.rs +++ b/src/s3/client/get_bucket_versioning.rs @@ -13,10 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::Client; -use crate::s3::builders::GetBucketVersioning; +use crate::s3::builders::{GetBucketVersioning, GetBucketVersioningBldr}; +use crate::s3::client::MinioClient; -impl Client { +impl MinioClient { /// Creates a [`GetBucketVersioning`] request builder. /// /// To execute the request, call [`GetBucketVersioning::send()`](crate::s3::types::S3Api::send), @@ -27,21 +27,23 @@ impl Client { /// # Example /// /// ```no_run - /// use minio::s3::Client; + /// use minio::s3::MinioClient; /// use minio::s3::response::GetBucketVersioningResponse; /// use minio::s3::types::S3Api; /// use minio::s3::response::a_response_traits::HasBucket; /// /// #[tokio::main] /// async fn main() { - /// let client: Client = Default::default(); // configure your client here + /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here /// let resp: GetBucketVersioningResponse = client /// .get_bucket_versioning("bucket-name") - /// .send().await.unwrap(); + /// .build().send().await.unwrap(); /// println!("retrieved versioning status '{:?}' from bucket '{}'", resp.status(), resp.bucket()); /// } /// ``` - pub fn get_bucket_versioning>(&self, bucket: S) -> GetBucketVersioning { - GetBucketVersioning::new(self.clone(), bucket.into()) + pub fn get_bucket_versioning>(&self, bucket: S) -> GetBucketVersioningBldr { + GetBucketVersioning::builder() + .client(self.clone()) + .bucket(bucket) } } diff --git a/src/s3/client/get_object.rs b/src/s3/client/get_object.rs index 539cb5b8..1c35ab4b 100644 --- a/src/s3/client/get_object.rs +++ b/src/s3/client/get_object.rs @@ -13,10 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::Client; -use crate::s3::builders::GetObject; +use crate::s3::builders::{GetObject, GetObjectBldr}; +use crate::s3::client::MinioClient; -impl Client { +impl MinioClient { /// Creates a [`GetObject`] request builder to download an object from a specified S3 bucket. /// This allows retrieval of the full content and metadata for the object. /// @@ -28,16 +28,16 @@ impl Client { /// # Example /// /// ```no_run - /// use minio::s3::Client; + /// use minio::s3::MinioClient; /// 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 client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here /// let resp: GetObjectResponse = client /// .get_object("bucket-name", "object-name") - /// .send().await.unwrap(); + /// .build().send().await.unwrap(); /// let content_bytes = resp.content().unwrap().to_segmented_bytes().await.unwrap().to_bytes(); /// let content_str = String::from_utf8(content_bytes.to_vec()).unwrap(); /// println!("retrieved content '{content_str}'"); @@ -47,7 +47,10 @@ impl Client { &self, bucket: S1, object: S2, - ) -> GetObject { - GetObject::new(self.clone(), bucket.into(), object.into()) + ) -> GetObjectBldr { + GetObject::builder() + .client(self.clone()) + .bucket(bucket) + .object(object) } } diff --git a/src/s3/client/get_object_legal_hold.rs b/src/s3/client/get_object_legal_hold.rs index 13ab6fb0..6af5f9cc 100644 --- a/src/s3/client/get_object_legal_hold.rs +++ b/src/s3/client/get_object_legal_hold.rs @@ -13,10 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::Client; -use crate::s3::builders::GetObjectLegalHold; +use crate::s3::builders::{GetObjectLegalHold, GetObjectLegalHoldBldr}; +use crate::s3::client::MinioClient; -impl Client { +impl MinioClient { /// Creates a [`GetObjectLegalHold`] request builder. /// /// To execute the request, call [`GetObjectLegalHold::send()`](crate::s3::types::S3Api::send), @@ -27,17 +27,17 @@ impl Client { /// # Example /// /// ```no_run - /// use minio::s3::Client; + /// use minio::s3::MinioClient; /// use minio::s3::response::GetObjectLegalHoldResponse; /// use minio::s3::types::S3Api; /// use minio::s3::response::a_response_traits::{HasBucket, HasObject}; /// /// #[tokio::main] /// async fn main() { - /// let client: Client = Default::default(); // configure your client here + /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here /// let resp: GetObjectLegalHoldResponse = client /// .get_object_legal_hold("bucket-name", "object-name") - /// .send().await.unwrap(); + /// .build().send().await.unwrap(); /// println!("legal hold of object '{}' in bucket '{}' is enabled: {:?}", resp.object(), resp.bucket(), resp.enabled()); /// } /// ``` @@ -45,7 +45,10 @@ impl Client { &self, bucket: S1, object: S2, - ) -> GetObjectLegalHold { - GetObjectLegalHold::new(self.clone(), bucket.into(), object.into()) + ) -> GetObjectLegalHoldBldr { + GetObjectLegalHold::builder() + .client(self.clone()) + .bucket(bucket) + .object(object) } } diff --git a/src/s3/client/get_object_lock_config.rs b/src/s3/client/get_object_lock_config.rs index f97c64c5..d7475bfe 100644 --- a/src/s3/client/get_object_lock_config.rs +++ b/src/s3/client/get_object_lock_config.rs @@ -13,10 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::Client; -use crate::s3::builders::GetObjectLockConfig; +use crate::s3::builders::{GetObjectLockConfig, GetObjectLockConfigBldr}; +use crate::s3::client::MinioClient; -impl Client { +impl MinioClient { /// Creates a [`GetObjectLockConfig`] request builder. /// /// To execute the request, call [`GetObjectLockConfig::send()`](crate::s3::types::S3Api::send), @@ -27,21 +27,23 @@ impl Client { /// # Example /// /// ```no_run - /// use minio::s3::Client; + /// use minio::s3::MinioClient; /// use minio::s3::response::GetObjectLockConfigResponse; /// use minio::s3::types::S3Api; /// use minio::s3::response::a_response_traits::HasBucket; /// /// #[tokio::main] /// async fn main() { - /// let client: Client = Default::default(); // configure your client here + /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here /// let resp: GetObjectLockConfigResponse = client /// .get_object_lock_config("bucket-name") - /// .send().await.unwrap(); + /// .build().send().await.unwrap(); /// println!("retrieved object lock config '{:?}' from bucket '{}' is enabled", resp.config(), resp.bucket()); /// } /// ``` - pub fn get_object_lock_config>(&self, bucket: S) -> GetObjectLockConfig { - GetObjectLockConfig::new(self.clone(), bucket.into()) + pub fn get_object_lock_config>(&self, bucket: S) -> GetObjectLockConfigBldr { + GetObjectLockConfig::builder() + .client(self.clone()) + .bucket(bucket) } } diff --git a/src/s3/client/get_object_prompt.rs b/src/s3/client/get_object_prompt.rs index 7f64c560..2ba2317f 100644 --- a/src/s3/client/get_object_prompt.rs +++ b/src/s3/client/get_object_prompt.rs @@ -13,11 +13,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::s3::builders::GetObjectPrompt; +use crate::s3::builders::{GetObjectPrompt, GetObjectPromptBldr}; -use super::Client; +use crate::s3::client::MinioClient; -impl Client { +impl MinioClient { /// Creates a [`GetObjectPrompt`] request builder. Prompt an object using natural language. /// /// To execute the request, call [`GetObjectPrompt::send()`](crate::s3::types::S3Api::send), @@ -26,16 +26,16 @@ impl Client { /// # Example /// /// ```no_run - /// use minio::s3::Client; + /// use minio::s3::MinioClient; /// 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 client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here /// let resp: GetObjectPromptResponse = client /// .get_object_prompt("bucket-name", "object-name", "What is it about?") - /// .send().await.unwrap(); + /// .build().send().await.unwrap(); /// println!("the prompt response is: '{:?}'", resp.prompt_response()); /// } /// ``` @@ -44,7 +44,11 @@ impl Client { bucket: S1, object: S2, prompt: S3, - ) -> GetObjectPrompt { - GetObjectPrompt::new(self.clone(), bucket.into(), object.into(), prompt.into()) + ) -> GetObjectPromptBldr { + GetObjectPrompt::builder() + .client(self.clone()) + .bucket(bucket) + .object(object) + .prompt(prompt) } } diff --git a/src/s3/client/get_object_retention.rs b/src/s3/client/get_object_retention.rs index 06288dc9..c9072d53 100644 --- a/src/s3/client/get_object_retention.rs +++ b/src/s3/client/get_object_retention.rs @@ -13,10 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::Client; -use crate::s3::builders::GetObjectRetention; +use crate::s3::builders::{GetObjectRetention, GetObjectRetentionBldr}; +use crate::s3::client::MinioClient; -impl Client { +impl MinioClient { /// Creates a [`GetObjectRetention`] request builder. /// /// To execute the request, call [`GetObjectRetention::send()`](crate::s3::types::S3Api::send), @@ -27,17 +27,17 @@ impl Client { /// # Example /// /// ```no_run - /// use minio::s3::Client; + /// use minio::s3::MinioClient; /// use minio::s3::response::GetObjectRetentionResponse; /// use minio::s3::types::S3Api; /// use minio::s3::response::a_response_traits::HasBucket; /// /// #[tokio::main] /// async fn main() { - /// let client: Client = Default::default(); // configure your client here + /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here /// let resp: GetObjectRetentionResponse = client /// .get_object_retention("bucket-name", "object-name") - /// .send().await.unwrap(); + /// .build().send().await.unwrap(); /// println!("retrieved retention mode '{:?}' until '{:?}' from bucket '{}' is enabled", resp.retention_mode(), resp.retain_until_date(), resp.bucket()); /// } /// ``` @@ -45,7 +45,10 @@ impl Client { &self, bucket: S1, object: S2, - ) -> GetObjectRetention { - GetObjectRetention::new(self.clone(), bucket.into(), object.into()) + ) -> GetObjectRetentionBldr { + GetObjectRetention::builder() + .client(self.clone()) + .bucket(bucket) + .object(object) } } diff --git a/src/s3/client/get_object_tagging.rs b/src/s3/client/get_object_tagging.rs index ce57404a..085eb1ea 100644 --- a/src/s3/client/get_object_tagging.rs +++ b/src/s3/client/get_object_tagging.rs @@ -13,10 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::Client; -use crate::s3::builders::GetObjectTagging; +use crate::s3::builders::{GetObjectTagging, GetObjectTaggingBldr}; +use crate::s3::client::MinioClient; -impl Client { +impl MinioClient { /// Creates a [`GetObjectTagging`] request builder. /// /// To execute the request, call [`GetObjectTagging::send()`](crate::s3::types::S3Api::send), @@ -27,17 +27,17 @@ impl Client { /// # Example /// /// ```no_run - /// use minio::s3::Client; + /// use minio::s3::MinioClient; /// use minio::s3::response::GetObjectTaggingResponse; /// use minio::s3::types::S3Api; /// use minio::s3::response::a_response_traits::{HasBucket, HasObject, HasTagging}; /// /// #[tokio::main] /// async fn main() { - /// let client: Client = Default::default(); // configure your client here + /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here /// let resp: GetObjectTaggingResponse = client /// .get_object_tagging("bucket-name", "object-name") - /// .send().await.unwrap(); + /// .build().send().await.unwrap(); /// println!("retrieved object tags '{:?}' from object '{}' in bucket '{}' is enabled", resp.tags(), resp.object(), resp.bucket()); /// } /// ``` @@ -45,7 +45,10 @@ impl Client { &self, bucket: S1, object: S2, - ) -> GetObjectTagging { - GetObjectTagging::new(self.clone(), bucket.into(), object.into()) + ) -> GetObjectTaggingBldr { + GetObjectTagging::builder() + .client(self.clone()) + .bucket(bucket) + .object(object) } } diff --git a/src/s3/client/get_presigned_object_url.rs b/src/s3/client/get_presigned_object_url.rs index 7202c3cc..42fa1109 100644 --- a/src/s3/client/get_presigned_object_url.rs +++ b/src/s3/client/get_presigned_object_url.rs @@ -13,11 +13,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::s3::Client; -use crate::s3::builders::GetPresignedObjectUrl; +use crate::s3::builders::{GetPresignedObjectUrl, GetPresignedObjectUrlBldr}; +use crate::s3::client::MinioClient; use http::Method; -impl Client { +impl MinioClient { /// Creates a [`GetPresignedObjectUrl`] request builder. /// /// To execute the request, call [`GetPresignedObjectUrl::send()`](crate::s3::types::S3Api::send), @@ -27,16 +27,16 @@ impl Client { /// /// ```no_run /// use http::Method; - /// use minio::s3::Client; + /// use minio::s3::MinioClient; /// use minio::s3::response::GetPresignedObjectUrlResponse; /// use minio::s3::types::S3Api; /// /// #[tokio::main] /// async fn main() { - /// let client: Client = Default::default(); // configure your client here + /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here /// let resp: GetPresignedObjectUrlResponse = client /// .get_presigned_object_url("bucket-name", "object-name", Method::GET) - /// .send().await.unwrap(); + /// .build().send().await.unwrap(); /// println!("the presigned url: '{:?}'", resp.url); /// } /// ``` @@ -45,7 +45,11 @@ impl Client { bucket: S1, object: S2, method: Method, - ) -> GetPresignedObjectUrl { - GetPresignedObjectUrl::new(self.clone(), bucket.into(), object.into(), method) + ) -> GetPresignedObjectUrlBldr { + GetPresignedObjectUrl::builder() + .client(self.clone()) + .bucket(bucket) + .object(object) + .method(method) } } diff --git a/src/s3/client/get_presigned_post_form_data.rs b/src/s3/client/get_presigned_post_form_data.rs index 02ce18e7..c562d4ee 100644 --- a/src/s3/client/get_presigned_post_form_data.rs +++ b/src/s3/client/get_presigned_post_form_data.rs @@ -13,10 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::s3::Client; -use crate::s3::builders::{GetPresignedPolicyFormData, PostPolicy}; +use crate::s3::builders::{GetPresignedPolicyFormData, GetPresignedPolicyFormDataBldr, PostPolicy}; +use crate::s3::client::MinioClient; -impl Client { +impl MinioClient { /// Creates a [`GetPresignedPolicyFormData`] request builder. /// /// To execute the request, call [`GetPresignedPolicyFormData::send()`](crate::s3::types::S3Api::send), @@ -28,7 +28,7 @@ impl Client { /// use http::Method; /// use std::collections::HashMap; /// use chrono::{DateTime, Utc}; - /// use minio::s3::Client; + /// use minio::s3::MinioClient; /// use minio::s3::types::S3Api; /// use minio::s3::builders::PostPolicy; /// use minio::s3::utils::utc_now; @@ -45,15 +45,20 @@ impl Client { /// /// #[tokio::main] /// async fn main() { - /// let client: Client = Default::default(); // configure your client here + /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here /// let policy: PostPolicy = create_post_policy_example("bucket-name", "object-name"); /// let resp: HashMap = client /// .get_presigned_post_form_data(policy) - /// .send().await.unwrap(); + /// .build().send().await.unwrap(); /// println!("presigned post form data: '{:?}'", resp); /// } /// ``` - pub fn get_presigned_post_form_data(&self, policy: PostPolicy) -> GetPresignedPolicyFormData { - GetPresignedPolicyFormData::new(self.clone(), policy) + pub fn get_presigned_post_form_data( + &self, + policy: PostPolicy, + ) -> GetPresignedPolicyFormDataBldr { + GetPresignedPolicyFormData::builder() + .client(self.clone()) + .policy(policy) } } diff --git a/src/s3/client/get_region.rs b/src/s3/client/get_region.rs index 3e84a9fe..53d04c21 100644 --- a/src/s3/client/get_region.rs +++ b/src/s3/client/get_region.rs @@ -13,13 +13,12 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::{Client, DEFAULT_REGION}; -use crate::s3::builders::GetRegion; - +use super::{DEFAULT_REGION, MinioClient}; +use crate::s3::builders::{GetRegion, GetRegionBldr}; use crate::s3::error::{Error, ValidationErr}; use crate::s3::types::S3Api; -impl Client { +impl MinioClient { /// Creates a [`GetRegion`] request builder. /// /// To execute the request, call [`GetRegion::send()`](crate::s3::types::S3Api::send), @@ -28,22 +27,22 @@ impl Client { /// # Example /// /// ```no_run - /// use minio::s3::Client; + /// use minio::s3::MinioClient; /// use minio::s3::response::GetRegionResponse; /// use minio::s3::types::S3Api; /// use minio::s3::response::a_response_traits::HasBucket; /// /// #[tokio::main] /// async fn main() { - /// let client: Client = Default::default(); // configure your client here + /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here /// let resp: GetRegionResponse = client /// .get_region("bucket-name") - /// .send().await.unwrap(); + /// .build().send().await.unwrap(); /// println!("retrieved region '{:?}' for bucket '{}'", resp.region_response(), resp.bucket()); /// } /// ``` - pub fn get_region>(&self, bucket: S) -> GetRegion { - GetRegion::new(self.clone(), bucket.into()) + pub fn get_region>(&self, bucket: S) -> GetRegionBldr { + GetRegion::builder().client(self.clone()).bucket(bucket) } /// Retrieves the region for the specified bucket name from the cache. @@ -86,7 +85,12 @@ impl Client { // Otherwise, fetch the region from the server and cache it let resolved_region: String = { - let region = self.get_region(&bucket).send().await?.region_response()?; + let region = self + .get_region(&bucket) + .build() + .send() + .await? + .region_response()?; if !region.is_empty() { region } else { diff --git a/src/s3/client/list_buckets.rs b/src/s3/client/list_buckets.rs index 5f8c3e91..d8d17875 100644 --- a/src/s3/client/list_buckets.rs +++ b/src/s3/client/list_buckets.rs @@ -13,10 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::Client; -use crate::s3::builders::ListBuckets; +use crate::s3::builders::{ListBuckets, ListBucketsBldr}; +use crate::s3::client::MinioClient; -impl Client { +impl MinioClient { /// Creates a [`ListBuckets`] request builder to retrieve the list of all buckets owned by the authenticated sender of the request. /// /// To execute the request, call [`ListBuckets::send()`](crate::s3::types::S3Api::send), @@ -27,20 +27,20 @@ impl Client { /// # Example /// /// ```no_run - /// use minio::s3::Client; + /// use minio::s3::MinioClient; /// use minio::s3::response::ListBucketsResponse; /// use minio::s3::types::S3Api; /// /// #[tokio::main] /// async fn main() { - /// let client: Client = Default::default(); // configure your client here + /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here /// let resp: ListBucketsResponse = client /// .list_buckets() - /// .send().await.unwrap(); + /// .build().send().await.unwrap(); /// println!("retrieved buckets '{:?}'", resp.buckets()); /// } /// ``` - pub fn list_buckets(&self) -> ListBuckets { - ListBuckets::new(self.clone()) + pub fn list_buckets(&self) -> ListBucketsBldr { + ListBuckets::builder().client(self.clone()) } } diff --git a/src/s3/client/list_objects.rs b/src/s3/client/list_objects.rs index 9e361d02..7c1864ed 100644 --- a/src/s3/client/list_objects.rs +++ b/src/s3/client/list_objects.rs @@ -13,10 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::Client; -use crate::s3::builders::ListObjects; +use crate::s3::builders::{ListObjectBldr, ListObjects}; +use crate::s3::client::MinioClient; -impl Client { +impl MinioClient { /// Creates a [`ListObjects`] request builder. /// /// List objects with version information optionally. This function handles @@ -29,35 +29,35 @@ impl Client { /// # Example /// /// ```no_run - /// use minio::s3::Client; + /// use minio::s3::MinioClient; /// use minio::s3::types::{ToStream, S3Api}; - /// /// use futures_util::StreamExt; /// /// #[tokio::main] /// async fn main() { - /// let client: Client = Default::default(); // configure your client here - /// - /// let mut resp = client - /// .list_objects("bucket-name") - /// .recursive(true) - /// .use_api_v1(false) // use v2 - /// .include_versions(true) - /// .to_stream().await; - /// - /// while let Some(result) = resp.next().await { - /// match result { - /// Ok(resp) => { - /// for item in resp.contents { - /// println!("{:?}", item); - /// } - /// } - /// Err(e) => println!("Error: {:?}", e), - /// } - /// } - ///} + /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here + /// + /// let mut resp = client + /// .list_objects("bucket-name") + /// .recursive(true) + /// .use_api_v1(false) // use v2 + /// .include_versions(true) + /// .build() + /// .to_stream().await; + /// + /// while let Some(result) = resp.next().await { + /// match result { + /// Ok(resp) => { + /// for item in resp.contents { + /// println!("{:?}", item); + /// } + /// } + /// Err(e) => println!("Error: {:?}", e), + /// } + /// } + /// } /// ``` - pub fn list_objects>(&self, bucket: S) -> ListObjects { - ListObjects::new(self.clone(), bucket.into()) + pub fn list_objects>(&self, bucket: S) -> ListObjectBldr { + ListObjects::builder().client(self.clone()).bucket(bucket) } } diff --git a/src/s3/client/listen_bucket_notification.rs b/src/s3/client/listen_bucket_notification.rs index cd210e46..cfff25a0 100644 --- a/src/s3/client/listen_bucket_notification.rs +++ b/src/s3/client/listen_bucket_notification.rs @@ -15,10 +15,10 @@ //! MinIO Extension API for S3 Buckets: ListenBucketNotification -use super::Client; -use crate::s3::builders::ListenBucketNotification; +use crate::s3::builders::{ListenBucketNotification, ListenBucketNotificationBldr}; +use crate::s3::client::MinioClient; -impl Client { +impl MinioClient { /// Creates a [`ListenBucketNotification`] request builder. /// /// To execute the request, call [`ListenBucketNotification::send()`](crate::s3::types::S3Api::send), @@ -35,16 +35,16 @@ impl Client { /// # Example /// /// ```no_run - /// use minio::s3::Client; + /// use minio::s3::MinioClient; /// use minio::s3::types::{NotificationRecord, NotificationRecords, S3Api}; /// use futures_util::StreamExt; /// /// #[tokio::main] /// async fn main() { - /// let client: Client = Default::default(); // configure your client here + /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here /// let (_resp, mut event_stream) = client /// .listen_bucket_notification("bucket-name") - /// .send().await .unwrap(); + /// .build().send().await.unwrap(); /// /// while let Some(event) = event_stream.next().await { /// let event: NotificationRecords = event.unwrap(); @@ -56,7 +56,9 @@ impl Client { pub fn listen_bucket_notification>( &self, bucket: S, - ) -> ListenBucketNotification { - ListenBucketNotification::new(self.clone(), bucket.into()) + ) -> ListenBucketNotificationBldr { + ListenBucketNotification::builder() + .client(self.clone()) + .bucket(bucket) } } diff --git a/src/s3/client/put_bucket_encryption.rs b/src/s3/client/put_bucket_encryption.rs index a78192cd..e2dff47b 100644 --- a/src/s3/client/put_bucket_encryption.rs +++ b/src/s3/client/put_bucket_encryption.rs @@ -13,10 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::Client; -use crate::s3::builders::PutBucketEncryption; +use crate::s3::builders::{PutBucketEncryption, PutBucketEncryptionBldr}; +use crate::s3::client::MinioClient; -impl Client { +impl MinioClient { /// Creates a [`PutBucketEncryption`] request builder. /// /// To execute the request, call [`SetBucketEncryption::send()`](crate::s3::types::S3Api::send), @@ -28,23 +28,25 @@ impl Client { /// /// ```no_run /// use minio::s3::types::SseConfig; - /// use minio::s3::Client; + /// use minio::s3::MinioClient; /// use minio::s3::response::PutBucketEncryptionResponse; /// use minio::s3::types::S3Api; /// use minio::s3::response::a_response_traits::HasBucket; /// /// #[tokio::main] /// async fn main() { - /// let client: Client = Default::default(); // configure your client here + /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here /// let config = SseConfig::default(); /// let resp: PutBucketEncryptionResponse = client /// .put_bucket_encryption("bucket-name") /// .sse_config(config) - /// .send().await.unwrap(); + /// .build().send().await.unwrap(); /// println!("set encryption on bucket '{}'", resp.bucket()); /// } /// ``` - pub fn put_bucket_encryption>(&self, bucket: S) -> PutBucketEncryption { - PutBucketEncryption::new(self.clone(), bucket.into()) + pub fn put_bucket_encryption>(&self, bucket: S) -> PutBucketEncryptionBldr { + PutBucketEncryption::builder() + .client(self.clone()) + .bucket(bucket) } } diff --git a/src/s3/client/put_bucket_lifecycle.rs b/src/s3/client/put_bucket_lifecycle.rs index 58e82683..2a52fd35 100644 --- a/src/s3/client/put_bucket_lifecycle.rs +++ b/src/s3/client/put_bucket_lifecycle.rs @@ -13,10 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::Client; -use crate::s3::builders::PutBucketLifecycle; +use crate::s3::builders::{PutBucketLifecycle, PutBucketLifecycleBldr}; +use crate::s3::client::MinioClient; -impl Client { +impl MinioClient { /// Creates a [`PutBucketLifecycle`] request builder. /// /// To execute the request, call [`SetBucketLifecycle::send()`](crate::s3::types::S3Api::send), @@ -26,7 +26,7 @@ impl Client { /// /// ```no_run /// use std::collections::HashMap; - /// use minio::s3::Client; + /// use minio::s3::MinioClient; /// use minio::s3::builders::VersioningStatus; /// use minio::s3::response::PutBucketLifecycleResponse; /// use minio::s3::types::{Filter, S3Api}; @@ -35,7 +35,7 @@ impl Client { /// /// #[tokio::main] /// async fn main() { - /// let client: Client = Default::default(); // configure your client here + /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here /// let rules: Vec = vec![LifecycleRule { /// id: String::from("rule1"), /// filter: Filter {and_operator: None, prefix: Some(String::from("logs/")), tag: None}, @@ -47,11 +47,13 @@ impl Client { /// let resp: PutBucketLifecycleResponse = client /// .put_bucket_lifecycle("bucket-name") /// .life_cycle_config(LifecycleConfig { rules }) - /// .send().await.unwrap(); + /// .build().send().await.unwrap(); /// println!("set bucket replication policy on bucket '{}'", resp.bucket()); /// } /// ``` - pub fn put_bucket_lifecycle>(&self, bucket: S) -> PutBucketLifecycle { - PutBucketLifecycle::new(self.clone(), bucket.into()) + pub fn put_bucket_lifecycle>(&self, bucket: S) -> PutBucketLifecycleBldr { + PutBucketLifecycle::builder() + .client(self.clone()) + .bucket(bucket) } } diff --git a/src/s3/client/put_bucket_notification.rs b/src/s3/client/put_bucket_notification.rs index 0086f593..c5055394 100644 --- a/src/s3/client/put_bucket_notification.rs +++ b/src/s3/client/put_bucket_notification.rs @@ -13,10 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::Client; -use crate::s3::builders::PutBucketNotification; +use crate::s3::builders::{PutBucketNotification, PutBucketNotificationBldr}; +use crate::s3::client::MinioClient; -impl Client { +impl MinioClient { /// Creates a [`PutBucketNotification`] request builder. /// /// To execute the request, call [`SetBucketNotification::send()`](crate::s3::types::S3Api::send), @@ -25,14 +25,14 @@ impl Client { /// # Example /// /// ```no_run - /// use minio::s3::Client; + /// use minio::s3::MinioClient; /// use minio::s3::types::{NotificationConfig, PrefixFilterRule, QueueConfig, S3Api, SuffixFilterRule}; /// use minio::s3::response::PutBucketNotificationResponse; /// use minio::s3::response::a_response_traits::HasBucket; /// /// #[tokio::main] /// async fn main() { - /// let client: Client = Default::default(); // configure your client here + /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here /// let config = NotificationConfig { /// cloud_func_config_list: None, /// queue_config_list: Some(vec![QueueConfig { @@ -55,11 +55,13 @@ impl Client { /// let resp: PutBucketNotificationResponse = client /// .put_bucket_notification("bucket-name") /// .notification_config(config) - /// .send().await.unwrap(); + /// .build().send().await.unwrap(); /// println!("set bucket notification for bucket '{:?}'", resp.bucket()); /// } /// ``` - pub fn put_bucket_notification>(&self, bucket: S) -> PutBucketNotification { - PutBucketNotification::new(self.clone(), bucket.into()) + pub fn put_bucket_notification>(&self, bucket: S) -> PutBucketNotificationBldr { + PutBucketNotification::builder() + .client(self.clone()) + .bucket(bucket) } } diff --git a/src/s3/client/put_bucket_policy.rs b/src/s3/client/put_bucket_policy.rs index ced7e484..8c2e9759 100644 --- a/src/s3/client/put_bucket_policy.rs +++ b/src/s3/client/put_bucket_policy.rs @@ -13,10 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::Client; -use crate::s3::builders::PutBucketPolicy; +use crate::s3::builders::{PutBucketPolicy, PutBucketPolicyBldr}; +use crate::s3::client::MinioClient; -impl Client { +impl MinioClient { /// Creates a [`PutBucketPolicy`] request builder. /// /// To execute the request, call [`SetBucketPolicy::send()`](crate::s3::types::S3Api::send), @@ -26,7 +26,7 @@ impl Client { /// /// ```no_run /// use std::collections::HashMap; - /// use minio::s3::Client; + /// use minio::s3::MinioClient; /// use minio::s3::builders::VersioningStatus; /// use minio::s3::response::PutBucketPolicyResponse; /// use minio::s3::types::{S3Api, AndOperator, Destination, Filter, ReplicationConfig, ReplicationRule}; @@ -34,7 +34,7 @@ impl Client { /// /// #[tokio::main] /// async fn main() { - /// let client: Client = Default::default(); // configure your client here + /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here /// /// let config = r#"{ /// "Version": "2012-10-17", @@ -63,11 +63,13 @@ impl Client { /// let resp: PutBucketPolicyResponse = client /// .put_bucket_policy("bucket-name") /// .config(config.to_owned()) - /// .send().await.unwrap(); + /// .build().send().await.unwrap(); /// println!("set bucket replication policy on bucket '{}'", resp.bucket()); /// } /// ``` - pub fn put_bucket_policy>(&self, bucket: S) -> PutBucketPolicy { - PutBucketPolicy::new(self.clone(), bucket.into()) + pub fn put_bucket_policy>(&self, bucket: S) -> PutBucketPolicyBldr { + PutBucketPolicy::builder() + .client(self.clone()) + .bucket(bucket) } } diff --git a/src/s3/client/put_bucket_replication.rs b/src/s3/client/put_bucket_replication.rs index 3dcce231..911c137f 100644 --- a/src/s3/client/put_bucket_replication.rs +++ b/src/s3/client/put_bucket_replication.rs @@ -13,10 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::Client; -use crate::s3::builders::PutBucketReplication; +use crate::s3::builders::{PutBucketReplication, PutBucketReplicationBldr}; +use crate::s3::client::MinioClient; -impl Client { +impl MinioClient { /// Creates a [`PutBucketReplication`] request builder. /// /// To execute the request, call [`SetBucketReplication::send()`](crate::s3::types::S3Api::send), @@ -27,17 +27,16 @@ impl Client { /// # Example /// /// ```no_run - /// use minio::s3::Client; + /// use minio::s3::MinioClient; /// use minio::s3::builders::VersioningStatus; /// use minio::s3::response::PutBucketReplicationResponse; /// use minio::s3::types::{S3Api, AndOperator, Destination, Filter, ReplicationConfig, ReplicationRule}; /// use minio::s3::response::a_response_traits::HasBucket; - /// /// use std::collections::HashMap; /// /// #[tokio::main] /// async fn main() { - /// let client: Client = Default::default(); // configure your client here + /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here /// /// let mut tags: HashMap = HashMap::new(); /// tags.insert(String::from("key1"), String::from("value1")); @@ -75,11 +74,13 @@ impl Client { /// let resp: PutBucketReplicationResponse = client /// .put_bucket_replication("bucket-name") /// .replication_config(ReplicationConfig {role: None, rules}) - /// .send().await.unwrap(); + /// .build().send().await.unwrap(); /// println!("enabled versioning on bucket '{}'", resp.bucket()); /// } /// ``` - pub fn put_bucket_replication>(&self, bucket: S) -> PutBucketReplication { - PutBucketReplication::new(self.clone(), bucket.into()) + pub fn put_bucket_replication>(&self, bucket: S) -> PutBucketReplicationBldr { + PutBucketReplication::builder() + .client(self.clone()) + .bucket(bucket) } } diff --git a/src/s3/client/put_bucket_tagging.rs b/src/s3/client/put_bucket_tagging.rs index de02b9bf..adff893b 100644 --- a/src/s3/client/put_bucket_tagging.rs +++ b/src/s3/client/put_bucket_tagging.rs @@ -13,10 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::Client; -use crate::s3::builders::PutBucketTagging; +use crate::s3::builders::{PutBucketTagging, PutBucketTaggingBldr}; +use crate::s3::client::MinioClient; -impl Client { +impl MinioClient { /// Creates a [`PutBucketTagging`] request builder. /// /// To execute the request, call [`PutBucketTagging::send()`](crate::s3::types::S3Api::send), @@ -27,17 +27,16 @@ impl Client { /// # Example /// /// ```no_run - /// use minio::s3::Client; + /// use minio::s3::MinioClient; /// use minio::s3::builders::VersioningStatus; /// use minio::s3::response::PutBucketTaggingResponse; /// use minio::s3::types::S3Api; /// use minio::s3::response::a_response_traits::HasBucket; - /// /// use std::collections::HashMap; /// /// #[tokio::main] /// async fn main() { - /// let client: Client = Default::default(); // configure your client here + /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here /// /// let mut tags: HashMap = HashMap::new(); /// tags.insert(String::from("Project"), String::from("Project One")); @@ -46,11 +45,13 @@ impl Client { /// let resp: PutBucketTaggingResponse = client /// .put_bucket_tagging("bucket-name") /// .tags(tags) - /// .send().await.unwrap(); + /// .build().send().await.unwrap(); /// println!("set tags on bucket '{}'", resp.bucket()); /// } /// ``` - pub fn put_bucket_tagging>(&self, bucket: S) -> PutBucketTagging { - PutBucketTagging::new(self.clone(), bucket.into()) + pub fn put_bucket_tagging>(&self, bucket: S) -> PutBucketTaggingBldr { + PutBucketTagging::builder() + .client(self.clone()) + .bucket(bucket) } } diff --git a/src/s3/client/put_bucket_versioning.rs b/src/s3/client/put_bucket_versioning.rs index 12ce0146..04583bc0 100644 --- a/src/s3/client/put_bucket_versioning.rs +++ b/src/s3/client/put_bucket_versioning.rs @@ -13,10 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::Client; -use crate::s3::builders::PutBucketVersioning; +use crate::s3::builders::{PutBucketVersioning, PutBucketVersioningBldr}; +use crate::s3::client::MinioClient; -impl Client { +impl MinioClient { /// Creates a [`PutBucketVersioning`] request builder. /// /// To execute the request, call [`SetBucketVersioning::send()`](crate::s3::types::S3Api::send), @@ -27,7 +27,7 @@ impl Client { /// # Example /// /// ```no_run - /// use minio::s3::Client; + /// use minio::s3::MinioClient; /// use minio::s3::builders::VersioningStatus; /// use minio::s3::response::PutBucketVersioningResponse; /// use minio::s3::types::{S3Api, ObjectLockConfig, RetentionMode}; @@ -35,16 +35,18 @@ impl Client { /// /// #[tokio::main] /// async fn main() { - /// let client: Client = Default::default(); // configure your client here + /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here /// /// let resp: PutBucketVersioningResponse = client /// .put_bucket_versioning("bucket-name") /// .versioning_status(VersioningStatus::Enabled) - /// .send().await.unwrap(); + /// .build().send().await.unwrap(); /// println!("enabled versioning on bucket '{}'", resp.bucket()); /// } /// ``` - pub fn put_bucket_versioning>(&self, bucket: S) -> PutBucketVersioning { - PutBucketVersioning::new(self.clone(), bucket.into()) + pub fn put_bucket_versioning>(&self, bucket: S) -> PutBucketVersioningBldr { + PutBucketVersioning::builder() + .client(self.clone()) + .bucket(bucket) } } diff --git a/src/s3/client/put_object.rs b/src/s3/client/put_object.rs index aec33f02..a8cf2a20 100644 --- a/src/s3/client/put_object.rs +++ b/src/s3/client/put_object.rs @@ -13,26 +13,25 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::Client; +use crate::s3::client::MinioClient; use crate::s3::segmented_bytes::SegmentedBytes; use crate::s3::{ builders::{ - AbortMultipartUpload, CompleteMultipartUpload, CreateMultipartUpload, ObjectContent, - PutObject, PutObjectContent, UploadPart, + AbortMultipartUpload, AbortMultipartUploadBldr, CompleteMultipartUpload, + CompleteMultipartUploadBldr, CreateMultipartUpload, CreateMultipartUploadBldr, + ObjectContent, PutObject, PutObjectBldr, PutObjectContent, PutObjectContentBldr, + UploadPart, UploadPartBldr, }, types::PartInfo, }; +use std::sync::Arc; -impl Client { +impl MinioClient { /// Creates a [`PutObject`] request builder to upload an object to a specified bucket in S3-compatible storage. /// This method performs a simple, non-multipart upload of the provided content as an object. /// /// For handling large files requiring multipart upload, see [`create_multipart_upload`](#method.create_multipart_upload). /// - /// For handling large files requiring multipart upload, see [`create_multipart_upload`](#method.create_multipart_upload). - /// - /// For handling large files requiring multipart upload, see [`create_multipart_upload`](#method.create_multipart_upload). - /// /// To execute the request, call [`PutObjects::send()`](crate::s3::types::S3Api::send), /// which returns a [`Result`] containing a [`PutObjectResponse`](crate::s3::response::PutObjectResponse). /// @@ -41,7 +40,7 @@ impl Client { /// # Example /// /// ```no_run - /// use minio::s3::Client; + /// use minio::s3::MinioClient; /// use minio::s3::response::PutObjectResponse; /// use minio::s3::types::S3Api; /// use minio::s3::segmented_bytes::SegmentedBytes; @@ -49,10 +48,11 @@ impl Client { /// /// #[tokio::main] /// async fn main() { - /// let client: Client = Default::default(); // configure your client here + /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here /// let data = SegmentedBytes::from("Hello world".to_string()); - /// let resp: PutObjectResponse = - /// client.put_object("bucket-name", "object-name", data).send().await.unwrap(); + /// let resp: PutObjectResponse = client + /// .put_object("bucket-name", "object-name", data) + /// .build().send().await.unwrap(); /// println!("successfully put object '{}'", resp.object()); /// } /// ``` @@ -61,8 +61,14 @@ impl Client { bucket: S1, object: S2, data: SegmentedBytes, - ) -> PutObject { - PutObject::new(self.clone(), bucket.into(), object.into(), data) + ) -> PutObjectBldr { + let inner = UploadPart::builder() + .client(self.clone()) + .bucket(bucket) + .object(object) + .data(Arc::new(data)) + .build(); + PutObject::builder().inner(inner) } /// Creates a [`CreateMultipartUpload`] request builder to initiate a new multipart upload for a specified object in a bucket. @@ -75,16 +81,16 @@ impl Client { /// /// # Example /// ```no_run - /// use minio::s3::Client; + /// use minio::s3::MinioClient; /// use minio::s3::response::CreateMultipartUploadResponse; /// use minio::s3::types::S3Api; /// /// #[tokio::main] /// async fn main() { - /// let client: Client = Default::default(); + /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here /// let resp: CreateMultipartUploadResponse = client /// .create_multipart_upload("bucket-name", "large-object") - /// .send().await.unwrap(); + /// .build().send().await.unwrap(); /// println!("Initiated multipart upload with UploadId '{:?}'", resp.upload_id().await); /// } /// ``` @@ -92,8 +98,11 @@ impl Client { &self, bucket: S1, object: S2, - ) -> CreateMultipartUpload { - CreateMultipartUpload::new(self.clone(), bucket.into(), object.into()) + ) -> CreateMultipartUploadBldr { + CreateMultipartUpload::builder() + .client(self.clone()) + .bucket(bucket) + .object(object) } /// Creates an [`AbortMultipartUpload`] request builder to abort an ongoing multipart upload for an object. @@ -106,16 +115,16 @@ impl Client { /// /// # Example /// ```no_run - /// use minio::s3::Client; + /// use minio::s3::MinioClient; /// use minio::s3::response::AbortMultipartUploadResponse; /// use minio::s3::types::S3Api; /// /// #[tokio::main] /// async fn main() { - /// let client: Client = Default::default(); + /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here /// let resp: AbortMultipartUploadResponse = client /// .abort_multipart_upload("bucket-name", "object-name", "upload-id-123") - /// .send().await.unwrap(); + /// .build().send().await.unwrap(); /// println!("Aborted multipart upload for '{}', upload id '{}'", "object-name", "upload-id-123"); /// } /// ``` @@ -124,8 +133,12 @@ impl Client { bucket: S1, object: S2, upload_id: S3, - ) -> AbortMultipartUpload { - AbortMultipartUpload::new(self.clone(), bucket.into(), object.into(), upload_id.into()) + ) -> AbortMultipartUploadBldr { + AbortMultipartUpload::builder() + .client(self.clone()) + .bucket(bucket) + .object(object) + .upload_id(upload_id) } /// Creates a [`CompleteMultipartUpload`] request builder to complete a multipart upload by assembling previously uploaded parts into a single object. @@ -138,18 +151,18 @@ impl Client { /// /// # Example /// ```no_run - /// use minio::s3::Client; + /// use minio::s3::MinioClient; /// use minio::s3::response::CompleteMultipartUploadResponse; /// use minio::s3::types::{S3Api, PartInfo}; /// use minio::s3::response::a_response_traits::HasObject; /// /// #[tokio::main] /// async fn main() { - /// let client: Client = Default::default(); + /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here /// let parts: Vec = vec![]; // fill with your uploaded part info /// let resp: CompleteMultipartUploadResponse = client /// .complete_multipart_upload("bucket-name", "object-name", "upload-id-123", parts) - /// .send().await.unwrap(); + /// .build().send().await.unwrap(); /// println!("Completed multipart upload for '{}'", resp.object()); /// } /// ``` @@ -159,14 +172,13 @@ impl Client { object: S2, upload_id: S3, parts: Vec, - ) -> CompleteMultipartUpload { - CompleteMultipartUpload::new( - self.clone(), - bucket.into(), - object.into(), - upload_id.into(), - parts, - ) + ) -> CompleteMultipartUploadBldr { + CompleteMultipartUpload::builder() + .client(self.clone()) + .bucket(bucket) + .object(object) + .upload_id(upload_id) + .parts(parts) } /// Creates an [`UploadPart`] request builder to upload a single part as part of a multipart upload. @@ -179,7 +191,7 @@ impl Client { /// /// # Example /// ```no_run - /// use minio::s3::Client; + /// use minio::s3::MinioClient; /// use minio::s3::response::UploadPartResponse; /// use minio::s3::types::S3Api; /// use minio::s3::segmented_bytes::SegmentedBytes; @@ -187,11 +199,11 @@ impl Client { /// /// #[tokio::main] /// async fn main() { - /// let client: Client = Default::default(); + /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here /// let data = SegmentedBytes::from("Some part data".to_string()); /// let resp: UploadPartResponse = client /// .upload_part("bucket-name", "object-name", "upload-id", 1, data) - /// .send().await.unwrap(); + /// .build().send().await.unwrap(); /// println!("Uploaded object: {}", resp.object()); /// } /// ``` @@ -202,15 +214,14 @@ impl Client { upload_id: S3, part_number: u16, data: SegmentedBytes, - ) -> UploadPart { - UploadPart::new( - self.clone(), - bucket.into(), - object.into(), - upload_id.into(), - part_number, - data, - ) + ) -> UploadPartBldr { + UploadPart::builder() + .client(self.clone()) + .bucket(bucket) + .object(object) + .upload_id(upload_id.into()) + .part_number(part_number) + .data(Arc::new(data)) } /// Creates a [`PutObjectContent`] request builder to upload data to MinIO/S3, automatically handling multipart uploads for large content. @@ -223,18 +234,18 @@ impl Client { /// /// # Example /// ```no_run - /// use minio::s3::Client; + /// use minio::s3::MinioClient; /// use minio::s3::response::PutObjectContentResponse; /// use minio::s3::types::S3Api; /// use minio::s3::response::a_response_traits::{HasObject, HasEtagFromHeaders}; /// /// #[tokio::main] /// async fn main() { - /// let client: Client = Default::default(); + /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here /// let content = "Hello, world!".to_string(); /// let resp: PutObjectContentResponse = client /// .put_object_content("bucket", "object", content) - /// .send().await.unwrap(); + /// .build().send().await.unwrap(); /// println!("Uploaded object '{}' with ETag '{:?}'", resp.object(), resp.etag()); /// } /// ``` @@ -243,7 +254,11 @@ impl Client { bucket: S1, object: S2, content: C, - ) -> PutObjectContent { - PutObjectContent::new(self.clone(), bucket.into(), object.into(), content) + ) -> PutObjectContentBldr { + PutObjectContent::builder() + .client(self.clone()) + .bucket(bucket) + .object(object) + .input_content(content) } } diff --git a/src/s3/client/put_object_legal_hold.rs b/src/s3/client/put_object_legal_hold.rs index 22be7a0c..cdace50f 100644 --- a/src/s3/client/put_object_legal_hold.rs +++ b/src/s3/client/put_object_legal_hold.rs @@ -13,10 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::Client; -use crate::s3::builders::PutObjectLegalHold; +use crate::s3::builders::{PutObjectLegalHold, PutObjectLegalHoldBldr}; +use crate::s3::client::MinioClient; -impl Client { +impl MinioClient { /// Creates a [`PutObjectLegalHold`] request builder. /// /// To execute the request, call [`DisableObjectLegalHold::send()`](crate::s3::types::S3Api::send), @@ -27,17 +27,17 @@ impl Client { /// # Example /// /// ```no_run - /// use minio::s3::Client; + /// use minio::s3::MinioClient; /// use minio::s3::response::PutObjectLegalHoldResponse; /// use minio::s3::types::S3Api; /// use minio::s3::response::a_response_traits::HasBucket; /// /// #[tokio::main] /// async fn main() { - /// let client: Client = Default::default(); // configure your client here + /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here /// let resp: PutObjectLegalHoldResponse = client /// .put_object_legal_hold("bucket-name", "object-name", true) - /// .send().await.unwrap(); + /// .build().send().await.unwrap(); /// println!("legal hold of bucket '{}' is enabled", resp.bucket()); /// } /// ``` @@ -46,8 +46,11 @@ impl Client { bucket: S1, object: S2, legal_hold: bool, - ) -> PutObjectLegalHold { - PutObjectLegalHold::new(self.clone(), bucket.into(), object.into()) - .legal_hold(Some(legal_hold)) + ) -> PutObjectLegalHoldBldr { + PutObjectLegalHold::builder() + .client(self.clone()) + .bucket(bucket) + .object(object) + .legal_hold(legal_hold) } } diff --git a/src/s3/client/put_object_lock_config.rs b/src/s3/client/put_object_lock_config.rs index e8597f00..f916efe5 100644 --- a/src/s3/client/put_object_lock_config.rs +++ b/src/s3/client/put_object_lock_config.rs @@ -13,10 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::Client; -use crate::s3::builders::PutObjectLockConfig; +use crate::s3::builders::{PutObjectLockConfig, PutObjectLockConfigBldr}; +use crate::s3::client::MinioClient; -impl Client { +impl MinioClient { /// Creates a [`PutObjectLockConfig`] request builder. /// /// To execute the request, call [`SetObjectLockConfig::send()`](crate::s3::types::S3Api::send), @@ -27,29 +27,33 @@ impl Client { /// # Example /// /// ```no_run - /// use minio::s3::Client; + /// use minio::s3::MinioClient; /// use minio::s3::response::{CreateBucketResponse, PutObjectLockConfigResponse}; /// use minio::s3::types::{S3Api, ObjectLockConfig, RetentionMode}; /// use minio::s3::response::a_response_traits::HasBucket; /// /// #[tokio::main] /// async fn main() { - /// let client: Client = Default::default(); // configure your client here + /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here /// let bucket_name = "bucket-name"; /// - /// let resp: CreateBucketResponse = - /// client.create_bucket(bucket_name).object_lock(true).send().await.unwrap(); + /// let resp: CreateBucketResponse = client + /// .create_bucket(bucket_name).object_lock(true) + /// .build().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: PutObjectLockConfigResponse = - /// client.put_object_lock_config(bucket_name).config(config).send().await.unwrap(); + /// let resp: PutObjectLockConfigResponse = client + /// .put_object_lock_config(bucket_name).config(config) + /// .build().send().await.unwrap(); /// println!("configured object locking for bucket '{}'", resp.bucket()); /// } /// ``` - pub fn put_object_lock_config>(&self, bucket: S) -> PutObjectLockConfig { - PutObjectLockConfig::new(self.clone(), bucket.into()) + pub fn put_object_lock_config>(&self, bucket: S) -> PutObjectLockConfigBldr { + PutObjectLockConfig::builder() + .client(self.clone()) + .bucket(bucket) } } diff --git a/src/s3/client/put_object_retention.rs b/src/s3/client/put_object_retention.rs index e97b3c58..09779e77 100644 --- a/src/s3/client/put_object_retention.rs +++ b/src/s3/client/put_object_retention.rs @@ -13,10 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::Client; -use crate::s3::builders::PutObjectRetention; +use crate::s3::builders::{PutObjectRetention, PutObjectRetentionBldr}; +use crate::s3::client::MinioClient; -impl Client { +impl MinioClient { /// Creates a [`PutObjectRetention`] request builder. /// /// To execute the request, call [`SetObjectRetention::send()`](crate::s3::types::S3Api::send), @@ -27,7 +27,7 @@ impl Client { /// # Example /// /// ```no_run - /// use minio::s3::Client; + /// use minio::s3::MinioClient; /// use minio::s3::response::PutObjectRetentionResponse; /// use minio::s3::builders::ObjectToDelete; /// use minio::s3::types::{S3Api, RetentionMode}; @@ -36,13 +36,13 @@ impl Client { /// /// #[tokio::main] /// async fn main() { - /// let client: Client = Default::default(); // configure your client here + /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here /// let retain_until_date = utc_now() + chrono::Duration::days(1); /// let resp: PutObjectRetentionResponse = client /// .put_object_retention("bucket-name", "object-name") /// .retention_mode(Some(RetentionMode::GOVERNANCE)) /// .retain_until_date(Some(retain_until_date)) - /// .send().await.unwrap(); + /// .build().send().await.unwrap(); /// println!("set the object retention for object '{}'", resp.object()); /// } /// ``` @@ -50,7 +50,10 @@ impl Client { &self, bucket: S1, object: S2, - ) -> PutObjectRetention { - PutObjectRetention::new(self.clone(), bucket.into(), object.into()) + ) -> PutObjectRetentionBldr { + PutObjectRetention::builder() + .client(self.clone()) + .bucket(bucket) + .object(object) } } diff --git a/src/s3/client/put_object_tagging.rs b/src/s3/client/put_object_tagging.rs index 3189ef50..a1cd74e3 100644 --- a/src/s3/client/put_object_tagging.rs +++ b/src/s3/client/put_object_tagging.rs @@ -13,10 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::Client; -use crate::s3::builders::PutObjectTagging; +use crate::s3::builders::{PutObjectTagging, PutObjectTaggingBldr}; +use crate::s3::client::MinioClient; -impl Client { +impl MinioClient { /// Creates a [`PutObjectTagging`] request builder. /// /// To execute the request, call [`SetObjectTags::send()`](crate::s3::types::S3Api::send), @@ -28,14 +28,14 @@ impl Client { /// /// ```no_run /// use std::collections::HashMap; - /// use minio::s3::Client; + /// use minio::s3::MinioClient; /// use minio::s3::response::PutObjectTaggingResponse; /// use minio::s3::types::S3Api; /// use minio::s3::response::a_response_traits::HasObject; /// /// #[tokio::main] /// async fn main() { - /// let client: Client = Default::default(); // configure your client here + /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here /// let tags = HashMap::from([ /// (String::from("Project"), String::from("Project One")), /// (String::from("User"), String::from("jsmith")), @@ -43,11 +43,18 @@ impl Client { /// let resp: PutObjectTaggingResponse = client /// .put_object_tagging("bucket-name", "object-name") /// .tags(tags) - /// .send().await.unwrap(); + /// .build().send().await.unwrap(); /// println!("set the object tags for object '{}'", resp.object()); /// } /// ``` - pub fn put_object_tagging>(&self, bucket: S, object: S) -> PutObjectTagging { - PutObjectTagging::new(self.clone(), bucket.into(), object.into()) + pub fn put_object_tagging>( + &self, + bucket: S, + object: S, + ) -> PutObjectTaggingBldr { + PutObjectTagging::builder() + .client(self.clone()) + .bucket(bucket) + .object(object) } } diff --git a/src/s3/client/select_object_content.rs b/src/s3/client/select_object_content.rs index 6492ab11..6f114c0c 100644 --- a/src/s3/client/select_object_content.rs +++ b/src/s3/client/select_object_content.rs @@ -13,11 +13,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::Client; -use crate::s3::builders::SelectObjectContent; +use crate::s3::builders::{SelectObjectContent, SelectObjectContentBldr}; +use crate::s3::client::MinioClient; use crate::s3::types::SelectRequest; -impl Client { +impl MinioClient { /// Creates a [`SelectObjectContent`] request builder. /// /// To execute the request, call [`SelectObjectContent::send()`](crate::s3::types::S3Api::send), @@ -28,15 +28,14 @@ impl Client { /// # Example /// /// ```no_run - /// use minio::s3::Client; + /// use minio::s3::MinioClient; /// use minio::s3::response::SelectObjectContentResponse; /// use minio::s3::types::S3Api; - /// /// use minio::s3::types::{SelectRequest, CsvInputSerialization, CsvOutputSerialization, FileHeaderInfo, QuoteFields}; /// /// #[tokio::main] /// async fn main() { - /// let client: Client = Default::default(); // configure your client here + /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here /// let request = SelectRequest::new_csv_input_output( /// "select * from S3Object", /// CsvInputSerialization { @@ -60,7 +59,7 @@ impl Client { /// /// let resp: SelectObjectContentResponse = client /// .select_object_content("bucket-name", "object-name", request) - /// .send().await.unwrap(); + /// .build().send().await.unwrap(); /// println!("the progress: '{:?}'", resp.progress); /// } /// ``` @@ -69,7 +68,11 @@ impl Client { bucket: S1, object: S2, request: SelectRequest, - ) -> SelectObjectContent { - SelectObjectContent::new(self.clone(), bucket.into(), object.into()).request(request) + ) -> SelectObjectContentBldr { + SelectObjectContent::builder() + .client(self.clone()) + .bucket(bucket) + .object(object) + .request(request) } } diff --git a/src/s3/client/stat_object.rs b/src/s3/client/stat_object.rs index 0575eec3..92b29864 100644 --- a/src/s3/client/stat_object.rs +++ b/src/s3/client/stat_object.rs @@ -13,10 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::Client; -use crate::s3::builders::StatObject; +use crate::s3::builders::{StatObject, StatObjectBldr}; +use crate::s3::client::MinioClient; -impl Client { +impl MinioClient { /// Creates a [`StatObject`] request builder. Given a bucket and object name, return some statistics. /// /// To execute the request, call [`StatObject::send()`](crate::s3::types::S3Api::send), @@ -25,16 +25,16 @@ impl Client { /// # Example /// /// ```no_run - /// use minio::s3::Client; + /// use minio::s3::MinioClient; /// use minio::s3::response::StatObjectResponse; /// use minio::s3::types::S3Api; /// use minio::s3::response::a_response_traits::HasObject; /// /// #[tokio::main] /// async fn main() { - /// let client: Client = Default::default(); // configure your client here + /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here /// let resp: StatObjectResponse = - /// client.stat_object("bucket-name", "object-name").send().await.unwrap(); + /// client.stat_object("bucket-name", "object-name").build().send().await.unwrap(); /// println!("stat of object '{}' are {:#?}", resp.object(), resp); /// } /// ``` @@ -42,7 +42,10 @@ impl Client { &self, bucket: S1, object: S2, - ) -> StatObject { - StatObject::new(self.clone(), bucket.into(), object.into()) + ) -> StatObjectBldr { + StatObject::builder() + .client(self.clone()) + .bucket(bucket) + .object(object) } } diff --git a/src/s3/creds.rs b/src/s3/creds.rs index c194d201..65b9cb5e 100644 --- a/src/s3/creds.rs +++ b/src/s3/creds.rs @@ -15,7 +15,7 @@ //! Credential providers -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug)] /// Credentials contain access key, secret key and session token optionally pub struct Credentials { pub access_key: String, diff --git a/src/s3/http.rs b/src/s3/http.rs index 75c2b740..c884d43c 100644 --- a/src/s3/http.rs +++ b/src/s3/http.rs @@ -13,11 +13,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! HTTP URL definitions - use super::utils::urlencode_object_key; use crate::s3::client::DEFAULT_REGION; - use crate::s3::error::ValidationErr; use crate::s3::multimap_ext::{Multimap, MultimapExt}; use crate::s3::utils::match_hostname; @@ -80,7 +77,7 @@ impl fmt::Display for Url { } if self.port > 0 { - f.write_str(format!("{}:{}", self.host, self.port).as_str())?; + f.write_str(&format!("{}:{}", self.host, self.port))?; } else { f.write_str(&self.host)?; } diff --git a/src/s3/minio_error_response.rs b/src/s3/minio_error_response.rs index 030fb028..318f0b32 100644 --- a/src/s3/minio_error_response.rs +++ b/src/s3/minio_error_response.rs @@ -219,7 +219,7 @@ mod test_error_code { /// MinioErrorResponse Is the typed error returned by all API operations. /// equivalent of ErrorResponse in the minio-go SDK -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug)] pub struct MinioErrorResponse { code: MinioErrorCode, message: Option, diff --git a/src/s3/mod.rs b/src/s3/mod.rs index 91f99664..759c4c2b 100644 --- a/src/s3/mod.rs +++ b/src/s3/mod.rs @@ -32,4 +32,4 @@ pub mod sse; pub mod types; pub mod utils; -pub use client::{Client, ClientBuilder}; +pub use client::{MinioClient, MinioClientBuilder}; diff --git a/src/s3/response/bucket_exists.rs b/src/s3/response/bucket_exists.rs index b1065343..772023d5 100644 --- a/src/s3/response/bucket_exists.rs +++ b/src/s3/response/bucket_exists.rs @@ -24,7 +24,7 @@ use bytes::Bytes; use http::HeaderMap; use std::mem; -/// Represents the response of the [bucket_exists()](crate::s3::client::Client::bucket_exists) API call. +/// Represents the response of the [bucket_exists()](crate::s3::client::MinioClient::bucket_exists) API call. /// This struct contains metadata and information about the existence of a bucket. #[derive(Clone, Debug)] pub struct BucketExistsResponse { diff --git a/src/s3/response/copy_object.rs b/src/s3/response/copy_object.rs index aaf565d3..d48bf958 100644 --- a/src/s3/response/copy_object.rs +++ b/src/s3/response/copy_object.rs @@ -47,10 +47,10 @@ pub type UploadPartCopyResponse = S3Response2; /// Internal response type for copy operations pub type CopyObjectInternalResponse = S3Response2; -/// Represents the response of the [copy_object()](crate::s3::client::Client::copy_object) API call. +/// Represents the response of the [copy_object()](crate::s3::client::MinioClient::copy_object) API call. /// This struct contains metadata and information about the object being copied. pub type CopyObjectResponse = S3Response2; -/// Represents the response of the [compose_object()](crate::s3::client::Client::compose_object) API call. +/// Represents the response of the [compose_object()](crate::s3::client::MinioClient::compose_object) API call. /// This struct contains metadata and information about the composed object. pub type ComposeObjectResponse = S3Response2; diff --git a/src/s3/response/create_bucket.rs b/src/s3/response/create_bucket.rs index af7d1f03..2b608e94 100644 --- a/src/s3/response/create_bucket.rs +++ b/src/s3/response/create_bucket.rs @@ -23,7 +23,7 @@ use http::HeaderMap; use std::mem; /// Response of -/// [create_bucket()](crate::s3::client::Client::create_bucket) +/// [create_bucket()](crate::s3::client::MinioClient::create_bucket) /// API #[derive(Clone, Debug)] pub struct CreateBucketResponse { diff --git a/src/s3/response/delete_bucket.rs b/src/s3/response/delete_bucket.rs index 8b5d23e3..d531deaa 100644 --- a/src/s3/response/delete_bucket.rs +++ b/src/s3/response/delete_bucket.rs @@ -23,7 +23,7 @@ use http::HeaderMap; use std::mem; /// Response of -/// [delete_bucket()](crate::s3::client::Client::delete_bucket) +/// [delete_bucket()](crate::s3::client::MinioClient::delete_bucket) /// API #[derive(Clone, Debug)] pub struct DeleteBucketResponse { diff --git a/src/s3/response/delete_bucket_encryption.rs b/src/s3/response/delete_bucket_encryption.rs index fe4864f5..baefbd18 100644 --- a/src/s3/response/delete_bucket_encryption.rs +++ b/src/s3/response/delete_bucket_encryption.rs @@ -21,7 +21,7 @@ use bytes::Bytes; use http::HeaderMap; use std::mem; -/// Represents the response of the [delete_bucket_encryption()](crate::s3::client::Client::delete_bucket_encryption) API call. +/// Represents the response of the [delete_bucket_encryption()](crate::s3::client::MinioClient::delete_bucket_encryption) API call. /// This struct contains metadata and information about the bucket whose encryption configuration was removed. #[derive(Clone, Debug)] pub struct DeleteBucketEncryptionResponse { diff --git a/src/s3/response/delete_bucket_lifecycle.rs b/src/s3/response/delete_bucket_lifecycle.rs index 9a1ba1c8..a9de150c 100644 --- a/src/s3/response/delete_bucket_lifecycle.rs +++ b/src/s3/response/delete_bucket_lifecycle.rs @@ -21,7 +21,7 @@ use bytes::Bytes; use http::HeaderMap; use std::mem; -/// Represents the response of the [delete_bucket_lifecycle()](crate::s3::client::Client::delete_bucket_lifecycle) API call. +/// Represents the response of the [delete_bucket_lifecycle()](crate::s3::client::MinioClient::delete_bucket_lifecycle) API call. /// This struct contains metadata and information about the bucket whose lifecycle configuration was removed. #[derive(Clone, Debug)] pub struct DeleteBucketLifecycleResponse { diff --git a/src/s3/response/delete_bucket_notification.rs b/src/s3/response/delete_bucket_notification.rs index b3270126..7272d542 100644 --- a/src/s3/response/delete_bucket_notification.rs +++ b/src/s3/response/delete_bucket_notification.rs @@ -21,7 +21,7 @@ use bytes::Bytes; use http::HeaderMap; use std::mem; -/// Represents the response of the [delete_bucket_notification()](crate::s3::client::Client::delete_bucket_notification) API call. +/// Represents the response of the [delete_bucket_notification()](crate::s3::client::MinioClient::delete_bucket_notification) API call. /// This struct contains metadata and information about the bucket whose notifications were removed. #[derive(Clone, Debug)] pub struct DeleteBucketNotificationResponse { diff --git a/src/s3/response/delete_bucket_policy.rs b/src/s3/response/delete_bucket_policy.rs index cc2b8931..9e6cdcc4 100644 --- a/src/s3/response/delete_bucket_policy.rs +++ b/src/s3/response/delete_bucket_policy.rs @@ -23,7 +23,7 @@ use bytes::Bytes; use http::HeaderMap; use std::mem; -/// Represents the response of the [delete_bucket_policy()](crate::s3::client::Client::delete_bucket_policy) API call. +/// Represents the response of the [delete_bucket_policy()](crate::s3::client::MinioClient::delete_bucket_policy) API call. /// This struct contains metadata and information about the bucket whose policy was removed. #[derive(Clone, Debug)] pub struct DeleteBucketPolicyResponse { diff --git a/src/s3/response/delete_bucket_replication.rs b/src/s3/response/delete_bucket_replication.rs index 3bc34ee6..19a02a98 100644 --- a/src/s3/response/delete_bucket_replication.rs +++ b/src/s3/response/delete_bucket_replication.rs @@ -23,7 +23,7 @@ use bytes::Bytes; use http::HeaderMap; use std::mem; -/// Represents the response of the `[delete_bucket_replication()](crate::s3::client::Client::delete_bucket_replication) API call. +/// Represents the response of the `[delete_bucket_replication()](crate::s3::client::MinioClient::delete_bucket_replication) API call. /// This struct contains metadata and information about the bucket whose replication configuration was removed. #[derive(Clone, Debug)] pub struct DeleteBucketReplicationResponse { diff --git a/src/s3/response/delete_bucket_tagging.rs b/src/s3/response/delete_bucket_tagging.rs index cb900882..9f9bd686 100644 --- a/src/s3/response/delete_bucket_tagging.rs +++ b/src/s3/response/delete_bucket_tagging.rs @@ -21,7 +21,7 @@ use bytes::Bytes; use http::HeaderMap; use std::mem; -/// Represents the response of the [delete_bucket_tagging()](crate::s3::client::Client::delete_bucket_tagging) API call. +/// Represents the response of the [delete_bucket_tagging()](crate::s3::client::MinioClient::delete_bucket_tagging) API call. /// This struct contains metadata and information about the bucket whose tags were removed. #[derive(Clone, Debug)] pub struct DeleteBucketTaggingResponse { diff --git a/src/s3/response/delete_object.rs b/src/s3/response/delete_object.rs index bbf20269..58661510 100644 --- a/src/s3/response/delete_object.rs +++ b/src/s3/response/delete_object.rs @@ -84,9 +84,9 @@ impl DeleteResult { } /// Response of -/// [delete_objects()](crate::s3::client::Client::delete_objects) +/// [delete_objects()](crate::s3::client::MinioClient::delete_objects) /// S3 API. It is also returned by the -/// [remove_objects()](crate::s3::client::Client::delete_objects_streaming) API in the +/// [remove_objects()](crate::s3::client::MinioClient::delete_objects_streaming) API in the /// form of a stream. #[derive(Clone, Debug)] pub struct DeleteObjectsResponse { diff --git a/src/s3/response/delete_object_lock_config.rs b/src/s3/response/delete_object_lock_config.rs index 75cfa473..75a2b6b2 100644 --- a/src/s3/response/delete_object_lock_config.rs +++ b/src/s3/response/delete_object_lock_config.rs @@ -21,7 +21,7 @@ use bytes::Bytes; use http::HeaderMap; use std::mem; -/// Response from the [`delete_object_lock_config`](crate::s3::client::Client::delete_object_lock_config) API call, +/// Response from the [`delete_object_lock_config`](crate::s3::client::MinioClient::delete_object_lock_config) API call, /// indicating that the Object Lock configuration has been successfully removed from the specified S3 bucket. /// /// Removing the Object Lock configuration disables the default retention settings for new objects added to the bucket. diff --git a/src/s3/response/delete_object_tagging.rs b/src/s3/response/delete_object_tagging.rs index 4f6407a8..baabbcaf 100644 --- a/src/s3/response/delete_object_tagging.rs +++ b/src/s3/response/delete_object_tagging.rs @@ -23,7 +23,7 @@ use bytes::Bytes; use http::HeaderMap; use std::mem; -/// Response from the [`delete_object_tagging`](crate::s3::client::Client::delete_object_tagging) API call, +/// Response from the [`delete_object_tagging`](crate::s3::client::MinioClient::delete_object_tagging) API call, /// indicating that all tags have been successfully removed from a specific object (or object version) in an S3 bucket. /// /// This operation deletes the entire tag set associated with the specified object. If the bucket is versioning-enabled, diff --git a/src/s3/response/get_bucket_encryption.rs b/src/s3/response/get_bucket_encryption.rs index dcda29a1..9fdc88f2 100644 --- a/src/s3/response/get_bucket_encryption.rs +++ b/src/s3/response/get_bucket_encryption.rs @@ -25,7 +25,7 @@ use http::HeaderMap; use std::mem; use xmltree::Element; -/// Response from the [`get_bucket_encryption`](crate::s3::client::Client::get_bucket_encryption) API call, +/// Response from the [`get_bucket_encryption`](crate::s3::client::MinioClient::get_bucket_encryption) API call, /// providing the default server-side encryption configuration of an S3 bucket. /// /// This configuration determines how Amazon S3 encrypts objects stored in the bucket by default. diff --git a/src/s3/response/get_bucket_lifecycle.rs b/src/s3/response/get_bucket_lifecycle.rs index 03df0998..e402e75e 100644 --- a/src/s3/response/get_bucket_lifecycle.rs +++ b/src/s3/response/get_bucket_lifecycle.rs @@ -24,7 +24,7 @@ use http::HeaderMap; use std::mem; use xmltree::Element; -/// Response from the [`get_bucket_lifecycle`](crate::s3::client::Client::get_bucket_lifecycle) API call, +/// Response from the [`get_bucket_lifecycle`](crate::s3::client::MinioClient::get_bucket_lifecycle) API call, /// providing the lifecycle configuration of an S3 bucket. /// /// The lifecycle configuration defines rules for managing the lifecycle of objects in the bucket, diff --git a/src/s3/response/get_bucket_notification.rs b/src/s3/response/get_bucket_notification.rs index 840efa84..e8d355e0 100644 --- a/src/s3/response/get_bucket_notification.rs +++ b/src/s3/response/get_bucket_notification.rs @@ -22,7 +22,7 @@ use http::HeaderMap; use std::mem; use xmltree::Element; -/// Response from the [`get_bucket_notification`](crate::s3::client::Client::get_bucket_notification) API call, +/// Response from the [`get_bucket_notification`](crate::s3::client::MinioClient::get_bucket_notification) API call, /// providing the notification configuration of an S3 bucket. /// /// This configuration specifies the events for which Amazon S3 sends notifications and the destinations diff --git a/src/s3/response/get_bucket_policy.rs b/src/s3/response/get_bucket_policy.rs index d8cf7973..c769415c 100644 --- a/src/s3/response/get_bucket_policy.rs +++ b/src/s3/response/get_bucket_policy.rs @@ -23,7 +23,7 @@ use bytes::Bytes; use http::HeaderMap; use std::mem; -/// Response from the [`get_bucket_policy`](crate::s3::client::Client::get_bucket_policy) API call, +/// Response from the [`get_bucket_policy`](crate::s3::client::MinioClient::get_bucket_policy) API call, /// providing the bucket policy associated with an S3 bucket. /// /// The bucket policy is a JSON-formatted string that defines permissions for the bucket, diff --git a/src/s3/response/get_bucket_replication.rs b/src/s3/response/get_bucket_replication.rs index 324bb171..5770bfe4 100644 --- a/src/s3/response/get_bucket_replication.rs +++ b/src/s3/response/get_bucket_replication.rs @@ -22,7 +22,7 @@ use http::HeaderMap; use std::mem; use xmltree::Element; -/// Response from the [`get_bucket_replication`](crate::s3::client::Client::get_bucket_replication) API call, +/// Response from the [`get_bucket_replication`](crate::s3::client::MinioClient::get_bucket_replication) API call, /// providing the replication configuration of an S3 bucket. /// /// This includes the rules and settings that define how objects in the bucket are replicated to other buckets. diff --git a/src/s3/response/get_bucket_tagging.rs b/src/s3/response/get_bucket_tagging.rs index 500d3613..25a8437f 100644 --- a/src/s3/response/get_bucket_tagging.rs +++ b/src/s3/response/get_bucket_tagging.rs @@ -23,7 +23,7 @@ use bytes::Bytes; use http::HeaderMap; use std::mem; -/// Response from the [`get_bucket_tagging`](crate::s3::client::Client::get_bucket_tagging) API call, +/// Response from the [`get_bucket_tagging`](crate::s3::client::MinioClient::get_bucket_tagging) API call, /// providing the set of tags associated with an S3 bucket. /// /// Tags are key-value pairs that help organize and manage resources, diff --git a/src/s3/response/get_bucket_versioning.rs b/src/s3/response/get_bucket_versioning.rs index 62ad5883..c2199915 100644 --- a/src/s3/response/get_bucket_versioning.rs +++ b/src/s3/response/get_bucket_versioning.rs @@ -24,7 +24,7 @@ use http::HeaderMap; use std::mem; use xmltree::Element; -/// Response from the [`get_bucket_versioning`](crate::s3::client::Client::get_bucket_versioning) API call, +/// Response from the [`get_bucket_versioning`](crate::s3::client::MinioClient::get_bucket_versioning) API call, /// providing the versioning configuration of a bucket. /// /// This includes the current versioning status and the MFA (Multi-Factor Authentication) delete setting, diff --git a/src/s3/response/get_object_legal_hold.rs b/src/s3/response/get_object_legal_hold.rs index e2f68913..ae626f56 100644 --- a/src/s3/response/get_object_legal_hold.rs +++ b/src/s3/response/get_object_legal_hold.rs @@ -26,7 +26,7 @@ use std::mem; use xmltree::Element; /// Response of -/// [get_object_legal_hold()](crate::s3::client::Client::get_object_legal_hold) +/// [get_object_legal_hold()](crate::s3::client::MinioClient::get_object_legal_hold) /// API #[derive(Clone, Debug)] pub struct GetObjectLegalHoldResponse { diff --git a/src/s3/response/get_object_lock_config.rs b/src/s3/response/get_object_lock_config.rs index fa5cadb6..ec215b92 100644 --- a/src/s3/response/get_object_lock_config.rs +++ b/src/s3/response/get_object_lock_config.rs @@ -22,7 +22,7 @@ use http::HeaderMap; use std::mem; use xmltree::Element; -/// Response from the [`get_object_lock_config`](crate::s3::client::Client::get_object_lock_config) API call, +/// Response from the [`get_object_lock_config`](crate::s3::client::MinioClient::get_object_lock_config) API call, /// which retrieves the Object Lock configuration of a bucket. /// /// This configuration determines the default retention mode and period applied to new objects, diff --git a/src/s3/response/get_object_retention.rs b/src/s3/response/get_object_retention.rs index 5cbe4177..ee00d68c 100644 --- a/src/s3/response/get_object_retention.rs +++ b/src/s3/response/get_object_retention.rs @@ -27,7 +27,7 @@ use http::HeaderMap; use std::mem; use xmltree::Element; -/// Response of [get_object_retention()](crate::s3::client::Client::get_object_retention) API +/// Response of [get_object_retention()](crate::s3::client::MinioClient::get_object_retention) API #[derive(Clone, Debug)] pub struct GetObjectRetentionResponse { request: S3Request, diff --git a/src/s3/response/get_object_tagging.rs b/src/s3/response/get_object_tagging.rs index a71124bf..b0647ac6 100644 --- a/src/s3/response/get_object_tagging.rs +++ b/src/s3/response/get_object_tagging.rs @@ -24,7 +24,7 @@ use http::HeaderMap; use std::mem; /// Response of -/// [get_object_tags()](crate::s3::client::Client::get_object_tagging) +/// [get_object_tags()](crate::s3::client::MinioClient::get_object_tagging) /// API #[derive(Clone, Debug)] pub struct GetObjectTaggingResponse { diff --git a/src/s3/response/get_presigned_object_url.rs b/src/s3/response/get_presigned_object_url.rs index 40fa6332..477791b5 100644 --- a/src/s3/response/get_presigned_object_url.rs +++ b/src/s3/response/get_presigned_object_url.rs @@ -1,5 +1,5 @@ #[derive(Clone, Debug)] -/// Response of [get_presigned_object_url()](crate::s3::client::Client::get_presigned_object_url) API +/// Response of [get_presigned_object_url()](crate::s3::client::MinioClient::get_presigned_object_url) API pub struct GetPresignedObjectUrlResponse { /// The AWS region where the bucket resides. pub region: String, diff --git a/src/s3/response/get_region.rs b/src/s3/response/get_region.rs index 033b53c1..4f7d2887 100644 --- a/src/s3/response/get_region.rs +++ b/src/s3/response/get_region.rs @@ -24,7 +24,7 @@ use std::mem; use xmltree::Element; /// Response of -/// [get_region()](crate::s3::client::Client::get_region) +/// [get_region()](crate::s3::client::MinioClient::get_region) /// API #[derive(Clone, Debug)] pub struct GetRegionResponse { diff --git a/src/s3/response/list_buckets.rs b/src/s3/response/list_buckets.rs index 04b92284..6c3ad1df 100644 --- a/src/s3/response/list_buckets.rs +++ b/src/s3/response/list_buckets.rs @@ -23,7 +23,7 @@ use http::HeaderMap; use std::mem; use xmltree::Element; -/// Response of [list_buckets()](crate::s3::client::Client::list_buckets) API +/// Response of [list_buckets()](crate::s3::client::MinioClient::list_buckets) API #[derive(Debug, Clone)] pub struct ListBucketsResponse { request: S3Request, diff --git a/src/s3/response/list_objects.rs b/src/s3/response/list_objects.rs index 899b1a3b..a9e3329e 100644 --- a/src/s3/response/list_objects.rs +++ b/src/s3/response/list_objects.rs @@ -181,7 +181,7 @@ fn parse_list_objects_common_prefixes( Ok(()) } -/// Response of [list_objects_v1()](crate::s3::client::Client::list_objects_v1) S3 API +/// Response of [list_objects_v1()](crate::s3::client::MinioClient::list_objects_v1) S3 API #[derive(Clone, Debug)] pub struct ListObjectsV1Response { request: S3Request, @@ -243,7 +243,7 @@ impl FromS3Response for ListObjectsV1Response { } } -/// Response of [list_objects_v2()](crate::s3::client::Client::list_objects_v2) S3 API +/// Response of [list_objects_v2()](crate::s3::client::MinioClient::list_objects_v2) S3 API #[derive(Clone, Debug)] pub struct ListObjectsV2Response { request: S3Request, @@ -312,7 +312,7 @@ impl FromS3Response for ListObjectsV2Response { } } -/// Response of [list_object_versions()](crate::s3::client::Client::list_object_versions) S3 API +/// Response of [list_object_versions()](crate::s3::client::MinioClient::list_object_versions) S3 API #[derive(Clone, Debug)] pub struct ListObjectVersionsResponse { request: S3Request, @@ -378,8 +378,8 @@ impl FromS3Response for ListObjectVersionsResponse { } } -/// Response of [list_objects()](crate::s3::client::Client::list_objects) API -#[derive(Clone, Debug, Default)] +/// Response of [list_objects()](crate::s3::client::MinioClient::list_objects) API +#[derive(Clone, Debug)] pub struct ListObjectsResponse { request: S3Request, headers: HeaderMap, @@ -430,7 +430,13 @@ impl From for ListObjectsResponse { next_key_marker: value.next_key_marker, version_id_marker: value.version_id_marker, next_version_id_marker: value.next_version_id_marker, - ..Default::default() + + marker: None, + next_marker: None, + key_count: None, + start_after: None, + continuation_token: None, + next_continuation_token: None, } } } @@ -453,7 +459,13 @@ impl From for ListObjectsResponse { start_after: value.start_after, continuation_token: value.continuation_token, next_continuation_token: value.next_continuation_token, - ..Default::default() + + marker: None, + next_marker: None, + key_marker: None, + next_key_marker: None, + version_id_marker: None, + next_version_id_marker: None, } } } @@ -474,7 +486,15 @@ impl From for ListObjectsResponse { contents: value.contents, marker: value.marker, next_marker: value.next_marker, - ..Default::default() + + key_count: None, + start_after: None, + continuation_token: None, + next_continuation_token: None, + key_marker: None, + next_key_marker: None, + version_id_marker: None, + next_version_id_marker: None, } } } diff --git a/src/s3/response/listen_bucket_notification.rs b/src/s3/response/listen_bucket_notification.rs index ee2e7786..a0dced79 100644 --- a/src/s3/response/listen_bucket_notification.rs +++ b/src/s3/response/listen_bucket_notification.rs @@ -24,7 +24,7 @@ use http::HeaderMap; use std::mem; /// Response of -/// [listen_bucket_notification()](crate::s3::client::Client::listen_bucket_notification) +/// [listen_bucket_notification()](crate::s3::client::MinioClient::listen_bucket_notification) /// API #[derive(Clone, Debug)] pub struct ListenBucketNotificationResponse { diff --git a/src/s3/response/put_bucket_encryption.rs b/src/s3/response/put_bucket_encryption.rs index e3a82423..fd038a6e 100644 --- a/src/s3/response/put_bucket_encryption.rs +++ b/src/s3/response/put_bucket_encryption.rs @@ -24,7 +24,7 @@ use std::mem; use xmltree::Element; /// Response of -/// [put_bucket_encryption()](crate::s3::client::Client::put_bucket_encryption) +/// [put_bucket_encryption()](crate::s3::client::MinioClient::put_bucket_encryption) /// API #[derive(Clone, Debug)] pub struct PutBucketEncryptionResponse { diff --git a/src/s3/response/put_bucket_lifecycle.rs b/src/s3/response/put_bucket_lifecycle.rs index 7f9de2ba..e72adc18 100644 --- a/src/s3/response/put_bucket_lifecycle.rs +++ b/src/s3/response/put_bucket_lifecycle.rs @@ -21,7 +21,7 @@ use bytes::Bytes; use http::HeaderMap; use std::mem; -/// Response of [put_bucket_lifecycle()](crate::s3::client::Client::put_bucket_lifecycle) API +/// Response of [put_bucket_lifecycle()](crate::s3::client::MinioClient::put_bucket_lifecycle) API #[derive(Clone, Debug)] pub struct PutBucketLifecycleResponse { request: S3Request, diff --git a/src/s3/response/put_bucket_notification.rs b/src/s3/response/put_bucket_notification.rs index 39f43256..cf403a71 100644 --- a/src/s3/response/put_bucket_notification.rs +++ b/src/s3/response/put_bucket_notification.rs @@ -21,7 +21,7 @@ use bytes::Bytes; use http::HeaderMap; use std::mem; -/// Response of [put_bucket_notification()](crate::s3::client::Client::put_bucket_notification) API +/// Response of [put_bucket_notification()](crate::s3::client::MinioClient::put_bucket_notification) API #[derive(Clone, Debug)] pub struct PutBucketNotificationResponse { request: S3Request, diff --git a/src/s3/response/put_bucket_policy.rs b/src/s3/response/put_bucket_policy.rs index 9909db8e..e396ff7c 100644 --- a/src/s3/response/put_bucket_policy.rs +++ b/src/s3/response/put_bucket_policy.rs @@ -21,7 +21,7 @@ use bytes::Bytes; use http::HeaderMap; use std::mem; -/// Response of [put_bucket_policy()](crate::s3::client::Client::put_bucket_policy) API +/// Response of [put_bucket_policy()](crate::s3::client::MinioClient::put_bucket_policy) API #[derive(Clone, Debug)] pub struct PutBucketPolicyResponse { request: S3Request, diff --git a/src/s3/response/put_bucket_replication.rs b/src/s3/response/put_bucket_replication.rs index 3c5e3fee..9cb22020 100644 --- a/src/s3/response/put_bucket_replication.rs +++ b/src/s3/response/put_bucket_replication.rs @@ -21,7 +21,7 @@ use bytes::Bytes; use http::HeaderMap; use std::mem; -/// Response of [put_bucket_replication()](crate::s3::client::Client::put_bucket_replication) API +/// Response of [put_bucket_replication()](crate::s3::client::MinioClient::put_bucket_replication) API #[derive(Clone, Debug)] pub struct PutBucketReplicationResponse { request: S3Request, diff --git a/src/s3/response/put_bucket_tagging.rs b/src/s3/response/put_bucket_tagging.rs index 327876e9..5155b402 100644 --- a/src/s3/response/put_bucket_tagging.rs +++ b/src/s3/response/put_bucket_tagging.rs @@ -22,7 +22,7 @@ use http::HeaderMap; use std::mem; /// Response of -/// [put_bucket_tagging()](crate::s3::client::Client::put_bucket_tagging) +/// [put_bucket_tagging()](crate::s3::client::MinioClient::put_bucket_tagging) /// API #[derive(Clone, Debug)] pub struct PutBucketTaggingResponse { diff --git a/src/s3/response/put_bucket_versioning.rs b/src/s3/response/put_bucket_versioning.rs index a9205ec4..7ce6a922 100644 --- a/src/s3/response/put_bucket_versioning.rs +++ b/src/s3/response/put_bucket_versioning.rs @@ -21,7 +21,7 @@ use bytes::Bytes; use http::HeaderMap; use std::mem; -/// Response of [put_bucket_versioning()](crate::s3::client::Client::put_bucket_versioning) API +/// Response of [put_bucket_versioning()](crate::s3::client::MinioClient::put_bucket_versioning) API #[derive(Clone, Debug)] pub struct PutBucketVersioningResponse { request: S3Request, diff --git a/src/s3/response/put_object.rs b/src/s3/response/put_object.rs index 53ab279b..ca47c95f 100644 --- a/src/s3/response/put_object.rs +++ b/src/s3/response/put_object.rs @@ -106,19 +106,19 @@ impl S3MultipartResponse { } } -/// Response of [put_object_api()](crate::s3::client::Client::put_object) API +/// Response of [put_object_api()](crate::s3::client::MinioClient::put_object) API pub type PutObjectResponse = S3Response1; -/// Response of [create_multipart_upload()](crate::s3::client::Client::create_multipart_upload) API +/// Response of [create_multipart_upload()](crate::s3::client::MinioClient::create_multipart_upload) API pub type CreateMultipartUploadResponse = S3MultipartResponse; -/// Response of [abort_multipart_upload()](crate::s3::client::Client::abort_multipart_upload) API +/// Response of [abort_multipart_upload()](crate::s3::client::MinioClient::abort_multipart_upload) API pub type AbortMultipartUploadResponse = S3MultipartResponse; -/// Response of [complete_multipart_upload()](crate::s3::client::Client::complete_multipart_upload) API +/// Response of [complete_multipart_upload()](crate::s3::client::MinioClient::complete_multipart_upload) API pub type CompleteMultipartUploadResponse = S3Response1; -/// Response of [upload_part()](crate::s3::client::Client::upload_part) API +/// Response of [upload_part()](crate::s3::client::MinioClient::upload_part) API pub type UploadPartResponse = S3Response1; /// Response for put_object operations that include object size information diff --git a/src/s3/response/put_object_legal_hold.rs b/src/s3/response/put_object_legal_hold.rs index a5ea4a68..67efd6e2 100644 --- a/src/s3/response/put_object_legal_hold.rs +++ b/src/s3/response/put_object_legal_hold.rs @@ -23,7 +23,7 @@ use bytes::Bytes; use http::HeaderMap; use std::mem; -/// Response from the [`put_object_legal_hold`](crate::s3::client::Client::put_object_legal_hold) API call, +/// Response from the [`put_object_legal_hold`](crate::s3::client::MinioClient::put_object_legal_hold) API call, /// indicating that a legal hold has been successfully removed from a specific object version in an S3 bucket. /// /// Removing a legal hold allows the specified object version to be deleted or overwritten, subject to the bucket's diff --git a/src/s3/response/put_object_lock_config.rs b/src/s3/response/put_object_lock_config.rs index 9309ea69..1a35d1fc 100644 --- a/src/s3/response/put_object_lock_config.rs +++ b/src/s3/response/put_object_lock_config.rs @@ -22,7 +22,7 @@ use http::HeaderMap; use std::mem; /// Response of -/// [put_object_lock_config()](crate::s3::client::Client::put_object_lock_config) +/// [put_object_lock_config()](crate::s3::client::MinioClient::put_object_lock_config) /// API #[derive(Clone, Debug)] pub struct PutObjectLockConfigResponse { diff --git a/src/s3/response/put_object_retention.rs b/src/s3/response/put_object_retention.rs index 763073b7..3c2fa00b 100644 --- a/src/s3/response/put_object_retention.rs +++ b/src/s3/response/put_object_retention.rs @@ -24,7 +24,7 @@ use http::HeaderMap; use std::mem; /// Response of -/// [put_object_retention()](crate::s3::client::Client::put_object_retention) +/// [put_object_retention()](crate::s3::client::MinioClient::put_object_retention) /// API #[derive(Clone, Debug)] pub struct PutObjectRetentionResponse { diff --git a/src/s3/response/put_object_tagging.rs b/src/s3/response/put_object_tagging.rs index 124f0fa1..3d4b32ba 100644 --- a/src/s3/response/put_object_tagging.rs +++ b/src/s3/response/put_object_tagging.rs @@ -24,7 +24,7 @@ use http::HeaderMap; use std::mem; /// Response of -/// [put_object_tagging()](crate::s3::client::Client::put_object_tagging) +/// [put_object_tagging()](crate::s3::client::MinioClient::put_object_tagging) /// API #[derive(Clone, Debug)] pub struct PutObjectTaggingResponse { diff --git a/src/s3/response/select_object_content.rs b/src/s3/response/select_object_content.rs index 956272d7..ffbccfa9 100644 --- a/src/s3/response/select_object_content.rs +++ b/src/s3/response/select_object_content.rs @@ -28,9 +28,9 @@ use std::mem; use xmltree::Element; /// Response of -/// [select_object_content()](crate::s3::client::Client::select_object_content) +/// [select_object_content()](crate::s3::client::MinioClient::select_object_content) /// API -/// Response of [select_object_content()](crate::s3::client::Client::select_object_content) API +/// Response of [select_object_content()](crate::s3::client::MinioClient::select_object_content) API #[derive(Debug)] pub struct SelectObjectContentResponse { request: S3Request, diff --git a/src/s3/response/stat_object.rs b/src/s3/response/stat_object.rs index 2889a1c7..83702de9 100644 --- a/src/s3/response/stat_object.rs +++ b/src/s3/response/stat_object.rs @@ -29,7 +29,7 @@ use std::collections::HashMap; use std::mem; #[derive(Clone, Debug)] -/// Response from the [`stat_object`](crate::s3::client::Client::stat_object) API call, +/// Response from the [`stat_object`](crate::s3::client::MinioClient::stat_object) API call, /// providing metadata about an object stored in S3 or a compatible service. pub struct StatObjectResponse { request: S3Request, diff --git a/src/s3/types.rs b/src/s3/types.rs index e3e65450..ab07f0c2 100644 --- a/src/s3/types.rs +++ b/src/s3/types.rs @@ -13,9 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Various types for S3 API requests and responses - -use super::client::{Client, DEFAULT_REGION}; +use super::client::{DEFAULT_REGION, MinioClient}; use crate::s3::error::{Error, ValidationErr}; use crate::s3::header_constants::*; use crate::s3::multimap_ext::Multimap; @@ -28,65 +26,42 @@ use serde::{Deserialize, Serialize}; use std::collections::HashMap; use std::fmt; use std::sync::Arc; +use typed_builder::TypedBuilder; use xmltree::Element; -#[derive(Clone, Default, Debug)] +#[derive(Clone, Debug, TypedBuilder)] /// Generic S3Request pub struct S3Request { - pub(crate) client: Client, + #[builder(!default)] // force required + pub(crate) client: MinioClient, + #[builder(!default)] // force required method: Method, + + #[builder(default, setter(into))] region: Option, + + #[builder(default, setter(into))] pub(crate) bucket: Option, + + #[builder(default, setter(into))] pub(crate) object: Option, + + #[builder(default)] pub(crate) query_params: Multimap, + + #[builder(default)] headers: Multimap, + + #[builder(default, setter(into))] body: Option>, /// region computed by [`S3Request::execute`] + #[builder(default, setter(skip))] pub(crate) inner_region: String, } impl S3Request { - pub fn new(client: Client, method: Method) -> Self { - Self { - client, - method, - ..Default::default() - } - } - - /// Sets the region for the request - pub fn region(mut self, region: Option) -> Self { - self.region = region; - self - } - - pub fn bucket(mut self, bucket: Option) -> Self { - self.bucket = bucket; - self - } - - pub fn object(mut self, object: Option) -> Self { - self.object = object; - self - } - - pub fn query_params(mut self, query_params: Multimap) -> Self { - self.query_params = query_params; - self - } - - pub fn headers(mut self, headers: Multimap) -> Self { - self.headers = headers; - self - } - - pub fn body(mut self, body: Option) -> Self { - self.body = body.map(Arc::new); - self - } - async fn compute_inner_region(&self) -> Result { Ok(match &self.bucket { Some(b) => self.client.get_region_cached(b, &self.region).await?, @@ -115,7 +90,7 @@ impl S3Request { /// /// This trait is implemented by all S3 request builders and serves as an /// intermediate step in the request execution pipeline. It enables the -/// conversion from a strongly-typed request builder into a generic +/// conversion from a strongly typed request builder into a generic /// [`S3Request`] that can be executed over HTTP. /// /// The [`S3Api::send`] method uses this trait to convert request builders @@ -134,7 +109,7 @@ pub trait ToS3Request: Sized { /// that can be executed against an S3-compatible service. The transformation /// includes: /// - /// * Setting appropriate HTTP method (GET, PUT, POST, etc.) + /// * Setting the appropriate HTTP method (GET, PUT, POST, etc.) /// * Building the request URL with path and query parameters /// * Adding required headers (authentication, content-type, etc.) /// * Attaching the request body, if applicable @@ -147,7 +122,7 @@ pub trait ToS3Request: Sized { fn to_s3request(self) -> Result; } -/// Trait for converting HTTP responses into strongly-typed S3 response objects. +/// Trait for converting HTTP responses into strongly typed S3 response objects. /// /// This trait is implemented by all S3 response types in the SDK and provides /// a way to parse and validate raw HTTP responses from S3-compatible services. @@ -161,7 +136,7 @@ pub trait ToS3Request: Sized { /// * [`ToS3Request`] - The counterpart trait for converting request builders into HTTP requests #[async_trait] pub trait FromS3Response: Sized { - /// Asynchronously converts an HTTP response into a strongly-typed S3 response. + /// Asynchronously converts an HTTP response into a strongly typed S3 response. /// /// This method takes both the original S3 request and the HTTP response (or error) /// that resulted from executing that request. It then parses the response data @@ -191,10 +166,10 @@ pub trait FromS3Response: Sized { /// Trait that defines a common interface for all S3 API request builders. /// /// This trait is implemented by all request builders in the SDK and provides -/// a consistent way to send requests and obtain typed responses. It works in +/// a consistent way to send requests and get typed responses. It works in /// conjunction with [`ToS3Request`] to convert the builder into a concrete /// HTTP request and with [`FromS3Response`] to convert the HTTP response back -/// into a strongly-typed S3 response object. +/// into a strongly typed S3 response object. /// /// # Type Parameters /// @@ -234,8 +209,8 @@ pub trait ToStream: Sized { async fn to_stream(self) -> Box> + Unpin + Send>; } -#[derive(Clone, Debug, Default)] -/// Contains information of an item of [list_objects()](crate::s3::client::Client::list_objects) API +#[derive(Clone, Debug)] +/// Contains information of an item of [list_objects()](crate::s3::client::MinioClient::list_objects) API pub struct ListEntry { pub name: String, pub last_modified: Option, @@ -254,7 +229,7 @@ pub struct ListEntry { } #[derive(Clone, Debug)] -/// Contains bucket name and creation date +/// Contains the bucket name and creation date pub struct Bucket { pub name: String, pub creation_date: UtcTime, @@ -310,7 +285,7 @@ pub struct Retention { pub retain_until_date: UtcTime, } -/// Parses legal hold string value +/// Parses 'legal hold' string value pub fn parse_legal_hold(s: &str) -> Result { if s.eq_ignore_ascii_case("ON") { Ok(true) @@ -389,7 +364,7 @@ impl fmt::Display for QuoteFields { } } -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug)] /// CSV input serialization definitions pub struct CsvInputSerialization { pub compression_type: Option, @@ -402,18 +377,18 @@ pub struct CsvInputSerialization { pub record_delimiter: Option, } -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug)] /// JSON input serialization definitions pub struct JsonInputSerialization { pub compression_type: Option, pub json_type: Option, } -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug)] /// Parquet input serialization definitions pub struct ParquetInputSerialization; -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug)] /// CSV output serialization definitions pub struct CsvOutputSerialization { pub field_delimiter: Option, @@ -423,14 +398,15 @@ pub struct CsvOutputSerialization { pub record_delimiter: Option, } -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug)] /// JSON output serialization definitions pub struct JsonOutputSerialization { pub record_delimiter: Option, } -#[derive(Clone, Debug, Default)] -/// Select request for [select_object_content()](crate::s3::client::Client::select_object_content) API +#[derive(Clone, Debug)] +/// Select request for [select_object_content()](crate::s3::client::MinioClient::select_object_content) API +#[derive(Default)] pub struct SelectRequest { pub expr: String, pub csv_input: Option, @@ -690,7 +666,7 @@ impl SelectRequest { } } -/// Progress information of [select_object_content()](crate::s3::client::Client::select_object_content) API +/// Progress information of [select_object_content()](crate::s3::client::MinioClient::select_object_content) API #[derive(Clone, Debug)] pub struct SelectProgress { pub bytes_scanned: usize, @@ -699,7 +675,7 @@ pub struct SelectProgress { } /// User identity contains principal ID -#[derive(Debug, Deserialize, Serialize, Clone, Default)] +#[derive(Debug, Deserialize, Serialize, Clone)] pub struct UserIdentity { #[serde(alias = "principalId", default)] pub principal_id: String, @@ -708,11 +684,11 @@ pub struct UserIdentity { /// Owner identity contains principal ID pub type OwnerIdentity = UserIdentity; -/// Request parameters contain principal ID, region and source IP address, but +/// Request parameters contain principal ID, region, and source IP address, but /// they are represented as a string-to-string map in the MinIO server. So we /// provide methods to fetch the known fields and a map for underlying /// representation. -#[derive(Debug, Deserialize, Serialize, Clone, Default)] +#[derive(Debug, Deserialize, Serialize, Clone)] pub struct RequestParameters(HashMap); impl RequestParameters { @@ -766,21 +742,21 @@ impl ResponseElements { } } -#[derive(Debug, Deserialize, Serialize, Clone, Default)] +#[derive(Debug, Deserialize, Serialize, Clone)] /// S3 bucket information pub struct S3Bucket { - #[serde(alias = "name", default)] + #[serde(alias = "name")] pub name: String, - #[serde(alias = "arn", default)] + #[serde(alias = "arn")] pub arn: String, - #[serde(alias = "ownerIdentity", default)] + #[serde(alias = "ownerIdentity")] pub owner_identity: OwnerIdentity, } -#[derive(Debug, Deserialize, Serialize, Clone, Default)] +#[derive(Debug, Deserialize, Serialize, Clone)] /// S3 object information pub struct S3Object { - #[serde(alias = "key", default)] + #[serde(alias = "key")] pub key: String, #[serde(alias = "size")] pub size: Option, @@ -796,16 +772,16 @@ pub struct S3Object { pub sequencer: String, } -#[derive(Debug, Deserialize, Serialize, Clone, Default)] +#[derive(Debug, Deserialize, Serialize, Clone)] /// S3 definitions for NotificationRecord pub struct S3 { - #[serde(alias = "s3SchemaVersion", default)] + #[serde(alias = "s3SchemaVersion")] pub s3_schema_version: String, - #[serde(alias = "configurationId", default)] + #[serde(alias = "configurationId")] pub configuration_id: String, - #[serde(alias = "bucket", default)] + #[serde(alias = "bucket")] pub bucket: S3Bucket, - #[serde(alias = "object", default)] + #[serde(alias = "object")] pub object: S3Object, } @@ -823,11 +799,11 @@ pub struct Source { /// Notification record information #[derive(Debug, Deserialize, Serialize, Clone)] pub struct NotificationRecord { - #[serde(alias = "eventVersion", default)] + #[serde(alias = "eventVersion")] pub event_version: String, - #[serde(alias = "eventSource", default)] + #[serde(alias = "eventSource")] pub event_source: String, - #[serde(alias = "awsRegion", default)] + #[serde(alias = "awsRegion")] pub aws_region: String, #[serde( alias = "eventTime", @@ -835,17 +811,17 @@ pub struct NotificationRecord { with = "crate::s3::utils::aws_date_format" )] pub event_time: UtcTime, - #[serde(alias = "eventName", default)] + #[serde(alias = "eventName")] pub event_name: String, - #[serde(alias = "userIdentity", default)] + #[serde(alias = "userIdentity")] pub user_identity: UserIdentity, - #[serde(alias = "requestParameters", default)] + #[serde(alias = "requestParameters")] pub request_parameters: Option, - #[serde(alias = "responseElements", default)] + #[serde(alias = "responseElements")] pub response_elements: ResponseElements, - #[serde(alias = "s3", default)] + #[serde(alias = "s3")] pub s3: S3, - #[serde(alias = "source", default)] + #[serde(alias = "source")] pub source: Source, } @@ -934,7 +910,7 @@ pub struct Tag { } #[derive(PartialEq, Clone, Debug)] -/// And operator contains prefix and tags +/// The 'And' operator contains prefix and tags pub struct AndOperator { pub prefix: Option, pub tags: Option>, @@ -955,7 +931,9 @@ impl Filter { prefix: match v.get_child("Prefix") { Some(p) => Some( p.get_text() - .ok_or(ValidationErr::xml_error("text of tag not found"))? + .ok_or(ValidationErr::xml_error( + "the text of -tag not found", + ))? .to_string(), ), None => None, @@ -983,7 +961,9 @@ impl Filter { let prefix = match element.get_child("Prefix") { Some(v) => Some( v.get_text() - .ok_or(ValidationErr::xml_error("text of tag not found"))? + .ok_or(ValidationErr::xml_error( + "the text of -tag not found", + ))? .to_string(), ), None => None, @@ -1071,7 +1051,9 @@ fn parse_common_notification_config( while let Some(v) = element.take_child("Event") { events.push( v.get_text() - .ok_or(ValidationErr::xml_error("text of tag not found"))? + .ok_or(ValidationErr::xml_error( + "the text of the -tag is not found", + ))? .to_string(), ); } @@ -1825,7 +1807,7 @@ impl ObjectLockConfig { } Err(ValidationErr::InvalidObjectLockConfig( - "only one days or years must be set".into(), + "only one field 'days' or 'years' must be set".into(), )) } diff --git a/src/s3/utils.rs b/src/s3/utils.rs index f9763ed4..4a802a3f 100644 --- a/src/s3/utils.rs +++ b/src/s3/utils.rs @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::s3::Client; +use crate::s3::MinioClient; use crate::s3::error::ValidationErr; use crate::s3::multimap_ext::Multimap; use crate::s3::segmented_bytes::SegmentedBytes; @@ -407,7 +407,7 @@ pub fn check_object_name(object_name: impl AsRef) -> Result<(), ValidationE } /// Validates SSE (Server-Side Encryption) settings. -pub fn check_sse(sse: &Option>, client: &Client) -> Result<(), ValidationErr> { +pub fn check_sse(sse: &Option>, client: &MinioClient) -> Result<(), ValidationErr> { if let Some(v) = &sse && v.tls_required() && !client.is_secure() @@ -418,7 +418,10 @@ pub fn check_sse(sse: &Option>, client: &Client) -> Result<(), Vali } /// Validates SSE-C (Server-Side Encryption with Customer-Provided Keys) settings. -pub fn check_ssec(ssec: &Option, client: &Client) -> Result<(), ValidationErr> { +pub fn check_ssec( + ssec: &Option, + client: &MinioClient, +) -> Result<(), ValidationErr> { if ssec.is_some() && !client.is_secure() { return Err(ValidationErr::SseTlsRequired(None)); } @@ -428,7 +431,7 @@ pub fn check_ssec(ssec: &Option, client: &Client) -> Result<(), /// Validates SSE-C (Server-Side Encryption with Customer-Provided Keys) settings and logs an error pub fn check_ssec_with_log( ssec: &Option, - client: &Client, + client: &MinioClient, bucket: &str, object: &str, version: &Option, diff --git a/tests/test_append_object.rs b/tests/test_append_object.rs index aa60ef19..c6df2b44 100644 --- a/tests/test_append_object.rs +++ b/tests/test_append_object.rs @@ -43,6 +43,7 @@ async fn create_object_helper( let resp: PutObjectResponse = ctx .client .put_object(bucket_name, object_name, data) + .build() .send() .await .unwrap(); @@ -52,6 +53,7 @@ async fn create_object_helper( let resp: GetObjectResponse = ctx .client .get_object(bucket_name, object_name) + .build() .send() .await .unwrap(); @@ -59,7 +61,7 @@ async fn create_object_helper( assert_eq!(resp.object(), object_name); assert_eq!(resp.object_size().unwrap(), size); - // double check that the content we just have put is "aaaa" + // double-check that the content we just have put is "aaaa" let content1: String = String::from_utf8( resp.content() .unwrap() @@ -90,6 +92,7 @@ async fn append_object_0(ctx: TestContext, bucket_name: String) { let resp: AppendObjectResponse = ctx .client .append_object(&bucket_name, &object_name, data2, offset_bytes) + .build() .send() .await .unwrap(); @@ -100,6 +103,7 @@ async fn append_object_0(ctx: TestContext, bucket_name: String) { let resp: GetObjectResponse = ctx .client .get_object(&bucket_name, &object_name) + .build() .send() .await .unwrap(); @@ -139,6 +143,7 @@ async fn append_object_1(ctx: TestContext, bucket_name: String) { let resp: AppendObjectResponse = ctx .client .append_object(&bucket_name, &object_name, data2, offset_bytes) + .build() .send() .await .unwrap(); @@ -149,6 +154,7 @@ async fn append_object_1(ctx: TestContext, bucket_name: String) { let resp: GetObjectResponse = ctx .client .get_object(&bucket_name, &object_name) + .build() .send() .await .unwrap(); @@ -188,6 +194,7 @@ async fn append_object_2(ctx: TestContext, bucket_name: String) { let resp: Result = ctx .client .append_object(&bucket_name, &object_name, data2, offset_bytes) + .build() .send() .await; @@ -217,6 +224,7 @@ async fn append_object_3(ctx: TestContext, bucket_name: String) { let resp: Result = ctx .client .append_object(&bucket_name, &object_name, data2, offset_bytes) + .build() .send() .await; @@ -243,6 +251,7 @@ async fn append_object_4(ctx: TestContext, bucket_name: String) { let resp: AppendObjectResponse = ctx .client .append_object(&bucket_name, &object_name, data1, offset_bytes) + .build() .send() .await .unwrap(); @@ -253,6 +262,7 @@ async fn append_object_4(ctx: TestContext, bucket_name: String) { let resp: GetObjectResponse = ctx .client .get_object(&bucket_name, &object_name) + .build() .send() .await .unwrap(); @@ -286,6 +296,7 @@ async fn append_object_5(ctx: TestContext, bucket_name: String) { let resp: Result = ctx .client .append_object(&bucket_name, &object_name, data1, offset_bytes) + .build() .send() .await; @@ -311,6 +322,7 @@ async fn append_object_content_0(ctx: TestContext, bucket_name: String) { let resp: AppendObjectResponse = ctx .client .append_object_content(&bucket_name, &object_name, content2) + .build() .send() .await .unwrap(); @@ -321,6 +333,7 @@ async fn append_object_content_0(ctx: TestContext, bucket_name: String) { let resp: GetObjectResponse = ctx .client .get_object(&bucket_name, &object_name) + .build() .send() .await .unwrap(); @@ -353,6 +366,7 @@ async fn append_object_content_1(ctx: TestContext, bucket_name: String) { let resp: PutObjectContentResponse = ctx .client .put_object_content(&bucket_name, &object_name, data1) + .build() .send() .await .unwrap(); @@ -367,6 +381,7 @@ async fn append_object_content_1(ctx: TestContext, bucket_name: String) { let resp: AppendObjectResponse = ctx .client .append_object_content(&bucket_name, &object_name, data2) + .build() .send() .await .unwrap(); @@ -377,6 +392,7 @@ async fn append_object_content_1(ctx: TestContext, bucket_name: String) { let resp: StatObjectResponse = ctx .client .stat_object(&bucket_name, &object_name) + .build() .send() .await .unwrap(); @@ -398,6 +414,7 @@ async fn append_object_content_2(ctx: TestContext, bucket_name: String) { let resp: PutObjectContentResponse = ctx .client .put_object_content(&bucket_name, &object_name, data1) + .build() .send() .await .unwrap(); @@ -410,6 +427,7 @@ async fn append_object_content_2(ctx: TestContext, bucket_name: String) { let resp: AppendObjectResponse = ctx .client .append_object_content(&bucket_name, &object_name, data2) + .build() .send() .await .unwrap(); @@ -420,6 +438,7 @@ async fn append_object_content_2(ctx: TestContext, bucket_name: String) { let resp: StatObjectResponse = ctx .client .stat_object(&bucket_name, &object_name) + .build() .send() .await .unwrap(); @@ -464,6 +483,7 @@ async fn append_object_content_3(ctx: TestContext, bucket_name: String) { let resp: PutObjectContentResponse = client .put_object_content(&test_bucket, &object_name, content) + .build() .send() .await .unwrap(); @@ -471,6 +491,7 @@ async fn append_object_content_3(ctx: TestContext, bucket_name: String) { let resp: AppendObjectResponse = client .append_object_content(&test_bucket, &object_name, item) + .build() .send() .await .unwrap(); @@ -479,6 +500,7 @@ async fn append_object_content_3(ctx: TestContext, bucket_name: String) { let resp: StatObjectResponse = client .stat_object(&test_bucket, &object_name) + .build() .send() .await .unwrap(); @@ -486,6 +508,7 @@ async fn append_object_content_3(ctx: TestContext, bucket_name: String) { assert_eq!(resp.etag().unwrap(), etag); client .delete_object(&test_bucket, &object_name) + .build() .send() .await .unwrap(); diff --git a/tests/test_bucket_create_delete.rs b/tests/test_bucket_create_delete.rs index 50fced68..c59da78a 100644 --- a/tests/test_bucket_create_delete.rs +++ b/tests/test_bucket_create_delete.rs @@ -29,19 +29,31 @@ async fn bucket_create(ctx: TestContext) { let bucket_name = rand_bucket_name(); // try to create a bucket that does not exist - let resp: CreateBucketResponse = ctx.client.create_bucket(&bucket_name).send().await.unwrap(); + let resp: CreateBucketResponse = ctx + .client + .create_bucket(&bucket_name) + .build() + .send() + .await + .unwrap(); assert_eq!(resp.bucket(), bucket_name); assert_eq!(resp.region(), DEFAULT_REGION); // check that the bucket exists - let resp: BucketExistsResponse = ctx.client.bucket_exists(&bucket_name).send().await.unwrap(); + let resp: BucketExistsResponse = ctx + .client + .bucket_exists(&bucket_name) + .build() + .send() + .await + .unwrap(); assert!(resp.exists()); assert_eq!(resp.bucket(), bucket_name); assert_eq!(resp.region(), DEFAULT_REGION); // try to create a bucket that already exists let resp: Result = - ctx.client.create_bucket(&bucket_name).send().await; + ctx.client.create_bucket(&bucket_name).build().send().await; match resp { Ok(_) => panic!("Bucket already exists, but was created again"), Err(Error::S3Server(S3ServerError::S3Error(e))) @@ -59,7 +71,7 @@ async fn bucket_delete(ctx: TestContext) { // try to remove a bucket that does not exist let resp: Result = - ctx.client.delete_bucket(&bucket_name).send().await; + ctx.client.delete_bucket(&bucket_name).build().send().await; match resp { Ok(_) => panic!("Bucket does not exist, but was removed"), Err(Error::S3Server(S3ServerError::S3Error(e))) @@ -71,23 +83,47 @@ async fn bucket_delete(ctx: TestContext) { } // create a new bucket - let resp: CreateBucketResponse = ctx.client.create_bucket(&bucket_name).send().await.unwrap(); + let resp: CreateBucketResponse = ctx + .client + .create_bucket(&bucket_name) + .build() + .send() + .await + .unwrap(); assert_eq!(resp.bucket(), bucket_name); assert_eq!(resp.region(), DEFAULT_REGION); // check that the bucket exists - let resp: BucketExistsResponse = ctx.client.bucket_exists(&bucket_name).send().await.unwrap(); + let resp: BucketExistsResponse = ctx + .client + .bucket_exists(&bucket_name) + .build() + .send() + .await + .unwrap(); assert!(resp.exists()); assert_eq!(resp.bucket(), bucket_name); assert_eq!(resp.region(), DEFAULT_REGION); // try to remove a bucket that exists - let resp: DeleteBucketResponse = ctx.client.delete_bucket(&bucket_name).send().await.unwrap(); + let resp: DeleteBucketResponse = ctx + .client + .delete_bucket(&bucket_name) + .build() + .send() + .await + .unwrap(); assert_eq!(resp.bucket(), bucket_name); assert_eq!(resp.region(), DEFAULT_REGION); // check that the bucket does not exist anymore - let resp: BucketExistsResponse = ctx.client.bucket_exists(&bucket_name).send().await.unwrap(); + let resp: BucketExistsResponse = ctx + .client + .bucket_exists(&bucket_name) + .build() + .send() + .await + .unwrap(); assert!(!resp.exists()); assert_eq!(resp.bucket(), bucket_name); assert_eq!(resp.region(), ""); @@ -97,6 +133,7 @@ async fn test_bucket_delete_and_purge(ctx: &TestContext, bucket_name: &str, obje let resp: PutObjectContentResponse = ctx .client .put_object_content(bucket_name, object_name, "Hello, World!") + .build() .send() .await .unwrap(); @@ -105,7 +142,7 @@ async fn test_bucket_delete_and_purge(ctx: &TestContext, bucket_name: &str, obje // try to remove the bucket without purging, this should fail because the bucket is not empty let resp: Result = - ctx.client.delete_bucket(bucket_name).send().await; + ctx.client.delete_bucket(bucket_name).build().send().await; assert!(resp.is_err()); diff --git a/tests/test_bucket_encryption.rs b/tests/test_bucket_encryption.rs index 7ac15587..d1c8574e 100644 --- a/tests/test_bucket_encryption.rs +++ b/tests/test_bucket_encryption.rs @@ -31,6 +31,7 @@ async fn bucket_encryption(ctx: TestContext, bucket_name: String) { .client .put_bucket_encryption(&bucket_name) .sse_config(config.clone()) + .build() .send() .await .unwrap(); @@ -42,6 +43,7 @@ async fn bucket_encryption(ctx: TestContext, bucket_name: String) { let resp: GetBucketEncryptionResponse = ctx .client .get_bucket_encryption(&bucket_name) + .build() .send() .await .unwrap(); @@ -52,6 +54,7 @@ async fn bucket_encryption(ctx: TestContext, bucket_name: String) { let resp: DeleteBucketEncryptionResponse = ctx .client .delete_bucket_encryption(&bucket_name) + .build() .send() .await .unwrap(); @@ -61,6 +64,7 @@ async fn bucket_encryption(ctx: TestContext, bucket_name: String) { let resp: GetBucketEncryptionResponse = ctx .client .get_bucket_encryption(&bucket_name) + .build() .send() .await .unwrap(); diff --git a/tests/test_bucket_exists.rs b/tests/test_bucket_exists.rs index a1e84567..7d5ec50a 100644 --- a/tests/test_bucket_exists.rs +++ b/tests/test_bucket_exists.rs @@ -21,16 +21,34 @@ use minio_common::test_context::TestContext; #[minio_macros::test(no_cleanup)] async fn bucket_exists(ctx: TestContext, bucket_name: String) { - let resp: BucketExistsResponse = ctx.client.bucket_exists(&bucket_name).send().await.unwrap(); + let resp: BucketExistsResponse = ctx + .client + .bucket_exists(&bucket_name) + .build() + .send() + .await + .unwrap(); assert!(resp.exists()); assert_eq!(resp.bucket(), bucket_name); assert_eq!(resp.region(), DEFAULT_REGION); - let resp: DeleteBucketResponse = ctx.client.delete_bucket(&bucket_name).send().await.unwrap(); + let resp: DeleteBucketResponse = ctx + .client + .delete_bucket(&bucket_name) + .build() + .send() + .await + .unwrap(); assert_eq!(resp.bucket(), bucket_name); assert_eq!(resp.region(), DEFAULT_REGION); - let resp: BucketExistsResponse = ctx.client.bucket_exists(&bucket_name).send().await.unwrap(); + let resp: BucketExistsResponse = ctx + .client + .bucket_exists(&bucket_name) + .build() + .send() + .await + .unwrap(); assert!(!resp.exists()); assert_eq!(resp.bucket(), bucket_name); assert_eq!(resp.region(), ""); diff --git a/tests/test_bucket_lifecycle.rs b/tests/test_bucket_lifecycle.rs index d613509f..b77953b3 100644 --- a/tests/test_bucket_lifecycle.rs +++ b/tests/test_bucket_lifecycle.rs @@ -33,6 +33,7 @@ async fn bucket_lifecycle(ctx: TestContext, bucket_name: String) { .client .put_bucket_lifecycle(&bucket_name) .life_cycle_config(config.clone()) + .build() .send() .await .unwrap(); @@ -43,6 +44,7 @@ async fn bucket_lifecycle(ctx: TestContext, bucket_name: String) { .client .get_bucket_lifecycle(&bucket_name) .with_updated_at(false) + .build() .send() .await .unwrap(); @@ -55,6 +57,7 @@ async fn bucket_lifecycle(ctx: TestContext, bucket_name: String) { .client .get_bucket_lifecycle(&bucket_name) .with_updated_at(true) + .build() .send() .await .unwrap(); @@ -66,14 +69,19 @@ async fn bucket_lifecycle(ctx: TestContext, bucket_name: String) { let resp: DeleteBucketLifecycleResponse = ctx .client .delete_bucket_lifecycle(&bucket_name) + .build() .send() .await .unwrap(); assert_eq!(resp.bucket(), bucket_name); assert_eq!(resp.region(), DEFAULT_REGION); - let resp: Result = - ctx.client.get_bucket_lifecycle(&bucket_name).send().await; + let resp: Result = ctx + .client + .get_bucket_lifecycle(&bucket_name) + .build() + .send() + .await; match resp { Err(Error::S3Server(S3ServerError::S3Error(e))) => { assert_eq!(e.code(), MinioErrorCode::NoSuchLifecycleConfiguration) diff --git a/tests/test_bucket_notification.rs b/tests/test_bucket_notification.rs index 4c443eb7..ec83c7f5 100644 --- a/tests/test_bucket_notification.rs +++ b/tests/test_bucket_notification.rs @@ -32,6 +32,7 @@ async fn test_bucket_notification(ctx: TestContext, bucket_name: String) { .client .put_bucket_notification(&bucket_name) .notification_config(config.clone()) + .build() .send() .await .unwrap(); @@ -42,6 +43,7 @@ async fn test_bucket_notification(ctx: TestContext, bucket_name: String) { let resp: GetBucketNotificationResponse = ctx .client .get_bucket_notification(&bucket_name) + .build() .send() .await .unwrap(); @@ -86,6 +88,7 @@ async fn test_bucket_notification(ctx: TestContext, bucket_name: String) { let resp: DeleteBucketNotificationResponse = ctx .client .delete_bucket_notification(&bucket_name) + .build() .send() .await .unwrap(); @@ -96,6 +99,7 @@ async fn test_bucket_notification(ctx: TestContext, bucket_name: String) { let resp: GetBucketNotificationResponse = ctx .client .get_bucket_notification(&bucket_name) + .build() .send() .await .unwrap(); diff --git a/tests/test_bucket_policy.rs b/tests/test_bucket_policy.rs index 3b006926..0fe89244 100644 --- a/tests/test_bucket_policy.rs +++ b/tests/test_bucket_policy.rs @@ -30,6 +30,7 @@ async fn bucket_policy(ctx: TestContext, bucket_name: String) { .client .put_bucket_policy(&bucket_name) .config(config.clone()) + .build() .send() .await .unwrap(); @@ -39,6 +40,7 @@ async fn bucket_policy(ctx: TestContext, bucket_name: String) { let resp: GetBucketPolicyResponse = ctx .client .get_bucket_policy(&bucket_name) + .build() .send() .await .unwrap(); @@ -52,6 +54,7 @@ async fn bucket_policy(ctx: TestContext, bucket_name: String) { let resp: DeleteBucketPolicyResponse = ctx .client .delete_bucket_policy(&bucket_name) + .build() .send() .await .unwrap(); @@ -61,6 +64,7 @@ async fn bucket_policy(ctx: TestContext, bucket_name: String) { let resp: GetBucketPolicyResponse = ctx .client .get_bucket_policy(&bucket_name) + .build() .send() .await .unwrap(); diff --git a/tests/test_bucket_replication.rs b/tests/test_bucket_replication.rs index d95c0098..3517c23b 100644 --- a/tests/test_bucket_replication.rs +++ b/tests/test_bucket_replication.rs @@ -38,6 +38,7 @@ async fn bucket_replication_s3(ctx: TestContext, bucket_name: String) { .client .put_bucket_versioning(&bucket_name) .versioning_status(VersioningStatus::Enabled) + .build() .send() .await .unwrap(); @@ -48,6 +49,7 @@ async fn bucket_replication_s3(ctx: TestContext, bucket_name: String) { .client .put_bucket_versioning(&bucket_name2) .versioning_status(VersioningStatus::Enabled) + .build() .send() .await .unwrap(); @@ -57,6 +59,7 @@ async fn bucket_replication_s3(ctx: TestContext, bucket_name: String) { let resp: GetBucketVersioningResponse = ctx .client .get_bucket_versioning(&bucket_name) + .build() .send() .await .unwrap(); @@ -71,6 +74,7 @@ async fn bucket_replication_s3(ctx: TestContext, bucket_name: String) { .client .put_bucket_policy(&bucket_name) .config(config.clone()) + .build() .send() .await .unwrap(); @@ -79,6 +83,7 @@ async fn bucket_replication_s3(ctx: TestContext, bucket_name: String) { .client .put_bucket_policy(&bucket_name2) .config(config.clone()) + .build() .send() .await .unwrap(); @@ -94,6 +99,7 @@ async fn bucket_replication_s3(ctx: TestContext, bucket_name: String) { .client .put_bucket_replication(&bucket_name) .replication_config(config.clone()) + .build() .send() .await .unwrap(); @@ -104,6 +110,7 @@ async fn bucket_replication_s3(ctx: TestContext, bucket_name: String) { let resp: GetBucketReplicationResponse = ctx .client .get_bucket_replication(&bucket_name) + .build() .send() .await .unwrap(); @@ -115,6 +122,7 @@ async fn bucket_replication_s3(ctx: TestContext, bucket_name: String) { let resp: DeleteBucketReplicationResponse = ctx .client .delete_bucket_replication(&bucket_name) + .build() .send() .await .unwrap(); @@ -123,6 +131,7 @@ async fn bucket_replication_s3(ctx: TestContext, bucket_name: String) { let _resp: GetBucketVersioningResponse = ctx .client .get_bucket_versioning(&bucket_name) + .build() .send() .await .unwrap(); @@ -138,6 +147,7 @@ async fn bucket_replication_s3express(ctx: TestContext, bucket_name: String) { .client .put_bucket_replication(&bucket_name) .replication_config(config.clone()) + .build() .send() .await; match resp { @@ -147,8 +157,12 @@ async fn bucket_replication_s3express(ctx: TestContext, bucket_name: String) { v => panic!("Expected error S3Error(NotSupported): but got {v:?}"), } - let resp: Result = - ctx.client.get_bucket_replication(&bucket_name).send().await; + let resp: Result = ctx + .client + .get_bucket_replication(&bucket_name) + .build() + .send() + .await; match resp { Err(Error::S3Server(S3ServerError::S3Error(e))) => { assert_eq!(e.code(), MinioErrorCode::NotSupported) @@ -159,6 +173,7 @@ async fn bucket_replication_s3express(ctx: TestContext, bucket_name: String) { let resp: Result = ctx .client .delete_bucket_replication(&bucket_name) + .build() .send() .await; match resp { diff --git a/tests/test_bucket_tagging.rs b/tests/test_bucket_tagging.rs index ca775de9..1d3b70f6 100644 --- a/tests/test_bucket_tagging.rs +++ b/tests/test_bucket_tagging.rs @@ -32,6 +32,7 @@ async fn bucket_tags_s3(ctx: TestContext, bucket_name: String) { .client .put_bucket_tagging(&bucket_name) .tags(tags.clone()) + .build() .send() .await .unwrap(); @@ -41,6 +42,7 @@ async fn bucket_tags_s3(ctx: TestContext, bucket_name: String) { let resp: GetBucketTaggingResponse = ctx .client .get_bucket_tagging(&bucket_name) + .build() .send() .await .unwrap(); @@ -51,6 +53,7 @@ async fn bucket_tags_s3(ctx: TestContext, bucket_name: String) { let resp: DeleteBucketTaggingResponse = ctx .client .delete_bucket_tagging(&bucket_name) + .build() .send() .await .unwrap(); @@ -60,6 +63,7 @@ async fn bucket_tags_s3(ctx: TestContext, bucket_name: String) { let resp: GetBucketTaggingResponse = ctx .client .get_bucket_tagging(&bucket_name) + .build() .send() .await .unwrap(); @@ -76,6 +80,7 @@ async fn bucket_tags_s3express(ctx: TestContext, bucket_name: String) { .client .put_bucket_tagging(&bucket_name) .tags(tags.clone()) + .build() .send() .await; match resp { @@ -85,8 +90,12 @@ async fn bucket_tags_s3express(ctx: TestContext, bucket_name: String) { v => panic!("Expected error S3Error(NotSupported): but got {v:?}"), } - let resp: Result = - ctx.client.get_bucket_tagging(&bucket_name).send().await; + let resp: Result = ctx + .client + .get_bucket_tagging(&bucket_name) + .build() + .send() + .await; match resp { Err(Error::S3Server(S3ServerError::S3Error(e))) => { assert_eq!(e.code(), MinioErrorCode::NotSupported) @@ -94,8 +103,12 @@ async fn bucket_tags_s3express(ctx: TestContext, bucket_name: String) { v => panic!("Expected error S3Error(NotSupported): but got {v:?}"), } - let resp: Result = - ctx.client.delete_bucket_tagging(&bucket_name).send().await; + let resp: Result = ctx + .client + .delete_bucket_tagging(&bucket_name) + .build() + .send() + .await; match resp { Err(Error::S3Server(S3ServerError::S3Error(e))) => { assert_eq!(e.code(), MinioErrorCode::NotSupported) diff --git a/tests/test_bucket_versioning.rs b/tests/test_bucket_versioning.rs index 837b5f3b..c45e64d0 100644 --- a/tests/test_bucket_versioning.rs +++ b/tests/test_bucket_versioning.rs @@ -28,6 +28,7 @@ async fn bucket_versioning_s3(ctx: TestContext, bucket_name: String) { .client .put_bucket_versioning(&bucket_name) .versioning_status(VersioningStatus::Enabled) + .build() .send() .await .unwrap(); @@ -37,6 +38,7 @@ async fn bucket_versioning_s3(ctx: TestContext, bucket_name: String) { let resp: GetBucketVersioningResponse = ctx .client .get_bucket_versioning(&bucket_name) + .build() .send() .await .unwrap(); @@ -48,6 +50,7 @@ async fn bucket_versioning_s3(ctx: TestContext, bucket_name: String) { .client .put_bucket_versioning(&bucket_name) .versioning_status(VersioningStatus::Suspended) + .build() .send() .await .unwrap(); @@ -57,6 +60,7 @@ async fn bucket_versioning_s3(ctx: TestContext, bucket_name: String) { let resp: GetBucketVersioningResponse = ctx .client .get_bucket_versioning(&bucket_name) + .build() .send() .await .unwrap(); @@ -71,6 +75,7 @@ async fn bucket_versioning_s3express(ctx: TestContext, bucket_name: String) { .client .put_bucket_versioning(&bucket_name) .versioning_status(VersioningStatus::Enabled) + .build() .send() .await; match resp { @@ -80,8 +85,12 @@ async fn bucket_versioning_s3express(ctx: TestContext, bucket_name: String) { v => panic!("Expected error S3Error(NotSupported): but got {v:?}"), } - let resp: Result = - ctx.client.get_bucket_versioning(&bucket_name).send().await; + let resp: Result = ctx + .client + .get_bucket_versioning(&bucket_name) + .build() + .send() + .await; match resp { Err(Error::S3Server(S3ServerError::S3Error(e))) => { assert_eq!(e.code(), MinioErrorCode::NotSupported) diff --git a/tests/test_get_object.rs b/tests/test_get_object.rs index f970245b..ce00254f 100644 --- a/tests/test_get_object.rs +++ b/tests/test_get_object.rs @@ -25,6 +25,7 @@ async fn test_get_object(ctx: &TestContext, bucket_name: &str, object_name: &str let resp: PutObjectContentResponse = ctx .client .put_object_content(bucket_name, object_name, data.clone()) + .build() .send() .await .unwrap(); @@ -35,6 +36,7 @@ async fn test_get_object(ctx: &TestContext, bucket_name: &str, object_name: &str let resp: GetObjectResponse = ctx .client .get_object(bucket_name, object_name) + .build() .send() .await .unwrap(); diff --git a/tests/test_get_presigned_object_url.rs b/tests/test_get_presigned_object_url.rs index 1e911bed..50de8b4e 100644 --- a/tests/test_get_presigned_object_url.rs +++ b/tests/test_get_presigned_object_url.rs @@ -26,6 +26,7 @@ async fn get_presigned_object_url(ctx: TestContext, bucket_name: String) { let resp: GetPresignedObjectUrlResponse = ctx .client .get_presigned_object_url(&bucket_name, &object_name, Method::GET) + .build() .send() .await .unwrap(); diff --git a/tests/test_get_presigned_post_form_data.rs b/tests/test_get_presigned_post_form_data.rs index 2b1defdd..227a6d37 100644 --- a/tests/test_get_presigned_post_form_data.rs +++ b/tests/test_get_presigned_post_form_data.rs @@ -29,6 +29,7 @@ async fn get_presigned_post_form_data(ctx: TestContext, bucket_name: String) { let form_data: HashMap = ctx .client .get_presigned_post_form_data(policy) + .build() .send() .await .unwrap(); diff --git a/tests/test_list_buckets.rs b/tests/test_list_buckets.rs index f928fd79..e9a8d4f6 100644 --- a/tests/test_list_buckets.rs +++ b/tests/test_list_buckets.rs @@ -33,7 +33,7 @@ async fn list_buckets(ctx: TestContext) { assert_eq!(names.len(), N_BUCKETS); let mut count = 0; - let resp: ListBucketsResponse = ctx.client.list_buckets().send().await.unwrap(); + let resp: ListBucketsResponse = ctx.client.list_buckets().build().send().await.unwrap(); for bucket in resp.buckets().unwrap().iter() { if names.contains(&bucket.name) { diff --git a/tests/test_list_objects.rs b/tests/test_list_objects.rs index 456834c0..076bfdf3 100644 --- a/tests/test_list_objects.rs +++ b/tests/test_list_objects.rs @@ -58,6 +58,7 @@ async fn test_list_objects( let resp: PutObjectContentResponse = ctx .client .put_object_content(&bucket_name, &object_name, "hello world") + .build() .send() .await .unwrap(); @@ -72,6 +73,7 @@ async fn test_list_objects( .use_api_v1(use_api_v1) .include_versions(include_versions) .recursive(true) + .build() .to_stream() .await; @@ -128,6 +130,7 @@ async fn test_list_one_object(ctx: &TestContext, bucket_name: &str, object_name: let resp: PutObjectContentResponse = ctx .client .put_object_content(bucket_name, object_name, "Hello, World!") + .build() .send() .await .unwrap(); @@ -139,6 +142,7 @@ async fn test_list_one_object(ctx: &TestContext, bucket_name: &str, object_name: .list_objects(bucket_name) .use_api_v1(false) // S3-Express does not support V1 API .include_versions(false) // S3-Express does not support versions + .build() .to_stream() .await; diff --git a/tests/test_listen_bucket_notification.rs b/tests/test_listen_bucket_notification.rs index 00c696af..09843a2a 100644 --- a/tests/test_listen_bucket_notification.rs +++ b/tests/test_listen_bucket_notification.rs @@ -45,6 +45,7 @@ async fn listen_bucket_notification(ctx: TestContext, bucket_name: String) { let (_resp, mut event_stream) = ctx2 .client .listen_bucket_notification(&bucket_name2) + .build() .send() .await .unwrap(); @@ -81,6 +82,7 @@ async fn listen_bucket_notification(ctx: TestContext, bucket_name: String) { &object_name, ObjectContent::new_from_stream(RandSrc::new(size), Some(size)), ) + .build() .send() .await .unwrap(); diff --git a/tests/test_object_compose.rs b/tests/test_object_compose.rs index e7940977..6f81fd84 100644 --- a/tests/test_object_compose.rs +++ b/tests/test_object_compose.rs @@ -32,6 +32,7 @@ async fn compose_object(ctx: TestContext, bucket_name: String) { let resp: PutObjectContentResponse = ctx .client .put_object_content(&bucket_name, &object_name_src, content) + .build() .send() .await .unwrap(); @@ -49,6 +50,7 @@ async fn compose_object(ctx: TestContext, bucket_name: String) { let resp: ComposeObjectResponse = ctx .client .compose_object(&bucket_name, &object_name_dst, sources) + .build() .send() .await .unwrap(); @@ -58,6 +60,7 @@ async fn compose_object(ctx: TestContext, bucket_name: String) { let resp: StatObjectResponse = ctx .client .stat_object(&bucket_name, &object_name_dst) + .build() .send() .await .unwrap(); diff --git a/tests/test_object_copy.rs b/tests/test_object_copy.rs index 05f161b7..8331ac7a 100644 --- a/tests/test_object_copy.rs +++ b/tests/test_object_copy.rs @@ -33,6 +33,7 @@ async fn test_copy_object( let resp: PutObjectContentResponse = ctx .client .put_object_content(bucket_name, object_name_src, content) + .build() .send() .await .unwrap(); @@ -42,7 +43,13 @@ async fn test_copy_object( let resp: CopyObjectResponse = ctx .client .copy_object(bucket_name, object_name_dst) - .source(CopySource::new(bucket_name, object_name_src).unwrap()) + .source( + CopySource::builder() + .bucket(bucket_name) + .object(object_name_src) + .build(), + ) + .build() .send() .await .unwrap(); @@ -52,6 +59,7 @@ async fn test_copy_object( let resp: StatObjectResponse = ctx .client .stat_object(bucket_name, object_name_dst) + .build() .send() .await .unwrap(); diff --git a/tests/test_object_delete.rs b/tests/test_object_delete.rs index 7269ddb0..7b446d69 100644 --- a/tests/test_object_delete.rs +++ b/tests/test_object_delete.rs @@ -31,6 +31,7 @@ async fn create_object_helper( let resp: PutObjectContentResponse = ctx .client .put_object_content(bucket_name, object_name, "hello world") + .build() .send() .await .unwrap(); @@ -45,6 +46,7 @@ async fn test_delete_object(ctx: &TestContext, bucket_name: &str, object_name: & let resp: DeleteObjectResponse = ctx .client .delete_object(bucket_name, object_name) + .build() .send() .await .unwrap(); @@ -80,8 +82,9 @@ async fn delete_objects(ctx: TestContext, bucket_name: String) { let resp: DeleteObjectsResponse = ctx .client - .delete_objects::<&String, ObjectToDelete>(&bucket_name, del_items) + .delete_objects::<&String>(&bucket_name, del_items) .verbose_mode(true) // Enable verbose mode to get detailed response + .build() .send() .await .unwrap(); diff --git a/tests/test_object_legal_hold.rs b/tests/test_object_legal_hold.rs index 3fa891b9..f1d68f39 100644 --- a/tests/test_object_legal_hold.rs +++ b/tests/test_object_legal_hold.rs @@ -32,6 +32,7 @@ async fn object_legal_hold_s3(ctx: TestContext, bucket_name: String) { let resp: PutObjectContentResponse = ctx .client .put_object_content(&bucket_name, &object_name, data.clone()) + .build() .send() .await .unwrap(); @@ -42,6 +43,7 @@ async fn object_legal_hold_s3(ctx: TestContext, bucket_name: String) { let resp: PutObjectLegalHoldResponse = ctx .client .put_object_legal_hold(&bucket_name, &object_name, true) + .build() .send() .await .unwrap(); @@ -53,6 +55,7 @@ async fn object_legal_hold_s3(ctx: TestContext, bucket_name: String) { let resp: GetObjectLegalHoldResponse = ctx .client .get_object_legal_hold(&bucket_name, &object_name) + .build() .send() .await .unwrap(); @@ -65,6 +68,7 @@ async fn object_legal_hold_s3(ctx: TestContext, bucket_name: String) { let resp: PutObjectLegalHoldResponse = ctx .client .put_object_legal_hold(&bucket_name, &object_name, true) + .build() .send() .await .unwrap(); @@ -76,6 +80,7 @@ async fn object_legal_hold_s3(ctx: TestContext, bucket_name: String) { let resp: GetObjectLegalHoldResponse = ctx .client .get_object_legal_hold(&bucket_name, &object_name) + .build() .send() .await .unwrap(); diff --git a/tests/test_object_lock_config.rs b/tests/test_object_lock_config.rs index 756b8670..34813135 100644 --- a/tests/test_object_lock_config.rs +++ b/tests/test_object_lock_config.rs @@ -31,6 +31,7 @@ async fn object_lock_config(ctx: TestContext, bucket_name: String) { .client .put_object_lock_config(&bucket_name) .config(config) + .build() .send() .await .unwrap(); @@ -40,6 +41,7 @@ async fn object_lock_config(ctx: TestContext, bucket_name: String) { let resp: GetObjectLockConfigResponse = ctx .client .get_object_lock_config(&bucket_name) + .build() .send() .await .unwrap(); @@ -54,6 +56,7 @@ async fn object_lock_config(ctx: TestContext, bucket_name: String) { let resp: DeleteObjectLockConfigResponse = ctx .client .delete_object_lock_config(&bucket_name) + .build() .send() .await .unwrap(); @@ -63,6 +66,7 @@ async fn object_lock_config(ctx: TestContext, bucket_name: String) { let resp: GetObjectLockConfigResponse = ctx .client .get_object_lock_config(&bucket_name) + .build() .send() .await .unwrap(); diff --git a/tests/test_object_put.rs b/tests/test_object_put.rs index d2b6afd7..447f5bd5 100644 --- a/tests/test_object_put.rs +++ b/tests/test_object_put.rs @@ -14,6 +14,7 @@ // limitations under the License. use http::header; +use minio::s3::builders::Size::Known; use minio::s3::builders::{MIN_PART_SIZE, ObjectContent}; use minio::s3::response::a_response_traits::{ HasBucket, HasEtagFromHeaders, HasIsDeleteMarker, HasObject, HasS3Fields, @@ -34,6 +35,7 @@ async fn test_put_object(ctx: &TestContext, bucket_name: &str, object_name: &str object_name, ObjectContent::new_from_stream(RandSrc::new(size), Some(size)), ) + .build() .send() .await .unwrap(); @@ -45,6 +47,7 @@ async fn test_put_object(ctx: &TestContext, bucket_name: &str, object_name: &str let resp: StatObjectResponse = ctx .client .stat_object(bucket_name, object_name) + .build() .send() .await .unwrap(); @@ -79,6 +82,7 @@ async fn put_object_multipart(ctx: TestContext, bucket_name: String) { &object_name, ObjectContent::new_from_stream(RandSrc::new(size), Some(size)), ) + .build() .send() .await .unwrap(); @@ -89,6 +93,7 @@ async fn put_object_multipart(ctx: TestContext, bucket_name: String) { let resp: StatObjectResponse = ctx .client .stat_object(&bucket_name, &object_name) + .build() .send() .await .unwrap(); @@ -111,6 +116,7 @@ async fn put_object_content_1(ctx: TestContext, bucket_name: String) { ObjectContent::new_from_stream(RandSrc::new(*size), Some(*size)), ) .content_type(String::from("image/jpeg")) + .build() .send() .await .unwrap(); @@ -120,6 +126,7 @@ async fn put_object_content_1(ctx: TestContext, bucket_name: String) { let resp: StatObjectResponse = ctx .client .stat_object(&bucket_name, &object_name) + .build() .send() .await .unwrap(); @@ -133,6 +140,7 @@ async fn put_object_content_1(ctx: TestContext, bucket_name: String) { let resp: DeleteObjectResponse = ctx .client .delete_object(&bucket_name, &object_name) + .build() .send() .await .unwrap(); @@ -156,7 +164,8 @@ async fn put_object_content_2(ctx: TestContext, bucket_name: String) { &object_name, ObjectContent::new_from_stream(data_src, None), ) - .part_size(Some(MIN_PART_SIZE)) + .part_size(Known(MIN_PART_SIZE)) + .build() .send() .await .unwrap(); @@ -166,6 +175,7 @@ async fn put_object_content_2(ctx: TestContext, bucket_name: String) { let resp: StatObjectResponse = ctx .client .stat_object(&bucket_name, &object_name) + .build() .send() .await .unwrap(); @@ -206,6 +216,7 @@ async fn put_object_content_3(ctx: TestContext, bucket_name: String) { while let Some(item) = receiver.recv().await { let resp: PutObjectContentResponse = client .put_object_content(&test_bucket, &object_name, item) + .build() .send() .await .unwrap(); @@ -213,6 +224,7 @@ async fn put_object_content_3(ctx: TestContext, bucket_name: String) { let etag = resp.etag().unwrap(); let resp: StatObjectResponse = client .stat_object(&test_bucket, &object_name) + .build() .send() .await .unwrap(); diff --git a/tests/test_object_retention.rs b/tests/test_object_retention.rs index a7c2d1c4..f1fbc6e2 100644 --- a/tests/test_object_retention.rs +++ b/tests/test_object_retention.rs @@ -38,6 +38,7 @@ async fn object_retention(ctx: TestContext, bucket_name: String) { &object_name, ObjectContent::new_from_stream(RandSrc::new(size), Some(size)), ) + .build() .send() .await .unwrap(); @@ -52,8 +53,9 @@ async fn object_retention(ctx: TestContext, bucket_name: String) { let resp: PutObjectRetentionResponse = ctx .client .put_object_retention(&bucket_name, &object_name) - .retention_mode(Some(RetentionMode::GOVERNANCE)) - .retain_until_date(Some(retain_until_date)) + .retention_mode(RetentionMode::GOVERNANCE) + .retain_until_date(retain_until_date) + .build() .send() .await .unwrap(); @@ -65,6 +67,7 @@ async fn object_retention(ctx: TestContext, bucket_name: String) { let resp: GetObjectRetentionResponse = ctx .client .get_object_retention(&bucket_name, &object_name) + .build() .send() .await .unwrap(); @@ -81,6 +84,7 @@ async fn object_retention(ctx: TestContext, bucket_name: String) { .client .put_object_retention(&bucket_name, &object_name) .bypass_governance_mode(true) + .build() .send() .await .unwrap(); @@ -92,6 +96,7 @@ async fn object_retention(ctx: TestContext, bucket_name: String) { let resp: GetObjectRetentionResponse = ctx .client .get_object_retention(&bucket_name, &object_name) + .build() .send() .await .unwrap(); diff --git a/tests/test_object_tagging.rs b/tests/test_object_tagging.rs index 3a345871..3b3b9679 100644 --- a/tests/test_object_tagging.rs +++ b/tests/test_object_tagging.rs @@ -40,6 +40,7 @@ async fn object_tags(ctx: TestContext, bucket_name: String) { &object_name, ObjectContent::new_from_stream(RandSrc::new(size), Some(size)), ) + .build() .send() .await .unwrap(); @@ -58,6 +59,7 @@ async fn object_tags(ctx: TestContext, bucket_name: String) { .client .put_object_tagging(&bucket_name, &object_name) .tags(tags.clone()) + .build() .send() .await .unwrap(); @@ -69,6 +71,7 @@ async fn object_tags(ctx: TestContext, bucket_name: String) { let resp: GetObjectTaggingResponse = ctx .client .get_object_tagging(&bucket_name, &object_name) + .build() .send() .await .unwrap(); @@ -81,6 +84,7 @@ async fn object_tags(ctx: TestContext, bucket_name: String) { let resp: DeleteObjectTaggingResponse = ctx .client .delete_object_tagging(&bucket_name, &object_name) + .build() .send() .await .unwrap(); @@ -92,6 +96,7 @@ async fn object_tags(ctx: TestContext, bucket_name: String) { let resp: GetObjectTaggingResponse = ctx .client .get_object_tagging(&bucket_name, &object_name) + .build() .send() .await .unwrap(); diff --git a/tests/test_select_object_content.rs b/tests/test_select_object_content.rs index 843b345e..7fd06b5e 100644 --- a/tests/test_select_object_content.rs +++ b/tests/test_select_object_content.rs @@ -30,6 +30,7 @@ async fn select_object_content_s3(ctx: TestContext, bucket_name: String) { let resp: PutObjectContentResponse = ctx .client .put_object_content(&bucket_name, &object_name, select_body.clone()) + .build() .send() .await .unwrap(); @@ -41,6 +42,7 @@ async fn select_object_content_s3(ctx: TestContext, bucket_name: String) { let mut resp: SelectObjectContentResponse = ctx .client .select_object_content(&bucket_name, &object_name, select_request) + .build() .send() .await .unwrap(); @@ -64,6 +66,7 @@ async fn select_object_content_express(ctx: TestContext, bucket_name: String) { let _resp: PutObjectContentResponse = ctx .client .put_object_content(&bucket_name, &object_name, select_body) + .build() .send() .await .unwrap(); @@ -73,6 +76,7 @@ async fn select_object_content_express(ctx: TestContext, bucket_name: String) { let resp: Result = ctx .client .select_object_content(&bucket_name, &object_name, select_request) + .build() .send() .await; match resp { diff --git a/tests/test_upload_download_object.rs b/tests/test_upload_download_object.rs index 9831d262..7021a100 100644 --- a/tests/test_upload_download_object.rs +++ b/tests/test_upload_download_object.rs @@ -68,6 +68,7 @@ async fn test_upload_download_object( let resp: PutObjectContentResponse = ctx .client .put_object_content(bucket_name, object_name, obj) + .build() .send() .await .unwrap(); @@ -79,6 +80,7 @@ async fn test_upload_download_object( let resp: GetObjectResponse = ctx .client .get_object(bucket_name, object_name) + .build() .send() .await .unwrap(); From 2c6f9434013c608e2babbbd15f4b25d4f072d316 Mon Sep 17 00:00:00 2001 From: Henk-Jan Lebbink Date: Tue, 23 Sep 2025 09:56:50 +0200 Subject: [PATCH 2/3] code review updates --- .claude/settings.local.json | 10 +++++++--- benches/s3/bench_object_retention.rs | 4 ++-- src/s3/builders/append_object.rs | 5 +++-- src/s3/builders/put_object.rs | 13 ++++++------- src/s3/client/put_object_retention.rs | 6 +++++- src/s3/object_content.rs | 11 ++++++++++- tests/test_object_put.rs | 3 +-- 7 files changed, 34 insertions(+), 18 deletions(-) diff --git a/.claude/settings.local.json b/.claude/settings.local.json index c994be3e..c0cdf882 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -1,9 +1,13 @@ { + "$schema": "https://json.schemastore.org/claude-code-settings.json", "permissions": { "allow": [ - "Bash(grep:*)" + "Bash(grep:*)", + "WebSearch", + "Bash(cargo check:*)", + "Bash(cargo test:*)", + "Bash(find:*)" ], "deny": [] - }, - "$schema": "https://json.schemastore.org/claude-code-settings.json" + } } \ No newline at end of file diff --git a/benches/s3/bench_object_retention.rs b/benches/s3/bench_object_retention.rs index 07a27ead..9cc0bff1 100644 --- a/benches/s3/bench_object_retention.rs +++ b/benches/s3/bench_object_retention.rs @@ -34,7 +34,7 @@ pub(crate) async fn bench_put_object_retention(criterion: &mut Criterion) { .client(ctx.client.clone()) .bucket(ctx.bucket.clone()) .object(ctx.object.clone()) - .retention_mode(Some(RetentionMode::GOVERNANCE)) + .retention_mode(RetentionMode::GOVERNANCE) .retain_until_date(Some(utc_now() + chrono::Duration::days(1))) .build() }, @@ -53,7 +53,7 @@ pub(crate) async fn bench_get_object_retention(criterion: &mut Criterion) { .client(ctx.client.clone()) .bucket(ctx.bucket.clone()) .object(ctx.object.clone()) - .retention_mode(Some(RetentionMode::GOVERNANCE)) + .retention_mode(RetentionMode::GOVERNANCE) .retain_until_date(Some(utc_now() + chrono::Duration::days(1))) .build() .send() diff --git a/src/s3/builders/append_object.rs b/src/s3/builders/append_object.rs index de23022c..8a1a051a 100644 --- a/src/s3/builders/append_object.rs +++ b/src/s3/builders/append_object.rs @@ -231,9 +231,10 @@ impl AppendObjectContent { data: Arc::new(seg_bytes), }; ao.send().await - } else if object_size.is_known() && (seg_bytes.len() as u64) < part_size { + } else if let Some(expected) = object_size.value() + && (seg_bytes.len() as u64) < part_size + { // Not enough data! - let expected = object_size.as_u64().unwrap(); let got = seg_bytes.len() as u64; Err(ValidationErr::InsufficientData { expected, got })? } else { diff --git a/src/s3/builders/put_object.rs b/src/s3/builders/put_object.rs index f01afbbb..de186ff3 100644 --- a/src/s3/builders/put_object.rs +++ b/src/s3/builders/put_object.rs @@ -450,7 +450,7 @@ pub struct PutObjectContent { retention: Option, #[builder(default = false)] legal_hold: bool, - #[builder(default)] + #[builder(default, setter(into))] part_size: Size, #[builder(default, setter(into))] content_type: Option, @@ -548,9 +548,10 @@ impl PutObjectContent { .await?; Ok(PutObjectContentResponse::new(resp, size)) - } else if object_size.is_known() && (seg_bytes.len() as u64) < part_size { + } else if let Some(expected) = object_size.value() + && (seg_bytes.len() as u64) < part_size + { // Not enough data! - let expected: u64 = object_size.as_u64().unwrap(); let got: u64 = seg_bytes.len() as u64; Err(ValidationErr::InsufficientData { expected, got }.into()) } else { @@ -642,8 +643,7 @@ impl PutObjectContent { return Err(ValidationErr::TooManyParts(part_number as u64).into()); } - if object_size.is_known() { - let exp = object_size.as_u64().unwrap(); + if let Some(exp) = object_size.value() { if exp < total_read { return Err(ValidationErr::TooMuchData(exp).into()); } @@ -686,8 +686,7 @@ impl PutObjectContent { // Complete the multipart upload. let size = parts.iter().map(|p| p.size).sum(); - if object_size.is_known() { - let expected = object_size.as_u64().unwrap(); + if let Some(expected) = object_size.value() { if expected != size { return Err(ValidationErr::InsufficientData { expected, diff --git a/src/s3/client/put_object_retention.rs b/src/s3/client/put_object_retention.rs index 09779e77..d9db74f5 100644 --- a/src/s3/client/put_object_retention.rs +++ b/src/s3/client/put_object_retention.rs @@ -24,6 +24,10 @@ impl MinioClient { /// /// 🛈 This operation is not supported for express buckets. /// + /// Note: there is no separate delete object retention API. To remove object retention, you must + /// call put_object_retention without '.retention_mode()' or '.retain_until_date()' to remove the retention. + /// You must set '.bypass_governance_mode(true)' to remove retention from objects in GOVERNANCE mode. + /// /// # Example /// /// ```no_run @@ -40,7 +44,7 @@ impl MinioClient { /// let retain_until_date = utc_now() + chrono::Duration::days(1); /// let resp: PutObjectRetentionResponse = client /// .put_object_retention("bucket-name", "object-name") - /// .retention_mode(Some(RetentionMode::GOVERNANCE)) + /// .retention_mode(RetentionMode::GOVERNANCE) /// .retain_until_date(Some(retain_until_date)) /// .build().send().await.unwrap(); /// println!("set the object retention for object '{}'", resp.object()); diff --git a/src/s3/object_content.rs b/src/s3/object_content.rs index 0135e7a8..e7e428c7 100644 --- a/src/s3/object_content.rs +++ b/src/s3/object_content.rs @@ -36,15 +36,18 @@ pub enum Size { } impl Size { + /// Returns `true` if the size is known and `false` otherwise. pub fn is_known(&self) -> bool { matches!(self, Size::Known(_)) } + /// Returns `true` if the size is unknown and `false` otherwise. pub fn is_unknown(&self) -> bool { matches!(self, Size::Unknown) } - pub fn as_u64(&self) -> Option { + /// Returns the size if known, otherwise returns `None`. + pub fn value(&self) -> Option { match self { Size::Known(v) => Some(*v), Size::Unknown => None, @@ -61,6 +64,12 @@ impl From> for Size { } } +impl From for Size { + fn from(value: u64) -> Self { + Size::Known(value) + } +} + #[cfg(test)] impl Arbitrary for Size { fn arbitrary(g: &mut quickcheck::Gen) -> Self { diff --git a/tests/test_object_put.rs b/tests/test_object_put.rs index 447f5bd5..619f28f8 100644 --- a/tests/test_object_put.rs +++ b/tests/test_object_put.rs @@ -14,7 +14,6 @@ // limitations under the License. use http::header; -use minio::s3::builders::Size::Known; use minio::s3::builders::{MIN_PART_SIZE, ObjectContent}; use minio::s3::response::a_response_traits::{ HasBucket, HasEtagFromHeaders, HasIsDeleteMarker, HasObject, HasS3Fields, @@ -164,7 +163,7 @@ async fn put_object_content_2(ctx: TestContext, bucket_name: String) { &object_name, ObjectContent::new_from_stream(data_src, None), ) - .part_size(Known(MIN_PART_SIZE)) + .part_size(MIN_PART_SIZE) .build() .send() .await From 991b1cb614dea426de73fd733bdd7353eedb50b0 Mon Sep 17 00:00:00 2001 From: Henk-Jan Lebbink Date: Thu, 16 Oct 2025 14:40:00 +0200 Subject: [PATCH 3/3] Code review updates --- .claude/settings.local.json | 13 ------- Cargo.toml | 7 ++-- README.md | 12 ++++-- examples/append_object.rs | 7 +++- src/lib.rs | 6 ++- src/s3/builders/copy_object.rs | 2 +- src/s3/client.rs | 14 ++++--- src/s3/client/append_object.rs | 12 +++++- src/s3/client/bucket_exists.rs | 6 ++- src/s3/client/copy_object.rs | 12 +++++- src/s3/client/create_bucket.rs | 6 ++- src/s3/client/delete_bucket.rs | 20 ++++++++-- src/s3/client/delete_bucket_encryption.rs | 6 ++- src/s3/client/delete_bucket_lifecycle.rs | 6 ++- src/s3/client/delete_bucket_notification.rs | 6 ++- src/s3/client/delete_bucket_policy.rs | 6 ++- src/s3/client/delete_bucket_replication.rs | 6 ++- src/s3/client/delete_bucket_tagging.rs | 6 ++- src/s3/client/delete_object_lock_config.rs | 6 ++- src/s3/client/delete_object_tagging.rs | 6 ++- src/s3/client/delete_objects.rs | 6 ++- src/s3/client/get_bucket_encryption.rs | 6 ++- src/s3/client/get_bucket_lifecycle.rs | 6 ++- src/s3/client/get_bucket_notification.rs | 6 ++- src/s3/client/get_bucket_policy.rs | 6 ++- src/s3/client/get_bucket_replication.rs | 6 ++- src/s3/client/get_bucket_tagging.rs | 6 ++- src/s3/client/get_bucket_versioning.rs | 6 ++- src/s3/client/get_object.rs | 6 ++- src/s3/client/get_object_legal_hold.rs | 6 ++- src/s3/client/get_object_lock_config.rs | 6 ++- src/s3/client/get_object_prompt.rs | 6 ++- src/s3/client/get_object_retention.rs | 6 ++- src/s3/client/get_object_tagging.rs | 6 ++- src/s3/client/get_presigned_object_url.rs | 6 ++- src/s3/client/get_presigned_post_form_data.rs | 6 ++- src/s3/client/get_region.rs | 6 ++- src/s3/client/list_buckets.rs | 6 ++- src/s3/client/list_objects.rs | 6 ++- src/s3/client/listen_bucket_notification.rs | 6 ++- src/s3/client/put_bucket_encryption.rs | 6 ++- src/s3/client/put_bucket_lifecycle.rs | 6 ++- src/s3/client/put_bucket_notification.rs | 6 ++- src/s3/client/put_bucket_policy.rs | 6 ++- src/s3/client/put_bucket_replication.rs | 6 ++- src/s3/client/put_bucket_tagging.rs | 6 ++- src/s3/client/put_bucket_versioning.rs | 6 ++- src/s3/client/put_object.rs | 38 +++++++++++++++---- src/s3/client/put_object_legal_hold.rs | 6 ++- src/s3/client/put_object_lock_config.rs | 6 ++- src/s3/client/put_object_retention.rs | 6 ++- src/s3/client/put_object_tagging.rs | 6 ++- src/s3/client/select_object_content.rs | 6 ++- src/s3/client/stat_object.rs | 6 ++- src/s3/http.rs | 8 ++-- src/s3/utils.rs | 4 +- tests/test_upload_download_object.rs | 2 +- 57 files changed, 321 insertions(+), 94 deletions(-) delete mode 100644 .claude/settings.local.json diff --git a/.claude/settings.local.json b/.claude/settings.local.json deleted file mode 100644 index c0cdf882..00000000 --- a/.claude/settings.local.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "$schema": "https://json.schemastore.org/claude-code-settings.json", - "permissions": { - "allow": [ - "Bash(grep:*)", - "WebSearch", - "Bash(cargo check:*)", - "Bash(cargo test:*)", - "Bash(find:*)" - ], - "deny": [] - } -} \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index ed269cfd..a67d1b71 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,6 +17,7 @@ native-tls = ["reqwest/native-tls"] rustls-tls = ["reqwest/rustls-tls"] default-crypto = ["dep:sha2", "dep:hmac"] ring = ["dep:ring"] +localhost = [] [workspace.dependencies] uuid = "1.18" @@ -49,7 +50,7 @@ md5 = "0.8" multimap = "0.10" percent-encoding = "2.3" url = "2.5" -regex = "1.11" +regex = "1.12" ring = { version = "0.17", optional = true, default-features = false, features = ["alloc"] } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" @@ -58,12 +59,12 @@ urlencoding = "2.1" xmltree = "0.11" http = "1.3" thiserror = "2.0" -typed-builder = "0.21" +typed-builder = "0.22" [dev-dependencies] minio-common = { path = "./common" } minio-macros = { path = "./macros" } -tokio = { version = "1.47", features = ["full"] } +tokio = { version = "1.48", features = ["full"] } async-std = { version = "1.13", features = ["attributes", "tokio1"] } clap = { version = "4.5", features = ["derive"] } rand = { version = "0.9", features = ["small_rng"] } diff --git a/README.md b/README.md index 38fad224..8b2ccd0a 100644 --- a/README.md +++ b/README.md @@ -18,14 +18,18 @@ All request builders implement the [`S3Api`] trait, which provides the async [`s ## Basic Usage ```no_run -use minio::s3::Client; +use minio::s3::MinioClient; +use minio::s3::creds::StaticProvider; +use minio::s3::http::BaseUrl; use minio::s3::types::S3Api; use minio::s3::response::BucketExistsResponse; #[tokio::main] async fn main() { - let client = Client::create_client_on_localhost().unwrap(); // configure your client here - + let base_url = "play.min.io".parse::().unwrap(); + let static_provider = StaticProvider::new("Q3AM3UQ867SPQQA43P2F", "zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG", None); + let client = MinioClient::new(base_url, Some(static_provider), None, None).unwrap(); + let exists: BucketExistsResponse = client .bucket_exists("my-bucket") .send() @@ -46,7 +50,7 @@ async fn main() { ## Design -- Each API method on the [`Client`] returns a builder struct +- Each API method on the [`MinioClient`] returns a builder struct - Builders implement [`ToS3Request`] for request conversion and [`S3Api`] for execution - Responses implement [`FromS3Response`] for consistent deserialization diff --git a/examples/append_object.rs b/examples/append_object.rs index a2d5fc08..375da8dc 100644 --- a/examples/append_object.rs +++ b/examples/append_object.rs @@ -17,6 +17,8 @@ mod common; use crate::common::create_bucket_if_not_exists; use minio::s3::MinioClient; +use minio::s3::creds::StaticProvider; +use minio::s3::http::BaseUrl; use minio::s3::response::a_response_traits::HasObjectSize; use minio::s3::response::{AppendObjectResponse, StatObjectResponse}; use minio::s3::segmented_bytes::SegmentedBytes; @@ -27,7 +29,10 @@ use rand::distr::Alphanumeric; #[tokio::main] async fn main() -> Result<(), Box> { env_logger::init(); // Note: set environment variable RUST_LOG="INFO" to log info and higher - let client: MinioClient = MinioClient::create_client_on_localhost()?; + + let base_url = "http://localhost:9000/".parse::()?; + let static_provider = StaticProvider::new("minioadmin", "minioadmin", None); + let client = MinioClient::new(base_url, Some(static_provider), None, None)?; if !client.is_minio_express().await { println!("Need (MinIO) Express mode to run this example"); diff --git a/src/lib.rs b/src/lib.rs index 16808ef3..b9599d5f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -27,12 +27,16 @@ //! //! ```no_run //! use minio::s3::MinioClient; +//! use minio::s3::creds::StaticProvider; +//! use minio::s3::http::BaseUrl; //! use minio::s3::types::S3Api; //! use minio::s3::response::BucketExistsResponse; //! //! #[tokio::main] //! async fn main() { -//! let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here +//! let base_url = "play.min.io".parse::().unwrap(); +//! let static_provider = StaticProvider::new("Q3AM3UQ867SPQQA43P2F", "zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG", None); +//! let client = MinioClient::new(base_url, Some(static_provider), None, None).unwrap(); //! //! let exists: BucketExistsResponse = client //! .bucket_exists("my-bucket") diff --git a/src/s3/builders/copy_object.rs b/src/s3/builders/copy_object.rs index f8553b7c..cbdf5fdc 100644 --- a/src/s3/builders/copy_object.rs +++ b/src/s3/builders/copy_object.rs @@ -706,7 +706,7 @@ impl ComposeObjectInternal { /// This struct constructs the parameters required for the [`Client::copy_object`](crate::s3::client::MinioClient::copy_object) method. #[derive(Clone, Debug, TypedBuilder)] pub struct ComposeObject { - //#[builder(!default)] // force required + #[builder(!default)] // force required client: MinioClient, #[builder(default)] extra_headers: Option, diff --git a/src/s3/client.rs b/src/s3/client.rs index fffe0355..ff640d3e 100644 --- a/src/s3/client.rs +++ b/src/s3/client.rs @@ -28,7 +28,9 @@ use std::sync::{Arc, OnceLock}; use uuid::Uuid; use crate::s3::builders::{BucketExists, ComposeSource}; -use crate::s3::creds::{Provider, StaticProvider}; +use crate::s3::creds::Provider; +#[cfg(feature = "localhost")] +use crate::s3::creds::StaticProvider; use crate::s3::error::{Error, IoError, NetworkError, S3ServerError, ValidationErr}; use crate::s3::header_constants::*; use crate::s3::http::BaseUrl; @@ -124,15 +126,14 @@ pub const MAX_MULTIPART_COUNT: u16 = 10_000; /// compatible object storage service. #[derive(Debug)] pub struct MinioClientBuilder { - //#[builder(!default)] // force required base_url: BaseUrl, - //#[builder(default, setter(into, doc = "Set the credential provider. If not, set anonymous access is used."))] + /// Set the credential provider. If not, set anonymous access is used. provider: Option>, - //#[builder(default, setter(into, doc = "Set file for loading CAs certs to trust. This is in addition to the system trust store. The file must contain PEM encoded certificates."))] + /// Set file for loading CAs certs to trust. This is in addition to the system trust store. The file must contain PEM encoded certificates. ssl_cert_file: Option, - //#[builder(default, setter(into, doc = "Set flag to ignore certificate check. This is insecure and should only be used for testing."))] + /// Set flag to ignore certificate check. This is insecure and should only be used for testing. ignore_cert_check: Option, - //#[builder(default, setter(into, doc = "Set the app info as an Option of (app_name, app_version) pair. This will show up in the client's user-agent."))] + /// Set the app info as an Option of (app_name, app_version) pair. This will show up in the client's user-agent. app_info: Option<(String, String)>, } @@ -612,6 +613,7 @@ impl MinioClient { } /// create an example client for testing on localhost + #[cfg(feature = "localhost")] pub fn create_client_on_localhost() -> Result> { let base_url = "http://localhost:9000/".parse::()?; diff --git a/src/s3/client/append_object.rs b/src/s3/client/append_object.rs index db7cea71..213bd10e 100644 --- a/src/s3/client/append_object.rs +++ b/src/s3/client/append_object.rs @@ -35,6 +35,8 @@ impl MinioClient { /// /// ```no_run /// use minio::s3::MinioClient; + /// use minio::s3::creds::StaticProvider; + /// use minio::s3::http::BaseUrl; /// use minio::s3::response::{AppendObjectResponse, PutObjectResponse}; /// use minio::s3::segmented_bytes::SegmentedBytes; /// use minio::s3::types::S3Api; @@ -42,7 +44,9 @@ impl MinioClient { /// /// #[tokio::main] /// async fn main() { - /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here + /// let base_url = "http://localhost:9000/".parse::().unwrap(); + /// let static_provider = StaticProvider::new("minioadmin", "minioadmin", None); + /// let client = MinioClient::new(base_url, Some(static_provider), None, None).unwrap(); /// let data1: SegmentedBytes = SegmentedBytes::from("aaaa".to_string()); /// let data2: SegmentedBytes = SegmentedBytes::from("bbbb".to_string()); /// let resp: PutObjectResponse = client @@ -83,6 +87,8 @@ impl MinioClient { /// /// ```no_run /// use minio::s3::MinioClient; + /// use minio::s3::creds::StaticProvider; + /// use minio::s3::http::BaseUrl; /// use minio::s3::response::{AppendObjectResponse, PutObjectResponse}; /// use minio::s3::builders::ObjectContent; /// use minio::s3::segmented_bytes::SegmentedBytes; @@ -91,7 +97,9 @@ impl MinioClient { /// /// #[tokio::main] /// async fn main() { - /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here + /// let base_url = "http://localhost:9000/".parse::().unwrap(); + /// let static_provider = StaticProvider::new("minioadmin", "minioadmin", None); + /// let client = MinioClient::new(base_url, Some(static_provider), None, None).unwrap(); /// let data1: SegmentedBytes = SegmentedBytes::from("aaaa".to_string()); /// let content2: String = "bbbb".to_string(); /// let resp: PutObjectResponse = client diff --git a/src/s3/client/bucket_exists.rs b/src/s3/client/bucket_exists.rs index c42a6071..8b1e8d36 100644 --- a/src/s3/client/bucket_exists.rs +++ b/src/s3/client/bucket_exists.rs @@ -26,13 +26,17 @@ impl MinioClient { /// /// ```no_run /// use minio::s3::MinioClient; + /// use minio::s3::creds::StaticProvider; + /// use minio::s3::http::BaseUrl; /// use minio::s3::response::BucketExistsResponse; /// use minio::s3::types::S3Api; /// use minio::s3::response::a_response_traits::HasBucket; /// /// #[tokio::main] /// async fn main() { - /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here + /// let base_url = "http://localhost:9000/".parse::().unwrap(); + /// let static_provider = StaticProvider::new("minioadmin", "minioadmin", None); + /// let client = MinioClient::new(base_url, Some(static_provider), None, None).unwrap(); /// let resp: BucketExistsResponse = client /// .bucket_exists("bucket-name") /// .build().send().await.unwrap(); diff --git a/src/s3/client/copy_object.rs b/src/s3/client/copy_object.rs index 97dfef7d..7019033a 100644 --- a/src/s3/client/copy_object.rs +++ b/src/s3/client/copy_object.rs @@ -31,6 +31,8 @@ impl MinioClient { /// /// ```no_run /// use minio::s3::MinioClient; + /// use minio::s3::creds::StaticProvider; + /// use minio::s3::http::BaseUrl; /// use minio::s3::response::UploadPartCopyResponse; /// use minio::s3::segmented_bytes::SegmentedBytes; /// use minio::s3::types::S3Api; @@ -38,7 +40,9 @@ impl MinioClient { /// /// #[tokio::main] /// async fn main() { - /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here + /// let base_url = "http://localhost:9000/".parse::().unwrap(); + /// let static_provider = StaticProvider::new("minioadmin", "minioadmin", None); + /// let client = MinioClient::new(base_url, Some(static_provider), None, None).unwrap(); /// let data1: SegmentedBytes = SegmentedBytes::from("aaaa".to_string()); /// todo!(); /// let resp: UploadPartCopyResponse = client @@ -95,6 +99,8 @@ impl MinioClient { /// /// ```no_run /// use minio::s3::MinioClient; + /// use minio::s3::creds::StaticProvider; + /// use minio::s3::http::BaseUrl; /// use minio::s3::response::CopyObjectResponse; /// use minio::s3::builders::CopySource; /// use minio::s3::types::S3Api; @@ -102,7 +108,9 @@ impl MinioClient { /// #[tokio::main] /// async fn main() { /// use minio::s3::response::a_response_traits::HasVersion; - /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here + /// let base_url = "http://localhost:9000/".parse::().unwrap(); + /// let static_provider = StaticProvider::new("minioadmin", "minioadmin", None); + /// let client = MinioClient::new(base_url, Some(static_provider), None, None).unwrap(); /// let resp: CopyObjectResponse = client /// .copy_object("bucket-name-dst", "object-name-dst") /// .source(CopySource::builder().bucket("bucket-name-src").object("object-name-src").build()) diff --git a/src/s3/client/create_bucket.rs b/src/s3/client/create_bucket.rs index 566ce027..1723d560 100644 --- a/src/s3/client/create_bucket.rs +++ b/src/s3/client/create_bucket.rs @@ -26,13 +26,17 @@ impl MinioClient { /// /// ```no_run /// use minio::s3::MinioClient; + /// use minio::s3::creds::StaticProvider; + /// use minio::s3::http::BaseUrl; /// use minio::s3::response::CreateBucketResponse; /// use minio::s3::types::S3Api; /// use minio::s3::response::a_response_traits::{HasBucket, HasRegion}; /// /// #[tokio::main] /// async fn main() { - /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here + /// let base_url = "http://localhost:9000/".parse::().unwrap(); + /// let static_provider = StaticProvider::new("minioadmin", "minioadmin", None); + /// let client = MinioClient::new(base_url, Some(static_provider), None, None).unwrap(); /// let resp: CreateBucketResponse = client /// .create_bucket("bucket-name") /// .build().send().await.unwrap(); diff --git a/src/s3/client/delete_bucket.rs b/src/s3/client/delete_bucket.rs index 0e1bbea7..935e15a5 100644 --- a/src/s3/client/delete_bucket.rs +++ b/src/s3/client/delete_bucket.rs @@ -38,13 +38,17 @@ impl MinioClient { /// /// ```no_run /// use minio::s3::MinioClient; + /// use minio::s3::creds::StaticProvider; + /// use minio::s3::http::BaseUrl; /// use minio::s3::response::DeleteBucketResponse; /// use minio::s3::types::S3Api; /// use minio::s3::response::a_response_traits::{HasBucket, HasRegion}; /// /// #[tokio::main] /// async fn main() { - /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here + /// let base_url = "http://localhost:9000/".parse::().unwrap(); + /// let static_provider = StaticProvider::new("minioadmin", "minioadmin", None); + /// let client = MinioClient::new(base_url, Some(static_provider), None, None).unwrap(); /// let resp: DeleteBucketResponse = client /// .delete_bucket("bucket-name") /// .build().send().await.unwrap(); @@ -66,7 +70,12 @@ impl MinioClient { let resp: BucketExistsResponse = self.bucket_exists(&bucket).build().send().await?; if !resp.exists { // if the bucket does not exist, we can return early - let dummy: S3Request = S3Request::builder().client(self.clone()).method(Method::DELETE).bucket(bucket).headers(MultiMap::default()).build(/* S3RequestBuilder_Error_Missing_required_field_headers */); + let dummy: S3Request = S3Request::builder() + .client(self.clone()) + .method(Method::DELETE) + .bucket(bucket) + .headers(MultiMap::default()) + .build(); return Ok(DeleteBucketResponse { request: dummy, //TODO consider how to handle this @@ -141,7 +150,12 @@ impl MinioClient { Ok(resp) => Ok(resp), Err(Error::S3Server(S3Error(mut e))) => { if matches!(e.code(), MinioErrorCode::NoSuchBucket) { - let dummy: S3Request = S3Request::builder().client(self.clone()).method(Method::DELETE).bucket(bucket).headers(MultiMap::default()).build(/* S3RequestBuilder_Error_Missing_required_field_headers */); + let dummy: S3Request = S3Request::builder() + .client(self.clone()) + .method(Method::DELETE) + .bucket(bucket) + .headers(MultiMap::default()) + .build(); Ok(DeleteBucketResponse { request: dummy, //TODO consider how to handle this diff --git a/src/s3/client/delete_bucket_encryption.rs b/src/s3/client/delete_bucket_encryption.rs index a25e11e1..8cfc45a9 100644 --- a/src/s3/client/delete_bucket_encryption.rs +++ b/src/s3/client/delete_bucket_encryption.rs @@ -26,13 +26,17 @@ impl MinioClient { /// /// ```no_run /// use minio::s3::MinioClient; + /// use minio::s3::creds::StaticProvider; + /// use minio::s3::http::BaseUrl; /// use minio::s3::response::DeleteBucketEncryptionResponse; /// use minio::s3::types::S3Api; /// use minio::s3::response::a_response_traits::HasBucket; /// /// #[tokio::main] /// async fn main() { - /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here + /// let base_url = "http://localhost:9000/".parse::().unwrap(); + /// let static_provider = StaticProvider::new("minioadmin", "minioadmin", None); + /// let client = MinioClient::new(base_url, Some(static_provider), None, None).unwrap(); /// let resp: DeleteBucketEncryptionResponse = client /// .delete_bucket_encryption("bucket-name") /// .build().send().await.unwrap(); diff --git a/src/s3/client/delete_bucket_lifecycle.rs b/src/s3/client/delete_bucket_lifecycle.rs index 4489e434..287a8502 100644 --- a/src/s3/client/delete_bucket_lifecycle.rs +++ b/src/s3/client/delete_bucket_lifecycle.rs @@ -26,13 +26,17 @@ impl MinioClient { /// /// ```no_run /// use minio::s3::MinioClient; + /// use minio::s3::creds::StaticProvider; + /// use minio::s3::http::BaseUrl; /// use minio::s3::response::DeleteBucketLifecycleResponse; /// use minio::s3::types::S3Api; /// use minio::s3::response::a_response_traits::HasBucket; /// /// #[tokio::main] /// async fn main() { - /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here + /// let base_url = "http://localhost:9000/".parse::().unwrap(); + /// let static_provider = StaticProvider::new("minioadmin", "minioadmin", None); + /// let client = MinioClient::new(base_url, Some(static_provider), None, None).unwrap(); /// let resp: DeleteBucketLifecycleResponse = client /// .delete_bucket_lifecycle("bucket-name") /// .build().send().await.unwrap(); diff --git a/src/s3/client/delete_bucket_notification.rs b/src/s3/client/delete_bucket_notification.rs index a9c2df90..fd9e7650 100644 --- a/src/s3/client/delete_bucket_notification.rs +++ b/src/s3/client/delete_bucket_notification.rs @@ -26,13 +26,17 @@ impl MinioClient { /// /// ```no_run /// use minio::s3::MinioClient; + /// use minio::s3::creds::StaticProvider; + /// use minio::s3::http::BaseUrl; /// use minio::s3::response::DeleteBucketNotificationResponse; /// use minio::s3::types::S3Api; /// use minio::s3::response::a_response_traits::HasBucket; /// /// #[tokio::main] /// async fn main() { - /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here + /// let base_url = "http://localhost:9000/".parse::().unwrap(); + /// let static_provider = StaticProvider::new("minioadmin", "minioadmin", None); + /// let client = MinioClient::new(base_url, Some(static_provider), None, None).unwrap(); /// let resp: DeleteBucketNotificationResponse = client /// .delete_bucket_notification("bucket-name") /// .build().send().await.unwrap(); diff --git a/src/s3/client/delete_bucket_policy.rs b/src/s3/client/delete_bucket_policy.rs index 1f3676eb..f77d7e4f 100644 --- a/src/s3/client/delete_bucket_policy.rs +++ b/src/s3/client/delete_bucket_policy.rs @@ -26,13 +26,17 @@ impl MinioClient { /// /// ```no_run /// use minio::s3::MinioClient; + /// use minio::s3::creds::StaticProvider; + /// use minio::s3::http::BaseUrl; /// use minio::s3::response::DeleteBucketPolicyResponse; /// use minio::s3::types::S3Api; /// use minio::s3::response::a_response_traits::HasBucket; /// /// #[tokio::main] /// async fn main() { - /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here + /// let base_url = "http://localhost:9000/".parse::().unwrap(); + /// let static_provider = StaticProvider::new("minioadmin", "minioadmin", None); + /// let client = MinioClient::new(base_url, Some(static_provider), None, None).unwrap(); /// let resp: DeleteBucketPolicyResponse = client /// .delete_bucket_policy("bucket-name") /// .build().send().await.unwrap(); diff --git a/src/s3/client/delete_bucket_replication.rs b/src/s3/client/delete_bucket_replication.rs index 9f52ca5e..73f36868 100644 --- a/src/s3/client/delete_bucket_replication.rs +++ b/src/s3/client/delete_bucket_replication.rs @@ -28,13 +28,17 @@ impl MinioClient { /// /// ```no_run /// use minio::s3::MinioClient; + /// use minio::s3::creds::StaticProvider; + /// use minio::s3::http::BaseUrl; /// use minio::s3::response::DeleteBucketReplicationResponse; /// use minio::s3::types::S3Api; /// use minio::s3::response::a_response_traits::HasBucket; /// /// #[tokio::main] /// async fn main() { - /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here + /// let base_url = "http://localhost:9000/".parse::().unwrap(); + /// let static_provider = StaticProvider::new("minioadmin", "minioadmin", None); + /// let client = MinioClient::new(base_url, Some(static_provider), None, None).unwrap(); /// let resp: DeleteBucketReplicationResponse = client /// .delete_bucket_replication("bucket-name") /// .build().send().await.unwrap(); diff --git a/src/s3/client/delete_bucket_tagging.rs b/src/s3/client/delete_bucket_tagging.rs index e35a2dc2..d4c38a37 100644 --- a/src/s3/client/delete_bucket_tagging.rs +++ b/src/s3/client/delete_bucket_tagging.rs @@ -28,13 +28,17 @@ impl MinioClient { /// /// ```no_run /// use minio::s3::MinioClient; + /// use minio::s3::creds::StaticProvider; + /// use minio::s3::http::BaseUrl; /// use minio::s3::response::DeleteBucketTaggingResponse; /// use minio::s3::types::S3Api; /// use minio::s3::response::a_response_traits::HasBucket; /// /// #[tokio::main] /// async fn main() { - /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here + /// let base_url = "http://localhost:9000/".parse::().unwrap(); + /// let static_provider = StaticProvider::new("minioadmin", "minioadmin", None); + /// let client = MinioClient::new(base_url, Some(static_provider), None, None).unwrap(); /// let resp: DeleteBucketTaggingResponse = client /// .delete_bucket_tagging("bucket-name") /// .build().send().await.unwrap(); diff --git a/src/s3/client/delete_object_lock_config.rs b/src/s3/client/delete_object_lock_config.rs index 15f286fd..ab6b38cd 100644 --- a/src/s3/client/delete_object_lock_config.rs +++ b/src/s3/client/delete_object_lock_config.rs @@ -28,13 +28,17 @@ impl MinioClient { /// /// ```no_run /// use minio::s3::MinioClient; + /// use minio::s3::creds::StaticProvider; + /// use minio::s3::http::BaseUrl; /// use minio::s3::response::{DeleteObjectLockConfigResponse, CreateBucketResponse, PutObjectLockConfigResponse}; /// use minio::s3::types::{S3Api, ObjectLockConfig, RetentionMode}; /// use minio::s3::response::a_response_traits::HasBucket; /// /// #[tokio::main] /// async fn main() { - /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here + /// let base_url = "http://localhost:9000/".parse::().unwrap(); + /// let static_provider = StaticProvider::new("minioadmin", "minioadmin", None); + /// let client = MinioClient::new(base_url, Some(static_provider), None, None).unwrap(); /// let bucket_name = "bucket-name"; /// /// let resp: CreateBucketResponse = client diff --git a/src/s3/client/delete_object_tagging.rs b/src/s3/client/delete_object_tagging.rs index b80119fa..4ce99344 100644 --- a/src/s3/client/delete_object_tagging.rs +++ b/src/s3/client/delete_object_tagging.rs @@ -28,13 +28,17 @@ impl MinioClient { /// /// ```no_run /// use minio::s3::MinioClient; + /// use minio::s3::creds::StaticProvider; + /// use minio::s3::http::BaseUrl; /// use minio::s3::response::DeleteObjectTaggingResponse; /// use minio::s3::types::S3Api; /// use minio::s3::response::a_response_traits::{HasBucket, HasObject}; /// /// #[tokio::main] /// async fn main() { - /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here + /// let base_url = "http://localhost:9000/".parse::().unwrap(); + /// let static_provider = StaticProvider::new("minioadmin", "minioadmin", None); + /// let client = MinioClient::new(base_url, Some(static_provider), None, None).unwrap(); /// let resp: DeleteObjectTaggingResponse = client /// .delete_object_tagging("bucket-name", "object_name") /// .build().send().await.unwrap(); diff --git a/src/s3/client/delete_objects.rs b/src/s3/client/delete_objects.rs index b2f3f152..7fe5d9ac 100644 --- a/src/s3/client/delete_objects.rs +++ b/src/s3/client/delete_objects.rs @@ -29,6 +29,8 @@ impl MinioClient { /// /// ```no_run /// use minio::s3::MinioClient; + /// use minio::s3::creds::StaticProvider; + /// use minio::s3::http::BaseUrl; /// use minio::s3::response::DeleteObjectResponse; /// use minio::s3::builders::ObjectToDelete; /// use minio::s3::types::S3Api; @@ -36,7 +38,9 @@ impl MinioClient { /// /// #[tokio::main] /// async fn main() { - /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here + /// let base_url = "http://localhost:9000/".parse::().unwrap(); + /// let static_provider = StaticProvider::new("minioadmin", "minioadmin", None); + /// let client = MinioClient::new(base_url, Some(static_provider), None, None).unwrap(); /// let resp: DeleteObjectResponse = client /// .delete_object("bucket-name", ObjectToDelete::from("object-name")) /// .build().send().await.unwrap(); diff --git a/src/s3/client/get_bucket_encryption.rs b/src/s3/client/get_bucket_encryption.rs index 242eed5c..49a61ef2 100644 --- a/src/s3/client/get_bucket_encryption.rs +++ b/src/s3/client/get_bucket_encryption.rs @@ -26,13 +26,17 @@ impl MinioClient { /// /// ```no_run /// use minio::s3::MinioClient; + /// use minio::s3::creds::StaticProvider; + /// use minio::s3::http::BaseUrl; /// use minio::s3::response::GetBucketEncryptionResponse; /// use minio::s3::types::S3Api; /// use minio::s3::response::a_response_traits::HasBucket; /// /// #[tokio::main] /// async fn main() { - /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here + /// let base_url = "http://localhost:9000/".parse::().unwrap(); + /// let static_provider = StaticProvider::new("minioadmin", "minioadmin", None); + /// let client = MinioClient::new(base_url, Some(static_provider), None, None).unwrap(); /// let resp: GetBucketEncryptionResponse = client /// .get_bucket_encryption("bucket-name") /// .build().send().await.unwrap(); diff --git a/src/s3/client/get_bucket_lifecycle.rs b/src/s3/client/get_bucket_lifecycle.rs index ecf31ed4..ceaa799e 100644 --- a/src/s3/client/get_bucket_lifecycle.rs +++ b/src/s3/client/get_bucket_lifecycle.rs @@ -26,13 +26,17 @@ impl MinioClient { /// /// ```no_run /// use minio::s3::MinioClient; + /// use minio::s3::creds::StaticProvider; + /// use minio::s3::http::BaseUrl; /// use minio::s3::response::GetBucketLifecycleResponse; /// use minio::s3::types::S3Api; /// use minio::s3::response::a_response_traits::HasBucket; /// /// #[tokio::main] /// async fn main() { - /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here + /// let base_url = "http://localhost:9000/".parse::().unwrap(); + /// let static_provider = StaticProvider::new("minioadmin", "minioadmin", None); + /// let client = MinioClient::new(base_url, Some(static_provider), None, None).unwrap(); /// let resp: GetBucketLifecycleResponse = client /// .get_bucket_lifecycle("bucket-name") /// .build().send().await.unwrap(); diff --git a/src/s3/client/get_bucket_notification.rs b/src/s3/client/get_bucket_notification.rs index f41073b9..5a1c5f31 100644 --- a/src/s3/client/get_bucket_notification.rs +++ b/src/s3/client/get_bucket_notification.rs @@ -26,13 +26,17 @@ impl MinioClient { /// /// ```no_run /// use minio::s3::MinioClient; + /// use minio::s3::creds::StaticProvider; + /// use minio::s3::http::BaseUrl; /// use minio::s3::response::GetBucketNotificationResponse; /// use minio::s3::types::S3Api; /// use minio::s3::response::a_response_traits::HasBucket; /// /// #[tokio::main] /// async fn main() { - /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here + /// let base_url = "http://localhost:9000/".parse::().unwrap(); + /// let static_provider = StaticProvider::new("minioadmin", "minioadmin", None); + /// let client = MinioClient::new(base_url, Some(static_provider), None, None).unwrap(); /// let resp: GetBucketNotificationResponse = client /// .get_bucket_notification("bucket-name") /// .build().send().await.unwrap(); diff --git a/src/s3/client/get_bucket_policy.rs b/src/s3/client/get_bucket_policy.rs index 6952dead..4e33e76e 100644 --- a/src/s3/client/get_bucket_policy.rs +++ b/src/s3/client/get_bucket_policy.rs @@ -26,13 +26,17 @@ impl MinioClient { /// /// ```no_run /// use minio::s3::MinioClient; + /// use minio::s3::creds::StaticProvider; + /// use minio::s3::http::BaseUrl; /// use minio::s3::response::GetBucketPolicyResponse; /// use minio::s3::types::S3Api; /// use minio::s3::response::a_response_traits::HasBucket; /// /// #[tokio::main] /// async fn main() { - /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here + /// let base_url = "http://localhost:9000/".parse::().unwrap(); + /// let static_provider = StaticProvider::new("minioadmin", "minioadmin", None); + /// let client = MinioClient::new(base_url, Some(static_provider), None, None).unwrap(); /// let resp: GetBucketPolicyResponse = client /// .get_bucket_policy("bucket-name") /// .build().send().await.unwrap(); diff --git a/src/s3/client/get_bucket_replication.rs b/src/s3/client/get_bucket_replication.rs index a3f3af70..17722219 100644 --- a/src/s3/client/get_bucket_replication.rs +++ b/src/s3/client/get_bucket_replication.rs @@ -28,13 +28,17 @@ impl MinioClient { /// /// ```no_run /// use minio::s3::MinioClient; + /// use minio::s3::creds::StaticProvider; + /// use minio::s3::http::BaseUrl; /// use minio::s3::response::GetBucketReplicationResponse; /// use minio::s3::types::S3Api; /// use minio::s3::response::a_response_traits::HasBucket; /// /// #[tokio::main] /// async fn main() { - /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here + /// let base_url = "http://localhost:9000/".parse::().unwrap(); + /// let static_provider = StaticProvider::new("minioadmin", "minioadmin", None); + /// let client = MinioClient::new(base_url, Some(static_provider), None, None).unwrap(); /// let resp: GetBucketReplicationResponse = client /// .get_bucket_replication("bucket-name") /// .build().send().await.unwrap(); diff --git a/src/s3/client/get_bucket_tagging.rs b/src/s3/client/get_bucket_tagging.rs index 4d1bde96..28422161 100644 --- a/src/s3/client/get_bucket_tagging.rs +++ b/src/s3/client/get_bucket_tagging.rs @@ -28,13 +28,17 @@ impl MinioClient { /// /// ```no_run /// use minio::s3::MinioClient; + /// use minio::s3::creds::StaticProvider; + /// use minio::s3::http::BaseUrl; /// use minio::s3::response::GetBucketTaggingResponse; /// use minio::s3::types::S3Api; /// use minio::s3::response::a_response_traits::{HasBucket, HasTagging}; /// /// #[tokio::main] /// async fn main() { - /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here + /// let base_url = "http://localhost:9000/".parse::().unwrap(); + /// let static_provider = StaticProvider::new("minioadmin", "minioadmin", None); + /// let client = MinioClient::new(base_url, Some(static_provider), None, None).unwrap(); /// let resp: GetBucketTaggingResponse = client /// .get_bucket_tagging("bucket-name") /// .build().send().await.unwrap(); diff --git a/src/s3/client/get_bucket_versioning.rs b/src/s3/client/get_bucket_versioning.rs index ac808fb7..db8d7671 100644 --- a/src/s3/client/get_bucket_versioning.rs +++ b/src/s3/client/get_bucket_versioning.rs @@ -28,13 +28,17 @@ impl MinioClient { /// /// ```no_run /// use minio::s3::MinioClient; + /// use minio::s3::creds::StaticProvider; + /// use minio::s3::http::BaseUrl; /// use minio::s3::response::GetBucketVersioningResponse; /// use minio::s3::types::S3Api; /// use minio::s3::response::a_response_traits::HasBucket; /// /// #[tokio::main] /// async fn main() { - /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here + /// let base_url = "http://localhost:9000/".parse::().unwrap(); + /// let static_provider = StaticProvider::new("minioadmin", "minioadmin", None); + /// let client = MinioClient::new(base_url, Some(static_provider), None, None).unwrap(); /// let resp: GetBucketVersioningResponse = client /// .get_bucket_versioning("bucket-name") /// .build().send().await.unwrap(); diff --git a/src/s3/client/get_object.rs b/src/s3/client/get_object.rs index 1c35ab4b..35b2b19c 100644 --- a/src/s3/client/get_object.rs +++ b/src/s3/client/get_object.rs @@ -29,12 +29,16 @@ impl MinioClient { /// /// ```no_run /// use minio::s3::MinioClient; + /// use minio::s3::creds::StaticProvider; + /// use minio::s3::http::BaseUrl; /// use minio::s3::response::GetObjectResponse; /// use minio::s3::types::S3Api; /// /// #[tokio::main] /// async fn main() { - /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here + /// let base_url = "http://localhost:9000/".parse::().unwrap(); + /// let static_provider = StaticProvider::new("minioadmin", "minioadmin", None); + /// let client = MinioClient::new(base_url, Some(static_provider), None, None).unwrap(); /// let resp: GetObjectResponse = client /// .get_object("bucket-name", "object-name") /// .build().send().await.unwrap(); diff --git a/src/s3/client/get_object_legal_hold.rs b/src/s3/client/get_object_legal_hold.rs index 6af5f9cc..2eb1acf7 100644 --- a/src/s3/client/get_object_legal_hold.rs +++ b/src/s3/client/get_object_legal_hold.rs @@ -28,13 +28,17 @@ impl MinioClient { /// /// ```no_run /// use minio::s3::MinioClient; + /// use minio::s3::creds::StaticProvider; + /// use minio::s3::http::BaseUrl; /// use minio::s3::response::GetObjectLegalHoldResponse; /// use minio::s3::types::S3Api; /// use minio::s3::response::a_response_traits::{HasBucket, HasObject}; /// /// #[tokio::main] /// async fn main() { - /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here + /// let base_url = "http://localhost:9000/".parse::().unwrap(); + /// let static_provider = StaticProvider::new("minioadmin", "minioadmin", None); + /// let client = MinioClient::new(base_url, Some(static_provider), None, None).unwrap(); /// let resp: GetObjectLegalHoldResponse = client /// .get_object_legal_hold("bucket-name", "object-name") /// .build().send().await.unwrap(); diff --git a/src/s3/client/get_object_lock_config.rs b/src/s3/client/get_object_lock_config.rs index d7475bfe..c5a6654b 100644 --- a/src/s3/client/get_object_lock_config.rs +++ b/src/s3/client/get_object_lock_config.rs @@ -28,13 +28,17 @@ impl MinioClient { /// /// ```no_run /// use minio::s3::MinioClient; + /// use minio::s3::creds::StaticProvider; + /// use minio::s3::http::BaseUrl; /// use minio::s3::response::GetObjectLockConfigResponse; /// use minio::s3::types::S3Api; /// use minio::s3::response::a_response_traits::HasBucket; /// /// #[tokio::main] /// async fn main() { - /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here + /// let base_url = "http://localhost:9000/".parse::().unwrap(); + /// let static_provider = StaticProvider::new("minioadmin", "minioadmin", None); + /// let client = MinioClient::new(base_url, Some(static_provider), None, None).unwrap(); /// let resp: GetObjectLockConfigResponse = client /// .get_object_lock_config("bucket-name") /// .build().send().await.unwrap(); diff --git a/src/s3/client/get_object_prompt.rs b/src/s3/client/get_object_prompt.rs index 2ba2317f..399a7442 100644 --- a/src/s3/client/get_object_prompt.rs +++ b/src/s3/client/get_object_prompt.rs @@ -27,12 +27,16 @@ impl MinioClient { /// /// ```no_run /// use minio::s3::MinioClient; + /// use minio::s3::creds::StaticProvider; + /// use minio::s3::http::BaseUrl; /// use minio::s3::response::GetObjectPromptResponse; /// use minio::s3::types::S3Api; /// /// #[tokio::main] /// async fn main() { - /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here + /// let base_url = "http://localhost:9000/".parse::().unwrap(); + /// let static_provider = StaticProvider::new("minioadmin", "minioadmin", None); + /// let client = MinioClient::new(base_url, Some(static_provider), None, None).unwrap(); /// let resp: GetObjectPromptResponse = client /// .get_object_prompt("bucket-name", "object-name", "What is it about?") /// .build().send().await.unwrap(); diff --git a/src/s3/client/get_object_retention.rs b/src/s3/client/get_object_retention.rs index c9072d53..07199948 100644 --- a/src/s3/client/get_object_retention.rs +++ b/src/s3/client/get_object_retention.rs @@ -28,13 +28,17 @@ impl MinioClient { /// /// ```no_run /// use minio::s3::MinioClient; + /// use minio::s3::creds::StaticProvider; + /// use minio::s3::http::BaseUrl; /// use minio::s3::response::GetObjectRetentionResponse; /// use minio::s3::types::S3Api; /// use minio::s3::response::a_response_traits::HasBucket; /// /// #[tokio::main] /// async fn main() { - /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here + /// let base_url = "http://localhost:9000/".parse::().unwrap(); + /// let static_provider = StaticProvider::new("minioadmin", "minioadmin", None); + /// let client = MinioClient::new(base_url, Some(static_provider), None, None).unwrap(); /// let resp: GetObjectRetentionResponse = client /// .get_object_retention("bucket-name", "object-name") /// .build().send().await.unwrap(); diff --git a/src/s3/client/get_object_tagging.rs b/src/s3/client/get_object_tagging.rs index 085eb1ea..a38662ea 100644 --- a/src/s3/client/get_object_tagging.rs +++ b/src/s3/client/get_object_tagging.rs @@ -28,13 +28,17 @@ impl MinioClient { /// /// ```no_run /// use minio::s3::MinioClient; + /// use minio::s3::creds::StaticProvider; + /// use minio::s3::http::BaseUrl; /// use minio::s3::response::GetObjectTaggingResponse; /// use minio::s3::types::S3Api; /// use minio::s3::response::a_response_traits::{HasBucket, HasObject, HasTagging}; /// /// #[tokio::main] /// async fn main() { - /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here + /// let base_url = "http://localhost:9000/".parse::().unwrap(); + /// let static_provider = StaticProvider::new("minioadmin", "minioadmin", None); + /// let client = MinioClient::new(base_url, Some(static_provider), None, None).unwrap(); /// let resp: GetObjectTaggingResponse = client /// .get_object_tagging("bucket-name", "object-name") /// .build().send().await.unwrap(); diff --git a/src/s3/client/get_presigned_object_url.rs b/src/s3/client/get_presigned_object_url.rs index 42fa1109..ad341528 100644 --- a/src/s3/client/get_presigned_object_url.rs +++ b/src/s3/client/get_presigned_object_url.rs @@ -28,12 +28,16 @@ impl MinioClient { /// ```no_run /// use http::Method; /// use minio::s3::MinioClient; + /// use minio::s3::creds::StaticProvider; + /// use minio::s3::http::BaseUrl; /// use minio::s3::response::GetPresignedObjectUrlResponse; /// use minio::s3::types::S3Api; /// /// #[tokio::main] /// async fn main() { - /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here + /// let base_url = "http://localhost:9000/".parse::().unwrap(); + /// let static_provider = StaticProvider::new("minioadmin", "minioadmin", None); + /// let client = MinioClient::new(base_url, Some(static_provider), None, None).unwrap(); /// let resp: GetPresignedObjectUrlResponse = client /// .get_presigned_object_url("bucket-name", "object-name", Method::GET) /// .build().send().await.unwrap(); diff --git a/src/s3/client/get_presigned_post_form_data.rs b/src/s3/client/get_presigned_post_form_data.rs index c562d4ee..76dde969 100644 --- a/src/s3/client/get_presigned_post_form_data.rs +++ b/src/s3/client/get_presigned_post_form_data.rs @@ -29,6 +29,8 @@ impl MinioClient { /// use std::collections::HashMap; /// use chrono::{DateTime, Utc}; /// use minio::s3::MinioClient; + /// use minio::s3::creds::StaticProvider; + /// use minio::s3::http::BaseUrl; /// use minio::s3::types::S3Api; /// use minio::s3::builders::PostPolicy; /// use minio::s3::utils::utc_now; @@ -45,7 +47,9 @@ impl MinioClient { /// /// #[tokio::main] /// async fn main() { - /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here + /// let base_url = "http://localhost:9000/".parse::().unwrap(); + /// let static_provider = StaticProvider::new("minioadmin", "minioadmin", None); + /// let client = MinioClient::new(base_url, Some(static_provider), None, None).unwrap(); /// let policy: PostPolicy = create_post_policy_example("bucket-name", "object-name"); /// let resp: HashMap = client /// .get_presigned_post_form_data(policy) diff --git a/src/s3/client/get_region.rs b/src/s3/client/get_region.rs index 53d04c21..1ccde5c5 100644 --- a/src/s3/client/get_region.rs +++ b/src/s3/client/get_region.rs @@ -28,13 +28,17 @@ impl MinioClient { /// /// ```no_run /// use minio::s3::MinioClient; + /// use minio::s3::creds::StaticProvider; + /// use minio::s3::http::BaseUrl; /// use minio::s3::response::GetRegionResponse; /// use minio::s3::types::S3Api; /// use minio::s3::response::a_response_traits::HasBucket; /// /// #[tokio::main] /// async fn main() { - /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here + /// let base_url = "http://localhost:9000/".parse::().unwrap(); + /// let static_provider = StaticProvider::new("minioadmin", "minioadmin", None); + /// let client = MinioClient::new(base_url, Some(static_provider), None, None).unwrap(); /// let resp: GetRegionResponse = client /// .get_region("bucket-name") /// .build().send().await.unwrap(); diff --git a/src/s3/client/list_buckets.rs b/src/s3/client/list_buckets.rs index d8d17875..53fb4eac 100644 --- a/src/s3/client/list_buckets.rs +++ b/src/s3/client/list_buckets.rs @@ -28,12 +28,16 @@ impl MinioClient { /// /// ```no_run /// use minio::s3::MinioClient; + /// use minio::s3::creds::StaticProvider; + /// use minio::s3::http::BaseUrl; /// use minio::s3::response::ListBucketsResponse; /// use minio::s3::types::S3Api; /// /// #[tokio::main] /// async fn main() { - /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here + /// let base_url = "http://localhost:9000/".parse::().unwrap(); + /// let static_provider = StaticProvider::new("minioadmin", "minioadmin", None); + /// let client = MinioClient::new(base_url, Some(static_provider), None, None).unwrap(); /// let resp: ListBucketsResponse = client /// .list_buckets() /// .build().send().await.unwrap(); diff --git a/src/s3/client/list_objects.rs b/src/s3/client/list_objects.rs index 7c1864ed..20d25694 100644 --- a/src/s3/client/list_objects.rs +++ b/src/s3/client/list_objects.rs @@ -30,12 +30,16 @@ impl MinioClient { /// /// ```no_run /// use minio::s3::MinioClient; + /// use minio::s3::creds::StaticProvider; + /// use minio::s3::http::BaseUrl; /// use minio::s3::types::{ToStream, S3Api}; /// use futures_util::StreamExt; /// /// #[tokio::main] /// async fn main() { - /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here + /// let base_url = "http://localhost:9000/".parse::().unwrap(); + /// let static_provider = StaticProvider::new("minioadmin", "minioadmin", None); + /// let client = MinioClient::new(base_url, Some(static_provider), None, None).unwrap(); /// /// let mut resp = client /// .list_objects("bucket-name") diff --git a/src/s3/client/listen_bucket_notification.rs b/src/s3/client/listen_bucket_notification.rs index cfff25a0..9c40b7ca 100644 --- a/src/s3/client/listen_bucket_notification.rs +++ b/src/s3/client/listen_bucket_notification.rs @@ -36,12 +36,16 @@ impl MinioClient { /// /// ```no_run /// use minio::s3::MinioClient; + /// use minio::s3::creds::StaticProvider; + /// use minio::s3::http::BaseUrl; /// use minio::s3::types::{NotificationRecord, NotificationRecords, S3Api}; /// use futures_util::StreamExt; /// /// #[tokio::main] /// async fn main() { - /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here + /// let base_url = "http://localhost:9000/".parse::().unwrap(); + /// let static_provider = StaticProvider::new("minioadmin", "minioadmin", None); + /// let client = MinioClient::new(base_url, Some(static_provider), None, None).unwrap(); /// let (_resp, mut event_stream) = client /// .listen_bucket_notification("bucket-name") /// .build().send().await.unwrap(); diff --git a/src/s3/client/put_bucket_encryption.rs b/src/s3/client/put_bucket_encryption.rs index e2dff47b..4d3b5c3a 100644 --- a/src/s3/client/put_bucket_encryption.rs +++ b/src/s3/client/put_bucket_encryption.rs @@ -29,13 +29,17 @@ impl MinioClient { /// ```no_run /// use minio::s3::types::SseConfig; /// use minio::s3::MinioClient; + /// use minio::s3::creds::StaticProvider; + /// use minio::s3::http::BaseUrl; /// use minio::s3::response::PutBucketEncryptionResponse; /// use minio::s3::types::S3Api; /// use minio::s3::response::a_response_traits::HasBucket; /// /// #[tokio::main] /// async fn main() { - /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here + /// let base_url = "http://localhost:9000/".parse::().unwrap(); + /// let static_provider = StaticProvider::new("minioadmin", "minioadmin", None); + /// let client = MinioClient::new(base_url, Some(static_provider), None, None).unwrap(); /// let config = SseConfig::default(); /// let resp: PutBucketEncryptionResponse = client /// .put_bucket_encryption("bucket-name") diff --git a/src/s3/client/put_bucket_lifecycle.rs b/src/s3/client/put_bucket_lifecycle.rs index 2a52fd35..4bd22cb7 100644 --- a/src/s3/client/put_bucket_lifecycle.rs +++ b/src/s3/client/put_bucket_lifecycle.rs @@ -27,6 +27,8 @@ impl MinioClient { /// ```no_run /// use std::collections::HashMap; /// use minio::s3::MinioClient; + /// use minio::s3::creds::StaticProvider; + /// use minio::s3::http::BaseUrl; /// use minio::s3::builders::VersioningStatus; /// use minio::s3::response::PutBucketLifecycleResponse; /// use minio::s3::types::{Filter, S3Api}; @@ -35,7 +37,9 @@ impl MinioClient { /// /// #[tokio::main] /// async fn main() { - /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here + /// let base_url = "http://localhost:9000/".parse::().unwrap(); + /// let static_provider = StaticProvider::new("minioadmin", "minioadmin", None); + /// let client = MinioClient::new(base_url, Some(static_provider), None, None).unwrap(); /// let rules: Vec = vec![LifecycleRule { /// id: String::from("rule1"), /// filter: Filter {and_operator: None, prefix: Some(String::from("logs/")), tag: None}, diff --git a/src/s3/client/put_bucket_notification.rs b/src/s3/client/put_bucket_notification.rs index c5055394..ef72eb5f 100644 --- a/src/s3/client/put_bucket_notification.rs +++ b/src/s3/client/put_bucket_notification.rs @@ -26,13 +26,17 @@ impl MinioClient { /// /// ```no_run /// use minio::s3::MinioClient; + /// use minio::s3::creds::StaticProvider; + /// use minio::s3::http::BaseUrl; /// use minio::s3::types::{NotificationConfig, PrefixFilterRule, QueueConfig, S3Api, SuffixFilterRule}; /// use minio::s3::response::PutBucketNotificationResponse; /// use minio::s3::response::a_response_traits::HasBucket; /// /// #[tokio::main] /// async fn main() { - /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here + /// let base_url = "http://localhost:9000/".parse::().unwrap(); + /// let static_provider = StaticProvider::new("minioadmin", "minioadmin", None); + /// let client = MinioClient::new(base_url, Some(static_provider), None, None).unwrap(); /// let config = NotificationConfig { /// cloud_func_config_list: None, /// queue_config_list: Some(vec![QueueConfig { diff --git a/src/s3/client/put_bucket_policy.rs b/src/s3/client/put_bucket_policy.rs index 8c2e9759..4a2f47c6 100644 --- a/src/s3/client/put_bucket_policy.rs +++ b/src/s3/client/put_bucket_policy.rs @@ -27,6 +27,8 @@ impl MinioClient { /// ```no_run /// use std::collections::HashMap; /// use minio::s3::MinioClient; + /// use minio::s3::creds::StaticProvider; + /// use minio::s3::http::BaseUrl; /// use minio::s3::builders::VersioningStatus; /// use minio::s3::response::PutBucketPolicyResponse; /// use minio::s3::types::{S3Api, AndOperator, Destination, Filter, ReplicationConfig, ReplicationRule}; @@ -34,7 +36,9 @@ impl MinioClient { /// /// #[tokio::main] /// async fn main() { - /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here + /// let base_url = "http://localhost:9000/".parse::().unwrap(); + /// let static_provider = StaticProvider::new("minioadmin", "minioadmin", None); + /// let client = MinioClient::new(base_url, Some(static_provider), None, None).unwrap(); /// /// let config = r#"{ /// "Version": "2012-10-17", diff --git a/src/s3/client/put_bucket_replication.rs b/src/s3/client/put_bucket_replication.rs index 911c137f..fb1b8e93 100644 --- a/src/s3/client/put_bucket_replication.rs +++ b/src/s3/client/put_bucket_replication.rs @@ -28,6 +28,8 @@ impl MinioClient { /// /// ```no_run /// use minio::s3::MinioClient; + /// use minio::s3::creds::StaticProvider; + /// use minio::s3::http::BaseUrl; /// use minio::s3::builders::VersioningStatus; /// use minio::s3::response::PutBucketReplicationResponse; /// use minio::s3::types::{S3Api, AndOperator, Destination, Filter, ReplicationConfig, ReplicationRule}; @@ -36,7 +38,9 @@ impl MinioClient { /// /// #[tokio::main] /// async fn main() { - /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here + /// let base_url = "http://localhost:9000/".parse::().unwrap(); + /// let static_provider = StaticProvider::new("minioadmin", "minioadmin", None); + /// let client = MinioClient::new(base_url, Some(static_provider), None, None).unwrap(); /// /// let mut tags: HashMap = HashMap::new(); /// tags.insert(String::from("key1"), String::from("value1")); diff --git a/src/s3/client/put_bucket_tagging.rs b/src/s3/client/put_bucket_tagging.rs index adff893b..7cd96a99 100644 --- a/src/s3/client/put_bucket_tagging.rs +++ b/src/s3/client/put_bucket_tagging.rs @@ -28,6 +28,8 @@ impl MinioClient { /// /// ```no_run /// use minio::s3::MinioClient; + /// use minio::s3::creds::StaticProvider; + /// use minio::s3::http::BaseUrl; /// use minio::s3::builders::VersioningStatus; /// use minio::s3::response::PutBucketTaggingResponse; /// use minio::s3::types::S3Api; @@ -36,7 +38,9 @@ impl MinioClient { /// /// #[tokio::main] /// async fn main() { - /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here + /// let base_url = "http://localhost:9000/".parse::().unwrap(); + /// let static_provider = StaticProvider::new("minioadmin", "minioadmin", None); + /// let client = MinioClient::new(base_url, Some(static_provider), None, None).unwrap(); /// /// let mut tags: HashMap = HashMap::new(); /// tags.insert(String::from("Project"), String::from("Project One")); diff --git a/src/s3/client/put_bucket_versioning.rs b/src/s3/client/put_bucket_versioning.rs index 04583bc0..05c51e62 100644 --- a/src/s3/client/put_bucket_versioning.rs +++ b/src/s3/client/put_bucket_versioning.rs @@ -28,6 +28,8 @@ impl MinioClient { /// /// ```no_run /// use minio::s3::MinioClient; + /// use minio::s3::creds::StaticProvider; + /// use minio::s3::http::BaseUrl; /// use minio::s3::builders::VersioningStatus; /// use minio::s3::response::PutBucketVersioningResponse; /// use minio::s3::types::{S3Api, ObjectLockConfig, RetentionMode}; @@ -35,7 +37,9 @@ impl MinioClient { /// /// #[tokio::main] /// async fn main() { - /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here + /// let base_url = "http://localhost:9000/".parse::().unwrap(); + /// let static_provider = StaticProvider::new("minioadmin", "minioadmin", None); + /// let client = MinioClient::new(base_url, Some(static_provider), None, None).unwrap(); /// /// let resp: PutBucketVersioningResponse = client /// .put_bucket_versioning("bucket-name") diff --git a/src/s3/client/put_object.rs b/src/s3/client/put_object.rs index a8cf2a20..907471a2 100644 --- a/src/s3/client/put_object.rs +++ b/src/s3/client/put_object.rs @@ -32,7 +32,7 @@ impl MinioClient { /// /// For handling large files requiring multipart upload, see [`create_multipart_upload`](#method.create_multipart_upload). /// - /// To execute the request, call [`PutObjects::send()`](crate::s3::types::S3Api::send), + /// To execute the request, call [`PutObject::send()`](crate::s3::types::S3Api::send), /// which returns a [`Result`] containing a [`PutObjectResponse`](crate::s3::response::PutObjectResponse). /// /// For more information, refer to the [AWS S3 PutObject API documentation](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html). @@ -41,6 +41,8 @@ impl MinioClient { /// /// ```no_run /// use minio::s3::MinioClient; + /// use minio::s3::creds::StaticProvider; + /// use minio::s3::http::BaseUrl; /// use minio::s3::response::PutObjectResponse; /// use minio::s3::types::S3Api; /// use minio::s3::segmented_bytes::SegmentedBytes; @@ -48,7 +50,9 @@ impl MinioClient { /// /// #[tokio::main] /// async fn main() { - /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here + /// let base_url = "http://localhost:9000/".parse::().unwrap(); + /// let static_provider = StaticProvider::new("minioadmin", "minioadmin", None); + /// let client = MinioClient::new(base_url, Some(static_provider), None, None).unwrap(); /// let data = SegmentedBytes::from("Hello world".to_string()); /// let resp: PutObjectResponse = client /// .put_object("bucket-name", "object-name", data) @@ -82,12 +86,16 @@ impl MinioClient { /// # Example /// ```no_run /// use minio::s3::MinioClient; + /// use minio::s3::creds::StaticProvider; + /// use minio::s3::http::BaseUrl; /// use minio::s3::response::CreateMultipartUploadResponse; /// use minio::s3::types::S3Api; /// /// #[tokio::main] /// async fn main() { - /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here + /// let base_url = "http://localhost:9000/".parse::().unwrap(); + /// let static_provider = StaticProvider::new("minioadmin", "minioadmin", None); + /// let client = MinioClient::new(base_url, Some(static_provider), None, None).unwrap(); /// let resp: CreateMultipartUploadResponse = client /// .create_multipart_upload("bucket-name", "large-object") /// .build().send().await.unwrap(); @@ -116,12 +124,16 @@ impl MinioClient { /// # Example /// ```no_run /// use minio::s3::MinioClient; + /// use minio::s3::creds::StaticProvider; + /// use minio::s3::http::BaseUrl; /// use minio::s3::response::AbortMultipartUploadResponse; /// use minio::s3::types::S3Api; /// /// #[tokio::main] /// async fn main() { - /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here + /// let base_url = "http://localhost:9000/".parse::().unwrap(); + /// let static_provider = StaticProvider::new("minioadmin", "minioadmin", None); + /// let client = MinioClient::new(base_url, Some(static_provider), None, None).unwrap(); /// let resp: AbortMultipartUploadResponse = client /// .abort_multipart_upload("bucket-name", "object-name", "upload-id-123") /// .build().send().await.unwrap(); @@ -152,13 +164,17 @@ impl MinioClient { /// # Example /// ```no_run /// use minio::s3::MinioClient; + /// use minio::s3::creds::StaticProvider; + /// use minio::s3::http::BaseUrl; /// use minio::s3::response::CompleteMultipartUploadResponse; /// use minio::s3::types::{S3Api, PartInfo}; /// use minio::s3::response::a_response_traits::HasObject; /// /// #[tokio::main] /// async fn main() { - /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here + /// let base_url = "http://localhost:9000/".parse::().unwrap(); + /// let static_provider = StaticProvider::new("minioadmin", "minioadmin", None); + /// let client = MinioClient::new(base_url, Some(static_provider), None, None).unwrap(); /// let parts: Vec = vec![]; // fill with your uploaded part info /// let resp: CompleteMultipartUploadResponse = client /// .complete_multipart_upload("bucket-name", "object-name", "upload-id-123", parts) @@ -192,6 +208,8 @@ impl MinioClient { /// # Example /// ```no_run /// use minio::s3::MinioClient; + /// use minio::s3::creds::StaticProvider; + /// use minio::s3::http::BaseUrl; /// use minio::s3::response::UploadPartResponse; /// use minio::s3::types::S3Api; /// use minio::s3::segmented_bytes::SegmentedBytes; @@ -199,7 +217,9 @@ impl MinioClient { /// /// #[tokio::main] /// async fn main() { - /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here + /// let base_url = "http://localhost:9000/".parse::().unwrap(); + /// let static_provider = StaticProvider::new("minioadmin", "minioadmin", None); + /// let client = MinioClient::new(base_url, Some(static_provider), None, None).unwrap(); /// let data = SegmentedBytes::from("Some part data".to_string()); /// let resp: UploadPartResponse = client /// .upload_part("bucket-name", "object-name", "upload-id", 1, data) @@ -235,13 +255,17 @@ impl MinioClient { /// # Example /// ```no_run /// use minio::s3::MinioClient; + /// use minio::s3::creds::StaticProvider; + /// use minio::s3::http::BaseUrl; /// use minio::s3::response::PutObjectContentResponse; /// use minio::s3::types::S3Api; /// use minio::s3::response::a_response_traits::{HasObject, HasEtagFromHeaders}; /// /// #[tokio::main] /// async fn main() { - /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here + /// let base_url = "http://localhost:9000/".parse::().unwrap(); + /// let static_provider = StaticProvider::new("minioadmin", "minioadmin", None); + /// let client = MinioClient::new(base_url, Some(static_provider), None, None).unwrap(); /// let content = "Hello, world!".to_string(); /// let resp: PutObjectContentResponse = client /// .put_object_content("bucket", "object", content) diff --git a/src/s3/client/put_object_legal_hold.rs b/src/s3/client/put_object_legal_hold.rs index cdace50f..20f2c6ba 100644 --- a/src/s3/client/put_object_legal_hold.rs +++ b/src/s3/client/put_object_legal_hold.rs @@ -28,13 +28,17 @@ impl MinioClient { /// /// ```no_run /// use minio::s3::MinioClient; + /// use minio::s3::creds::StaticProvider; + /// use minio::s3::http::BaseUrl; /// use minio::s3::response::PutObjectLegalHoldResponse; /// use minio::s3::types::S3Api; /// use minio::s3::response::a_response_traits::HasBucket; /// /// #[tokio::main] /// async fn main() { - /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here + /// let base_url = "http://localhost:9000/".parse::().unwrap(); + /// let static_provider = StaticProvider::new("minioadmin", "minioadmin", None); + /// let client = MinioClient::new(base_url, Some(static_provider), None, None).unwrap(); /// let resp: PutObjectLegalHoldResponse = client /// .put_object_legal_hold("bucket-name", "object-name", true) /// .build().send().await.unwrap(); diff --git a/src/s3/client/put_object_lock_config.rs b/src/s3/client/put_object_lock_config.rs index f916efe5..5135cae1 100644 --- a/src/s3/client/put_object_lock_config.rs +++ b/src/s3/client/put_object_lock_config.rs @@ -28,13 +28,17 @@ impl MinioClient { /// /// ```no_run /// use minio::s3::MinioClient; + /// use minio::s3::creds::StaticProvider; + /// use minio::s3::http::BaseUrl; /// use minio::s3::response::{CreateBucketResponse, PutObjectLockConfigResponse}; /// use minio::s3::types::{S3Api, ObjectLockConfig, RetentionMode}; /// use minio::s3::response::a_response_traits::HasBucket; /// /// #[tokio::main] /// async fn main() { - /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here + /// let base_url = "http://localhost:9000/".parse::().unwrap(); + /// let static_provider = StaticProvider::new("minioadmin", "minioadmin", None); + /// let client = MinioClient::new(base_url, Some(static_provider), None, None).unwrap(); /// let bucket_name = "bucket-name"; /// /// let resp: CreateBucketResponse = client diff --git a/src/s3/client/put_object_retention.rs b/src/s3/client/put_object_retention.rs index d9db74f5..0ec70021 100644 --- a/src/s3/client/put_object_retention.rs +++ b/src/s3/client/put_object_retention.rs @@ -32,6 +32,8 @@ impl MinioClient { /// /// ```no_run /// use minio::s3::MinioClient; + /// use minio::s3::creds::StaticProvider; + /// use minio::s3::http::BaseUrl; /// use minio::s3::response::PutObjectRetentionResponse; /// use minio::s3::builders::ObjectToDelete; /// use minio::s3::types::{S3Api, RetentionMode}; @@ -40,7 +42,9 @@ impl MinioClient { /// /// #[tokio::main] /// async fn main() { - /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here + /// let base_url = "http://localhost:9000/".parse::().unwrap(); + /// let static_provider = StaticProvider::new("minioadmin", "minioadmin", None); + /// let client = MinioClient::new(base_url, Some(static_provider), None, None).unwrap(); /// let retain_until_date = utc_now() + chrono::Duration::days(1); /// let resp: PutObjectRetentionResponse = client /// .put_object_retention("bucket-name", "object-name") diff --git a/src/s3/client/put_object_tagging.rs b/src/s3/client/put_object_tagging.rs index a1cd74e3..3997e9b0 100644 --- a/src/s3/client/put_object_tagging.rs +++ b/src/s3/client/put_object_tagging.rs @@ -29,13 +29,17 @@ impl MinioClient { /// ```no_run /// use std::collections::HashMap; /// use minio::s3::MinioClient; + /// use minio::s3::creds::StaticProvider; + /// use minio::s3::http::BaseUrl; /// use minio::s3::response::PutObjectTaggingResponse; /// use minio::s3::types::S3Api; /// use minio::s3::response::a_response_traits::HasObject; /// /// #[tokio::main] /// async fn main() { - /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here + /// let base_url = "http://localhost:9000/".parse::().unwrap(); + /// let static_provider = StaticProvider::new("minioadmin", "minioadmin", None); + /// let client = MinioClient::new(base_url, Some(static_provider), None, None).unwrap(); /// let tags = HashMap::from([ /// (String::from("Project"), String::from("Project One")), /// (String::from("User"), String::from("jsmith")), diff --git a/src/s3/client/select_object_content.rs b/src/s3/client/select_object_content.rs index 6f114c0c..a1f69f2d 100644 --- a/src/s3/client/select_object_content.rs +++ b/src/s3/client/select_object_content.rs @@ -29,13 +29,17 @@ impl MinioClient { /// /// ```no_run /// use minio::s3::MinioClient; + /// use minio::s3::creds::StaticProvider; + /// use minio::s3::http::BaseUrl; /// use minio::s3::response::SelectObjectContentResponse; /// use minio::s3::types::S3Api; /// use minio::s3::types::{SelectRequest, CsvInputSerialization, CsvOutputSerialization, FileHeaderInfo, QuoteFields}; /// /// #[tokio::main] /// async fn main() { - /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here + /// let base_url = "http://localhost:9000/".parse::().unwrap(); + /// let static_provider = StaticProvider::new("minioadmin", "minioadmin", None); + /// let client = MinioClient::new(base_url, Some(static_provider), None, None).unwrap(); /// let request = SelectRequest::new_csv_input_output( /// "select * from S3Object", /// CsvInputSerialization { diff --git a/src/s3/client/stat_object.rs b/src/s3/client/stat_object.rs index 92b29864..b2fc1b51 100644 --- a/src/s3/client/stat_object.rs +++ b/src/s3/client/stat_object.rs @@ -26,13 +26,17 @@ impl MinioClient { /// /// ```no_run /// use minio::s3::MinioClient; + /// use minio::s3::creds::StaticProvider; + /// use minio::s3::http::BaseUrl; /// use minio::s3::response::StatObjectResponse; /// use minio::s3::types::S3Api; /// use minio::s3::response::a_response_traits::HasObject; /// /// #[tokio::main] /// async fn main() { - /// let client = MinioClient::create_client_on_localhost().unwrap(); // configure your client here + /// let base_url = "http://localhost:9000/".parse::().unwrap(); + /// let static_provider = StaticProvider::new("minioadmin", "minioadmin", None); + /// let client = MinioClient::new(base_url, Some(static_provider), None, None).unwrap(); /// let resp: StatObjectResponse = /// client.stat_object("bucket-name", "object-name").build().send().await.unwrap(); /// println!("stat of object '{}' are {:#?}", resp.object(), resp); diff --git a/src/s3/http.rs b/src/s3/http.rs index c884d43c..f7fe1a6c 100644 --- a/src/s3/http.rs +++ b/src/s3/http.rs @@ -66,17 +66,15 @@ impl Default for Url { impl fmt::Display for Url { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - if self.host.is_empty() { - return Err(std::fmt::Error); - } - if self.https { f.write_str("https://")?; } else { f.write_str("http://")?; } - if self.port > 0 { + if self.host.is_empty() { + f.write_str("")?; + } else if self.port > 0 { f.write_str(&format!("{}:{}", self.host, self.port))?; } else { f.write_str(&self.host)?; diff --git a/src/s3/utils.rs b/src/s3/utils.rs index 4a802a3f..c1b566ac 100644 --- a/src/s3/utils.rs +++ b/src/s3/utils.rs @@ -91,7 +91,7 @@ pub fn sha256_hash(data: &[u8]) -> String { } #[cfg(not(feature = "ring"))] { - hex_encode(Sha256::new_with_prefix(data).finalize().as_slice()) + hex_encode(Sha256::new_with_prefix(data).finalize().as_ref()) } } @@ -164,7 +164,7 @@ pub fn sha256_hash_sb(sb: Arc) -> String { for data in sb.iter() { hasher.update(data); } - hex_encode(hasher.finalize().as_slice()) + hex_encode(hasher.finalize().as_ref()) } } diff --git a/tests/test_upload_download_object.rs b/tests/test_upload_download_object.rs index 7021a100..214ba3f1 100644 --- a/tests/test_upload_download_object.rs +++ b/tests/test_upload_download_object.rs @@ -45,7 +45,7 @@ async fn get_hash(filename: &str) -> String { let mut buf = Vec::new(); file.read_to_end(&mut buf).await.unwrap(); hasher.update(&buf); - hex_encode(hasher.finalize().as_slice()) + hex_encode(hasher.finalize().as_ref()) } }