2025-03-17 21:28:08 +01:00
|
|
|
use async_trait::async_trait;
|
|
|
|
|
use crate::domain::entities::file::File;
|
2025-03-19 00:44:27 +01:00
|
|
|
use crate::domain::services::path_service::StoragePath;
|
2025-03-20 09:22:31 +01:00
|
|
|
use crate::common::errors::DomainError;
|
2025-03-19 00:44:27 +01:00
|
|
|
use futures::Stream;
|
|
|
|
|
use bytes::Bytes;
|
2025-03-17 21:28:08 +01:00
|
|
|
|
|
|
|
|
/// Error types for file repository operations
|
|
|
|
|
#[derive(Debug, thiserror::Error)]
|
|
|
|
|
#[allow(dead_code)]
|
|
|
|
|
pub enum FileRepositoryError {
|
|
|
|
|
#[error("File not found: {0}")]
|
|
|
|
|
NotFound(String),
|
|
|
|
|
|
|
|
|
|
#[error("File already exists: {0}")]
|
|
|
|
|
AlreadyExists(String),
|
|
|
|
|
|
|
|
|
|
#[error("Invalid file path: {0}")]
|
|
|
|
|
InvalidPath(String),
|
|
|
|
|
|
2025-03-24 16:47:42 +01:00
|
|
|
#[error("Operation not supported: {0}")]
|
|
|
|
|
OperationNotSupported(String),
|
|
|
|
|
|
2025-03-17 21:28:08 +01:00
|
|
|
#[error("IO Error: {0}")]
|
|
|
|
|
IoError(#[from] std::io::Error),
|
|
|
|
|
|
2025-03-19 00:44:27 +01:00
|
|
|
#[error("Mapping error: {0}")]
|
|
|
|
|
MappingError(String),
|
|
|
|
|
|
2025-03-20 09:22:31 +01:00
|
|
|
#[error("ID Mapping error: {0}")]
|
|
|
|
|
IdMappingError(String),
|
|
|
|
|
|
2025-03-19 00:44:27 +01:00
|
|
|
#[error("Timeout error: {0}")]
|
|
|
|
|
Timeout(String),
|
|
|
|
|
|
2025-03-20 09:22:31 +01:00
|
|
|
#[error("Domain error: {0}")]
|
|
|
|
|
DomainError(#[from] DomainError),
|
|
|
|
|
|
2025-03-17 21:28:08 +01:00
|
|
|
#[error("Other error: {0}")]
|
|
|
|
|
Other(String),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Result type for file repository operations
|
|
|
|
|
pub type FileRepositoryResult<T> = Result<T, FileRepositoryError>;
|
|
|
|
|
|
|
|
|
|
/// Repository interface for file operations (primary port)
|
2025-03-19 00:44:27 +01:00
|
|
|
/// Esta interfaz define las operaciones de negocio relacionadas con archivos
|
|
|
|
|
/// sin exponer detalles de implementación como rutas o sistemas de archivos
|
2025-03-17 21:28:08 +01:00
|
|
|
#[async_trait]
|
|
|
|
|
pub trait FileRepository: Send + Sync + 'static {
|
|
|
|
|
/// Saves a file from bytes
|
|
|
|
|
async fn save_file_from_bytes(
|
|
|
|
|
&self,
|
|
|
|
|
name: String,
|
|
|
|
|
folder_id: Option<String>,
|
|
|
|
|
content_type: String,
|
|
|
|
|
content: Vec<u8>,
|
|
|
|
|
) -> FileRepositoryResult<File>;
|
|
|
|
|
|
|
|
|
|
/// Saves a file with a specific ID
|
|
|
|
|
#[allow(dead_code)]
|
|
|
|
|
async fn save_file_with_id(
|
|
|
|
|
&self,
|
|
|
|
|
id: String,
|
|
|
|
|
name: String,
|
|
|
|
|
folder_id: Option<String>,
|
|
|
|
|
content_type: String,
|
|
|
|
|
content: Vec<u8>,
|
|
|
|
|
) -> FileRepositoryResult<File>;
|
|
|
|
|
|
|
|
|
|
/// Gets a file by its ID
|
|
|
|
|
async fn get_file_by_id(&self, id: &str) -> FileRepositoryResult<File>;
|
|
|
|
|
|
|
|
|
|
/// Lists files in a folder
|
|
|
|
|
async fn list_files(&self, folder_id: Option<&str>) -> FileRepositoryResult<Vec<File>>;
|
|
|
|
|
|
|
|
|
|
/// Deletes a file
|
|
|
|
|
async fn delete_file(&self, id: &str) -> FileRepositoryResult<()>;
|
|
|
|
|
|
2025-03-19 00:44:27 +01:00
|
|
|
/// Deletes a file and its entry from mapping systems
|
2025-03-17 21:28:08 +01:00
|
|
|
#[allow(dead_code)]
|
|
|
|
|
async fn delete_file_entry(&self, id: &str) -> FileRepositoryResult<()>;
|
|
|
|
|
|
2025-03-19 00:44:27 +01:00
|
|
|
/// Gets file content as bytes - use only for small files
|
2025-03-17 21:28:08 +01:00
|
|
|
async fn get_file_content(&self, id: &str) -> FileRepositoryResult<Vec<u8>>;
|
|
|
|
|
|
2025-03-19 00:44:27 +01:00
|
|
|
/// Gets file content as a stream - better for large files
|
|
|
|
|
#[allow(clippy::type_complexity)]
|
|
|
|
|
async fn get_file_stream(&self, id: &str) -> FileRepositoryResult<Box<dyn Stream<Item = Result<Bytes, std::io::Error>> + Send>>;
|
|
|
|
|
|
|
|
|
|
/// Moves a file to a different folder
|
|
|
|
|
async fn move_file(&self, id: &str, target_folder_id: Option<String>) -> FileRepositoryResult<File>;
|
|
|
|
|
|
|
|
|
|
/// Gets the storage path for a file
|
|
|
|
|
async fn get_file_path(&self, id: &str) -> FileRepositoryResult<StoragePath>;
|
2025-03-24 16:47:42 +01:00
|
|
|
|
|
|
|
|
/// Moves a file to trash
|
|
|
|
|
async fn move_to_trash(&self, file_id: &str) -> FileRepositoryResult<()>;
|
|
|
|
|
|
|
|
|
|
/// Restores a file from trash
|
|
|
|
|
async fn restore_from_trash(&self, file_id: &str, original_path: &str) -> FileRepositoryResult<()>;
|
|
|
|
|
|
|
|
|
|
/// Permanently deletes a file (used for trash cleanup)
|
|
|
|
|
async fn delete_file_permanently(&self, file_id: &str) -> FileRepositoryResult<()>;
|
2025-03-17 21:28:08 +01:00
|
|
|
}
|