Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 32 additions & 30 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -33,41 +34,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.12"
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.22"

[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.48", 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"
Expand Down
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,17 @@ 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 = Default::default(); // configure your client
let base_url = "play.min.io".parse::<BaseUrl>().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")
Expand All @@ -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

Expand Down
7 changes: 6 additions & 1 deletion benches/s3/bench_bucket_exists.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
},
);
}
20 changes: 17 additions & 3 deletions benches/s3/bench_bucket_lifecycle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
},
)
}
Expand All @@ -42,19 +45,30 @@ 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) {
benchmark_s3_api(
"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()
},
)
}
20 changes: 17 additions & 3 deletions benches/s3/bench_bucket_notification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
},
)
}
Expand All @@ -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)]
Expand All @@ -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()
},
)
}
25 changes: 21 additions & 4 deletions benches/s3/bench_bucket_policy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
},
)
}
Expand All @@ -38,21 +42,34 @@ 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) {
benchmark_s3_api(
"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()
},
)
}
25 changes: 22 additions & 3 deletions benches/s3/bench_bucket_replication.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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();
Expand All @@ -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()
},
)
}
Expand All @@ -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();
Expand All @@ -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)]
Expand All @@ -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();
Expand All @@ -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()
},
)
}
20 changes: 17 additions & 3 deletions benches/s3/bench_bucket_tagging.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
},
)
}
Expand All @@ -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) {
Expand All @@ -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()
},
)
}
Loading