diff options
| author | 魏曹先生 <1992414357@qq.com> | 2026-06-18 00:46:35 +0800 |
|---|---|---|
| committer | 魏曹先生 <1992414357@qq.com> | 2026-06-18 00:46:35 +0800 |
| commit | 2833dd80e7783c555d90c59e9548502700a69ae4 (patch) | |
| tree | a67ea088ba29f6284efaa01c4282f2fe491ded7c /rola-bucket | |
| parent | 330e5ed096cfde3eb6217d4364ee62b92c97c826 (diff) | |
feat(protocol): add LocalFileSystemProtocol
Implement a local filesystem-based bucket transfer protocol with client
and bucket side operations.
Diffstat (limited to 'rola-bucket')
| -rw-r--r-- | rola-bucket/src/protocol.rs | 3 | ||||
| -rw-r--r-- | rola-bucket/src/protocol/local_fs.rs | 92 |
2 files changed, 95 insertions, 0 deletions
diff --git a/rola-bucket/src/protocol.rs b/rola-bucket/src/protocol.rs index 949e6d4..b4d60a8 100644 --- a/rola-bucket/src/protocol.rs +++ b/rola-bucket/src/protocol.rs @@ -3,6 +3,9 @@ use std::path::Path; mod error; pub use error::*; +mod local_fs; +pub use local_fs::*; + /// Request used in [BucketTransferProtocol] or [AsyncBucketTransferProtocol] pub struct UploadToBucketRequest<'a, Info> where diff --git a/rola-bucket/src/protocol/local_fs.rs b/rola-bucket/src/protocol/local_fs.rs new file mode 100644 index 0000000..1f287f2 --- /dev/null +++ b/rola-bucket/src/protocol/local_fs.rs @@ -0,0 +1,92 @@ +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<Self::TransferInfo>, + ) -> 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<Self::TransferInfo>, + ) -> 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<Self::TransferInfo>, + ) -> 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<Self::TransferInfo>, + ) -> 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(()) + } +} |
