use std::path::Path;
use async_trait::async_trait;
use bytes::Bytes;
use opendal::Reader;
#[cfg(feature = "storage_aws_s3")]
pub mod aws;
#[cfg(feature = "storage_azure")]
pub mod azure;
#[cfg(feature = "storage_gcp")]
pub mod gcp;
pub mod local;
pub mod mem;
pub mod null;
pub mod opendal_adapter;
use super::{stream::BytesStream, StorageResult};
#[derive(Debug)]
pub struct UploadResponse {
pub e_tag: Option<String>,
pub version: Option<String>,
}
pub struct GetResponse {
stream: Reader,
}
impl GetResponse {
pub(crate) fn new(stream: Reader) -> Self {
Self { stream }
}
pub async fn bytes(&self) -> StorageResult<Bytes> {
Ok(self.stream.read(..).await?.to_bytes())
}
pub async fn into_stream(self) -> StorageResult<BytesStream> {
BytesStream::from_reader(self.stream).await
}
}
#[async_trait]
pub trait StoreDriver: Sync + Send {
async fn upload(&self, path: &Path, content: &Bytes) -> StorageResult<UploadResponse>;
async fn get(&self, path: &Path) -> StorageResult<GetResponse>;
async fn delete(&self, path: &Path) -> StorageResult<()>;
async fn rename(&self, from: &Path, to: &Path) -> StorageResult<()>;
async fn copy(&self, from: &Path, to: &Path) -> StorageResult<()>;
async fn exists(&self, path: &Path) -> StorageResult<bool>;
async fn get_stream(&self, path: &Path) -> StorageResult<BytesStream> {
let response = self.get(path).await?;
response.into_stream().await
}
async fn upload_stream(
&self,
path: &Path,
stream: BytesStream,
) -> StorageResult<UploadResponse> {
let bytes = stream
.collect()
.await
.map_err(|e| super::StorageError::Any(Box::new(e)))?;
self.upload(path, &bytes).await
}
}