diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index ed0683d2..80d9e06e 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -52,19 +52,6 @@ jobs: - uses: actions/checkout@v5 - name: Install cargo-msrv run: cargo install cargo-msrv - - name: Downgrade object_store dependencies - # Necessary because tokio 1.30.0 updates MSRV to 1.63 - # and url 2.5.1, updates to 1.67 - run: | - cargo update -p tokio --precise 1.29.1 - cargo update -p url --precise 2.5.0 - cargo update -p once_cell --precise 1.20.3 - cargo update -p tracing-core --precise 0.1.33 - cargo update -p tracing-attributes --precise 0.1.28 - cargo update -p parking_lot --precise 0.12.4 - cargo update -p parking_lot_core --precise 0.9.11 - cargo update -p lock_api --precise 0.4.13 - cargo update -p syn --precise 2.0.106 - name: Check run: | # run `cargo msrv verify` to see problems diff --git a/Cargo.toml b/Cargo.toml index 137d2c54..e02d3b35 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,13 +18,13 @@ [package] name = "object_store" version = "0.12.4" -edition = "2021" +edition = "2024" license = "MIT/Apache-2.0" readme = "README.md" description = "A generic object store interface for uniformly interacting with AWS S3, Google Cloud Storage, Azure Blob Storage and local files." keywords = ["object", "storage", "cloud"] repository = "https://github.com/apache/arrow-rs-object-store" -rust-version = "1.64.0" +rust-version = "1.85" include = ["src/**/*.rs", "README.md", "LICENSE.txt", "NOTICE.txt", "Cargo.toml"] [package.metadata.docs.rs] diff --git a/src/aws/builder.rs b/src/aws/builder.rs index e8333646..04d9d317 100644 --- a/src/aws/builder.rs +++ b/src/aws/builder.rs @@ -24,11 +24,11 @@ use crate::aws::{ AmazonS3, AwsCredential, AwsCredentialProvider, Checksum, S3ConditionalPut, S3CopyIfNotExists, STORE, }; -use crate::client::{http_connector, HttpConnector, TokenCredentialProvider}; +use crate::client::{HttpConnector, TokenCredentialProvider, http_connector}; use crate::config::ConfigValue; use crate::{ClientConfigKey, ClientOptions, Result, RetryConfig, StaticCredentialProvider}; -use base64::prelude::BASE64_STANDARD; use base64::Engine; +use base64::prelude::BASE64_STANDARD; use itertools::Itertools; use md5::{Digest, Md5}; use reqwest::header::{HeaderMap, HeaderValue}; @@ -75,7 +75,10 @@ enum Error { #[error("Invalid Zone suffix for bucket '{bucket}'")] ZoneSuffix { bucket: String }, - #[error("Invalid encryption type: {}. Valid values are \"AES256\", \"sse:kms\", \"sse:kms:dsse\" and \"sse-c\".", passed)] + #[error( + "Invalid encryption type: {}. Valid values are \"AES256\", \"sse:kms\", \"sse:kms:dsse\" and \"sse-c\".", + passed + )] InvalidEncryptionType { passed: String }, #[error( diff --git a/src/aws/client.rs b/src/aws/client.rs index aee3af89..63371875 100644 --- a/src/aws/client.rs +++ b/src/aws/client.rs @@ -19,12 +19,12 @@ use crate::aws::builder::S3EncryptionHeaders; use crate::aws::checksum::Checksum; use crate::aws::credential::{AwsCredential, CredentialExt}; use crate::aws::{ - AwsAuthorizer, AwsCredentialProvider, S3ConditionalPut, S3CopyIfNotExists, COPY_SOURCE_HEADER, + AwsAuthorizer, AwsCredentialProvider, COPY_SOURCE_HEADER, S3ConditionalPut, S3CopyIfNotExists, STORE, STRICT_PATH_ENCODE_SET, TAGS_HEADER, }; use crate::client::builder::{HttpRequestBuilder, RequestBuilderError}; use crate::client::get::GetClient; -use crate::client::header::{get_etag, HeaderConfig}; +use crate::client::header::{HeaderConfig, get_etag}; use crate::client::header::{get_put_result, get_version}; use crate::client::list::ListClient; use crate::client::retry::{RetryContext, RetryExt}; @@ -40,8 +40,8 @@ use crate::{ PutPayload, PutResult, Result, RetryConfig, TagSet, }; use async_trait::async_trait; -use base64::prelude::BASE64_STANDARD; use base64::Engine; +use base64::prelude::BASE64_STANDARD; use bytes::{Buf, Bytes}; use http::header::{ CACHE_CONTROL, CONTENT_DISPOSITION, CONTENT_ENCODING, CONTENT_LANGUAGE, CONTENT_LENGTH, @@ -50,7 +50,7 @@ use http::header::{ use http::{HeaderMap, HeaderName, Method}; use itertools::Itertools; use md5::{Digest, Md5}; -use percent_encoding::{utf8_percent_encode, PercentEncode}; +use percent_encoding::{PercentEncode, utf8_percent_encode}; use quick_xml::events::{self as xml_events}; use ring::digest; use ring::digest::Context; @@ -953,10 +953,10 @@ fn encode_path(path: &Path) -> PercentEncode<'_> { #[cfg(test)] mod tests { use super::*; - use crate::client::mock_server::MockServer; use crate::client::HttpClient; - use http::header::CONTENT_LENGTH; + use crate::client::mock_server::MockServer; use http::Response; + use http::header::CONTENT_LENGTH; #[tokio::test] async fn test_create_multipart_has_content_length() { diff --git a/src/aws/credential.rs b/src/aws/credential.rs index 97d93cf6..170c3e44 100644 --- a/src/aws/credential.rs +++ b/src/aws/credential.rs @@ -25,7 +25,7 @@ use crate::{CredentialProvider, Result, RetryConfig}; use async_trait::async_trait; use bytes::Buf; use chrono::{DateTime, Utc}; -use http::header::{HeaderMap, HeaderName, HeaderValue, AUTHORIZATION}; +use http::header::{AUTHORIZATION, HeaderMap, HeaderName, HeaderValue}; use http::{Method, StatusCode}; use percent_encoding::utf8_percent_encode; use serde::Deserialize; @@ -863,8 +863,8 @@ struct CreateSessionOutput { mod tests { use super::*; use crate::aws::{AmazonS3Builder, AmazonS3ConfigKey}; - use crate::client::mock_server::MockServer; use crate::client::HttpClient; + use crate::client::mock_server::MockServer; use http::Response; use reqwest::{Client, Method}; use std::env; @@ -908,7 +908,10 @@ mod tests { }; signer.authorize(&mut request, None); - assert_eq!(request.headers().get(&AUTHORIZATION).unwrap(), "AWS4-HMAC-SHA256 Credential=AKIAIOSFODNN7EXAMPLE/20220806/us-east-1/ec2/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date, Signature=a3c787a7ed37f7fdfbfd2d7056a3d7c9d85e6d52a2bfbec73793c0be6e7862d4") + assert_eq!( + request.headers().get(&AUTHORIZATION).unwrap(), + "AWS4-HMAC-SHA256 Credential=AKIAIOSFODNN7EXAMPLE/20220806/us-east-1/ec2/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date, Signature=a3c787a7ed37f7fdfbfd2d7056a3d7c9d85e6d52a2bfbec73793c0be6e7862d4" + ) } #[test] @@ -949,7 +952,10 @@ mod tests { }; signer.authorize(&mut request, None); - assert_eq!(request.headers().get(&AUTHORIZATION).unwrap(), "AWS4-HMAC-SHA256 Credential=AKIAIOSFODNN7EXAMPLE/20220806/us-east-1/ec2/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date;x-amz-request-payer, Signature=7030625a9e9b57ed2a40e63d749f4a4b7714b6e15004cab026152f870dd8565d") + assert_eq!( + request.headers().get(&AUTHORIZATION).unwrap(), + "AWS4-HMAC-SHA256 Credential=AKIAIOSFODNN7EXAMPLE/20220806/us-east-1/ec2/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date;x-amz-request-payer, Signature=7030625a9e9b57ed2a40e63d749f4a4b7714b6e15004cab026152f870dd8565d" + ) } #[test] @@ -990,7 +996,10 @@ mod tests { }; authorizer.authorize(&mut request, None); - assert_eq!(request.headers().get(&AUTHORIZATION).unwrap(), "AWS4-HMAC-SHA256 Credential=AKIAIOSFODNN7EXAMPLE/20220806/us-east-1/ec2/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date, Signature=653c3d8ea261fd826207df58bc2bb69fbb5003e9eb3c0ef06e4a51f2a81d8699"); + assert_eq!( + request.headers().get(&AUTHORIZATION).unwrap(), + "AWS4-HMAC-SHA256 Credential=AKIAIOSFODNN7EXAMPLE/20220806/us-east-1/ec2/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date, Signature=653c3d8ea261fd826207df58bc2bb69fbb5003e9eb3c0ef06e4a51f2a81d8699" + ); } #[test] @@ -1113,7 +1122,10 @@ mod tests { }; authorizer.authorize(&mut request, None); - assert_eq!(request.headers().get(&AUTHORIZATION).unwrap(), "AWS4-HMAC-SHA256 Credential=H20ABqCkLZID4rLe/20220809/us-east-1/s3/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date, Signature=9ebf2f92872066c99ac94e573b4e1b80f4dbb8a32b1e8e23178318746e7d1b4d") + assert_eq!( + request.headers().get(&AUTHORIZATION).unwrap(), + "AWS4-HMAC-SHA256 Credential=H20ABqCkLZID4rLe/20220809/us-east-1/s3/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date, Signature=9ebf2f92872066c99ac94e573b4e1b80f4dbb8a32b1e8e23178318746e7d1b4d" + ) } #[tokio::test] @@ -1320,7 +1332,10 @@ mod tests { (" a b c ", "a b c"), ("a \t b c ", "a b c"), ("\"a \t b c ", "\"a b c"), - (" \t\n\u{000b}\r\u{000c}a \t\n\u{000b}\r\u{000c} b \t\n\u{000b}\r\u{000c} c \t\n\u{000b}\r\u{000c}", "a b c"), + ( + " \t\n\u{000b}\r\u{000c}a \t\n\u{000b}\r\u{000c} b \t\n\u{000b}\r\u{000c} c \t\n\u{000b}\r\u{000c}", + "a b c", + ), ]; for (input, expected) in test_cases { diff --git a/src/aws/mod.rs b/src/aws/mod.rs index 8dac2bd7..3cd6ca87 100644 --- a/src/aws/mod.rs +++ b/src/aws/mod.rs @@ -37,9 +37,9 @@ use std::{sync::Arc, time::Duration}; use url::Url; use crate::aws::client::{CompleteMultipartMode, PutPartPayload, RequestError, S3Client}; +use crate::client::CredentialProvider; use crate::client::get::GetClientExt; use crate::client::list::{ListClient, ListClientExt}; -use crate::client::CredentialProvider; use crate::multipart::{MultipartStore, PartId}; use crate::signer::Signer; use crate::util::STRICT_ENCODE_SET; @@ -358,7 +358,7 @@ impl ObjectStore for AmazonS3 { None => { return Err(Error::NotSupported { source: "S3 does not support copy-if-not-exists".to_string().into(), - }) + }); } }; @@ -493,14 +493,14 @@ impl PaginatedListStore for AmazonS3 { #[cfg(test)] mod tests { use super::*; + use crate::ClientOptions; + use crate::client::SpawnedReqwestConnector; use crate::client::get::GetClient; use crate::client::retry::RetryContext; - use crate::client::SpawnedReqwestConnector; use crate::integration::*; use crate::tests::*; - use crate::ClientOptions; - use base64::prelude::BASE64_STANDARD; use base64::Engine; + use base64::prelude::BASE64_STANDARD; use http::HeaderMap; const NON_EXISTENT_NAME: &str = "nonexistentname"; diff --git a/src/azure/builder.rs b/src/azure/builder.rs index 182bdf04..e824217f 100644 --- a/src/azure/builder.rs +++ b/src/azure/builder.rs @@ -21,7 +21,7 @@ use crate::azure::credential::{ ImdsManagedIdentityProvider, WorkloadIdentityOAuthProvider, }; use crate::azure::{AzureCredential, AzureCredentialProvider, MicrosoftAzure, STORE}; -use crate::client::{http_connector, HttpConnector, TokenCredentialProvider}; +use crate::client::{HttpConnector, TokenCredentialProvider, http_connector}; use crate::config::ConfigValue; use crate::{ClientConfigKey, ClientOptions, Result, RetryConfig, StaticCredentialProvider}; use percent_encoding::percent_decode_str; diff --git a/src/azure/client.rs b/src/azure/client.rs index 1e96aac0..bce2c246 100644 --- a/src/azure/client.rs +++ b/src/azure/client.rs @@ -20,25 +20,25 @@ use crate::azure::credential::*; use crate::azure::{AzureCredentialProvider, STORE}; use crate::client::builder::HttpRequestBuilder; use crate::client::get::GetClient; -use crate::client::header::{get_put_result, HeaderConfig}; +use crate::client::header::{HeaderConfig, get_put_result}; use crate::client::list::ListClient; use crate::client::retry::{RetryContext, RetryExt}; use crate::client::{GetOptionsExt, HttpClient, HttpError, HttpRequest, HttpResponse}; use crate::list::{PaginatedListOptions, PaginatedListResult}; use crate::multipart::PartId; -use crate::util::{deserialize_rfc1123, GetRange}; +use crate::util::{GetRange, deserialize_rfc1123}; use crate::{ Attribute, Attributes, ClientOptions, GetOptions, ListResult, ObjectMeta, Path, PutMode, PutMultipartOptions, PutOptions, PutPayload, PutResult, Result, RetryConfig, TagSet, }; use async_trait::async_trait; -use base64::prelude::{BASE64_STANDARD, BASE64_STANDARD_NO_PAD}; use base64::Engine; +use base64::prelude::{BASE64_STANDARD, BASE64_STANDARD_NO_PAD}; use bytes::{Buf, Bytes}; use chrono::{DateTime, Utc}; use http::{ - header::{HeaderMap, HeaderValue, CONTENT_LENGTH, CONTENT_TYPE, IF_MATCH, IF_NONE_MATCH}, HeaderName, Method, + header::{CONTENT_LENGTH, CONTENT_TYPE, HeaderMap, HeaderValue, IF_MATCH, IF_NONE_MATCH}, }; use rand::Rng as _; use serde::{Deserialize, Serialize}; @@ -497,7 +497,7 @@ async fn parse_blob_batch_delete_body( code: code.to_string(), reason: part_response.reason.unwrap_or_default().to_string(), } - .into()) + .into()); } _ => return Err(invalid_response("missing part response status code").into()), } diff --git a/src/azure/credential.rs b/src/azure/credential.rs index 37208842..82477d57 100644 --- a/src/azure/credential.rs +++ b/src/azure/credential.rs @@ -16,23 +16,23 @@ // under the License. use super::client::UserDelegationKey; +use crate::RetryConfig; use crate::azure::STORE; -use crate::client::builder::{add_query_pairs, HttpRequestBuilder}; +use crate::client::builder::{HttpRequestBuilder, add_query_pairs}; use crate::client::retry::RetryExt; use crate::client::token::{TemporaryToken, TokenCache}; use crate::client::{CredentialProvider, HttpClient, HttpError, HttpRequest, TokenProvider}; use crate::util::hmac_sha256; -use crate::RetryConfig; use async_trait::async_trait; -use base64::prelude::{BASE64_STANDARD, BASE64_URL_SAFE_NO_PAD}; use base64::Engine; +use base64::prelude::{BASE64_STANDARD, BASE64_URL_SAFE_NO_PAD}; use chrono::{DateTime, SecondsFormat, Utc}; +use http::Method; use http::header::{ - HeaderMap, HeaderName, HeaderValue, ACCEPT, AUTHORIZATION, CONTENT_ENCODING, CONTENT_LANGUAGE, - CONTENT_LENGTH, CONTENT_TYPE, DATE, IF_MATCH, IF_MODIFIED_SINCE, IF_NONE_MATCH, + ACCEPT, AUTHORIZATION, CONTENT_ENCODING, CONTENT_LANGUAGE, CONTENT_LENGTH, CONTENT_TYPE, DATE, + HeaderMap, HeaderName, HeaderValue, IF_MATCH, IF_MODIFIED_SINCE, IF_NONE_MATCH, IF_UNMODIFIED_SINCE, RANGE, }; -use http::Method; use serde::Deserialize; use std::borrow::Cow; use std::collections::HashMap; @@ -1079,7 +1079,7 @@ mod tests { async fn test_managed_identity() { let server = MockServer::new().await; - std::env::set_var(MSI_SECRET_ENV_KEY, "env-secret"); + unsafe { std::env::set_var(MSI_SECRET_ENV_KEY, "env-secret") }; let endpoint = server.url(); let client = HttpClient::new(Client::new()); diff --git a/src/azure/mod.rs b/src/azure/mod.rs index f65bf9f3..c5344d74 100644 --- a/src/azure/mod.rs +++ b/src/azure/mod.rs @@ -23,11 +23,11 @@ //! //! Unused blocks will automatically be dropped after 7 days. use crate::{ + GetOptions, GetResult, ListResult, MultipartId, MultipartUpload, ObjectMeta, ObjectStore, + PutMultipartOptions, PutOptions, PutPayload, PutResult, Result, UploadPart, multipart::{MultipartStore, PartId}, path::Path, signer::Signer, - GetOptions, GetResult, ListResult, MultipartId, MultipartUpload, ObjectMeta, ObjectStore, - PutMultipartOptions, PutOptions, PutPayload, PutResult, Result, UploadPart, }; use async_trait::async_trait; use futures::stream::{BoxStream, StreamExt, TryStreamExt}; @@ -37,10 +37,10 @@ use std::sync::Arc; use std::time::Duration; use url::Url; +use crate::client::CredentialProvider; use crate::client::get::GetClientExt; use crate::client::list::{ListClient, ListClientExt}; -use crate::client::CredentialProvider; -pub use credential::{authority_hosts, AzureAccessKey, AzureAuthorizer}; +pub use credential::{AzureAccessKey, AzureAuthorizer, authority_hosts}; mod builder; mod client; diff --git a/src/chunked.rs b/src/chunked.rs index 8af3b2c4..1f784151 100644 --- a/src/chunked.rs +++ b/src/chunked.rs @@ -23,8 +23,8 @@ use std::sync::Arc; use async_trait::async_trait; use bytes::{BufMut, Bytes, BytesMut}; -use futures::stream::BoxStream; use futures::StreamExt; +use futures::stream::BoxStream; use crate::path::Path; use crate::{ @@ -120,7 +120,7 @@ impl ObjectStore for ChunkedStore { source: Box::new(e), }), (stream, buffer, exhausted, chunk_size), - )) + )); } }; } diff --git a/src/client/get.rs b/src/client/get.rs index 51d4e1bf..be285743 100644 --- a/src/client/get.rs +++ b/src/client/get.rs @@ -15,7 +15,7 @@ // specific language governing permissions and limitations // under the License. -use crate::client::header::{get_etag, header_meta, HeaderConfig}; +use crate::client::header::{HeaderConfig, get_etag, header_meta}; use crate::client::retry::RetryContext; use crate::client::{HttpResponse, HttpResponseBody}; use crate::path::Path; @@ -25,13 +25,13 @@ use crate::{ }; use async_trait::async_trait; use bytes::Bytes; -use futures::stream::BoxStream; use futures::StreamExt; +use futures::stream::BoxStream; +use http::StatusCode; use http::header::{ CACHE_CONTROL, CONTENT_DISPOSITION, CONTENT_ENCODING, CONTENT_LANGUAGE, CONTENT_RANGE, CONTENT_TYPE, }; -use http::StatusCode; use http_body_util::BodyExt; use reqwest::header::ToStrError; use std::ops::Range; @@ -494,7 +494,7 @@ mod http_tests { use http::{Response, StatusCode}; use hyper::body::Frame; use std::pin::Pin; - use std::task::{ready, Context, Poll}; + use std::task::{Context, Poll, ready}; use std::time::Duration; #[derive(Debug, thiserror::Error)] diff --git a/src/client/header.rs b/src/client/header.rs index d7e14b3f..4c9470c3 100644 --- a/src/client/header.rs +++ b/src/client/header.rs @@ -17,11 +17,11 @@ //! Logic for extracting ObjectMeta from headers used by AWS, GCP and Azure -use crate::path::Path; use crate::ObjectMeta; +use crate::path::Path; use chrono::{DateTime, TimeZone, Utc}; -use http::header::{CONTENT_LENGTH, ETAG, LAST_MODIFIED}; use http::HeaderMap; +use http::header::{CONTENT_LENGTH, ETAG, LAST_MODIFIED}; #[derive(Debug, Copy, Clone)] /// Configuration for header extraction diff --git a/src/client/http/body.rs b/src/client/http/body.rs index 504bebe0..f59da97f 100644 --- a/src/client/http/body.rs +++ b/src/client/http/body.rs @@ -16,10 +16,10 @@ // under the License. use crate::client::{HttpError, HttpErrorKind}; -use crate::{collect_bytes, PutPayload}; +use crate::{PutPayload, collect_bytes}; use bytes::Bytes; -use futures::stream::BoxStream; use futures::StreamExt; +use futures::stream::BoxStream; use http_body_util::combinators::BoxBody; use http_body_util::{BodyExt, Full}; use hyper::body::{Body, Frame, SizeHint}; diff --git a/src/client/http/connection.rs b/src/client/http/connection.rs index 48b75492..ae474ce2 100644 --- a/src/client/http/connection.rs +++ b/src/client/http/connection.rs @@ -15,9 +15,9 @@ // specific language governing permissions and limitations // under the License. +use crate::ClientOptions; use crate::client::builder::{HttpRequestBuilder, RequestBuilderError}; use crate::client::{HttpRequest, HttpResponse, HttpResponseBody}; -use crate::ClientOptions; use async_trait::async_trait; use http::{Method, Uri}; use http_body_util::BodyExt; @@ -232,8 +232,8 @@ impl HttpService for reqwest::Client { impl HttpService for reqwest::Client { async fn call(&self, req: HttpRequest) -> Result { use futures::{ - channel::{mpsc, oneshot}, SinkExt, StreamExt, TryStreamExt, + channel::{mpsc, oneshot}, }; use http_body_util::{Empty, StreamBody}; use wasm_bindgen_futures::spawn_local; diff --git a/src/client/http/spawn.rs b/src/client/http/spawn.rs index 32c7fc49..5450b63e 100644 --- a/src/client/http/spawn.rs +++ b/src/client/http/spawn.rs @@ -129,10 +129,10 @@ impl Body for SpawnBody { #[cfg(test)] mod tests { use super::*; + use crate::RetryConfig; + use crate::client::HttpClient; use crate::client::mock_server::MockServer; use crate::client::retry::RetryExt; - use crate::client::HttpClient; - use crate::RetryConfig; async fn test_client(client: HttpClient) { let (send, recv) = tokio::sync::oneshot::channel(); diff --git a/src/client/list.rs b/src/client/list.rs index 7a2cf62a..b7192bf2 100644 --- a/src/client/list.rs +++ b/src/client/list.rs @@ -15,10 +15,10 @@ // specific language governing permissions and limitations // under the License. +use crate::Result; use crate::client::pagination::stream_paginated; use crate::list::{PaginatedListOptions, PaginatedListResult}; -use crate::path::{Path, DELIMITER}; -use crate::Result; +use crate::path::{DELIMITER, Path}; use crate::{ListResult, ObjectMeta}; use async_trait::async_trait; use futures::stream::BoxStream; diff --git a/src/client/mock_server.rs b/src/client/mock_server.rs index 9caf731d..c27fc9ff 100644 --- a/src/client/mock_server.rs +++ b/src/client/mock_server.rs @@ -16,8 +16,8 @@ // under the License. use crate::client::{HttpResponse, HttpResponseBody}; -use futures::future::BoxFuture; use futures::FutureExt; +use futures::future::BoxFuture; use hyper::body::Incoming; use hyper::server::conn::http1; use hyper::service::service_fn; diff --git a/src/client/mod.rs b/src/client/mod.rs index 5a11b7ad..58b27d28 100644 --- a/src/client/mod.rs +++ b/src/client/mod.rs @@ -64,7 +64,7 @@ use std::time::Duration; #[cfg(not(target_arch = "wasm32"))] use reqwest::{NoProxy, Proxy}; -use crate::config::{fmt_duration, ConfigValue}; +use crate::config::{ConfigValue, fmt_duration}; use crate::path::Path; use crate::{GetOptions, Result}; @@ -841,8 +841,8 @@ where #[cfg(any(feature = "aws", feature = "azure", feature = "gcp"))] mod cloud { use super::*; - use crate::client::token::{TemporaryToken, TokenCache}; use crate::RetryConfig; + use crate::client::token::{TemporaryToken, TokenCache}; /// A [`CredentialProvider`] that uses [`HttpClient`] to fetch temporary tokens #[derive(Debug)] diff --git a/src/client/retry.rs b/src/client/retry.rs index 50cf079f..ed9bf0c4 100644 --- a/src/client/retry.rs +++ b/src/client/retry.rs @@ -17,14 +17,14 @@ //! [`RetryConfig`] connection retry policy +use crate::PutPayload; use crate::client::backoff::{Backoff, BackoffConfig}; use crate::client::builder::HttpRequestBuilder; use crate::client::{HttpClient, HttpError, HttpErrorKind, HttpRequest, HttpResponse}; -use crate::PutPayload; use futures::future::BoxFuture; use http::{Method, Uri}; -use reqwest::header::LOCATION; use reqwest::StatusCode; +use reqwest::header::LOCATION; #[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))] use std::time::{Duration, Instant}; use tracing::info; @@ -108,7 +108,8 @@ impl RetryContext { /// The reason a request failed #[derive(Debug, thiserror::Error)] pub enum RequestError { - #[error("Received redirect without LOCATION, this normally indicates an incorrectly configured region" + #[error( + "Received redirect without LOCATION, this normally indicates an incorrectly configured region" )] BareRedirect, @@ -507,15 +508,15 @@ impl RetryExt for HttpRequestBuilder { #[cfg(not(target_arch = "wasm32"))] #[cfg(test)] mod tests { + use crate::RetryConfig; use crate::client::mock_server::MockServer; - use crate::client::retry::{body_contains_error, RequestError, RetryContext, RetryExt}; + use crate::client::retry::{RequestError, RetryContext, RetryExt, body_contains_error}; use crate::client::{HttpClient, HttpResponse}; - use crate::RetryConfig; use http::StatusCode; + use hyper::Response; use hyper::header::LOCATION; use hyper::server::conn::http1; use hyper::service::service_fn; - use hyper::Response; use hyper_util::rt::TokioIo; use reqwest::{Client, Method}; use std::convert::Infallible; @@ -685,7 +686,10 @@ mod tests { let e = do_request().await.unwrap_err(); assert!(matches!(e.inner(), RequestError::BareRedirect)); - assert_eq!(e.inner().to_string(), "Received redirect without LOCATION, this normally indicates an incorrectly configured region"); + assert_eq!( + e.inner().to_string(), + "Received redirect without LOCATION, this normally indicates an incorrectly configured region" + ); // Gives up after the retrying the specified number of times for _ in 0..=retry.max_retries { diff --git a/src/gcp/builder.rs b/src/gcp/builder.rs index f22d66d2..1d3a4955 100644 --- a/src/gcp/builder.rs +++ b/src/gcp/builder.rs @@ -15,16 +15,16 @@ // specific language governing permissions and limitations // under the License. -use crate::client::{http_connector, HttpConnector, TokenCredentialProvider}; +use crate::client::{HttpConnector, TokenCredentialProvider, http_connector}; use crate::config::ConfigValue; use crate::gcp::client::{GoogleCloudStorageClient, GoogleCloudStorageConfig}; use crate::gcp::credential::{ - ApplicationDefaultCredentials, InstanceCredentialProvider, ServiceAccountCredentials, - DEFAULT_GCS_BASE_URL, + ApplicationDefaultCredentials, DEFAULT_GCS_BASE_URL, InstanceCredentialProvider, + ServiceAccountCredentials, }; use crate::gcp::{ - credential, GcpCredential, GcpCredentialProvider, GcpSigningCredential, - GcpSigningCredentialProvider, GoogleCloudStorage, STORE, + GcpCredential, GcpCredentialProvider, GcpSigningCredential, GcpSigningCredentialProvider, + GoogleCloudStorage, STORE, credential, }; use crate::{ClientConfigKey, ClientOptions, Result, RetryConfig, StaticCredentialProvider}; use serde::{Deserialize, Serialize}; diff --git a/src/gcp/client.rs b/src/gcp/client.rs index 47af709d..00d3168f 100644 --- a/src/gcp/client.rs +++ b/src/gcp/client.rs @@ -17,7 +17,7 @@ use crate::client::builder::HttpRequestBuilder; use crate::client::get::GetClient; -use crate::client::header::{get_put_result, get_version, HeaderConfig}; +use crate::client::header::{HeaderConfig, get_put_result, get_version}; use crate::client::list::ListClient; use crate::client::retry::{RetryContext, RetryExt}; use crate::client::s3::{ @@ -36,15 +36,15 @@ use crate::{ PutOptions, PutPayload, PutResult, Result, RetryConfig, }; use async_trait::async_trait; -use base64::prelude::BASE64_STANDARD; use base64::Engine; +use base64::prelude::BASE64_STANDARD; use bytes::Buf; use http::header::{ CACHE_CONTROL, CONTENT_DISPOSITION, CONTENT_ENCODING, CONTENT_LANGUAGE, CONTENT_LENGTH, CONTENT_TYPE, }; use http::{HeaderName, Method, StatusCode}; -use percent_encoding::{percent_encode, utf8_percent_encode, NON_ALPHANUMERIC}; +use percent_encoding::{NON_ALPHANUMERIC, percent_encode, utf8_percent_encode}; use serde::{Deserialize, Serialize}; use std::sync::Arc; diff --git a/src/gcp/credential.rs b/src/gcp/credential.rs index 1e067f53..2245829f 100644 --- a/src/gcp/credential.rs +++ b/src/gcp/credential.rs @@ -21,11 +21,11 @@ use crate::client::retry::RetryExt; use crate::client::token::TemporaryToken; use crate::client::{HttpClient, HttpError, TokenProvider}; use crate::gcp::{GcpSigningCredentialProvider, STORE}; -use crate::util::{hex_digest, hex_encode, STRICT_ENCODE_SET}; +use crate::util::{STRICT_ENCODE_SET, hex_digest, hex_encode}; use crate::{RetryConfig, StaticCredentialProvider}; use async_trait::async_trait; -use base64::prelude::BASE64_URL_SAFE_NO_PAD; use base64::Engine; +use base64::prelude::BASE64_URL_SAFE_NO_PAD; use chrono::{DateTime, Utc}; use futures::TryFutureExt; use http::{HeaderMap, Method}; diff --git a/src/gcp/mod.rs b/src/gcp/mod.rs index 442b24fe..44f2c2ce 100644 --- a/src/gcp/mod.rs +++ b/src/gcp/mod.rs @@ -41,9 +41,9 @@ use crate::client::CredentialProvider; use crate::gcp::credential::GCSAuthorizer; use crate::signer::Signer; use crate::{ - multipart::PartId, path::Path, GetOptions, GetResult, ListResult, MultipartId, MultipartUpload, - ObjectMeta, ObjectStore, PutMultipartOptions, PutOptions, PutPayload, PutResult, Result, - UploadPart, + GetOptions, GetResult, ListResult, MultipartId, MultipartUpload, ObjectMeta, ObjectStore, + PutMultipartOptions, PutOptions, PutPayload, PutResult, Result, UploadPart, multipart::PartId, + path::Path, }; use async_trait::async_trait; use client::GoogleCloudStorageClient; diff --git a/src/http/client.rs b/src/http/client.rs index d08e9faf..5b2d3434 100644 --- a/src/http/client.rs +++ b/src/http/client.rs @@ -20,7 +20,7 @@ use crate::client::get::GetClient; use crate::client::header::HeaderConfig; use crate::client::retry::{self, RetryConfig, RetryContext, RetryExt}; use crate::client::{GetOptionsExt, HttpClient, HttpError, HttpResponse}; -use crate::path::{Path, DELIMITER}; +use crate::path::{DELIMITER, Path}; use crate::util::deserialize_rfc1123; use crate::{Attribute, Attributes, ClientOptions, GetOptions, ObjectMeta, PutPayload, Result}; use async_trait::async_trait; @@ -197,7 +197,9 @@ impl Client { builder.header(CONTENT_TYPE, v.as_ref()) } Attribute::StorageClass => { - tracing::warn!("StorageClass attribute not supported on HTTP client as header key is unknown"); + tracing::warn!( + "StorageClass attribute not supported on HTTP client as header key is unknown" + ); builder } // Ignore metadata attributes @@ -232,7 +234,7 @@ impl Client { source, path: location.to_string(), } - .into()) + .into()); } }, } @@ -280,7 +282,7 @@ impl Client { source, path: location.map(|x| x.to_string()).unwrap_or_default(), } - .into()) + .into()); } }; diff --git a/src/http/mod.rs b/src/http/mod.rs index 8581f923..d573125b 100644 --- a/src/http/mod.rs +++ b/src/http/mod.rs @@ -41,7 +41,7 @@ use url::Url; use crate::client::get::GetClientExt; use crate::client::header::get_etag; -use crate::client::{http_connector, HttpConnector}; +use crate::client::{HttpConnector, http_connector}; use crate::http::client::Client; use crate::path::Path; use crate::{ diff --git a/src/integration.rs b/src/integration.rs index 1f769b18..e4e73e9a 100644 --- a/src/integration.rs +++ b/src/integration.rs @@ -34,7 +34,7 @@ use crate::{ use bytes::Bytes; use futures::stream::FuturesUnordered; use futures::{StreamExt, TryStreamExt}; -use rand::{rng, Rng}; +use rand::{Rng, rng}; use std::collections::HashSet; use std::slice; @@ -1156,15 +1156,9 @@ pub async fn multipart_out_of_order(storage: &dyn ObjectStore) { let path = Path::from("test_multipart_out_of_order"); let mut multipart_upload = storage.put_multipart(&path).await.unwrap(); - let part1 = std::iter::repeat(b'1') - .take(5 * 1024 * 1024) - .collect::(); - let part2 = std::iter::repeat(b'2') - .take(5 * 1024 * 1024) - .collect::(); - let part3 = std::iter::repeat(b'3') - .take(5 * 1024 * 1024) - .collect::(); + let part1 = std::iter::repeat_n(b'1', 5 * 1024 * 1024).collect::(); + let part2 = std::iter::repeat_n(b'2', 5 * 1024 * 1024).collect::(); + let part3 = std::iter::repeat_n(b'3', 5 * 1024 * 1024).collect::(); let full = [part1.as_ref(), part2.as_ref(), part3.as_ref()].concat(); let fut1 = multipart_upload.put_part(part1.into()); diff --git a/src/lib.rs b/src/lib.rs index e37fb693..7bd3c99d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -557,8 +557,8 @@ pub mod client; #[cfg(feature = "cloud")] pub use client::{ - backoff::BackoffConfig, retry::RetryConfig, ClientConfigKey, ClientOptions, CredentialProvider, - StaticCredentialProvider, + ClientConfigKey, ClientOptions, CredentialProvider, StaticCredentialProvider, + backoff::BackoffConfig, retry::RetryConfig, }; #[cfg(all(feature = "cloud", not(target_arch = "wasm32")))] @@ -585,10 +585,10 @@ pub mod integration; pub use attributes::*; -pub use parse::{parse_url, parse_url_opts, ObjectStoreScheme}; +pub use parse::{ObjectStoreScheme, parse_url, parse_url_opts}; pub use payload::*; pub use upload::*; -pub use util::{coalesce_ranges, collect_bytes, GetRange, OBJECT_STORE_COALESCE_DEFAULT}; +pub use util::{GetRange, OBJECT_STORE_COALESCE_DEFAULT, coalesce_ranges, collect_bytes}; // Re-export HTTP types used in public API pub use ::http::{Extensions, HeaderMap, HeaderValue}; @@ -599,7 +599,7 @@ use crate::util::maybe_spawn_blocking; use async_trait::async_trait; use bytes::Bytes; use chrono::{DateTime, Utc}; -use futures::{stream::BoxStream, StreamExt, TryStreamExt}; +use futures::{StreamExt, TryStreamExt, stream::BoxStream}; use std::fmt::{Debug, Formatter}; #[cfg(all(feature = "fs", not(target_arch = "wasm32")))] use std::io::{Read, Seek, SeekFrom}; diff --git a/src/limit.rs b/src/limit.rs index 85714967..ddafa929 100644 --- a/src/limit.rs +++ b/src/limit.rs @@ -276,10 +276,10 @@ impl MultipartUpload for LimitUpload { #[cfg(test)] mod tests { + use crate::ObjectStore; use crate::integration::*; use crate::limit::LimitStore; use crate::memory::InMemory; - use crate::ObjectStore; use futures::stream::StreamExt; use std::pin::Pin; use std::time::Duration; diff --git a/src/local.rs b/src/local.rs index 3404bc89..9294424a 100644 --- a/src/local.rs +++ b/src/local.rs @@ -16,7 +16,7 @@ // under the License. //! An object store implementation for a local filesystem -use std::fs::{metadata, symlink_metadata, File, Metadata, OpenOptions}; +use std::fs::{File, Metadata, OpenOptions, metadata, symlink_metadata}; use std::io::{ErrorKind, Read, Seek, SeekFrom, Write}; use std::ops::Range; use std::sync::Arc; @@ -27,19 +27,18 @@ use std::{collections::VecDeque, path::PathBuf}; use async_trait::async_trait; use bytes::Bytes; use chrono::{DateTime, Utc}; -use futures::{stream::BoxStream, StreamExt}; use futures::{FutureExt, TryStreamExt}; +use futures::{StreamExt, stream::BoxStream}; use parking_lot::Mutex; use url::Url; use walkdir::{DirEntry, WalkDir}; use crate::{ - maybe_spawn_blocking, - path::{absolute_path_to_url, Path}, - util::InvalidGetRange, Attributes, GetOptions, GetResult, GetResultPayload, ListResult, MultipartUpload, ObjectMeta, ObjectStore, PutMode, PutMultipartOptions, PutOptions, PutPayload, PutResult, Result, - UploadPart, + UploadPart, maybe_spawn_blocking, + path::{Path, absolute_path_to_url}, + util::InvalidGetRange, }; /// A specialized `Error` for filesystem object store-related errors @@ -556,23 +555,25 @@ impl ObjectStore for LocalFileSystem { // - atomically rename this temporary file into place // // This is necessary because hard_link returns an error if the destination already exists - maybe_spawn_blocking(move || loop { - let staged = staged_upload_path(&to, &id.to_string()); - match std::fs::hard_link(&from, &staged) { - Ok(_) => { - return std::fs::rename(&staged, &to).map_err(|source| { - let _ = std::fs::remove_file(&staged); // Attempt to clean up - Error::UnableToCopyFile { from, to, source }.into() - }); - } - Err(source) => match source.kind() { - ErrorKind::AlreadyExists => id += 1, - ErrorKind::NotFound => match from.exists() { - true => create_parent_dirs(&to, source)?, - false => return Err(Error::NotFound { path: from, source }.into()), + maybe_spawn_blocking(move || { + loop { + let staged = staged_upload_path(&to, &id.to_string()); + match std::fs::hard_link(&from, &staged) { + Ok(_) => { + return std::fs::rename(&staged, &to).map_err(|source| { + let _ = std::fs::remove_file(&staged); // Attempt to clean up + Error::UnableToCopyFile { from, to, source }.into() + }); + } + Err(source) => match source.kind() { + ErrorKind::AlreadyExists => id += 1, + ErrorKind::NotFound => match from.exists() { + true => create_parent_dirs(&to, source)?, + false => return Err(Error::NotFound { path: from, source }.into()), + }, + _ => return Err(Error::UnableToCopyFile { from, to, source }.into()), }, - _ => return Err(Error::UnableToCopyFile { from, to, source }.into()), - }, + } } }) .await @@ -581,16 +582,18 @@ impl ObjectStore for LocalFileSystem { async fn rename(&self, from: &Path, to: &Path) -> Result<()> { let from = self.path_to_filesystem(from)?; let to = self.path_to_filesystem(to)?; - maybe_spawn_blocking(move || loop { - match std::fs::rename(&from, &to) { - Ok(_) => return Ok(()), - Err(source) => match source.kind() { - ErrorKind::NotFound => match from.exists() { - true => create_parent_dirs(&to, source)?, - false => return Err(Error::NotFound { path: from, source }.into()), + maybe_spawn_blocking(move || { + loop { + match std::fs::rename(&from, &to) { + Ok(_) => return Ok(()), + Err(source) => match source.kind() { + ErrorKind::NotFound => match from.exists() { + true => create_parent_dirs(&to, source)?, + false => return Err(Error::NotFound { path: from, source }.into()), + }, + _ => return Err(Error::UnableToCopyFile { from, to, source }.into()), }, - _ => return Err(Error::UnableToCopyFile { from, to, source }.into()), - }, + } } }) .await @@ -600,23 +603,25 @@ impl ObjectStore for LocalFileSystem { let from = self.path_to_filesystem(from)?; let to = self.path_to_filesystem(to)?; - maybe_spawn_blocking(move || loop { - match std::fs::hard_link(&from, &to) { - Ok(_) => return Ok(()), - Err(source) => match source.kind() { - ErrorKind::AlreadyExists => { - return Err(Error::AlreadyExists { - path: to.to_str().unwrap().to_string(), - source, + maybe_spawn_blocking(move || { + loop { + match std::fs::hard_link(&from, &to) { + Ok(_) => return Ok(()), + Err(source) => match source.kind() { + ErrorKind::AlreadyExists => { + return Err(Error::AlreadyExists { + path: to.to_str().unwrap().to_string(), + source, + } + .into()); } - .into()) - } - ErrorKind::NotFound => match from.exists() { - true => create_parent_dirs(&to, source)?, - false => return Err(Error::NotFound { path: from, source }.into()), + ErrorKind::NotFound => match from.exists() { + true => create_parent_dirs(&to, source)?, + false => return Err(Error::NotFound { path: from, source }.into()), + }, + _ => return Err(Error::UnableToCopyFile { from, to, source }.into()), }, - _ => return Err(Error::UnableToCopyFile { from, to, source }.into()), - }, + } } }) .await @@ -1614,7 +1619,10 @@ mod tests { let b = Path::parse("bar#123").unwrap(); let err = integration.get(&b).await.unwrap_err().to_string(); - assert_eq!(err, "Generic LocalFileSystem error: Filenames containing trailing '/#\\d+/' are not supported: bar#123"); + assert_eq!( + err, + "Generic LocalFileSystem error: Filenames containing trailing '/#\\d+/' are not supported: bar#123" + ); let c = Path::parse("foo#123.txt").unwrap(); integration.put(&c, "test".into()).await.unwrap(); diff --git a/src/memory.rs b/src/memory.rs index e15c2465..517cb1dd 100644 --- a/src/memory.rs +++ b/src/memory.rs @@ -23,15 +23,15 @@ use std::sync::Arc; use async_trait::async_trait; use bytes::Bytes; use chrono::{DateTime, Utc}; -use futures::{stream::BoxStream, StreamExt}; +use futures::{StreamExt, stream::BoxStream}; use parking_lot::RwLock; use crate::multipart::{MultipartStore, PartId}; use crate::util::InvalidGetRange; use crate::{ - path::Path, Attributes, GetRange, GetResult, GetResultPayload, ListResult, MultipartId, - MultipartUpload, ObjectMeta, ObjectStore, PutMode, PutMultipartOptions, PutOptions, PutResult, - Result, UpdateVersion, UploadPart, + Attributes, GetRange, GetResult, GetResultPayload, ListResult, MultipartId, MultipartUpload, + ObjectMeta, ObjectStore, PutMode, PutMultipartOptions, PutOptions, PutResult, Result, + UpdateVersion, UploadPart, path::Path, }; use crate::{GetOptions, PutPayload}; diff --git a/src/parse.rs b/src/parse.rs index b1f653c5..b8b6fa41 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -15,11 +15,11 @@ // specific language governing permissions and limitations // under the License. +use crate::ObjectStore; #[cfg(all(feature = "fs", not(target_arch = "wasm32")))] use crate::local::LocalFileSystem; use crate::memory::InMemory; use crate::path::Path; -use crate::ObjectStore; use url::Url; #[derive(Debug, thiserror::Error)] @@ -230,7 +230,7 @@ where return Err(super::Error::Generic { store: "parse_url", source: format!("feature for {s:?} not enabled").into(), - }) + }); } }; @@ -402,7 +402,7 @@ mod tests { #[cfg(all(feature = "http", not(target_arch = "wasm32")))] async fn test_url_http() { use crate::client::mock_server::MockServer; - use http::{header::USER_AGENT, Response}; + use http::{Response, header::USER_AGENT}; let server = MockServer::new().await; diff --git a/src/path/parts.rs b/src/path/parts.rs index 9c6612bf..21705100 100644 --- a/src/path/parts.rs +++ b/src/path/parts.rs @@ -15,7 +15,7 @@ // specific language governing permissions and limitations // under the License. -use percent_encoding::{percent_encode, AsciiSet, CONTROLS}; +use percent_encoding::{AsciiSet, CONTROLS, percent_encode}; use std::borrow::Cow; use crate::path::DELIMITER_BYTE; diff --git a/src/prefix.rs b/src/prefix.rs index 4720c989..160fbbf6 100644 --- a/src/prefix.rs +++ b/src/prefix.rs @@ -17,7 +17,7 @@ //! An object store wrapper handling a constant path prefix use bytes::Bytes; -use futures::{stream::BoxStream, StreamExt, TryStreamExt}; +use futures::{StreamExt, TryStreamExt, stream::BoxStream}; use std::ops::Range; use crate::path::Path; diff --git a/src/registry.rs b/src/registry.rs index 81770c57..47948425 100644 --- a/src/registry.rs +++ b/src/registry.rs @@ -18,7 +18,7 @@ //! Map object URLs to [`ObjectStore`] use crate::path::{InvalidPart, Path, PathPart}; -use crate::{parse_url_opts, ObjectStore}; +use crate::{ObjectStore, parse_url_opts}; use parking_lot::RwLock; use std::collections::HashMap; use std::sync::Arc; @@ -274,9 +274,11 @@ mod tests { // Should not replace store let banana = Arc::new(PrefixStore::new(InMemory::new(), "banana")) as Arc; - assert!(registry - .register(banana_url.clone(), Arc::clone(&banana)) - .is_none()); + assert!( + registry + .register(banana_url.clone(), Arc::clone(&banana)) + .is_none() + ); // Should resolve to banana store let (resolved, path) = registry.resolve(&banana_url).unwrap(); @@ -317,9 +319,11 @@ mod tests { let nested_url2 = Url::parse("memory:///1/2/3").unwrap(); let nested2 = Arc::new(PrefixStore::new(InMemory::new(), "1/2/3")) as Arc; - assert!(registry - .register(nested_url2, Arc::clone(&nested2)) - .is_none()); + assert!( + registry + .register(nested_url2, Arc::clone(&nested2)) + .is_none() + ); let to_resolve = Url::parse("memory:///1/2/3/4/5/6").unwrap(); let (resolved, path) = registry.resolve(&to_resolve).unwrap(); @@ -328,9 +332,11 @@ mod tests { let custom_scheme_url = Url::parse("custom:///").unwrap(); let custom_scheme = Arc::new(InMemory::new()) as Arc; - assert!(registry - .register(custom_scheme_url, Arc::clone(&custom_scheme)) - .is_none()); + assert!( + registry + .register(custom_scheme_url, Arc::clone(&custom_scheme)) + .is_none() + ); let to_resolve = Url::parse("custom:///6/7").unwrap(); let (resolved, path) = registry.resolve(&to_resolve).unwrap(); diff --git a/src/signer.rs b/src/signer.rs index da55c689..ab3c7f91 100644 --- a/src/signer.rs +++ b/src/signer.rs @@ -17,7 +17,7 @@ //! Abstraction of signed URL generation for those object store implementations that support it -use crate::{path::Path, Result}; +use crate::{Result, path::Path}; use async_trait::async_trait; use reqwest::Method; use std::{fmt, time::Duration}; diff --git a/src/throttle.rs b/src/throttle.rs index dec642a7..85a91864 100644 --- a/src/throttle.rs +++ b/src/throttle.rs @@ -21,14 +21,14 @@ use std::ops::Range; use std::{convert::TryInto, sync::Arc}; use crate::multipart::{MultipartStore, PartId}; +use crate::{GetOptions, UploadPart}; use crate::{ - path::Path, GetResult, GetResultPayload, ListResult, MultipartId, MultipartUpload, ObjectMeta, - ObjectStore, PutMultipartOptions, PutOptions, PutPayload, PutResult, Result, + GetResult, GetResultPayload, ListResult, MultipartId, MultipartUpload, ObjectMeta, ObjectStore, + PutMultipartOptions, PutOptions, PutPayload, PutResult, Result, path::Path, }; -use crate::{GetOptions, UploadPart}; use async_trait::async_trait; use bytes::Bytes; -use futures::{stream::BoxStream, FutureExt, StreamExt}; +use futures::{FutureExt, StreamExt, stream::BoxStream}; use std::time::Duration; /// Configuration settings for throttled store @@ -559,7 +559,7 @@ mod tests { let path = Path::from("foo"); if let Some(n_bytes) = n_bytes { - let data: Vec<_> = std::iter::repeat(1u8).take(n_bytes).collect(); + let data: Vec<_> = std::iter::repeat_n(1u8, n_bytes).collect(); store.put(&path, data.into()).await.unwrap(); } else { // ensure object is absent @@ -651,7 +651,7 @@ mod tests { } async fn measure_put(store: &ThrottledStore, n_bytes: usize) -> Duration { - let data: Vec<_> = std::iter::repeat(1u8).take(n_bytes).collect(); + let data: Vec<_> = std::iter::repeat_n(1u8, n_bytes).collect(); let t0 = Instant::now(); store.put(&Path::from("foo"), data.into()).await.unwrap(); diff --git a/src/upload.rs b/src/upload.rs index af5975a7..a27d0dd6 100644 --- a/src/upload.rs +++ b/src/upload.rs @@ -248,10 +248,10 @@ mod tests { use rand::prelude::StdRng; use rand::{Rng, SeedableRng}; + use crate::ObjectStore; use crate::memory::InMemory; use crate::path::Path; use crate::throttle::{ThrottleConfig, ThrottledStore}; - use crate::ObjectStore; use super::*; diff --git a/src/util.rs b/src/util.rs index 4f297d95..b7f9182c 100644 --- a/src/util.rs +++ b/src/util.rs @@ -23,7 +23,7 @@ use std::{ use super::Result; use bytes::Bytes; -use futures::{stream::StreamExt, Stream, TryStreamExt}; +use futures::{Stream, TryStreamExt, stream::StreamExt}; #[cfg(any(feature = "azure", feature = "http"))] pub(crate) static RFC1123_FMT: &str = "%a, %d %h %Y %T GMT"; @@ -331,7 +331,7 @@ mod tests { use crate::Error; use super::*; - use rand::{rng, Rng}; + use rand::{Rng, rng}; use std::ops::Range; /// Calls coalesce_ranges and validates the returned data is correct diff --git a/tests/http.rs b/tests/http.rs index 6c417922..f23ef74f 100644 --- a/tests/http.rs +++ b/tests/http.rs @@ -18,7 +18,7 @@ //! Tests the HTTP store implementation #[cfg(feature = "http")] -use object_store::{http::HttpBuilder, path::Path, GetOptions, GetRange, ObjectStore}; +use object_store::{GetOptions, GetRange, ObjectStore, http::HttpBuilder, path::Path}; #[cfg(all(feature = "http", target_arch = "wasm32", target_os = "unknown"))] use wasm_bindgen_test::*;