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, ) -> 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, ) -> 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, ) -> 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, ) -> 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, ) -> impl Future> + 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, ) -> impl Future> + 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, ) -> impl Future> + 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, ) -> impl Future> + Send + Sync; } /// Blanket implementation: automatically provides async versions of all /// `BucketTransferProtocol` methods by wrapping them in `async {}` blocks. impl AsyncBucketTransferProtocol for T where T::TransferInfo: Sync, { type TransferInfo = T::TransferInfo; fn upload_to_bucket_async( &self, req: &UploadToBucketRequest, ) -> impl Future> + Send + Sync { async move { self.upload_to_bucket(req) } } fn download_from_bucket_async( &self, req: &DownloadFromBucketRequest, ) -> impl Future> + Send + Sync { async move { self.download_from_bucket(req) } } fn transfer_to_client_async( &self, req: &TransferToClientRequest, ) -> impl Future> + Send + Sync { async move { self.transfer_to_client(req) } } fn receive_from_client_async( &self, req: &ReceiveFromClientRequest, ) -> impl Future> + Send + Sync { async move { self.receive_from_client(req) } } }