use shared_functions::copy_with_temp_rename; use std::path::PathBuf; use crate::{ BucketTransferProtocol, BucketTransferProtocolError, LocalFileSystemProtocol::{BucketSide, ClientSide}, }; /// Represents the two sides of a local filesystem transfer protocol. /// /// This enum distinguishes between the **client side** (where the bucket root is local) /// and the **bucket side** (where the client root is local). Each variant stores the /// path to the corresponding root directory on the local machine. /// /// - `ClientSide { bucket_root }`: Used when this instance is running on the client side. /// The bucket root is the directory on the local filesystem that acts as the bucket. /// - `BucketSide { client_root }`: Used when this instance is running on the bucket side. /// The client root is the directory on the local filesystem where client data is stored. pub enum LocalFileSystemProtocol { /// The client side of the transfer; `bucket_root` is the local path to the bucket. ClientSide { bucket_root: PathBuf }, /// The bucket side of the transfer; `client_root` is the local path to the client's data. BucketSide { client_root: PathBuf }, } impl BucketTransferProtocol for LocalFileSystemProtocol { type TransferInfo = (); fn upload_to_bucket( &self, req: &super::UploadToBucketRequest, ) -> Result<(), BucketTransferProtocolError> { let ClientSide { bucket_root } = self else { // NOTE: As a local filesystem transfer protocol, // if this function is not executed on the client side, it does nothing by default. return Ok(()); }; let abs_send_path = req.absolute_file_path_to_upload; let abs_receive_path = bucket_root.join(req.relative_file_path_to_receive); copy_with_temp_rename(abs_send_path, abs_receive_path) .map_err(|e| BucketTransferProtocolError::IoError(e))?; Ok(()) } fn download_from_bucket( &self, req: &super::DownloadFromBucketRequest, ) -> Result<(), BucketTransferProtocolError> { let ClientSide { bucket_root } = self else { // NOTE: As a local filesystem transfer protocol, // if this function is not executed on the client side, it does nothing by default. return Ok(()); }; let abs_send_path = bucket_root.join(req.relative_file_path_to_transfer); let abs_receive_path = req.absolute_file_path_to_download; copy_with_temp_rename(abs_send_path, abs_receive_path) .map_err(|e| BucketTransferProtocolError::IoError(e))?; Ok(()) } fn transfer_to_client( &self, req: &super::TransferToClientRequest, ) -> Result<(), BucketTransferProtocolError> { let BucketSide { client_root } = self else { // NOTE: As a local filesystem transfer protocol, // if this function is not executed on the bucket side, it does nothing by default. return Ok(()); }; let abs_send_path = req.absolute_file_path_to_transfer; let abs_receive_path = client_root.join(req.relative_file_path_to_download); copy_with_temp_rename(abs_send_path, abs_receive_path) .map_err(|e| BucketTransferProtocolError::IoError(e))?; Ok(()) } fn receive_from_client( &self, req: &super::ReceiveFromClientRequest, ) -> Result<(), BucketTransferProtocolError> { let BucketSide { client_root } = self else { // NOTE: As a local filesystem transfer protocol, // if this function is not executed on the bucket side, it does nothing by default. return Ok(()); }; let abs_send_path = req.absolute_file_path_to_receive; let abs_receive_path = client_root.join(req.relative_file_path_to_upload); copy_with_temp_rename(abs_send_path, abs_receive_path) .map_err(|e| BucketTransferProtocolError::IoError(e))?; Ok(()) } }