summaryrefslogtreecommitdiff
path: root/rola-bucket/src/protocol.rs
diff options
context:
space:
mode:
author魏曹先生 <1992414357@qq.com>2026-06-18 00:46:20 +0800
committer魏曹先生 <1992414357@qq.com>2026-06-18 00:46:20 +0800
commit330e5ed096cfde3eb6217d4364ee62b92c97c826 (patch)
treef9aa4c8106b193160de272784d85392efcd965ac /rola-bucket/src/protocol.rs
parent346eefc2ccfc06a133dafaa4fb86f1e21599179d (diff)
feat(rola-bucket): add bucket transfer protocol and error handling
Diffstat (limited to 'rola-bucket/src/protocol.rs')
-rw-r--r--rola-bucket/src/protocol.rs169
1 files changed, 169 insertions, 0 deletions
diff --git a/rola-bucket/src/protocol.rs b/rola-bucket/src/protocol.rs
new file mode 100644
index 0000000..949e6d4
--- /dev/null
+++ b/rola-bucket/src/protocol.rs
@@ -0,0 +1,169 @@
+use std::path::Path;
+
+mod error;
+pub use error::*;
+
+/// Request used in [BucketTransferProtocol] or [AsyncBucketTransferProtocol]
+pub struct UploadToBucketRequest<'a, Info>
+where
+ Info: Clone + Sync + Send,
+{
+ /// Extra data to record during the transfer process
+ pub extra_info: &'a Info,
+
+ /// The relative file path in the bucket to store the uploaded file
+ pub relative_file_path_to_receive: &'a Path,
+
+ /// The absolute file path of the file to be uploaded to the remote bucket
+ pub absolute_file_path_to_upload: &'a Path,
+}
+
+/// Request used in [BucketTransferProtocol] or [AsyncBucketTransferProtocol]
+pub struct DownloadFromBucketRequest<'a, Info>
+where
+ Info: Clone + Sync + Send,
+{
+ /// Extra data to record during the transfer process
+ pub extra_info: &'a Info,
+
+ /// The relative file path in the bucket to download
+ pub relative_file_path_to_transfer: &'a Path,
+
+ /// The absolute file path to download the file to locally
+ pub absolute_file_path_to_download: &'a Path,
+}
+
+/// Request used in [BucketTransferProtocol] or [AsyncBucketTransferProtocol]
+pub struct TransferToClientRequest<'a, Info>
+where
+ Info: Clone + Sync + Send,
+{
+ /// Extra data to record during the transfer process
+ pub extra_info: &'a Info,
+
+ /// The relative file path for the client to download from the bucket
+ pub relative_file_path_to_download: &'a Path,
+
+ /// The absolute file path of the file to be transferred to the client
+ pub absolute_file_path_to_transfer: &'a Path,
+}
+
+/// Request used in [BucketTransferProtocol] or [AsyncBucketTransferProtocol]
+pub struct ReceiveFromClientRequest<'a, Info>
+where
+ Info: Clone + Sync + Send,
+{
+ /// Extra data to record during the transfer process
+ pub extra_info: &'a Info,
+
+ /// The relative file path in the bucket to store the uploaded file
+ pub relative_file_path_to_upload: &'a Path,
+
+ /// The absolute file path to download the file to locally
+ pub absolute_file_path_to_receive: &'a Path,
+}
+
+/// This trait is used to implement the specific workflow of file transfer
+pub trait BucketTransferProtocol {
+ /// Structure used to record transfer information
+ type TransferInfo: Clone + Sync + Send;
+
+ /// Upload a file to the storage bucket
+ /// The caller must ensure that this function performs the actual transfer operation
+ fn upload_to_bucket(
+ &self,
+ req: &UploadToBucketRequest<Self::TransferInfo>,
+ ) -> Result<(), BucketTransferProtocolError>;
+
+ /// Download a file from the storage bucket
+ /// The caller must ensure that after this function executes, a file (and only a file, not a directory) exists at the `path_to_save_file` path
+ fn download_from_bucket(
+ &self,
+ req: &DownloadFromBucketRequest<Self::TransferInfo>,
+ ) -> Result<(), BucketTransferProtocolError>;
+
+ /// Transfer a file to the client
+ /// The caller must ensure that this function performs the actual transfer operation
+ fn transfer_to_client(
+ &self,
+ req: &TransferToClientRequest<Self::TransferInfo>,
+ ) -> Result<(), BucketTransferProtocolError>;
+
+ /// Receive a file from the client
+ /// The caller must ensure that after this function executes, a file (and only a file, not a directory) exists at the `path_to_save_file` path
+ fn receive_from_client(
+ &self,
+ req: &ReceiveFromClientRequest<Self::TransferInfo>,
+ ) -> Result<(), BucketTransferProtocolError>;
+}
+
+/// This trait is used to implement the specific workflow of file transfer (asynchronous mode)
+pub trait AsyncBucketTransferProtocol {
+ /// Structure used to record transfer information
+ type TransferInfo: Clone + Sync + Send;
+
+ /// Asynchronously upload a file to the storage bucket
+ /// The caller must ensure that this function performs the actual transfer operation
+ fn upload_to_bucket_async(
+ &self,
+ req: &UploadToBucketRequest<Self::TransferInfo>,
+ ) -> impl Future<Output = Result<(), BucketTransferProtocolError>> + Send + Sync;
+
+ /// Asynchronously download a file from the storage bucket
+ /// The caller must ensure that after this function executes, a file (and only a file, not a directory) exists at the `path_to_save_file` path
+ fn download_from_bucket_async(
+ &self,
+ req: &DownloadFromBucketRequest<Self::TransferInfo>,
+ ) -> impl Future<Output = Result<(), BucketTransferProtocolError>> + Send + Sync;
+
+ /// Asynchronously transfer a file to the client
+ /// The caller must ensure that this function performs the actual transfer operation
+ fn transfer_to_client_async(
+ &self,
+ req: &TransferToClientRequest<Self::TransferInfo>,
+ ) -> impl Future<Output = Result<(), BucketTransferProtocolError>> + Send + Sync;
+
+ /// Asynchronously receive a file from the client
+ /// The caller must ensure that after this function executes, a file (and only a file, not a directory) exists at the `path_to_save_file` path
+ fn receive_from_client_async(
+ &self,
+ req: &ReceiveFromClientRequest<Self::TransferInfo>,
+ ) -> impl Future<Output = Result<(), BucketTransferProtocolError>> + Send + Sync;
+}
+
+/// Blanket implementation: automatically provides async versions of all
+/// `BucketTransferProtocol` methods by wrapping them in `async {}` blocks.
+impl<T: BucketTransferProtocol + Sync> AsyncBucketTransferProtocol for T
+where
+ T::TransferInfo: Sync,
+{
+ type TransferInfo = T::TransferInfo;
+
+ fn upload_to_bucket_async(
+ &self,
+ req: &UploadToBucketRequest<Self::TransferInfo>,
+ ) -> impl Future<Output = Result<(), BucketTransferProtocolError>> + Send + Sync {
+ async move { self.upload_to_bucket(req) }
+ }
+
+ fn download_from_bucket_async(
+ &self,
+ req: &DownloadFromBucketRequest<Self::TransferInfo>,
+ ) -> impl Future<Output = Result<(), BucketTransferProtocolError>> + Send + Sync {
+ async move { self.download_from_bucket(req) }
+ }
+
+ fn transfer_to_client_async(
+ &self,
+ req: &TransferToClientRequest<Self::TransferInfo>,
+ ) -> impl Future<Output = Result<(), BucketTransferProtocolError>> + Send + Sync {
+ async move { self.transfer_to_client(req) }
+ }
+
+ fn receive_from_client_async(
+ &self,
+ req: &ReceiveFromClientRequest<Self::TransferInfo>,
+ ) -> impl Future<Output = Result<(), BucketTransferProtocolError>> + Send + Sync {
+ async move { self.receive_from_client(req) }
+ }
+}