use crate::conditional::ConditionalHeaders;
use crate::error::StorageError;
use crate::kb::{KbManifest, ObjectMeta};
use crate::object_path::ObjectPath;
use crate::range::ByteRange;
use crate::slug::KbSlug;
use async_trait::async_trait;
use bytes::Bytes;
pub struct ObjectRead {
pub bytes: Bytes,
pub meta: ObjectMeta,
pub content_range: Option<String>,
}
#[derive(Debug)]
pub struct ListResponse {
pub objects: Vec<ObjectMeta>,
pub truncated: bool,
pub next_cursor: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PutOutcome {
pub etag: Option<String>,
}
#[async_trait]
pub trait Storage: Send + Sync {
async fn ensure_bucket(&self, kb: &KbSlug) -> Result<(), StorageError>;
async fn read_manifest(&self, kb: &KbSlug) -> Result<KbManifest, StorageError>;
async fn write_manifest(&self, kb: &KbSlug, manifest: &KbManifest) -> Result<(), StorageError>;
async fn head_object(
&self,
kb: &KbSlug,
path: &ObjectPath,
conditionals: ConditionalHeaders,
) -> Result<ObjectMeta, StorageError>;
async fn get_object(
&self,
kb: &KbSlug,
path: &ObjectPath,
range: Option<Vec<ByteRange>>,
conditionals: ConditionalHeaders,
) -> Result<ObjectRead, StorageError>;
async fn put_object(
&self,
kb: &KbSlug,
path: &ObjectPath,
bytes: Bytes,
content_type: Option<&str>,
conditionals: ConditionalHeaders,
) -> Result<PutOutcome, StorageError>;
async fn delete_object(
&self,
kb: &KbSlug,
path: &ObjectPath,
conditionals: ConditionalHeaders,
) -> Result<(), StorageError>;
async fn list_objects(
&self,
kb: &KbSlug,
prefix: Option<&str>,
limit: u32,
cursor: Option<&str>,
) -> Result<ListResponse, StorageError>;
}
#[cfg(test)]
mod tests {
fn assert_send_sync<T: Send + Sync + ?Sized>() {}
#[test]
fn storage_is_dyn_compatible_and_send_sync() {
assert_send_sync::<dyn crate::storage::Storage>();
}
}