use crate::{Blob, Id, ListOptions};
use bytes::Bytes;
use core::future::Future;
use futures_core::Stream;
pub trait Repository {
type Error;
fn is_empty(&self) -> impl Future<Output = Result<bool, Self::Error>> + Send
where
Self: Sync,
{
async {
let mut ids = core::pin::pin!(self.list(ListOptions::new().with_limit(1)));
match next(&mut ids).await {
None => Ok(true),
Some(result) => result.map(|_| false),
}
}
}
fn len(&self) -> impl Future<Output = Result<u64, Self::Error>> + Send
where
Self: Sync,
{
async {
let mut ids = core::pin::pin!(self.list(ListOptions::default()));
let mut count: u64 = 0;
while let Some(result) = next(&mut ids).await {
result?;
count += 1;
}
Ok(count)
}
}
fn contains(&self, id: &Id) -> impl Future<Output = Result<bool, Self::Error>> + Send
where
Self: Sync,
{
async { Ok(self.get(id).await?.is_some()) }
}
fn get(&self, id: &Id) -> impl Future<Output = Result<Option<Blob>, Self::Error>> + Send;
fn get_len(&self, id: &Id) -> impl Future<Output = Result<Option<u64>, Self::Error>> + Send
where
Self: Sync,
{
async { Ok(self.get(id).await?.map(|blob| blob.len())) }
}
fn put(&mut self, data: Bytes) -> impl Future<Output = Result<Id, Self::Error>> + Send;
fn remove(&mut self, id: &Id) -> impl Future<Output = Result<bool, Self::Error>> + Send;
fn clear(&mut self) -> impl Future<Output = Result<(), Self::Error>> + Send;
fn list(&self, options: ListOptions) -> impl Stream<Item = Result<Id, Self::Error>> + Send;
}
async fn next<S: Stream + Unpin>(stream: &mut S) -> Option<S::Item> {
core::future::poll_fn(|cx| core::pin::Pin::new(&mut *stream).poll_next(cx)).await
}