use std::cell::RefCell;
use std::rc::Rc;
use anyhow::Error;
use anyhow::anyhow;
pub struct Continue(pub bool);
pub trait Store {
fn push(&self, db: &'static str, key: &str, value: Vec<u8>)
-> Result<(), Error>;
fn pull<F, T>(&self, db: &'static str, key: &str, formatter: F)
-> Result<T, Error>
where F: Fn(&[u8]) -> Result<T, Error>;
fn iter<F>(&self, db: &'static str, prefix: &str, f: F)
-> Result<(), Error>
where F: Fn(&[u8]) -> Continue;
fn all<F, T>(&self, db: &'static str, prefix: &str, formatter: F)
-> Result<Vec<T>, Error>
where F: Fn(&[u8]) -> Result<T, Error> {
let output: Rc<RefCell<Vec<T>>> = Rc::new(RefCell::new(vec![]));
let out = output.clone();
self.iter(db, prefix, move |data| {
if let Ok(obj) = formatter(data) {
out.borrow_mut().push(obj);
}
Continue(true)
})?;
Ok(Rc::try_unwrap(output)
.map_err(|_| anyhow!("error reading from db"))?
.into_inner())
}
fn rm(&self, db: &'static str, key: &str) -> Result<(), Error>;
}