diff --git a/.rustfmt.toml b/.rustfmt.toml index 3a26366..751c817 100644 --- a/.rustfmt.toml +++ b/.rustfmt.toml @@ -1 +1,9 @@ -edition = "2021" +# rustfmt doc - https://rust-lang.github.io/rustfmt/ + +hard_tabs = false +edition = "2024" + +max_width = 100 +array_width = 60 # default is 60 +attr_fn_like_width = 70 # default is 70 +chain_width = 60 # default is 60 diff --git a/Cargo.toml b/Cargo.toml index ce107d3..0f46294 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "minio" version = "0.2.0-alpha" -edition = "2021" +edition = "2024" authors = ["MinIO Dev Team "] description = "MinIO SDK for Amazon S3 compatible object storage access" license = "Apache-2.0" @@ -23,33 +23,33 @@ rustls-tls = ["reqwest/rustls-tls"] [dependencies] async-recursion = "1.1.1" -async-trait = "0.1.86" +async-trait = "0.1.87" base64 = "0.22.1" byteorder = "1.5.0" -bytes = "1.9.0" -chrono = "0.4.39" +bytes = "1.10.1" +chrono = "0.4.40" crc = "3.2.1" dashmap = "6.1.0" derivative = "2.2.0" -env_logger = "0.11.6" +env_logger = "0.11.7" futures-util = "0.3.31" hex = "0.4.3" hmac = "0.12.1" -home = "0.5.9" +#home = "0.5.9" http = "1.2.0" hyper = { version = "1.6.0", features = ["full"] } lazy_static = "1.5.0" -log = "0.4.25" +log = "0.4.26" md5 = "0.7.0" multimap = "0.10.0" -os_info = "3.9.2" +os_info = "3.10.0" percent-encoding = "2.3.1" rand = { version = "0.8.5", features = ["small_rng"] } regex = "1.11.1" -serde = { version = "1.0.217", features = ["derive"] } -serde_json = "1.0.138" +serde = { version = "1.0.219", features = ["derive"] } +serde_json = "1.0.140" sha2 = "0.10.8" -tokio = { version = "1.43.0", features = ["full"] } +tokio = { version = "1.44.0", features = ["full"] } tokio-stream = "0.1.17" tokio-util = { version = "0.7.13", features = ["io"] } urlencoding = "2.1.3" @@ -57,7 +57,7 @@ xmltree = "0.11.0" [dev-dependencies] async-std = { version = "1.13.0", features = ["attributes", "tokio1"] } -clap = { version = "4.5.27", features = ["derive"] } +clap = { version = "4.5.31", features = ["derive"] } quickcheck = "1.0.3" [[example]] diff --git a/examples/bucket_encryption.rs b/examples/bucket_encryption.rs index b229e29..d91aa13 100644 --- a/examples/bucket_encryption.rs +++ b/examples/bucket_encryption.rs @@ -16,9 +16,9 @@ mod common; use crate::common::{create_bucket_if_not_exists, create_client_on_play}; +use minio::s3::Client; use minio::s3::response::{GetBucketEncryptionResponse, SetBucketEncryptionResponse}; use minio::s3::types::{S3Api, SseConfig}; -use minio::s3::Client; #[tokio::main] async fn main() -> Result<(), Box> { diff --git a/examples/bucket_lifecycle.rs b/examples/bucket_lifecycle.rs index 8ee3b7c..1acfaf3 100644 --- a/examples/bucket_lifecycle.rs +++ b/examples/bucket_lifecycle.rs @@ -16,11 +16,11 @@ mod common; use crate::common::{create_bucket_if_not_exists, create_client_on_play}; +use minio::s3::Client; use minio::s3::response::{ DeleteBucketLifecycleResponse, GetBucketLifecycleResponse, SetBucketLifecycleResponse, }; use minio::s3::types::{Filter, LifecycleConfig, LifecycleRule, S3Api}; -use minio::s3::Client; #[tokio::main] async fn main() -> Result<(), Box> { diff --git a/examples/bucket_versioning.rs b/examples/bucket_versioning.rs index c290990..3a823c1 100644 --- a/examples/bucket_versioning.rs +++ b/examples/bucket_versioning.rs @@ -16,10 +16,10 @@ mod common; use crate::common::{create_bucket_if_not_exists, create_client_on_play}; +use minio::s3::Client; use minio::s3::builders::VersioningStatus; use minio::s3::response::{GetBucketVersioningResponse, SetBucketVersioningResponse}; use minio::s3::types::S3Api; -use minio::s3::Client; #[tokio::main] async fn main() -> Result<(), Box> { diff --git a/examples/file_downloader.rs b/examples/file_downloader.rs index 450228e..03285ef 100644 --- a/examples/file_downloader.rs +++ b/examples/file_downloader.rs @@ -16,9 +16,9 @@ mod common; use crate::common::{create_bucket_if_not_exists, create_client_on_play}; +use minio::s3::Client; use minio::s3::builders::ObjectContent; use minio::s3::types::S3Api; -use minio::s3::Client; use std::path::Path; #[tokio::main] diff --git a/examples/file_uploader.rs b/examples/file_uploader.rs index af7294f..37dfa76 100644 --- a/examples/file_uploader.rs +++ b/examples/file_uploader.rs @@ -15,8 +15,8 @@ mod common; use crate::common::{create_bucket_if_not_exists, create_client_on_play}; -use minio::s3::builders::ObjectContent; use minio::s3::Client; +use minio::s3::builders::ObjectContent; use std::path::Path; #[tokio::main] diff --git a/src/s3/args.rs b/src/s3/args.rs index 1b6a9f9..3577674 100644 --- a/src/s3/args.rs +++ b/src/s3/args.rs @@ -23,13 +23,13 @@ use crate::s3::types::{ RetentionMode, SelectRequest, }; use crate::s3::utils::{ - b64encode, check_bucket_name, merge, to_amz_date, to_http_header_value, to_iso8601utc, - to_signer_date, urlencode, utc_now, Multimap, UtcTime, + Multimap, UtcTime, b64encode, check_bucket_name, merge, to_amz_date, to_http_header_value, + to_iso8601utc, to_signer_date, urlencode, utc_now, }; use hyper::http::Method; -use serde_json::json; use serde_json::Value; +use serde_json::json; use std::collections::HashMap; pub const MIN_PART_SIZE: usize = 5_242_880; // 5 MiB diff --git a/src/s3/builders/delete_bucket_encryption.rs b/src/s3/builders/delete_bucket_encryption.rs index bb05b28..fb7ecb5 100644 --- a/src/s3/builders/delete_bucket_encryption.rs +++ b/src/s3/builders/delete_bucket_encryption.rs @@ -13,12 +13,12 @@ // See the License for the specific language governing permissions and // limitations under the License. +use crate::s3::Client; use crate::s3::builders::BucketCommon; use crate::s3::error::Error; use crate::s3::response::DeleteBucketEncryptionResponse; use crate::s3::types::{S3Api, S3Request, ToS3Request}; use crate::s3::utils::check_bucket_name; -use crate::s3::Client; use http::Method; /// Argument builder for [delete_bucket_encryption()](Client::delete_bucket_encryption) API diff --git a/src/s3/builders/delete_bucket_lifecycle.rs b/src/s3/builders/delete_bucket_lifecycle.rs index 65fe474..4039a5d 100644 --- a/src/s3/builders/delete_bucket_lifecycle.rs +++ b/src/s3/builders/delete_bucket_lifecycle.rs @@ -13,12 +13,12 @@ // See the License for the specific language governing permissions and // limitations under the License. +use crate::s3::Client; use crate::s3::builders::BucketCommon; use crate::s3::error::Error; use crate::s3::response::DeleteBucketLifecycleResponse; use crate::s3::types::{S3Api, S3Request, ToS3Request}; use crate::s3::utils::check_bucket_name; -use crate::s3::Client; use http::Method; /// Argument builder for [delete_bucket_lifecycle()](Client::delete_bucket_lifecycle) API diff --git a/src/s3/builders/delete_bucket_policy.rs b/src/s3/builders/delete_bucket_policy.rs index 4ac903f..c1c6dd8 100644 --- a/src/s3/builders/delete_bucket_policy.rs +++ b/src/s3/builders/delete_bucket_policy.rs @@ -13,12 +13,12 @@ // See the License for the specific language governing permissions and // limitations under the License. +use crate::s3::Client; use crate::s3::builders::BucketCommon; use crate::s3::error::Error; use crate::s3::response::DeleteBucketPolicyResponse; use crate::s3::types::{S3Api, S3Request, ToS3Request}; use crate::s3::utils::check_bucket_name; -use crate::s3::Client; use http::Method; /// Argument builder for [delete_bucket_policy()](Client::delete_bucket_policy) API diff --git a/src/s3/builders/get_bucket_encryption.rs b/src/s3/builders/get_bucket_encryption.rs index 7c9fbef..eb3f0d8 100644 --- a/src/s3/builders/get_bucket_encryption.rs +++ b/src/s3/builders/get_bucket_encryption.rs @@ -17,7 +17,7 @@ use crate::s3::builders::BucketCommon; use crate::s3::error::Error; use crate::s3::response::GetBucketEncryptionResponse; use crate::s3::types::{S3Api, S3Request, ToS3Request}; -use crate::s3::utils::{check_bucket_name, merge, Multimap}; +use crate::s3::utils::{Multimap, check_bucket_name, merge}; use http::Method; /// Argument builder for [get_bucket_encryption()](crate::s3::client::Client::get_bucket_encryption) API diff --git a/src/s3/builders/get_bucket_lifecycle.rs b/src/s3/builders/get_bucket_lifecycle.rs index 862374f..77f601c 100644 --- a/src/s3/builders/get_bucket_lifecycle.rs +++ b/src/s3/builders/get_bucket_lifecycle.rs @@ -13,12 +13,12 @@ // See the License for the specific language governing permissions and // limitations under the License. +use crate::s3::Client; use crate::s3::builders::BucketCommon; use crate::s3::error::Error; use crate::s3::response::GetBucketLifecycleResponse; use crate::s3::types::{S3Api, S3Request, ToS3Request}; use crate::s3::utils::check_bucket_name; -use crate::s3::Client; use http::Method; /// Argument builder for [get_bucket_lifecycle()](Client::get_bucket_lifecycle) API diff --git a/src/s3/builders/get_bucket_policy.rs b/src/s3/builders/get_bucket_policy.rs index eda912f..85c7518 100644 --- a/src/s3/builders/get_bucket_policy.rs +++ b/src/s3/builders/get_bucket_policy.rs @@ -13,12 +13,12 @@ // See the License for the specific language governing permissions and // limitations under the License. +use crate::s3::Client; use crate::s3::builders::BucketCommon; use crate::s3::error::Error; use crate::s3::response::GetBucketPolicyResponse; use crate::s3::types::{S3Api, S3Request, ToS3Request}; use crate::s3::utils::check_bucket_name; -use crate::s3::Client; use http::Method; /// Argument builder for [get_bucket_policy()](Client::get_bucket_policy) API diff --git a/src/s3/builders/get_bucket_versioning.rs b/src/s3/builders/get_bucket_versioning.rs index 433d38f..a94e414 100644 --- a/src/s3/builders/get_bucket_versioning.rs +++ b/src/s3/builders/get_bucket_versioning.rs @@ -17,7 +17,7 @@ use crate::s3::builders::BucketCommon; use crate::s3::error::Error; use crate::s3::response::GetBucketVersioningResponse; use crate::s3::types::{S3Api, S3Request, ToS3Request}; -use crate::s3::utils::{check_bucket_name, merge, Multimap}; +use crate::s3::utils::{Multimap, check_bucket_name, merge}; use http::Method; /// Argument builder for [get_bucket_versioning()](crate::s3::client::Client::get_bucket_versioning) API diff --git a/src/s3/builders/get_object.rs b/src/s3/builders/get_object.rs index d295c9c..77fa375 100644 --- a/src/s3/builders/get_object.rs +++ b/src/s3/builders/get_object.rs @@ -21,7 +21,7 @@ use crate::s3::{ response::GetObjectResponse, sse::{Sse, SseCustomerKey}, types::{S3Api, S3Request, ToS3Request}, - utils::{check_bucket_name, merge, to_http_header_value, Multimap, UtcTime}, + utils::{Multimap, UtcTime, check_bucket_name, merge, to_http_header_value}, }; /// Argument builder for [list_objects()](Client::get_object) API. diff --git a/src/s3/builders/list_buckets.rs b/src/s3/builders/list_buckets.rs index f3925e8..64e22ae 100644 --- a/src/s3/builders/list_buckets.rs +++ b/src/s3/builders/list_buckets.rs @@ -17,10 +17,10 @@ use http::Method; use crate::s3::response::ListBucketsResponse; use crate::s3::{ + Client, error::Error, types::{S3Api, S3Request, ToS3Request}, utils::Multimap, - Client, }; /// Argument builder for [list_buckets()](Client::list_buckets) API. diff --git a/src/s3/builders/list_objects.rs b/src/s3/builders/list_objects.rs index 7a18cc1..4ff998b 100644 --- a/src/s3/builders/list_objects.rs +++ b/src/s3/builders/list_objects.rs @@ -13,18 +13,18 @@ //! Argument builders for ListObject APIs. use async_trait::async_trait; -use futures_util::{stream as futures_stream, Stream, StreamExt}; +use futures_util::{Stream, StreamExt, stream as futures_stream}; use http::Method; use crate::s3::{ client::Client, error::Error, + response::ListObjectsResponse, response::list_objects::{ ListObjectVersionsResponse, ListObjectsV1Response, ListObjectsV2Response, }, - response::ListObjectsResponse, types::{S3Api, S3Request, ToS3Request, ToStream}, - utils::{check_bucket_name, merge, Multimap}, + utils::{Multimap, check_bucket_name, merge}, }; fn add_common_list_objects_query_params( diff --git a/src/s3/builders/listen_bucket_notification.rs b/src/s3/builders/listen_bucket_notification.rs index dec20bd..cc19268 100644 --- a/src/s3/builders/listen_bucket_notification.rs +++ b/src/s3/builders/listen_bucket_notification.rs @@ -22,7 +22,7 @@ use crate::s3::{ error::Error, response::ListenBucketNotificationResponse, types::{NotificationRecords, S3Api, S3Request, ToS3Request}, - utils::{check_bucket_name, merge, Multimap}, + utils::{Multimap, check_bucket_name, merge}, }; /// Argument builder for diff --git a/src/s3/builders/object_prompt.rs b/src/s3/builders/object_prompt.rs index 45d8557..ce45caa 100644 --- a/src/s3/builders/object_prompt.rs +++ b/src/s3/builders/object_prompt.rs @@ -15,7 +15,7 @@ use crate::s3::builders::SegmentedBytes; use crate::s3::sse::{Sse, SseCustomerKey}; -use crate::s3::utils::{check_bucket_name, merge, Multimap}; +use crate::s3::utils::{Multimap, check_bucket_name, merge}; use crate::s3::{ client::Client, error::Error, diff --git a/src/s3/builders/put_object.rs b/src/s3/builders/put_object.rs index 731466d..5512f0b 100644 --- a/src/s3/builders/put_object.rs +++ b/src/s3/builders/put_object.rs @@ -29,7 +29,7 @@ use crate::s3::{ }, sse::Sse, types::{PartInfo, Retention, S3Api, S3Request, ToS3Request}, - utils::{check_bucket_name, md5sum_hash, merge, to_iso8601utc, urlencode, Multimap}, + utils::{Multimap, check_bucket_name, md5sum_hash, merge, to_iso8601utc, urlencode}, }; use super::{ObjectContent, SegmentedBytes}; diff --git a/src/s3/builders/remove_objects.rs b/src/s3/builders/remove_objects.rs index bb2b540..87c751f 100644 --- a/src/s3/builders/remove_objects.rs +++ b/src/s3/builders/remove_objects.rs @@ -19,17 +19,17 @@ use std::pin::Pin; use async_trait::async_trait; use bytes::Bytes; -use futures_util::{stream as futures_stream, Stream, StreamExt}; +use futures_util::{Stream, StreamExt, stream as futures_stream}; use http::Method; use tokio_stream::iter as stream_iter; use crate::s3::{ + Client, client_core::ClientCore, error::Error, response::{RemoveObjectResponse, RemoveObjectsResponse}, types::{S3Api, S3Request, ToS3Request, ToStream}, - utils::{check_bucket_name, md5sum_hash, merge, Multimap}, - Client, + utils::{Multimap, check_bucket_name, md5sum_hash, merge}, }; /// Specify an object to be deleted. The object can be specified by key or by diff --git a/src/s3/builders/set_bucket_encryption.rs b/src/s3/builders/set_bucket_encryption.rs index 4529a58..8422d41 100644 --- a/src/s3/builders/set_bucket_encryption.rs +++ b/src/s3/builders/set_bucket_encryption.rs @@ -13,12 +13,12 @@ // See the License for the specific language governing permissions and // limitations under the License. +use crate::s3::Client; use crate::s3::builders::SegmentedBytes; use crate::s3::error::Error; use crate::s3::response::SetBucketEncryptionResponse; use crate::s3::types::{S3Api, S3Request, SseConfig, ToS3Request}; -use crate::s3::utils::{check_bucket_name, Multimap}; -use crate::s3::Client; +use crate::s3::utils::{Multimap, check_bucket_name}; use bytes::Bytes; use http::Method; diff --git a/src/s3/builders/set_bucket_lifecycle.rs b/src/s3/builders/set_bucket_lifecycle.rs index 4932ddc..4bd1986 100644 --- a/src/s3/builders/set_bucket_lifecycle.rs +++ b/src/s3/builders/set_bucket_lifecycle.rs @@ -13,12 +13,12 @@ // See the License for the specific language governing permissions and // limitations under the License. +use crate::s3::Client; use crate::s3::builders::SegmentedBytes; use crate::s3::error::Error; use crate::s3::response::SetBucketLifecycleResponse; use crate::s3::types::{LifecycleConfig, S3Api, S3Request, ToS3Request}; -use crate::s3::utils::{check_bucket_name, md5sum_hash, Multimap}; -use crate::s3::Client; +use crate::s3::utils::{Multimap, check_bucket_name, md5sum_hash}; use bytes::Bytes; use http::Method; diff --git a/src/s3/builders/set_bucket_policy.rs b/src/s3/builders/set_bucket_policy.rs index 55659b1..7e26fd2 100644 --- a/src/s3/builders/set_bucket_policy.rs +++ b/src/s3/builders/set_bucket_policy.rs @@ -13,12 +13,12 @@ // See the License for the specific language governing permissions and // limitations under the License. +use crate::s3::Client; use crate::s3::builders::SegmentedBytes; use crate::s3::error::Error; use crate::s3::response::SetBucketLifecycleResponse; use crate::s3::types::{S3Api, S3Request, ToS3Request}; -use crate::s3::utils::{check_bucket_name, Multimap}; -use crate::s3::Client; +use crate::s3::utils::{Multimap, check_bucket_name}; use bytes::Bytes; use http::Method; diff --git a/src/s3/builders/set_bucket_versioning.rs b/src/s3/builders/set_bucket_versioning.rs index e701f4b..755a8f0 100644 --- a/src/s3/builders/set_bucket_versioning.rs +++ b/src/s3/builders/set_bucket_versioning.rs @@ -13,12 +13,12 @@ // See the License for the specific language governing permissions and // limitations under the License. +use crate::s3::Client; use crate::s3::builders::SegmentedBytes; use crate::s3::error::Error; use crate::s3::response::SetBucketVersioningResponse; use crate::s3::types::{S3Api, S3Request, ToS3Request}; -use crate::s3::utils::{check_bucket_name, Multimap}; -use crate::s3::Client; +use crate::s3::utils::{Multimap, check_bucket_name}; use bytes::Bytes; use http::Method; use std::fmt; @@ -130,7 +130,7 @@ impl ToS3Request for SetBucketVersioning { None => { return Err(Error::InvalidVersioningStatus( "Missing VersioningStatus".into(), - )) + )); } }; diff --git a/src/s3/client.rs b/src/s3/client.rs index 61793d3..45f9535 100644 --- a/src/s3/client.rs +++ b/src/s3/client.rs @@ -32,16 +32,16 @@ use crate::s3::types::{ Directive, NotificationConfig, ObjectLockConfig, Part, ReplicationConfig, RetentionMode, }; use crate::s3::utils::{ - from_iso8601utc, get_default_text, get_option_text, get_text, md5sum_hash, md5sum_hash_sb, - merge, sha256_hash_sb, to_amz_date, to_iso8601utc, utc_now, Multimap, + Multimap, from_iso8601utc, get_default_text, get_option_text, get_text, md5sum_hash, + md5sum_hash_sb, merge, sha256_hash_sb, to_amz_date, to_iso8601utc, utc_now, }; use async_recursion::async_recursion; use bytes::{Buf, Bytes}; use dashmap::DashMap; use hyper::http::Method; -use reqwest::header::HeaderMap; use reqwest::Body; +use reqwest::header::HeaderMap; use tokio::fs; use xmltree::Element; @@ -1044,16 +1044,24 @@ impl Client { { if let Some(v) = &args.metadata_directive { match v { - Directive::Copy => return Err(Error::InvalidCopyDirective(String::from("COPY metadata directive is not applicable to source object size greater than 5 GiB"))), - _ => todo!(), // Nothing to do. - } + Directive::Copy => { + return Err(Error::InvalidCopyDirective(String::from( + "COPY metadata directive is not applicable to source object size greater than 5 GiB", + ))); + } + _ => todo!(), // Nothing to do. + } } if let Some(v) = &args.tagging_directive { match v { - Directive::Copy => return Err(Error::InvalidCopyDirective(String::from("COPY tagging directive is not applicable to source object size greater than 5 GiB"))), - _ => todo!(), // Nothing to do. - } + Directive::Copy => { + return Err(Error::InvalidCopyDirective(String::from( + "COPY tagging directive is not applicable to source object size greater than 5 GiB", + ))); + } + _ => todo!(), // Nothing to do. + } } let mut src = ComposeSource::new(args.source.bucket, args.source.object)?; @@ -1994,9 +2002,12 @@ impl Client { } let data = match region { - "us-east-1" => String::new(), - _ => format!("{}", region), - }; + "us-east-1" => String::new(), + _ => format!( + "{}", + region + ), + }; let body = match data.is_empty() { true => None, diff --git a/src/s3/client_core.rs b/src/s3/client_core.rs index 58f9873..387544e 100644 --- a/src/s3/client_core.rs +++ b/src/s3/client_core.rs @@ -16,8 +16,8 @@ //! Module containing lower level APIs. use super::{ - builders::{ObjectToDelete, RemoveObjectsApi}, Client, + builders::{ObjectToDelete, RemoveObjectsApi}, }; /// ClientCore exposes lower-level APIs not exposed by the high-level client. diff --git a/src/s3/error.rs b/src/s3/error.rs index 7f88667..f5cf771 100644 --- a/src/s3/error.rs +++ b/src/s3/error.rs @@ -186,7 +186,13 @@ impl fmt::Display for Error { Error::S3Error(er) => write!( f, "s3 operation failed; code: {}, message: {}, resource: {}, request_id: {}, host_id: {}, bucket_name: {}, object_name: {}", - er.code, er.message, er.resource, er.request_id, er.host_id, er.bucket_name, er.object_name, + er.code, + er.message, + er.resource, + er.request_id, + er.host_id, + er.bucket_name, + er.object_name, ), Error::InvalidResponse(sc, ct) => write!( f, @@ -203,19 +209,68 @@ impl fmt::Display for Error { Error::SelectError(ec, em) => write!(f, "error code: {}, error message: {}", ec, em), Error::UnsupportedApi(a) => write!(f, "{} API is not supported in Amazon AWS S3", a), Error::InvalidComposeSource(m) => write!(f, "{}", m), - Error::InvalidComposeSourceOffset(b, o, v, of, os) => write!(f, "source {}/{}{}: offset {} is beyond object size {}", b, o, v.as_ref().map_or(String::new(), |v| String::from("?versionId=") + v), of, os), - Error::InvalidComposeSourceLength(b, o, v, l, os) => write!(f, "source {}/{}{}: length {} is beyond object size {}", b, o, v.as_ref().map_or(String::new(), |v| String::from("?versionId=") + v), l, os), - Error::InvalidComposeSourceSize(b, o, v, cs, os) => write!(f, "source {}/{}{}: compose size {} is beyond object size {}", b, o, v.as_ref().map_or(String::new(), |v| String::from("?versionId=") + v), cs, os), + Error::InvalidComposeSourceOffset(b, o, v, of, os) => write!( + f, + "source {}/{}{}: offset {} is beyond object size {}", + b, + o, + v.as_ref() + .map_or(String::new(), |v| String::from("?versionId=") + v), + of, + os + ), + Error::InvalidComposeSourceLength(b, o, v, l, os) => write!( + f, + "source {}/{}{}: length {} is beyond object size {}", + b, + o, + v.as_ref() + .map_or(String::new(), |v| String::from("?versionId=") + v), + l, + os + ), + Error::InvalidComposeSourceSize(b, o, v, cs, os) => write!( + f, + "source {}/{}{}: compose size {} is beyond object size {}", + b, + o, + v.as_ref() + .map_or(String::new(), |v| String::from("?versionId=") + v), + cs, + os + ), Error::InvalidDirective(m) => write!(f, "{}", m), Error::InvalidCopyDirective(m) => write!(f, "{}", m), - Error::InvalidComposeSourcePartSize(b, o, v, s, es) => write!(f, "source {}/{}{}: size {} must be greater than {}", b, o, v.as_ref().map_or(String::new(), |v| String::from("?versionId=") + v), s, es), - Error::InvalidComposeSourceMultipart(b, o, v, s, es) => write!(f, "source {}/{}{}: size {} for multipart split upload of {}, last part size is less than {}", b, o, v.as_ref().map_or(String::new(), |v| String::from("?versionId=") + v), s, s, es), + Error::InvalidComposeSourcePartSize(b, o, v, s, es) => write!( + f, + "source {}/{}{}: size {} must be greater than {}", + b, + o, + v.as_ref() + .map_or(String::new(), |v| String::from("?versionId=") + v), + s, + es + ), + Error::InvalidComposeSourceMultipart(b, o, v, s, es) => write!( + f, + "source {}/{}{}: size {} for multipart split upload of {}, last part size is less than {}", + b, + o, + v.as_ref() + .map_or(String::new(), |v| String::from("?versionId=") + v), + s, + s, + es + ), Error::InvalidMultipartCount(c) => write!( f, "Compose sources create more than allowed multipart count {}", c ), - Error::MissingLifecycleAction => write!(f, "at least one of action (AbortIncompleteMultipartUpload, Expiration, NoncurrentVersionExpiration, NoncurrentVersionTransition or Transition) must be specified in a rule"), + Error::MissingLifecycleAction => write!( + f, + "at least one of action (AbortIncompleteMultipartUpload, Expiration, NoncurrentVersionExpiration, NoncurrentVersionTransition or Transition) must be specified in a rule" + ), Error::InvalidExpiredObjectDeleteMarker => write!( f, "ExpiredObjectDeleteMarker must not be provided along with Date and Days" @@ -229,10 +284,16 @@ impl fmt::Display for Error { Error::PostPolicyError(m) => write!(f, "{}", m), Error::InvalidObjectLockConfig(m) => write!(f, "{}", m), Error::NoClientProvided => write!(f, "no client provided"), - Error::TagDecodingError(input, error_message) => write!(f, "tag decoding failed: {} on input '{}'", error_message, input), + Error::TagDecodingError(input, error_message) => write!( + f, + "tag decoding failed: {} on input '{}'", + error_message, input + ), Error::ContentLengthUnknown => write!(f, "content length is unknown"), Error::NoSuchTagSet => write!(f, "no such tag set"), - Error::ReplicationConfigurationNotFoundError => write!(f, "Replication configuration not found"), + Error::ReplicationConfigurationNotFoundError => { + write!(f, "Replication configuration not found") + } Error::NoSuchObjectLockConfiguration => write!(f, "no such object lock"), Error::NoSuchBucketPolicy => write!(f, "no such bucket policy"), } diff --git a/src/s3/http.rs b/src/s3/http.rs index 3293355..488f72c 100644 --- a/src/s3/http.rs +++ b/src/s3/http.rs @@ -17,10 +17,10 @@ use crate::s3::error::Error; use crate::s3::utils::match_hostname; -use crate::s3::utils::{to_query_string, Multimap}; +use crate::s3::utils::{Multimap, to_query_string}; use derivative::Derivative; -use hyper::http::Method; use hyper::Uri; +use hyper::http::Method; use lazy_static::lazy_static; use regex::Regex; use std::fmt; @@ -254,7 +254,7 @@ impl FromStr for BaseUrl { _ => { return Err(Error::InvalidBaseUrl(String::from( "scheme must be http or https", - ))) + ))); } }, }; @@ -264,7 +264,7 @@ impl FromStr for BaseUrl { _ => { return Err(Error::InvalidBaseUrl(String::from( "valid host must be provided", - ))) + ))); } }; diff --git a/src/s3/response.rs b/src/s3/response.rs index ff97ecd..98fe66e 100644 --- a/src/s3/response.rs +++ b/src/s3/response.rs @@ -24,11 +24,11 @@ use xmltree::Element; use crate::s3::error::Error; use crate::s3::types::{ - parse_legal_hold, NotificationConfig, ObjectLockConfig, ReplicationConfig, RetentionMode, - SelectProgress, + NotificationConfig, ObjectLockConfig, ReplicationConfig, RetentionMode, SelectProgress, + parse_legal_hold, }; use crate::s3::utils::{ - copy_slice, crc32, from_http_header_value, from_iso8601utc, get_text, uint32, UtcTime, + UtcTime, copy_slice, crc32, from_http_header_value, from_iso8601utc, get_text, uint32, }; mod delete_bucket_encryption; diff --git a/src/s3/response/listen_bucket_notification.rs b/src/s3/response/listen_bucket_notification.rs index 6b428d8..5c71db2 100644 --- a/src/s3/response/listen_bucket_notification.rs +++ b/src/s3/response/listen_bucket_notification.rs @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use futures_util::{stream, Stream, StreamExt}; +use futures_util::{Stream, StreamExt, stream}; use http::HeaderMap; use tokio::io::AsyncBufReadExt; use tokio_util::io::StreamReader; diff --git a/src/s3/signer.rs b/src/s3/signer.rs index 94b4d39..ffaef2e 100644 --- a/src/s3/signer.rs +++ b/src/s3/signer.rs @@ -16,8 +16,8 @@ //! Signature V4 for S3 API use crate::s3::utils::{ - get_canonical_headers, get_canonical_query_string, sha256_hash, to_amz_date, to_signer_date, - Multimap, UtcTime, + Multimap, UtcTime, get_canonical_headers, get_canonical_query_string, sha256_hash, to_amz_date, + to_signer_date, }; use hex::encode as hexencode; use hmac::{Hmac, Mac}; diff --git a/src/s3/types.rs b/src/s3/types.rs index 8db4ab7..b45723b 100644 --- a/src/s3/types.rs +++ b/src/s3/types.rs @@ -19,7 +19,7 @@ use super::builders::SegmentedBytes; use super::client::Client; use crate::s3::error::Error; use crate::s3::utils::{ - from_iso8601utc, get_default_text, get_option_text, get_text, to_iso8601utc, Multimap, UtcTime, + Multimap, UtcTime, from_iso8601utc, get_default_text, get_option_text, get_text, to_iso8601utc, }; use async_trait::async_trait; diff --git a/src/s3/utils.rs b/src/s3/utils.rs index 0e8e3bf..5c50599 100644 --- a/src/s3/utils.rs +++ b/src/s3/utils.rs @@ -17,15 +17,15 @@ use std::collections::{BTreeMap, HashMap}; -use base64::engine::general_purpose::STANDARD as BASE64; use base64::engine::Engine as _; +use base64::engine::general_purpose::STANDARD as BASE64; use byteorder::{BigEndian, ReadBytesExt}; use chrono::{DateTime, Datelike, NaiveDateTime, ParseError, Utc}; -use crc::{Crc, CRC_32_ISO_HDLC}; +use crc::{CRC_32_ISO_HDLC, Crc}; use lazy_static::lazy_static; use md5::compute as md5compute; use multimap::MultiMap; -use percent_encoding::{percent_decode_str, utf8_percent_encode, AsciiSet, NON_ALPHANUMERIC}; +use percent_encoding::{AsciiSet, NON_ALPHANUMERIC, percent_decode_str, utf8_percent_encode}; use regex::Regex; use sha2::{Digest, Sha256}; pub use urlencoding::decode as urldecode; @@ -162,7 +162,7 @@ pub fn urlencode_object_key(key: &str) -> String { } pub mod aws_date_format { - use super::{from_iso8601utc, to_iso8601utc, UtcTime}; + use super::{UtcTime, from_iso8601utc, to_iso8601utc}; use serde::{Deserialize, Deserializer, Serializer}; pub fn serialize(date: &UtcTime, serializer: S) -> Result @@ -485,7 +485,7 @@ pub fn parse_tags(s: &str) -> Result, Error> { return Err(Error::TagDecodingError( s.to_string(), "tag key was empty".to_string(), - )) + )); } }; let v = match kv.next() { diff --git a/tests/common.rs b/tests/common.rs index 7e8d3b4..590d826 100644 --- a/tests/common.rs +++ b/tests/common.rs @@ -15,9 +15,9 @@ use async_std::task; use bytes::Bytes; +use rand::SeedableRng; use rand::distributions::{Alphanumeric, DistString}; use rand::prelude::SmallRng; -use rand::SeedableRng; use std::path::{Path, PathBuf}; use std::{io, thread}; use tokio::io::AsyncRead; diff --git a/tests/test_bucket_encryption.rs b/tests/test_bucket_encryption.rs index e677139..4615999 100644 --- a/tests/test_bucket_encryption.rs +++ b/tests/test_bucket_encryption.rs @@ -15,7 +15,7 @@ mod common; -use crate::common::{create_bucket_helper, TestContext}; +use crate::common::{TestContext, create_bucket_helper}; use minio::s3::response::{DeleteBucketEncryptionResponse, GetBucketEncryptionResponse}; use minio::s3::types::{S3Api, SseConfig}; diff --git a/tests/test_bucket_exists.rs b/tests/test_bucket_exists.rs index 55919fb..4407f78 100644 --- a/tests/test_bucket_exists.rs +++ b/tests/test_bucket_exists.rs @@ -15,7 +15,7 @@ mod common; -use crate::common::{create_bucket_helper, TestContext}; +use crate::common::{TestContext, create_bucket_helper}; use minio::s3::args::BucketExistsArgs; #[tokio::test(flavor = "multi_thread", worker_threads = 10)] diff --git a/tests/test_bucket_lifecycle.rs b/tests/test_bucket_lifecycle.rs index 22cbb47..5461f9f 100644 --- a/tests/test_bucket_lifecycle.rs +++ b/tests/test_bucket_lifecycle.rs @@ -15,7 +15,7 @@ mod common; -use crate::common::{create_bucket_helper, TestContext}; +use crate::common::{TestContext, create_bucket_helper}; use minio::s3::response::{ DeleteBucketLifecycleResponse, GetBucketLifecycleResponse, SetBucketLifecycleResponse, }; diff --git a/tests/test_bucket_notification.rs b/tests/test_bucket_notification.rs index 1aea1cd..dd6053b 100644 --- a/tests/test_bucket_notification.rs +++ b/tests/test_bucket_notification.rs @@ -1,6 +1,6 @@ mod common; -use crate::common::{create_bucket_helper, TestContext}; +use crate::common::{TestContext, create_bucket_helper}; use minio::s3::args::{ DeleteBucketNotificationArgs, GetBucketNotificationArgs, SetBucketNotificationArgs, }; @@ -47,12 +47,16 @@ async fn set_get_delete_bucket_notification() { .await .unwrap(); assert_eq!(resp.config.queue_config_list.as_ref().unwrap().len(), 1); - assert!(resp.config.queue_config_list.as_ref().unwrap()[0] - .events - .contains(&String::from("s3:ObjectCreated:Put"))); - assert!(resp.config.queue_config_list.as_ref().unwrap()[0] - .events - .contains(&String::from("s3:ObjectCreated:Copy"))); + assert!( + resp.config.queue_config_list.as_ref().unwrap()[0] + .events + .contains(&String::from("s3:ObjectCreated:Put")) + ); + assert!( + resp.config.queue_config_list.as_ref().unwrap()[0] + .events + .contains(&String::from("s3:ObjectCreated:Copy")) + ); assert_eq!( resp.config.queue_config_list.as_ref().unwrap()[0] .prefix_filter_rule diff --git a/tests/test_bucket_policy.rs b/tests/test_bucket_policy.rs index c3add3c..ce0fde3 100644 --- a/tests/test_bucket_policy.rs +++ b/tests/test_bucket_policy.rs @@ -1,4 +1,4 @@ -use crate::common::{create_bucket_helper, TestContext}; +use crate::common::{TestContext, create_bucket_helper}; use minio::s3::types::S3Api; mod common; diff --git a/tests/test_bucket_tags.rs b/tests/test_bucket_tags.rs index 9694257..e3f0f4e 100644 --- a/tests/test_bucket_tags.rs +++ b/tests/test_bucket_tags.rs @@ -15,7 +15,7 @@ mod common; -use crate::common::{create_bucket_helper, TestContext}; +use crate::common::{TestContext, create_bucket_helper}; use minio::s3::args::{DeleteBucketTagsArgs, GetBucketTagsArgs, SetBucketTagsArgs}; use std::collections::HashMap; diff --git a/tests/test_bucket_versioning.rs b/tests/test_bucket_versioning.rs index da50822..ecbb37e 100644 --- a/tests/test_bucket_versioning.rs +++ b/tests/test_bucket_versioning.rs @@ -15,7 +15,7 @@ mod common; -use crate::common::{create_bucket_helper, TestContext}; +use crate::common::{TestContext, create_bucket_helper}; use minio::s3::builders::VersioningStatus; use minio::s3::response::GetBucketVersioningResponse; use minio::s3::types::S3Api; diff --git a/tests/test_compose_object.rs b/tests/test_compose_object.rs index 407841e..7708884 100644 --- a/tests/test_compose_object.rs +++ b/tests/test_compose_object.rs @@ -15,7 +15,7 @@ mod common; -use crate::common::{create_bucket_helper, rand_object_name, RandReader, TestContext}; +use crate::common::{RandReader, TestContext, create_bucket_helper, rand_object_name}; use minio::s3::args::{ComposeObjectArgs, ComposeSource, PutObjectArgs, StatObjectArgs}; use minio::s3::types::S3Api; diff --git a/tests/test_copy_object.rs b/tests/test_copy_object.rs index b11ffad..6849efc 100644 --- a/tests/test_copy_object.rs +++ b/tests/test_copy_object.rs @@ -15,7 +15,7 @@ mod common; -use crate::common::{create_bucket_helper, rand_object_name, RandReader, TestContext}; +use crate::common::{RandReader, TestContext, create_bucket_helper, rand_object_name}; use minio::s3::args::{CopyObjectArgs, CopySource, PutObjectArgs, StatObjectArgs}; use minio::s3::types::S3Api; diff --git a/tests/test_create_delete_bucket.rs b/tests/test_create_delete_bucket.rs index 0f338ec..3a2d96a 100644 --- a/tests/test_create_delete_bucket.rs +++ b/tests/test_create_delete_bucket.rs @@ -15,7 +15,7 @@ mod common; -use crate::common::{rand_bucket_name, TestContext}; +use crate::common::{TestContext, rand_bucket_name}; use minio::s3::args::{BucketExistsArgs, MakeBucketArgs, RemoveBucketArgs}; #[tokio::test(flavor = "multi_thread", worker_threads = 10)] diff --git a/tests/test_get_object.rs b/tests/test_get_object.rs index 7238a35..1765675 100644 --- a/tests/test_get_object.rs +++ b/tests/test_get_object.rs @@ -15,7 +15,7 @@ mod common; -use crate::common::{create_bucket_helper, rand_object_name, TestContext}; +use crate::common::{TestContext, create_bucket_helper, rand_object_name}; use bytes::Bytes; use minio::s3::args::{GetObjectArgs, PutObjectArgs}; use minio::s3::types::S3Api; diff --git a/tests/test_get_presigned_object_url.rs b/tests/test_get_presigned_object_url.rs index 7213a92..2b51e33 100644 --- a/tests/test_get_presigned_object_url.rs +++ b/tests/test_get_presigned_object_url.rs @@ -15,7 +15,7 @@ mod common; -use crate::common::{create_bucket_helper, rand_object_name, TestContext}; +use crate::common::{TestContext, create_bucket_helper, rand_object_name}; use http::Method; use minio::s3::args::GetPresignedObjectUrlArgs; diff --git a/tests/test_get_presigned_post_form_data.rs b/tests/test_get_presigned_post_form_data.rs index b1b0682..90f019d 100644 --- a/tests/test_get_presigned_post_form_data.rs +++ b/tests/test_get_presigned_post_form_data.rs @@ -15,7 +15,7 @@ mod common; -use crate::common::{create_bucket_helper, rand_object_name, TestContext}; +use crate::common::{TestContext, create_bucket_helper, rand_object_name}; use minio::s3::args::PostPolicy; use minio::s3::utils::utc_now; diff --git a/tests/test_list_buckets.rs b/tests/test_list_buckets.rs index 07f7551..a9b5ac9 100644 --- a/tests/test_list_buckets.rs +++ b/tests/test_list_buckets.rs @@ -1,4 +1,4 @@ -use crate::common::{create_bucket_helper, CleanupGuard, TestContext}; +use crate::common::{CleanupGuard, TestContext, create_bucket_helper}; // MinIO Rust Library for Amazon S3 Compatible Cloud Storage // Copyright 2025 MinIO, Inc. // diff --git a/tests/test_list_objects.rs b/tests/test_list_objects.rs index 42a0628..35b3dab 100644 --- a/tests/test_list_objects.rs +++ b/tests/test_list_objects.rs @@ -15,7 +15,7 @@ mod common; -use crate::common::{create_bucket_helper, rand_object_name, RandReader, TestContext}; +use crate::common::{RandReader, TestContext, create_bucket_helper, rand_object_name}; use minio::s3::args::PutObjectArgs; use minio::s3::builders::ObjectToDelete; use minio::s3::types::ToStream; diff --git a/tests/test_listen_bucket_notification.rs b/tests/test_listen_bucket_notification.rs index 10768a9..6ed20f7 100644 --- a/tests/test_listen_bucket_notification.rs +++ b/tests/test_listen_bucket_notification.rs @@ -15,12 +15,12 @@ mod common; -use crate::common::{create_bucket_helper, rand_object_name, RandReader, TestContext}; +use crate::common::{RandReader, TestContext, create_bucket_helper, rand_object_name}; use async_std::task; +use minio::s3::Client; use minio::s3::args::PutObjectArgs; use minio::s3::creds::StaticProvider; use minio::s3::types::{NotificationRecords, S3Api}; -use minio::s3::Client; use tokio::sync::mpsc; use tokio_stream::StreamExt; diff --git a/tests/test_object_lock_config.rs b/tests/test_object_lock_config.rs index ffa25d4..dfdc036 100644 --- a/tests/test_object_lock_config.rs +++ b/tests/test_object_lock_config.rs @@ -15,7 +15,7 @@ mod common; -use crate::common::{rand_bucket_name, CleanupGuard, TestContext}; +use crate::common::{CleanupGuard, TestContext, rand_bucket_name}; use minio::s3::args::{ DeleteObjectLockConfigArgs, GetObjectLockConfigArgs, MakeBucketArgs, SetObjectLockConfigArgs, }; diff --git a/tests/test_object_retention.rs b/tests/test_object_retention.rs index f1d71ec..70c7e53 100644 --- a/tests/test_object_retention.rs +++ b/tests/test_object_retention.rs @@ -15,7 +15,7 @@ mod common; -use crate::common::{rand_bucket_name, rand_object_name, CleanupGuard, RandReader, TestContext}; +use crate::common::{CleanupGuard, RandReader, TestContext, rand_bucket_name, rand_object_name}; use minio::s3::args::{ GetObjectRetentionArgs, MakeBucketArgs, PutObjectArgs, SetObjectRetentionArgs, }; diff --git a/tests/test_object_tags.rs b/tests/test_object_tags.rs index efbaacb..c9bb349 100644 --- a/tests/test_object_tags.rs +++ b/tests/test_object_tags.rs @@ -15,7 +15,7 @@ mod common; -use crate::common::{create_bucket_helper, rand_object_name, RandReader, TestContext}; +use crate::common::{RandReader, TestContext, create_bucket_helper, rand_object_name}; use minio::s3::args::{DeleteObjectTagsArgs, GetObjectTagsArgs, PutObjectArgs, SetObjectTagsArgs}; use minio::s3::types::S3Api; use std::collections::HashMap; diff --git a/tests/test_put_object_content.rs b/tests/test_put_object_content.rs index 79f8c50..b371dd0 100644 --- a/tests/test_put_object_content.rs +++ b/tests/test_put_object_content.rs @@ -15,7 +15,7 @@ mod common; -use crate::common::{create_bucket_helper, rand_object_name, RandReader, RandSrc, TestContext}; +use crate::common::{RandReader, RandSrc, TestContext, create_bucket_helper, rand_object_name}; use http::header; use minio::s3::args::{PutObjectArgs, StatObjectArgs}; use minio::s3::builders::ObjectContent; diff --git a/tests/test_remove_objects.rs b/tests/test_remove_objects.rs index 16eb943..49be235 100644 --- a/tests/test_remove_objects.rs +++ b/tests/test_remove_objects.rs @@ -15,7 +15,7 @@ mod common; -use crate::common::{create_bucket_helper, rand_object_name, RandReader, TestContext}; +use crate::common::{RandReader, TestContext, create_bucket_helper, rand_object_name}; use minio::s3::args::PutObjectArgs; use minio::s3::builders::ObjectToDelete; use minio::s3::types::ToStream; diff --git a/tests/test_select_object_content.rs b/tests/test_select_object_content.rs index 44211ff..f90237f 100644 --- a/tests/test_select_object_content.rs +++ b/tests/test_select_object_content.rs @@ -15,7 +15,7 @@ mod common; -use crate::common::{create_bucket_helper, rand_object_name, TestContext}; +use crate::common::{TestContext, create_bucket_helper, rand_object_name}; use minio::s3::args::{PutObjectArgs, SelectObjectContentArgs}; use minio::s3::types::{ CsvInputSerialization, CsvOutputSerialization, FileHeaderInfo, QuoteFields, S3Api, diff --git a/tests/test_upload_download_object.rs b/tests/test_upload_download_object.rs index 13d23e6..430a308 100644 --- a/tests/test_upload_download_object.rs +++ b/tests/test_upload_download_object.rs @@ -15,7 +15,7 @@ mod common; -use crate::common::{create_bucket_helper, rand_object_name, RandReader, TestContext}; +use crate::common::{RandReader, TestContext, create_bucket_helper, rand_object_name}; use minio::s3::args::{DownloadObjectArgs, UploadObjectArgs}; use minio::s3::types::S3Api; use sha2::{Digest, Sha256};