pub mod models;
use std::path::Path;
use std::sync::Arc;
use async_trait::async_trait;
use wildland_corex::dfs::interface::{
FsStat,
IStream,
OStream,
ProgressReporter,
SpaceUsage,
WlPermissions,
};
use wildland_corex::dfs::unix_timestamp::UnixTimestamp;
use wildland_corex::Storage;
use self::models::*;
#[async_trait]
pub trait StorageBackend: Send + Sync {
async fn read_dir(&self, path: &Path) -> Result<ReadDirResponse, StorageBackendError>;
async fn metadata(&self, path: &Path) -> Result<MetadataResponse, StorageBackendError>;
async fn create_dir(&self, path: &Path) -> Result<CreateDirResponse, StorageBackendError>;
async fn set_wildland_object_id(
&self,
path: &Path,
wildland_object_id: String,
) -> Result<SetWildlandObjectIdResponse, StorageBackendError>;
async fn remove_dir(
&self,
path: &Path,
is_recursive: bool,
) -> Result<RemoveDirResponse, StorageBackendError>;
async fn path_exists(&self, path: &Path) -> Result<bool, StorageBackendError>;
async fn remove_file(&self, path: &Path) -> Result<RemoveFileResponse, StorageBackendError>;
async fn rename(
&self,
old_path: &Path,
new_path: &Path,
) -> Result<RenameResponse, StorageBackendError>;
async fn set_permissions(
&self,
path: &Path,
permissions: WlPermissions,
) -> Result<SetPermissionsResponse, StorageBackendError>;
async fn stat_fs(&self) -> Result<FsStat, StorageBackendError>;
async fn mount(&self) -> Result<(), StorageBackendError>;
async fn get_space_usage(&self) -> Result<SpaceUsage, StorageBackendError>;
async fn download(
&self,
path: &Path,
output: Box<dyn OStream>,
progress_reporter: Box<dyn ProgressReporter>,
) -> Result<DownloadResponse, StorageBackendError>;
async fn upload(
&self,
path: &Path,
input: Box<dyn IStream>,
progress_reporter: Box<dyn ProgressReporter>,
creation_time: Option<UnixTimestamp>,
) -> Result<UploadResponse, StorageBackendError>;
async fn get_path_by_uuid(&self, uuid: String) -> Result<GetInfoResponse, StorageBackendError>;
}
pub trait StorageBackendFactory: Send + Sync {
fn init_backend(&self, storage: Storage) -> anyhow::Result<Arc<dyn StorageBackend>>;
}
pub struct MutexAdaptor<T>(tokio::sync::Mutex<T>)
where
T: StorageBackend;
impl<T> MutexAdaptor<T>
where
T: StorageBackend,
{
pub fn new(inner: T) -> Self {
Self(tokio::sync::Mutex::new(inner))
}
}
#[async_trait]
impl<T> StorageBackend for MutexAdaptor<T>
where
T: StorageBackend,
{
async fn read_dir(&self, path: &Path) -> Result<ReadDirResponse, StorageBackendError> {
self.0.lock().await.read_dir(path).await
}
async fn metadata(&self, path: &Path) -> Result<MetadataResponse, StorageBackendError> {
self.0.lock().await.metadata(path).await
}
async fn create_dir(&self, path: &Path) -> Result<CreateDirResponse, StorageBackendError> {
self.0.lock().await.create_dir(path).await
}
async fn set_wildland_object_id(
&self,
path: &Path,
wildland_object_uuid: String,
) -> Result<SetWildlandObjectIdResponse, StorageBackendError> {
self.0
.lock()
.await
.set_wildland_object_id(path, wildland_object_uuid)
.await
}
async fn remove_dir(
&self,
path: &Path,
is_recursive: bool,
) -> Result<RemoveDirResponse, StorageBackendError> {
self.0.lock().await.remove_dir(path, is_recursive).await
}
async fn path_exists(&self, path: &Path) -> Result<bool, StorageBackendError> {
self.0.lock().await.path_exists(path).await
}
async fn remove_file(&self, path: &Path) -> Result<RemoveFileResponse, StorageBackendError> {
self.0.lock().await.remove_file(path).await
}
async fn rename(
&self,
old_path: &Path,
new_path: &Path,
) -> Result<RenameResponse, StorageBackendError> {
self.0.lock().await.rename(old_path, new_path).await
}
async fn set_permissions(
&self,
path: &Path,
permissions: WlPermissions,
) -> Result<SetPermissionsResponse, StorageBackendError> {
self.0.lock().await.set_permissions(path, permissions).await
}
async fn stat_fs(&self) -> Result<FsStat, StorageBackendError> {
self.0.lock().await.stat_fs().await
}
async fn mount(&self) -> Result<(), StorageBackendError> {
self.0.lock().await.mount().await
}
async fn get_space_usage(&self) -> Result<SpaceUsage, StorageBackendError> {
self.0.lock().await.get_space_usage().await
}
async fn get_path_by_uuid(&self, uuid: String) -> Result<GetInfoResponse, StorageBackendError> {
self.0.lock().await.get_path_by_uuid(uuid).await
}
async fn download(
&self,
path: &Path,
output: Box<dyn OStream>,
progress_reporter: Box<dyn ProgressReporter>,
) -> Result<DownloadResponse, StorageBackendError> {
self.0
.lock()
.await
.download(path, output, progress_reporter)
.await
}
async fn upload(
&self,
path: &Path,
input: Box<dyn IStream>,
progress_reporter: Box<dyn ProgressReporter>,
creation_time: Option<UnixTimestamp>,
) -> Result<UploadResponse, StorageBackendError> {
self.0
.lock()
.await
.upload(path, input, progress_reporter, creation_time)
.await
}
}