use std::io::Read;
use async_trait::async_trait;
use serde::{Deserialize, Serialize};
use crate::error::StorageError;
use crate::metadata::{ChunkRange, FileMeta};
use crate::range::RangeSpec;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum WriteMode {
Create,
Overwrite,
Resume { offset: u64 },
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct DirEntry {
pub path: String,
pub is_dir: bool,
pub size: u64,
pub mtime: u64,
}
#[async_trait]
pub trait UploadSink: Send {
async fn write(&mut self, buf: &[u8]) -> Result<(), StorageError>;
async fn write_at(&mut self, _offset: u64, buf: &[u8]) -> Result<(), StorageError> {
self.write(buf).await
}
async fn received_ranges(&mut self) -> Result<Vec<ChunkRange>, StorageError> {
Ok(Vec::new())
}
async fn len(&self) -> Result<u64, StorageError>;
async fn commit(self: Box<Self>) -> Result<FileMeta, StorageError>;
async fn abort(self: Box<Self>) -> Result<(), StorageError>;
}
#[async_trait]
pub trait StorageBackend: Send + Sync + 'static {
async fn file_meta(&self, path: &str) -> Result<Option<FileMeta>, StorageError>;
async fn read_stream(
&self,
path: &str,
range: RangeSpec,
) -> Result<Box<dyn Read + Send>, StorageError>;
async fn write_stream(&self, path: &str, mode: WriteMode) -> Result<Box<dyn UploadSink>, StorageError>;
async fn write_stream_session(
&self,
path: &str,
_session: &str,
mode: WriteMode,
) -> Result<Box<dyn UploadSink>, StorageError> {
self.write_stream(path, mode).await
}
async fn list_dir(&self, path: &str) -> Result<Vec<DirEntry>, StorageError>;
async fn mkdir_all(&self, path: &str) -> Result<(), StorageError>;
async fn remove(&self, path: &str) -> Result<(), StorageError>;
async fn cleanup_stale_sessions(
&self,
max_age: std::time::Duration,
) -> Result<usize, StorageError> {
let _ = max_age;
Ok(0)
}
}