style: apply cargo fmt to entire codebase

Standardize code formatting across all 173 Rust source files
using rustfmt. No functional changes - purely cosmetic.

This establishes a consistent code style baseline for the
project going forward.
This commit is contained in:
Dionisio
2026-02-14 01:29:34 +01:00
parent 67137a3ef2
commit 4c98c5a657
173 changed files with 23368 additions and 17590 deletions
+178 -159
View File
@@ -1,32 +1,32 @@
use futures::{Future, future::join_all};
use std::sync::Arc;
use futures::{future::join_all, Future};
use thiserror::Error;
use tokio::sync::Semaphore;
use tracing::info;
use thiserror::Error;
use crate::application::ports::file_ports::{FileRetrievalUseCase, FileManagementUseCase};
use crate::application::services::folder_service::FolderService;
use crate::common::errors::DomainError;
use crate::common::config::AppConfig;
use crate::application::ports::inbound::FolderUseCase;
use crate::application::dtos::file_dto::FileDto;
use crate::application::dtos::folder_dto::FolderDto;
use crate::application::ports::file_ports::{FileManagementUseCase, FileRetrievalUseCase};
use crate::application::ports::inbound::FolderUseCase;
use crate::application::services::folder_service::FolderService;
use crate::common::config::AppConfig;
use crate::common::errors::DomainError;
/// Specific errors for batch operations
#[derive(Debug, Error)]
pub enum BatchOperationError {
#[error("Domain error: {0}")]
Domain(#[from] DomainError),
#[error("Operation cancelled: {0}")]
Cancelled(String),
#[error("Concurrency limit exceeded: {0}")]
ConcurrencyLimit(String),
#[error("Batch operation error: {0} ({1} of {2} completed)")]
PartialFailure(String, usize, usize),
#[error("Internal error: {0}")]
Internal(String),
}
@@ -72,11 +72,11 @@ impl BatchOperationService {
file_retrieval: Arc<dyn FileRetrievalUseCase>,
file_management: Arc<dyn FileManagementUseCase>,
folder_service: Arc<FolderService>,
config: AppConfig
config: AppConfig,
) -> Self {
// Limit concurrency based on configuration
let max_concurrency = config.concurrency.max_concurrent_files;
Self {
file_retrieval,
file_management,
@@ -85,16 +85,21 @@ impl BatchOperationService {
semaphore: Arc::new(Semaphore::new(max_concurrency)),
}
}
/// Creates a new instance with default configuration
pub fn default(
file_retrieval: Arc<dyn FileRetrievalUseCase>,
file_management: Arc<dyn FileManagementUseCase>,
folder_service: Arc<FolderService>
folder_service: Arc<FolderService>,
) -> Self {
Self::new(file_retrieval, file_management, folder_service, AppConfig::default())
Self::new(
file_retrieval,
file_management,
folder_service,
AppConfig::default(),
)
}
/// Copies multiple files in parallel
pub async fn copy_files(
&self,
@@ -103,7 +108,7 @@ impl BatchOperationService {
) -> Result<BatchResult<FileDto>, BatchOperationError> {
info!("Starting batch copy of {} files", file_ids.len());
let start_time = std::time::Instant::now();
// Create result structure
let mut result = BatchResult {
successful: Vec::new(),
@@ -113,30 +118,30 @@ impl BatchOperationService {
..Default::default()
},
};
// Define the operation to perform for each file
let operations = file_ids.into_iter().map(|file_id| {
let mgmt = self.file_management.clone();
let target_folder = target_folder_id.clone();
let semaphore = self.semaphore.clone();
async move {
// Acquire semaphore permit
let permit = semaphore.acquire().await.unwrap();
let copy_result = mgmt.move_file(&file_id, target_folder.clone()).await;
// Release the permit explicitly (also released on drop)
drop(permit);
// Return the result along with the ID to identify successes/failures
(file_id, copy_result)
}
});
// Execute all operations in parallel with concurrency control
let operation_results = join_all(operations).await;
// Process the results
for (file_id, operation_result) in operation_results {
match operation_result {
@@ -150,22 +155,23 @@ impl BatchOperationService {
}
}
}
// Complete statistics
result.stats.execution_time_ms = start_time.elapsed().as_millis();
result.stats.max_concurrency = self.config.concurrency.max_concurrent_files
result.stats.max_concurrency = self
.config
.concurrency
.max_concurrent_files
.min(result.stats.total);
info!(
"Batch copy completed: {}/{} successful in {}ms",
result.stats.successful,
result.stats.total,
result.stats.execution_time_ms
result.stats.successful, result.stats.total, result.stats.execution_time_ms
);
Ok(result)
}
/// Moves multiple files in parallel
pub async fn move_files(
&self,
@@ -174,7 +180,7 @@ impl BatchOperationService {
) -> Result<BatchResult<FileDto>, BatchOperationError> {
info!("Starting batch move of {} files", file_ids.len());
let start_time = std::time::Instant::now();
// Create result structure
let mut result = BatchResult {
successful: Vec::new(),
@@ -184,30 +190,30 @@ impl BatchOperationService {
..Default::default()
},
};
// Define the operation to perform for each file
let operations = file_ids.into_iter().map(|file_id| {
let mgmt = self.file_management.clone();
let target_folder = target_folder_id.clone();
let semaphore = self.semaphore.clone();
async move {
// Acquire semaphore permit
let permit = semaphore.acquire().await.unwrap();
let move_result = mgmt.move_file(&file_id, target_folder.clone()).await;
// Release the permit explicitly
drop(permit);
// Return the result along with the ID to identify successes/failures
(file_id, move_result)
}
});
// Execute all operations in parallel with concurrency control
let operation_results = join_all(operations).await;
// Process the results
for (file_id, operation_result) in operation_results {
match operation_result {
@@ -221,22 +227,23 @@ impl BatchOperationService {
}
}
}
// Complete statistics
result.stats.execution_time_ms = start_time.elapsed().as_millis();
result.stats.max_concurrency = self.config.concurrency.max_concurrent_files
result.stats.max_concurrency = self
.config
.concurrency
.max_concurrent_files
.min(result.stats.total);
info!(
"Batch move completed: {}/{} successful in {}ms",
result.stats.successful,
result.stats.total,
result.stats.execution_time_ms
result.stats.successful, result.stats.total, result.stats.execution_time_ms
);
Ok(result)
}
/// Deletes multiple files in parallel
pub async fn delete_files(
&self,
@@ -244,7 +251,7 @@ impl BatchOperationService {
) -> Result<BatchResult<String>, BatchOperationError> {
info!("Starting batch deletion of {} files", file_ids.len());
let start_time = std::time::Instant::now();
// Create result structure
let mut result = BatchResult {
successful: Vec::new(),
@@ -254,30 +261,30 @@ impl BatchOperationService {
..Default::default()
},
};
// Define the operation to perform for each file
let operations = file_ids.into_iter().map(|file_id| {
let mgmt = self.file_management.clone();
let semaphore = self.semaphore.clone();
let id_clone = file_id.clone();
async move {
// Acquire semaphore permit
let permit = semaphore.acquire().await.unwrap();
let delete_result = mgmt.delete_file(&file_id).await;
// Release the permit explicitly
drop(permit);
// Return the result along with the ID
(id_clone.clone(), delete_result.map(|_| id_clone))
}
});
// Execute all operations in parallel with concurrency control
let operation_results = join_all(operations).await;
// Process the results
for (file_id, operation_result) in operation_results {
match operation_result {
@@ -291,22 +298,23 @@ impl BatchOperationService {
}
}
}
// Complete statistics
result.stats.execution_time_ms = start_time.elapsed().as_millis();
result.stats.max_concurrency = self.config.concurrency.max_concurrent_files
result.stats.max_concurrency = self
.config
.concurrency
.max_concurrent_files
.min(result.stats.total);
info!(
"Batch deletion completed: {}/{} successful in {}ms",
result.stats.successful,
result.stats.total,
result.stats.execution_time_ms
result.stats.successful, result.stats.total, result.stats.execution_time_ms
);
Ok(result)
}
/// Loads multiple files in parallel (data in memory)
pub async fn get_multiple_files(
&self,
@@ -314,7 +322,7 @@ impl BatchOperationService {
) -> Result<BatchResult<FileDto>, BatchOperationError> {
info!("Starting batch load of {} files", file_ids.len());
let start_time = std::time::Instant::now();
// Create result structure
let mut result = BatchResult {
successful: Vec::new(),
@@ -324,29 +332,29 @@ impl BatchOperationService {
..Default::default()
},
};
// Define the operation to perform for each file
let operations = file_ids.into_iter().map(|file_id| {
let retrieval = self.file_retrieval.clone();
let semaphore = self.semaphore.clone();
async move {
// Acquire semaphore permit
let permit = semaphore.acquire().await.unwrap();
let get_result = retrieval.get_file(&file_id).await;
// Release the permit explicitly
drop(permit);
// Return the result along with the ID
(file_id, get_result)
}
});
// Execute all operations in parallel with concurrency control
let operation_results = join_all(operations).await;
// Process the results
for (file_id, operation_result) in operation_results {
match operation_result {
@@ -360,22 +368,23 @@ impl BatchOperationService {
}
}
}
// Complete statistics
result.stats.execution_time_ms = start_time.elapsed().as_millis();
result.stats.max_concurrency = self.config.concurrency.max_concurrent_files
result.stats.max_concurrency = self
.config
.concurrency
.max_concurrent_files
.min(result.stats.total);
info!(
"Batch load completed: {}/{} successful in {}ms",
result.stats.successful,
result.stats.total,
result.stats.execution_time_ms
result.stats.successful, result.stats.total, result.stats.execution_time_ms
);
Ok(result)
}
/// Deletes multiple folders in parallel
pub async fn delete_folders(
&self,
@@ -384,7 +393,7 @@ impl BatchOperationService {
) -> Result<BatchResult<String>, BatchOperationError> {
info!("Starting batch deletion of {} folders", folder_ids.len());
let start_time = std::time::Instant::now();
// Create result structure
let mut result = BatchResult {
successful: Vec::new(),
@@ -394,32 +403,32 @@ impl BatchOperationService {
..Default::default()
},
};
// Define the operation to perform for each folder
let operations = folder_ids.into_iter().map(|folder_id| {
let folder_service = self.folder_service.clone();
let semaphore = self.semaphore.clone();
let id_clone = folder_id.clone();
async move {
// Acquire semaphore permit
let permit = semaphore.acquire().await.unwrap();
// For both recursive and non-recursive, use the standard delete_folder method
// since FolderUseCase only has a single delete_folder method
let delete_result = folder_service.delete_folder(&folder_id).await;
// Release the permit explicitly
drop(permit);
// Return the result along with the ID
(id_clone.clone(), delete_result.map(|_| id_clone))
}
});
// Execute all operations in parallel with concurrency control
let operation_results = join_all(operations).await;
// Process the results
for (folder_id, operation_result) in operation_results {
match operation_result {
@@ -433,22 +442,23 @@ impl BatchOperationService {
}
}
}
// Complete statistics
result.stats.execution_time_ms = start_time.elapsed().as_millis();
result.stats.max_concurrency = self.config.concurrency.max_concurrent_files
result.stats.max_concurrency = self
.config
.concurrency
.max_concurrent_files
.min(result.stats.total);
info!(
"Batch folder deletion completed: {}/{} successful in {}ms",
result.stats.successful,
result.stats.total,
result.stats.execution_time_ms
result.stats.successful, result.stats.total, result.stats.execution_time_ms
);
Ok(result)
}
/// Generic batch operation for any type of async function
pub async fn generic_batch_operation<T, F, Fut>(
&self,
@@ -460,9 +470,12 @@ impl BatchOperationService {
F: Fn(T, Arc<Semaphore>) -> Fut + Clone + Send + Sync + 'static,
Fut: Future<Output = Result<T, DomainError>> + Send + 'static,
{
info!("Starting generic batch operation with {} items", items.len());
info!(
"Starting generic batch operation with {} items",
items.len()
);
let start_time = std::time::Instant::now();
// Create result structure
let mut result = BatchResult {
successful: Vec::new(),
@@ -472,25 +485,25 @@ impl BatchOperationService {
..Default::default()
},
};
// Convert each item to a task
let tasks = items.iter().map(|item| {
let item_clone = item.clone();
let op = operation.clone();
let semaphore = self.semaphore.clone();
async move {
// The provided function must handle semaphore acquisition
let op_result = op(item_clone.clone(), semaphore).await;
// Return the result along with the original item for identification
(item_clone, op_result)
}
});
// Execute all tasks in parallel
let operation_results = join_all(tasks).await;
// Process results
for (item, operation_result) in operation_results {
match operation_result {
@@ -505,22 +518,23 @@ impl BatchOperationService {
}
}
}
// Complete statistics
result.stats.execution_time_ms = start_time.elapsed().as_millis();
result.stats.max_concurrency = self.config.concurrency.max_concurrent_files
result.stats.max_concurrency = self
.config
.concurrency
.max_concurrent_files
.min(result.stats.total);
info!(
"Generic batch operation completed: {}/{} successful in {}ms",
result.stats.successful,
result.stats.total,
result.stats.execution_time_ms
result.stats.successful, result.stats.total, result.stats.execution_time_ms
);
Ok(result)
}
/// Create multiple folders in parallel
pub async fn create_folders(
&self,
@@ -528,7 +542,7 @@ impl BatchOperationService {
) -> Result<BatchResult<FolderDto>, BatchOperationError> {
info!("Starting batch creation of {} folders", folders.len());
let start_time = std::time::Instant::now();
// Create result structure
let mut result = BatchResult {
successful: Vec::new(),
@@ -538,34 +552,34 @@ impl BatchOperationService {
..Default::default()
},
};
// Define the operation for each folder
let operations = folders.into_iter().map(|(name, parent_id)| {
let folder_service = self.folder_service.clone();
let semaphore = self.semaphore.clone();
async move {
// Acquire semaphore permit
let permit = semaphore.acquire().await.unwrap();
let dto = crate::application::dtos::folder_dto::CreateFolderDto {
name: name.clone(),
parent_id: parent_id.clone()
parent_id: parent_id.clone(),
};
let create_result = folder_service.create_folder(dto).await;
// Release the permit explicitly
drop(permit);
// Return the result with an identifier for errors
let id = format!("{}:{}", name, parent_id.unwrap_or_default());
(id, create_result)
}
});
// Execute all operations in parallel
let operation_results = join_all(operations).await;
// Process the results
for (id, operation_result) in operation_results {
match operation_result {
@@ -579,22 +593,23 @@ impl BatchOperationService {
}
}
}
// Complete statistics
result.stats.execution_time_ms = start_time.elapsed().as_millis();
result.stats.max_concurrency = self.config.concurrency.max_concurrent_files
result.stats.max_concurrency = self
.config
.concurrency
.max_concurrent_files
.min(result.stats.total);
info!(
"Batch folder creation completed: {}/{} successful in {}ms",
result.stats.successful,
result.stats.total,
result.stats.execution_time_ms
result.stats.successful, result.stats.total, result.stats.execution_time_ms
);
Ok(result)
}
/// Get metadata of multiple folders in parallel
pub async fn get_multiple_folders(
&self,
@@ -602,7 +617,7 @@ impl BatchOperationService {
) -> Result<BatchResult<FolderDto>, BatchOperationError> {
info!("Starting batch load of {} folders", folder_ids.len());
let start_time = std::time::Instant::now();
// Create result structure
let mut result = BatchResult {
successful: Vec::new(),
@@ -612,29 +627,29 @@ impl BatchOperationService {
..Default::default()
},
};
// Define the operation for each folder
let operations = folder_ids.into_iter().map(|folder_id| {
let folder_service = self.folder_service.clone();
let semaphore = self.semaphore.clone();
async move {
// Acquire semaphore permit
let permit = semaphore.acquire().await.unwrap();
let get_result = folder_service.get_folder(&folder_id).await;
// Release the permit explicitly
drop(permit);
// Return the result with its ID
(folder_id, get_result)
}
});
// Execute all operations in parallel
let operation_results = join_all(operations).await;
// Process the results
for (folder_id, operation_result) in operation_results {
match operation_result {
@@ -648,19 +663,20 @@ impl BatchOperationService {
}
}
}
// Complete statistics
result.stats.execution_time_ms = start_time.elapsed().as_millis();
result.stats.max_concurrency = self.config.concurrency.max_concurrent_files
result.stats.max_concurrency = self
.config
.concurrency
.max_concurrent_files
.min(result.stats.total);
info!(
"Batch folder load completed: {}/{} successful in {}ms",
result.stats.successful,
result.stats.total,
result.stats.execution_time_ms
result.stats.successful, result.stats.total, result.stats.execution_time_ms
);
Ok(result)
}
}
@@ -668,26 +684,26 @@ impl BatchOperationService {
#[cfg(test)]
mod tests {
use super::*;
use crate::common::stubs::{StubFileManagementUseCase, StubFileRetrievalUseCase};
use std::sync::Arc;
use crate::common::stubs::{StubFileRetrievalUseCase, StubFileManagementUseCase};
#[tokio::test]
async fn test_generic_batch_operation() {
// Create the batch service with stubs
let batch_service = BatchOperationService::new(
Arc::new(StubFileRetrievalUseCase),
Arc::new(StubFileManagementUseCase),
Arc::new(FolderService::new(
Arc::new(crate::common::stubs::StubFolderStoragePort)
)),
AppConfig::default()
Arc::new(FolderService::new(Arc::new(
crate::common::stubs::StubFolderStoragePort,
))),
AppConfig::default(),
);
// Define a generic test operation
let operation = |item: i32, semaphore: Arc<Semaphore>| async move {
// Acquire and release the semaphore
let _permit = semaphore.acquire().await.unwrap();
if item % 2 == 0 {
// Simulate success for even numbers
Ok(item * 2)
@@ -696,22 +712,25 @@ mod tests {
Err(DomainError::validation_error("Odd number not allowed"))
}
};
// Execute the batch operation
let items = vec![1, 2, 3, 4, 5];
let result = batch_service.generic_batch_operation(items, operation).await.unwrap();
let result = batch_service
.generic_batch_operation(items, operation)
.await
.unwrap();
// Verify the results
assert_eq!(result.stats.total, 5);
assert_eq!(result.stats.successful, 2);
assert_eq!(result.stats.failed, 3);
// Even numbers should be in successes, doubled
assert!(result.successful.contains(&4)); // 2*2
assert!(result.successful.contains(&8)); // 4*2
// Odd numbers should be in failures
assert_eq!(result.failed.len(), 3);
}
}
}