chore(lint): clippy rules redundant_clone (#2554)

This commit is contained in:
Tunglies
2026-04-15 06:54:07 -07:00
committed by GitHub
parent 73e6542eea
commit 49366ee200
57 changed files with 100 additions and 119 deletions
+1
View File
@@ -74,6 +74,7 @@ unsafe_code = "deny"
[workspace.lints.clippy]
all = "warn"
needless_collect = "warn"
redundant_clone = "warn"
[workspace.dependencies]
# RustFS Internal Crates
+1 -1
View File
@@ -1097,7 +1097,7 @@ impl DataUsageInfo {
/// Add bucket usage info
pub fn add_bucket_usage(&mut self, bucket: String, usage: BucketUsageInfo) {
self.buckets_usage.insert(bucket.clone(), usage);
self.buckets_usage.insert(bucket, usage);
self.buckets_count = self.buckets_usage.len() as u64;
self.last_update = Some(SystemTime::now());
}
+1 -1
View File
@@ -685,7 +685,7 @@ pub fn current_path_updater(disk: &str, initial: &str) -> (UpdateCurrentPathFn,
};
let done_fn: CloseDiskFn = {
let disk = disk_name.clone();
let disk = disk_name;
Arc::new(move || {
let disk = disk.clone();
Box::pin(async move {
+1 -1
View File
@@ -448,7 +448,7 @@ mod tests {
// Initialize
let test_ak = "test_access_key".to_string();
let test_sk = "test_secret_key_123456".to_string();
init_global_action_credentials(Some(test_ak.clone()), Some(test_sk.clone())).ok();
init_global_action_credentials(Some(test_ak), Some(test_sk)).ok();
}
// Verify the state after initialization
@@ -593,7 +593,7 @@ impl BucketTargetSys {
};
if let Some(cli) = cli {
return Some(cli.clone());
return Some(cli);
}
// TODO: spawn a task to reload the target
@@ -821,7 +821,7 @@ pub async fn abort_incomplete_multipart_upload_due(
.as_ref()?
.days_after_initiation
.filter(|days| *days > 0)?;
Some((expected_expiry_time(initiated, days), rule.id.clone().unwrap_or_default()))
Some((expected_expiry_time(initiated, days), rule.id.unwrap_or_default()))
})
.min_by_key(|(due, _)| due.unix_timestamp_nanos())
}
@@ -83,7 +83,7 @@ impl LastDayTierStats {
#[allow(dead_code)]
fn merge(&self, m: LastDayTierStats) -> LastDayTierStats {
let mut cl = self.clone();
let mut cm = m.clone();
let mut cm = m;
let mut merged = LastDayTierStats::default();
if cl.updated_at.unix_timestamp() > cm.updated_at.unix_timestamp() {
+1 -1
View File
@@ -678,7 +678,7 @@ impl BucketMetadata {
// let x = data.clone();
// let str = std::str::from_utf8(&x).expect("Invalid UTF-8");
// println!("update config:{}", str);
self.bucket_targets_config_json = data.clone();
self.bucket_targets_config_json = data;
self.bucket_targets_config_updated_at = updated;
}
BUCKET_CORS_CONFIG => {
@@ -754,7 +754,7 @@ impl<S: StorageAPI> ReplicationPool<S> {
buckets: Vec<String>,
) -> Result<(), EcstoreError> {
// Load bucket metadata system in background
let pool_clone = self.clone();
let pool_clone = self;
tokio::spawn(async move {
pool_clone.start_resync_routine(buckets, cancellation_token).await;
+1 -1
View File
@@ -144,7 +144,7 @@ impl KVS {
pub fn insert(&mut self, key: String, value: String) {
for kv in self.0.iter_mut() {
if kv.key == key {
kv.value = value.clone();
kv.value = value;
return;
}
}
+1 -4
View File
@@ -724,10 +724,7 @@ mod tests {
let path = PathBuf::from("/test/path");
let io_error = std::io::Error::new(std::io::ErrorKind::PermissionDenied, "permission denied");
let context_error = FileAccessDeniedWithContext {
path: path.clone(),
source: io_error,
};
let context_error = FileAccessDeniedWithContext { path, source: io_error };
let display_str = format!("{context_error}");
assert!(display_str.contains("/test/path"));
+5 -5
View File
@@ -67,7 +67,7 @@ pub fn reduce_errs(errors: &[Option<Error>], ignored_errs: &[Error]) -> (usize,
let (best_err, best_count) = err_counts
.into_iter()
.max_by(|(_, c1), (_, c2)| c1.cmp(c2))
.unwrap_or((nil_error.clone(), 0));
.unwrap_or((nil_error, 0));
// Compare nil errors with the top non-nil error and prefer the nil error
if nil_count > best_count || (nil_count == best_count && nil_count > 0) {
@@ -112,7 +112,7 @@ mod tests {
fn test_reduce_errs_basic() {
let e1 = err_io("a");
let e2 = err_io("b");
let errors = vec![Some(e1.clone()), Some(e1.clone()), Some(e2.clone()), None];
let errors = vec![Some(e1.clone()), Some(e1.clone()), Some(e2), None];
let ignored = vec![];
let (count, err) = reduce_errs(&errors, &ignored);
assert_eq!(count, 2);
@@ -124,7 +124,7 @@ mod tests {
let e1 = err_io("a");
let e2 = err_io("b");
let errors = vec![Some(e1.clone()), Some(e2.clone()), Some(e1.clone()), Some(e2.clone()), None];
let ignored = vec![e2.clone()];
let ignored = vec![e2];
let (count, err) = reduce_errs(&errors, &ignored);
assert_eq!(count, 2);
assert_eq!(err, Some(e1));
@@ -134,7 +134,7 @@ mod tests {
fn test_reduce_quorum_errs() {
let e1 = err_io("a");
let e2 = err_io("b");
let errors = vec![Some(e1.clone()), Some(e1.clone()), Some(e2.clone()), None];
let errors = vec![Some(e1.clone()), Some(e1.clone()), Some(e2), None];
let ignored = vec![];
let quorum_err = Error::FaultyDisk;
// quorum = 2, should return e1
@@ -167,7 +167,7 @@ mod tests {
fn test_reduce_errs_nil_tiebreak() {
// Error::Nil and another error have the same count, should prefer Nil
let e1 = err_io("a");
let errors = vec![Some(e1.clone()), None, Some(e1.clone()), None]; // e1:2, Nil:2
let errors = vec![Some(e1.clone()), None, Some(e1), None]; // e1:2, Nil:2
let ignored = vec![];
let (count, err) = reduce_errs(&errors, &ignored);
assert_eq!(count, 2);
+1 -1
View File
@@ -1173,7 +1173,7 @@ mod tests {
fn test_io_error_with_disk_error_inside() {
// Test io::Error containing DiskError -> StorageError conversion
let original_disk_error = DiskError::FileNotFound;
let io_with_disk_error = std::io::Error::other(original_disk_error.clone());
let io_with_disk_error = std::io::Error::other(original_disk_error);
// Convert io::Error to StorageError
let storage_error: StorageError = io_with_disk_error.into();
+1 -1
View File
@@ -3684,7 +3684,7 @@ mod pools_tests {
#[test]
fn test_take_decommission_canceler_takes_and_clears_slot() {
let token = CancellationToken::new();
let mut cancelers = vec![Some(token.clone())];
let mut cancelers = vec![Some(token)];
let taken = take_decommission_canceler(cancelers.as_mut_slice(), 0);
assert!(taken.is_some());
+2 -2
View File
@@ -357,7 +357,7 @@ impl S3PeerSys {
ress.into_iter()
.filter(|op| op.is_some())
.find_map(|op| op.clone())
.find_map(|op| op)
.ok_or(Error::VolumeNotFound)
}
@@ -575,7 +575,7 @@ pub struct RemotePeerS3Client {
impl RemotePeerS3Client {
pub fn new(node: Option<Node>, pools: Option<Vec<usize>>) -> Self {
let addr = node.as_ref().map(|v| v.url.to_string()).unwrap_or_default().to_string();
let addr = node.as_ref().map(|v| v.url.to_string()).unwrap_or_default();
let client = Self {
node,
pools,
+1 -1
View File
@@ -109,7 +109,7 @@ impl RemoteDisk {
let disk = Self {
id: Mutex::new(None),
addr: addr.clone(),
addr,
endpoint: ep.clone(),
scanning: Arc::new(AtomicU32::new(0)),
health_check: opt.health_check && env_health_check,
+3 -3
View File
@@ -24,9 +24,9 @@ fn pool_lookup_not_found_error(bucket: &str, object: &str, opts: &ObjectOptions)
let object = decode_dir_object(object);
if let Some(version_id) = &opts.version_id {
StorageError::VersionNotFound(bucket.to_owned(), object.to_owned(), version_id.clone())
StorageError::VersionNotFound(bucket.to_owned(), object, version_id.clone())
} else {
StorageError::ObjectNotFound(bucket.to_owned(), object.to_owned())
StorageError::ObjectNotFound(bucket.to_owned(), object)
}
}
@@ -418,7 +418,7 @@ impl ECStore {
if is_err_object_not_found(err)
&& let Err(err) = opts.precondition_check(&pinfo.object_info)
{
return Err(err.clone());
return Err(err);
}
if !is_err_object_not_found(err) && !is_err_version_not_found(err) {
+1 -1
View File
@@ -508,7 +508,7 @@ fn from_external_tier_config(name: String, ext: ExternalTierConfig) -> io::Resul
} else {
ext.version.clone()
},
name: if ext.name.is_empty() { name.clone() } else { ext.name.clone() },
name: if ext.name.is_empty() { name } else { ext.name.clone() },
..Default::default()
};
+4 -4
View File
@@ -450,7 +450,7 @@ where
self.cache.policy_docs.store(Arc::new(cache));
let items: Vec<_> = m.into_iter().map(|(k, v)| (k, v.policy.clone())).collect();
let items: Vec<_> = m.into_iter().map(|(k, v)| (k, v.policy)).collect();
let futures: Vec<_> = items.iter().map(|(_, policy)| policy.match_resource(bucket_name)).collect();
@@ -516,7 +516,7 @@ where
self.cache.policy_docs.store(Arc::new(cache));
let items: Vec<_> = m.into_iter().map(|(k, v)| (k, v.clone())).collect();
let items: Vec<_> = m.into_iter().collect();
let futures: Vec<_> = items
.iter()
@@ -1876,7 +1876,7 @@ fn set_default_canned_policies(policies: &mut HashMap<String, PolicyDoc>) {
pub fn get_token_signing_key() -> Option<String> {
if let Some(s) = get_global_action_cred() {
Some(s.secret_key.clone())
Some(s.secret_key)
} else {
None
}
@@ -2201,7 +2201,7 @@ mod tests {
name: Some("service-account-name".to_string()),
description: Some("Updated service account".to_string()),
expiration: None,
session_policy: Some(policy.clone()),
session_policy: Some(policy),
};
assert_eq!(opts.secret_key, Some("new-secret-key".to_string()));
+1 -1
View File
@@ -163,7 +163,7 @@ impl ObjectStore {
let password = if !cred.access_key.is_empty() && !cred.secret_key.is_empty() {
format!("{}:{}", cred.access_key, cred.secret_key).into_bytes()
} else {
cred.secret_key.clone().into_bytes()
cred.secret_key.into_bytes()
};
let en = rustfs_crypto::encrypt_stream_io(&password, data)?;
Ok(en)
+1 -1
View File
@@ -967,7 +967,7 @@ impl<T: Store> IamSys<T> {
let (effective_groups, groups_source) = match args.groups.as_ref() {
Some(g) if !g.is_empty() => (args.groups.clone(), "args"),
_ => match self.store.get_user(parent_user).await {
Some(u) => (u.credentials.groups.clone(), "parent_user_credentials"),
Some(u) => (u.credentials.groups, "parent_user_credentials"),
None => {
tracing::warn!(
parent_user = %parent_user,
+4 -4
View File
@@ -249,7 +249,7 @@ mod tests {
#[test]
fn test_arc_data_clone() {
let data = vec![1u8, 2, 3, 4, 5];
let arc_data = ArcData::new(data.clone());
let arc_data = ArcData::new(data);
assert_eq!(arc_data.ref_count(), 1);
@@ -266,7 +266,7 @@ mod tests {
#[test]
fn test_arc_data_deref() {
let data = vec![1u8, 2, 3, 4, 5];
let arc_data = ArcData::new(data.clone());
let arc_data = ArcData::new(data);
// Test Deref trait
assert_eq!(arc_data.len(), 5);
@@ -289,7 +289,7 @@ mod tests {
let pool = SharedMemoryPool::with_defaults();
let data = vec![1u8, 2, 3, 4, 5];
let arc_data = pool.create(data.clone());
let arc_data = pool.create(data);
assert_eq!(arc_data.ref_count(), 1);
let shared = pool.share(&arc_data);
@@ -303,7 +303,7 @@ mod tests {
let pool = SharedMemoryPool::with_defaults();
let data = vec![1u8; 1024];
let arc_data = pool.create_with_size(data.clone(), 1024);
let arc_data = pool.create_with_size(data, 1024);
assert_eq!(arc_data.size(), Some(1024));
assert_eq!(pool.stats().current_memory.load(Ordering::Relaxed), 1024);
+1 -1
View File
@@ -84,7 +84,7 @@ mod tests {
assert!(Arc::ptr_eq(&metrics1, &metrics2));
// Create a MetricsCollector with the global metrics
let collector = MetricsCollector::new(metrics1.clone(), 100);
let collector = MetricsCollector::new(metrics1, 100);
// Record some data
let rt = tokio::runtime::Runtime::new().unwrap();
+1 -1
View File
@@ -267,7 +267,7 @@ impl KmsClient for LocalKmsClient {
key_id: uuid::Uuid::new_v4().to_string(),
master_key_id: request.master_key_id.clone(),
key_spec: request.key_spec.clone(),
encrypted_key: encrypted_key.clone(),
encrypted_key,
nonce,
encryption_context: request.encryption_context.clone(),
created_at: Zoned::now(),
+1 -1
View File
@@ -305,7 +305,7 @@ impl KmsClient for VaultKmsClient {
key_id: uuid::Uuid::new_v4().to_string(),
master_key_id: request.master_key_id.clone(),
key_spec: request.key_spec.clone(),
encrypted_key: encrypted_key.clone(),
encrypted_key,
nonce,
encryption_context: request.encryption_context.clone(),
created_at: Zoned::now(),
+1 -1
View File
@@ -80,7 +80,7 @@ impl KmsManager {
return Ok(GenerateDataKeyResponse {
key_id: request.key_id.clone(),
plaintext_key: cached_key.plaintext.clone(),
ciphertext_blob: cached_key.ciphertext.clone(),
ciphertext_blob: cached_key.ciphertext,
});
}
}
+2 -2
View File
@@ -1264,10 +1264,10 @@ mod tests {
// Test very long strings
let long_string = "a".repeat(1000);
let long_req = AddServiceAccountReq {
policy: Some(serde_json::json!({"Statement": [long_string.clone()]})),
policy: Some(serde_json::json!({"Statement": [long_string]})),
target_user: Some(long_string.clone()),
access_key: long_string.clone(),
secret_key: long_string.clone(),
secret_key: long_string,
name: Some("valid_name".to_string()),
description: Some("valid description".to_string()),
expiration: None,
+1 -1
View File
@@ -231,7 +231,7 @@ pub fn init_metrics_collectors(token: CancellationToken) {
.map(Duration::from_secs)
.unwrap_or(DEFAULT_SYSTEM_METRICS_INTERVAL);
let token_clone = token.clone();
let token_clone = token;
tokio::spawn(async move {
// Get current process PID
let pid = match sysinfo::get_current_pid() {
@@ -83,7 +83,7 @@ mod pattern_rules_tests {
let target_id = TargetID::new("prefix-target".to_string(), "webhook".to_string());
rules.add("uploads/*".to_string(), target_id.clone());
rules.add("images/*".to_string(), target_id.clone());
rules.add("images/*".to_string(), target_id);
assert!(rules.match_simple("uploads/test.csv"));
assert!(rules.match_simple("uploads/subdir/test.csv"));
@@ -153,7 +153,7 @@ mod pattern_rules_tests {
let target2 = TargetID::new("target2".to_string(), "webhook".to_string());
rules1.add("*.csv".to_string(), target1.clone());
rules2.add("*.jpg".to_string(), target2.clone());
rules2.add("*.jpg".to_string(), target2);
let combined = rules1.union(&rules2);
@@ -177,10 +177,10 @@ mod pattern_rules_tests {
// Add same target to multiple patterns in rules1
rules1.add("*.csv".to_string(), target1.clone());
rules1.add("*.jpg".to_string(), target1.clone());
rules1.add("*.txt".to_string(), target1.clone());
rules1.add("*.txt".to_string(), target1);
// Add different target to .jpg pattern in rules2
rules2.add("*.jpg".to_string(), target2.clone());
rules2.add("*.jpg".to_string(), target2);
let diff = rules1.difference(&rules2);
@@ -207,7 +207,7 @@ mod pattern_rules_tests {
rules1.add("*.txt".to_string(), target1.clone());
// Add same target to .jpg pattern in rules2
rules2.add("*.jpg".to_string(), target1.clone());
rules2.add("*.jpg".to_string(), target1);
let diff = rules1.difference(&rules2);
@@ -227,7 +227,7 @@ mod pattern_rules_tests {
let target_id = TargetID::new("test-target".to_string(), "webhook".to_string());
rules.add("*.csv".to_string(), target_id.clone());
rules.add("*.jpg".to_string(), target_id.clone());
rules.add("*.jpg".to_string(), target_id);
assert!(rules.match_simple("test.csv"));
assert!(rules.match_simple("test.jpg"));
+3 -3
View File
@@ -121,7 +121,7 @@ mod tests {
create_log_file(&dir, "other.log", 1024)?; // not managed
// Total managed = 3 072 bytes; limit = 2 048; keep_files = 2 → must delete 1.
let cleaner = make_cleaner(dir.clone(), 2, 2048);
let cleaner = make_cleaner(dir, 2, 2048);
let (deleted, freed) = cleaner.cleanup()?;
assert_eq!(deleted, 1, "should delete exactly one file");
@@ -138,7 +138,7 @@ mod tests {
create_log_file(&dir, &format!("app.log.2024-01-0{i}"), 1024)?;
}
let cleaner = make_cleaner(dir.clone(), 3, 0);
let cleaner = make_cleaner(dir, 3, 0);
let (deleted, _) = cleaner.cleanup()?;
// Updated expectation: keep_files acts as a limit (ceiling), so excess files are deleted.
@@ -213,7 +213,7 @@ mod tests {
create_log_file(&dir, "2026-03-01-06-22.rustfs.log", 1024)?;
create_log_file(&dir, "other.log", 1024)?; // not managed
let cleaner = LogCleaner::builder(dir.clone(), ".rustfs.log".to_string(), "current.log".to_string())
let cleaner = LogCleaner::builder(dir, ".rustfs.log".to_string(), "current.log".to_string())
.match_mode(FileMatchMode::Suffix)
.keep_files(1)
.max_total_size_bytes(1024)
+1 -7
View File
@@ -126,13 +126,7 @@ fn main() -> Result<(), AnyError> {
Err(_) => "flatc".to_string(),
};
match compile_flatbuffers_models(
&mut generated_mod_rs,
&flatc_path,
proto_dir.clone(),
flatbuffer_out_dir.clone(),
vec!["models"],
) {
match compile_flatbuffers_models(&mut generated_mod_rs, &flatc_path, proto_dir, flatbuffer_out_dir, vec!["models"]) {
Ok(_) => {
println!("Successfully compiled flatbuffers models.");
}
+3 -3
View File
@@ -285,7 +285,7 @@ impl HashReader {
Ok(Self {
inner,
size,
checksum: md5hex.clone(),
checksum: md5hex,
actual_size,
diskable_md5,
bytes_read: 0,
@@ -367,7 +367,7 @@ impl HashReader {
if let Some(checksum) = cs {
if checksum.checksum_type.trailing() {
self.trailer_s3s = trailing_headers.clone();
self.trailer_s3s = trailing_headers;
}
self.content_hash = Some(checksum.clone());
@@ -658,7 +658,7 @@ mod tests {
HashReader::from_stream(BufReader::new(Cursor::new(&data[..])), size, actual_size, etag.clone(), None, false)
.unwrap();
let etag_reader = EtagReader::new(reader3, etag.clone());
let hash_reader3 = HashReader::from_reader(etag_reader, size, actual_size, etag.clone(), None, false).unwrap();
let hash_reader3 = HashReader::from_reader(etag_reader, size, actual_size, etag, None, false).unwrap();
assert_eq!(hash_reader3.size(), size);
assert_eq!(hash_reader3.actual_size(), actual_size);
}
+1 -1
View File
@@ -1397,7 +1397,7 @@ impl DataUsageInfo {
/// Add bucket usage info
pub fn add_bucket_usage(&mut self, bucket: String, usage: BucketUsageInfo) {
self.buckets_usage.insert(bucket.clone(), usage);
self.buckets_usage.insert(bucket, usage);
self.buckets_count = self.buckets_usage.len() as u64;
self.last_update = Some(SystemTime::now());
}
+2 -2
View File
@@ -85,8 +85,8 @@ pub async fn init_data_scanner(ctx: CancellationToken, storeapi: Arc<ECStore>) {
// Force init global sleeper so config is read once at startup.
let _ = &*SCANNER_SLEEPER;
let ctx_clone = ctx.clone();
let storeapi_clone = storeapi.clone();
let ctx_clone = ctx;
let storeapi_clone = storeapi;
tokio::spawn(async move {
let sleep_time = initial_scanner_delay();
tokio::time::sleep(sleep_time).await;
+6 -6
View File
@@ -969,7 +969,7 @@ impl FolderScanner {
..Default::default()
})
.await
.map_err(|e| ScannerError::Other(e.to_string()))?;
.map_err(ScannerError::Other)?;
}
resolver.bucket = bucket.clone();
@@ -1399,7 +1399,7 @@ mod tests {
#[serial]
async fn test_should_skip_failed_respects_ttl() {
let (mut scanner, temp_dir) = build_test_scanner().await;
let _guard = TestGuard::new(60, 100, &mut scanner, temp_dir.clone());
let _guard = TestGuard::new(60, 100, &mut scanner, temp_dir);
let now = FolderScanner::now_secs();
scanner
@@ -1421,7 +1421,7 @@ mod tests {
#[serial]
async fn test_record_failed_ttl_zero_noop() {
let (mut scanner, temp_dir) = build_test_scanner().await;
let _guard = TestGuard::new(0, 100, &mut scanner, temp_dir.clone());
let _guard = TestGuard::new(0, 100, &mut scanner, temp_dir);
scanner.record_failed("path1");
assert!(scanner.new_cache.info.failed_objects.is_empty());
@@ -1435,7 +1435,7 @@ mod tests {
#[serial]
async fn test_record_failed_prunes_to_max_entries() {
let (mut scanner, temp_dir) = build_test_scanner().await;
let _guard = TestGuard::new(1000, 2, &mut scanner, temp_dir.clone());
let _guard = TestGuard::new(1000, 2, &mut scanner, temp_dir);
let now = FolderScanner::now_secs();
scanner
@@ -1467,7 +1467,7 @@ mod tests {
#[serial]
async fn test_prune_failed_objects_cache_drops_expired() {
let (mut scanner, temp_dir) = build_test_scanner().await;
let _guard = TestGuard::new(5, 10, &mut scanner, temp_dir.clone());
let _guard = TestGuard::new(5, 10, &mut scanner, temp_dir);
let now = FolderScanner::now_secs();
scanner
@@ -1491,7 +1491,7 @@ mod tests {
#[serial]
async fn test_prune_failed_objects_max_zero_keeps_fresh() {
let (mut scanner, temp_dir) = build_test_scanner().await;
let _guard = TestGuard::new(60, 0, &mut scanner, temp_dir.clone());
let _guard = TestGuard::new(60, 0, &mut scanner, temp_dir);
let now = FolderScanner::now_secs();
scanner
+1 -8
View File
@@ -100,14 +100,7 @@ pub fn sign_v2(
let headers = req.headers_mut();
let need_default_date = headers.get("Date").and_then(|v| v.to_str().ok()).is_none_or(|v| v.is_empty());
if need_default_date {
headers.insert(
"Date",
d2.format(&format_description::well_known::Rfc2822)
.unwrap()
.to_string()
.parse()
.unwrap(),
);
headers.insert("Date", d2.format(&format_description::well_known::Rfc2822).unwrap().parse().unwrap());
}
}
let string_to_sign = string_to_sign_v2(&req, virtual_host);
+4 -4
View File
@@ -59,7 +59,7 @@ pub fn get_signature(signing_key: [u8; 32], string_to_sign: &str) -> String {
pub fn get_scope(location: &str, t: OffsetDateTime, service_type: &str) -> String {
let format = format_description!("[year][month][day]");
let mut ans = String::from("");
ans.push_str(&t.format(&format).unwrap().to_string());
ans.push_str(&t.format(&format).unwrap());
ans.push('/');
ans.push_str(location);
ans.push('/');
@@ -234,7 +234,7 @@ pub fn pre_sign_v4(
}
query.push(("X-Amz-Algorithm".to_string(), SIGN_V4_ALGORITHM.to_string()));
let format = format_description!("[year][month][day]T[hour][minute][second]Z");
query.push(("X-Amz-Date".to_string(), t.format(&format).unwrap().to_string()));
query.push(("X-Amz-Date".to_string(), t.format(&format).unwrap()));
query.push(("X-Amz-Expires".to_string(), format!("{expires:010}")));
query.push(("X-Amz-SignedHeaders".to_string(), signed_headers));
query.push(("X-Amz-Credential".to_string(), credential));
@@ -312,7 +312,7 @@ fn sign_v4_inner(
let headers = req.headers_mut();
let format = format_description!("[year][month][day]T[hour][minute][second]Z");
headers.insert("X-Amz-Date", t.format(&format).unwrap().to_string().parse().unwrap());
headers.insert("X-Amz-Date", t.format(&format).unwrap().parse().unwrap());
if !session_token.is_empty() {
headers.insert("X-Amz-Security-Token", session_token.parse().unwrap());
@@ -364,7 +364,7 @@ fn _unsigned_trailer(mut req: request::Request<Body>, content_len: i64, trailer:
let headers = req.headers_mut();
let format = format_description!("[year][month][day]T[hour][minute][second]Z");
headers.insert("X-Amz-Date", t.format(&format).unwrap().to_string().parse().unwrap());
headers.insert("X-Amz-Date", t.format(&format).unwrap().parse().unwrap());
for (k, _) in &trailer {
headers.append("X-Amz-Trailer", k.as_str().to_lowercase().parse().unwrap());
+1 -1
View File
@@ -505,7 +505,7 @@ where
#[instrument(skip(args), fields(target_id_as_string = %id))]
pub fn new(id: String, args: MQTTArgs) -> Result<Self, TargetError> {
args.validate()?;
let target_id = TargetID::new(id.clone(), ChannelTargetType::Mqtt.as_str().to_string());
let target_id = TargetID::new(id, ChannelTargetType::Mqtt.as_str().to_string());
let queue_store = if !args.queue_dir.is_empty() {
let base_path = PathBuf::from(&args.queue_dir);
let unique_dir_name = format!("rustfs-{}-{}", ChannelTargetType::Mqtt.as_str(), target_id.id).replace(":", "_");
@@ -71,7 +71,7 @@ fn test_trusted_proxy_config() {
TrustedProxy::Cidr("10.0.0.0/8".parse().unwrap()),
];
let config = TrustedProxyConfig::new(proxies.clone(), ValidationMode::Strict, true, 10, true, vec![]);
let config = TrustedProxyConfig::new(proxies, ValidationMode::Strict, true, 10, true, vec![]);
assert_eq!(config.proxies.len(), 2);
assert_eq!(config.validation_mode, ValidationMode::Strict);
+1 -1
View File
@@ -150,7 +150,7 @@ fn test_base64_encoding_decoding() {
println!("Encoded: {}", &encoded_string);
let decoded_bytes = base64_decode_url_safe_no_pad(encoded_string.clone().as_bytes()).unwrap();
let decoded_bytes = base64_decode_url_safe_no_pad(encoded_string.as_bytes()).unwrap();
let decoded_string = String::from_utf8(decoded_bytes).unwrap();
assert_eq!(decoded_string, original_uuid_timestamp)
+1 -1
View File
@@ -346,7 +346,7 @@ pub fn path_to_bucket_object(s: &str) -> (String, String) {
/// If the prefix does not contain a separator, or resolves to root/current dir, an empty string is returned.
/// The result ensures a trailing slash if not empty.
pub fn base_dir_from_prefix(prefix: &str) -> String {
let mut base_dir = dir(prefix).to_owned();
let mut base_dir = dir(prefix);
if base_dir == "." || base_dir == "./" || base_dir == "/" {
base_dir = "".to_owned();
}
+1 -1
View File
@@ -601,7 +601,7 @@ impl Operation for ListAuditTargets {
Ok(Ok(true)) => "online",
_ => "offline",
};
((target.id().id.clone(), target.id().name.to_string()), status.to_string())
((target.id().id, target.id().name), status.to_string())
});
}
+1 -1
View File
@@ -523,7 +523,7 @@ impl Operation for ListNotificationTargets {
Ok(Ok(true)) => "online",
_ => "offline",
};
((target.id().id.clone(), target.id().name.to_string()), status.to_string())
((target.id().id, target.id().name), status.to_string())
});
}
+1 -1
View File
@@ -288,7 +288,7 @@ impl Operation for GetOidcConfigHandler {
groups_claim: provider.config.groups_claim.clone(),
roles_claim: provider.config.roles_claim.clone(),
email_claim: provider.config.email_claim.clone(),
username_claim: provider.config.username_claim.clone(),
username_claim: provider.config.username_claim,
})
.collect();
+2 -6
View File
@@ -193,9 +193,7 @@ impl Operation for AddServiceAccount {
return Err(s3_error!(InvalidRequest, "access key has spaces"));
}
create_req
.validate()
.map_err(|e| S3Error::with_message(InvalidRequest, e.to_string()))?;
create_req.validate().map_err(|e| S3Error::with_message(InvalidRequest, e))?;
let session_policy = if let Some(policy) = &create_req.policy {
let policy_bytes =
@@ -528,9 +526,7 @@ impl Operation for UpdateServiceAccount {
let update_req: UpdateServiceAccountReq =
serde_json::from_slice(&body[..]).map_err(|e| s3_error!(InvalidRequest, "unmarshal body failed, e: {:?}", e))?;
update_req
.validate()
.map_err(|e| S3Error::with_message(InvalidRequest, e.to_string()))?;
update_req.validate().map_err(|e| S3Error::with_message(InvalidRequest, e))?;
let (cred, owner) =
check_key_valid(get_session_token(&req.uri, &req.headers).unwrap_or_default(), &input_cred.access_key).await?;
+1 -1
View File
@@ -265,7 +265,7 @@ impl Operation for AddTier {
"tier connect error!",
))
} else if err.code == ERR_TIER_INVALID_CREDENTIALS.code {
Err(S3Error::with_message(S3ErrorCode::Custom(err.code.clone().into()), err.message.clone()))
Err(S3Error::with_message(S3ErrorCode::Custom(err.code.clone().into()), err.message))
} else {
warn!("tier_config_mgr add failed, e: {:?}", err);
Err(S3Error::with_message(
+7 -7
View File
@@ -364,7 +364,7 @@ mod deadlock_request_guard_tests {
assert_eq!(detector.tracked_count(), 1);
{
let _guard = DeadlockRequestGuard::new(Arc::clone(&detector), request_id.clone());
let _guard = DeadlockRequestGuard::new(Arc::clone(&detector), request_id);
// `_guard` is dropped at the end of this scope, which should unregister the request.
}
@@ -618,10 +618,10 @@ fn apply_put_request_metadata(
storage_class: Option<StorageClass>,
) -> S3Result<()> {
if let Some(cache_control) = cache_control {
metadata.insert("cache-control".to_string(), cache_control.to_string());
metadata.insert("cache-control".to_string(), cache_control);
}
if let Some(content_disposition) = content_disposition {
metadata.insert("content-disposition".to_string(), content_disposition.to_string());
metadata.insert("content-disposition".to_string(), content_disposition);
}
if let Some(content_encoding) = content_encoding
&& let Some(normalized_content_encoding) = normalize_content_encoding_for_storage(&content_encoding)
@@ -629,10 +629,10 @@ fn apply_put_request_metadata(
metadata.insert("content-encoding".to_string(), normalized_content_encoding);
}
if let Some(content_language) = content_language {
metadata.insert("content-language".to_string(), content_language.to_string());
metadata.insert("content-language".to_string(), content_language);
}
if let Some(content_type) = content_type {
metadata.insert("content-type".to_string(), content_type.to_string());
metadata.insert("content-type".to_string(), content_type);
}
if let Some(expires) = expires {
let mut formatted = Vec::new();
@@ -642,10 +642,10 @@ fn apply_put_request_metadata(
metadata.insert("expires".to_string(), String::from_utf8_lossy(&formatted).into_owned());
}
if let Some(website_redirect_location) = website_redirect_location {
metadata.insert(AMZ_WEBSITE_REDIRECT_LOCATION.to_string(), website_redirect_location.to_string());
metadata.insert(AMZ_WEBSITE_REDIRECT_LOCATION.to_string(), website_redirect_location);
}
if let Some(tags) = tagging {
metadata.insert(AMZ_OBJECT_TAGGING.to_owned(), tags.to_string());
metadata.insert(AMZ_OBJECT_TAGGING.to_owned(), tags);
}
if let Some(storage_class) = storage_class {
metadata.insert(AMZ_STORAGE_CLASS.to_string(), storage_class.as_str().to_string());
+1 -1
View File
@@ -168,7 +168,7 @@ impl S3Auth for IAMAuth {
Ok((Some(id), _valid)) => {
// Return secret key for signature verification regardless of user status.
// Authorization will be checked separately in the authorization phase.
return Ok(SecretKey::from(id.credentials.secret_key.clone()));
return Ok(SecretKey::from(id.credentials.secret_key));
}
Ok((None, _)) => {
warn!("get_secret_key failed: no such user, access_key: {access_key}");
+1 -1
View File
@@ -549,7 +549,7 @@ fn collect_config_info_json() -> ConfigInfoJson {
let profile = config.workload_profile();
let buffer_config = profile.config();
Some(WorkloadProfileJson {
name: config.workload_name().to_string(),
name: config.workload_name(),
buffer_min_size: buffer_config.min_size,
buffer_max_size: buffer_config.max_size,
default_unknown: buffer_config.default_unknown,
+2 -2
View File
@@ -530,7 +530,7 @@ mod tests {
thresholds: vec![(MI_B as i64, 64 * KI_B), (i64::MAX, 256 * KI_B)],
};
let profile = WorkloadProfile::Custom(custom_config.clone());
let profile = WorkloadProfile::Custom(custom_config);
let config = profile.config();
assert_eq!(config.calculate_buffer_size(512 * KI_B as i64), 64 * KI_B);
@@ -619,7 +619,7 @@ mod tests {
};
let custom2 = custom1.clone();
assert_eq!(WorkloadProfile::Custom(custom1.clone()), WorkloadProfile::Custom(custom2));
assert_eq!(WorkloadProfile::Custom(custom1), WorkloadProfile::Custom(custom2));
}
#[test]
+2 -2
View File
@@ -645,7 +645,7 @@ mod tests {
mime_patterns: vec!["text/*".to_string()],
min_size: 0,
};
let predicate = CompressionPredicate::new(config_disabled.clone());
let predicate = CompressionPredicate::new(config_disabled);
assert!(!predicate.config.enabled);
let config_enabled = CompressionConfig {
@@ -654,7 +654,7 @@ mod tests {
mime_patterns: vec!["text/*".to_string(), "application/json".to_string()],
min_size: 1000,
};
let predicate = CompressionPredicate::new(config_enabled.clone());
let predicate = CompressionPredicate::new(config_enabled);
assert!(predicate.config.enabled);
assert_eq!(predicate.config.extensions.len(), 2);
assert_eq!(predicate.config.mime_patterns.len(), 2);
+1 -1
View File
@@ -224,7 +224,7 @@ pub async fn start_http_server(
let secret_key = config.secret_key.clone();
b.set_auth(IAMAuth::new(access_key, secret_key));
b.set_access(store.clone());
b.set_access(store);
b.set_route(admin::make_admin_route(config.console_enable)?);
// Virtual-hosted-style requests are only set up for S3 API when server domains are configured and console is disabled
+1 -1
View File
@@ -119,7 +119,7 @@ impl ConcurrencyManager {
// Initialize metrics collector for I/O latency tracking
// Keep 1000 samples for P95/P99 calculation
let metrics_collector = Arc::new(MetricsCollector::new(performance_metrics.clone(), 1000));
let metrics_collector = Arc::new(MetricsCollector::new(performance_metrics, 1000));
// Build priority queue config
let queue_config = IoPriorityQueueConfig {
+1 -1
View File
@@ -1021,7 +1021,7 @@ mod tests {
"if-modified-since",
HeaderValue::from_str(&valid_mod_time.format(&RFC1123).unwrap()).unwrap(),
);
let info14 = info3.clone();
let info14 = info3;
assert!(check_preconditions(&headers14, &info14).is_ok());
// [15] If-Match with no ETag → PreconditionFailed
+2 -2
View File
@@ -60,7 +60,7 @@ where
{
match request_context {
Some(ctx) => {
let request_id = ctx.request_id.clone();
let request_id = ctx.request_id;
let span = info_span!("background-task", request_id = %request_id);
spawn_background(Instrument::instrument(fut, span));
}
@@ -136,7 +136,7 @@ impl OperationHelper {
let event_object = ObjectInfo {
bucket: bucket.clone(),
name: object_key.clone(),
name: object_key,
..Default::default()
};
+2 -2
View File
@@ -934,7 +934,7 @@ async fn apply_ssec_encryption_material(
) -> Result<EncryptionMaterial, ApiError> {
let params = SsecParams {
algorithm,
key: sse_key.to_string(),
key: sse_key,
key_md5: sse_key_md5,
};
@@ -1058,7 +1058,7 @@ async fn apply_managed_encryption_material(
}
// Determine KMS key ID to use for internal key wrapping.
let mut kms_key_candidate = kms_key_id.clone().map(|s| s.to_string());
let mut kms_key_candidate = kms_key_id.clone();
if kms_key_candidate.is_none() {
// Try to get default key from KMS service (if available)
if let Some(service) = get_global_encryption_service().await {
+1 -1
View File
@@ -206,7 +206,7 @@ mod tests {
let result = UpdateCheckResult {
update_available: true,
current_version: "1.1.0".to_string(),
latest_version: Some(version_info.clone()),
latest_version: Some(version_info),
check_time: check_time.clone(),
};