use async_trait::async_trait;
use ipfrs_core::{Block, Cid, Result};
use std::sync::Arc;
#[async_trait]
pub trait BlockStore: Send + Sync {
async fn put(&self, block: &Block) -> Result<()>;
async fn put_many(&self, blocks: &[Block]) -> Result<()> {
for block in blocks {
self.put(block).await?;
}
Ok(())
}
async fn get(&self, cid: &Cid) -> Result<Option<Block>>;
async fn get_many(&self, cids: &[Cid]) -> Result<Vec<Option<Block>>> {
let mut results = Vec::with_capacity(cids.len());
for cid in cids {
results.push(self.get(cid).await?);
}
Ok(results)
}
async fn has(&self, cid: &Cid) -> Result<bool>;
async fn has_many(&self, cids: &[Cid]) -> Result<Vec<bool>> {
let mut results = Vec::with_capacity(cids.len());
for cid in cids {
results.push(self.has(cid).await?);
}
Ok(results)
}
async fn delete(&self, cid: &Cid) -> Result<()>;
async fn delete_many(&self, cids: &[Cid]) -> Result<()> {
for cid in cids {
self.delete(cid).await?;
}
Ok(())
}
fn list_cids(&self) -> Result<Vec<Cid>>;
fn len(&self) -> usize;
fn is_empty(&self) -> bool {
self.len() == 0
}
async fn flush(&self) -> Result<()> {
Ok(())
}
async fn close(&self) -> Result<()> {
self.flush().await
}
}
#[async_trait]
impl<S: BlockStore> BlockStore for Arc<S> {
async fn put(&self, block: &Block) -> Result<()> {
(**self).put(block).await
}
async fn put_many(&self, blocks: &[Block]) -> Result<()> {
(**self).put_many(blocks).await
}
async fn get(&self, cid: &Cid) -> Result<Option<Block>> {
(**self).get(cid).await
}
async fn get_many(&self, cids: &[Cid]) -> Result<Vec<Option<Block>>> {
(**self).get_many(cids).await
}
async fn has(&self, cid: &Cid) -> Result<bool> {
(**self).has(cid).await
}
async fn has_many(&self, cids: &[Cid]) -> Result<Vec<bool>> {
(**self).has_many(cids).await
}
async fn delete(&self, cid: &Cid) -> Result<()> {
(**self).delete(cid).await
}
async fn delete_many(&self, cids: &[Cid]) -> Result<()> {
(**self).delete_many(cids).await
}
fn list_cids(&self) -> Result<Vec<Cid>> {
(**self).list_cids()
}
fn len(&self) -> usize {
(**self).len()
}
fn is_empty(&self) -> bool {
(**self).is_empty()
}
async fn flush(&self) -> Result<()> {
(**self).flush().await
}
async fn close(&self) -> Result<()> {
(**self).close().await
}
}