use std::rc::Rc;
use anyhow::Result;
use cid::{multihash, Cid};
pub mod tracking;
mod memory;
pub use memory::MemoryBlockstore;
mod block;
pub use block::*;
pub trait Blockstore {
fn get(&self, k: &Cid) -> Result<Option<Vec<u8>>>;
fn put_keyed(&self, k: &Cid, block: &[u8]) -> Result<()>;
fn has(&self, k: &Cid) -> Result<bool> {
Ok(self.get(k)?.is_some())
}
fn put<D>(&self, mh_code: multihash::Code, block: &Block<D>) -> Result<Cid>
where
Self: Sized,
D: AsRef<[u8]>,
{
let k = block.cid(mh_code);
self.put_keyed(&k, block.as_ref())?;
Ok(k)
}
fn put_many<D, I>(&self, blocks: I) -> Result<()>
where
Self: Sized,
D: AsRef<[u8]>,
I: IntoIterator<Item = (multihash::Code, Block<D>)>,
{
self.put_many_keyed(blocks.into_iter().map(|(mc, b)| (b.cid(mc), b)))?;
Ok(())
}
fn put_many_keyed<D, I>(&self, blocks: I) -> Result<()>
where
Self: Sized,
D: AsRef<[u8]>,
I: IntoIterator<Item = (Cid, D)>,
{
for (c, b) in blocks {
self.put_keyed(&c, b.as_ref())?
}
Ok(())
}
}
pub trait Buffered: Blockstore {
fn flush(&self, root: &Cid) -> Result<()>;
}
impl<BS> Blockstore for &BS
where
BS: Blockstore,
{
fn get(&self, k: &Cid) -> Result<Option<Vec<u8>>> {
(*self).get(k)
}
fn put_keyed(&self, k: &Cid, block: &[u8]) -> Result<()> {
(*self).put_keyed(k, block)
}
fn has(&self, k: &Cid) -> Result<bool> {
(*self).has(k)
}
fn put<D>(&self, mh_code: multihash::Code, block: &Block<D>) -> Result<Cid>
where
Self: Sized,
D: AsRef<[u8]>,
{
(*self).put(mh_code, block)
}
fn put_many<D, I>(&self, blocks: I) -> Result<()>
where
Self: Sized,
D: AsRef<[u8]>,
I: IntoIterator<Item = (multihash::Code, Block<D>)>,
{
(*self).put_many(blocks)
}
fn put_many_keyed<D, I>(&self, blocks: I) -> Result<()>
where
Self: Sized,
D: AsRef<[u8]>,
I: IntoIterator<Item = (Cid, D)>,
{
(*self).put_many_keyed(blocks)
}
}
impl<BS> Blockstore for Rc<BS>
where
BS: Blockstore,
{
fn get(&self, k: &Cid) -> Result<Option<Vec<u8>>> {
(**self).get(k)
}
fn put_keyed(&self, k: &Cid, block: &[u8]) -> Result<()> {
(**self).put_keyed(k, block)
}
fn has(&self, k: &Cid) -> Result<bool> {
(**self).has(k)
}
fn put<D>(&self, mh_code: multihash::Code, block: &Block<D>) -> Result<Cid>
where
Self: Sized,
D: AsRef<[u8]>,
{
(**self).put(mh_code, block)
}
fn put_many<D, I>(&self, blocks: I) -> Result<()>
where
Self: Sized,
D: AsRef<[u8]>,
I: IntoIterator<Item = (multihash::Code, Block<D>)>,
{
(**self).put_many(blocks)
}
fn put_many_keyed<D, I>(&self, blocks: I) -> Result<()>
where
Self: Sized,
D: AsRef<[u8]>,
I: IntoIterator<Item = (Cid, D)>,
{
(**self).put_many_keyed(blocks)
}
}