summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author魏曹先生 <1992414357@qq.com>2026-06-18 00:46:35 +0800
committer魏曹先生 <1992414357@qq.com>2026-06-18 00:46:35 +0800
commit2833dd80e7783c555d90c59e9548502700a69ae4 (patch)
treea67ea088ba29f6284efaa01c4282f2fe491ded7c
parent330e5ed096cfde3eb6217d4364ee62b92c97c826 (diff)
feat(protocol): add LocalFileSystemProtocol
Implement a local filesystem-based bucket transfer protocol with client and bucket side operations.
-rw-r--r--rola-bucket/src/protocol.rs3
-rw-r--r--rola-bucket/src/protocol/local_fs.rs92
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(())
+ }
+}