sdb 0.0.10

a user-friendly wrapper for sanakirja database
Documentation
use sanakirja::btree::{BTreePage, Cursor, Db_};
use sanakirja::{LoadPage, Storable};
use std::marker::PhantomData;

pub fn key_iter<'a, T, K, V, P>(
  txn: &'a T,
  db: &Db_<K, V, P>,
  key: &K,
) -> Result<Box<dyn Iterator<Item = Result<(&'a K, &'a V), T::Error>> + 'a>, T::Error>
where
  T: LoadPage,
  K: 'a + PartialEq + Storable + ?Sized,
  V: 'a + Storable + ?Sized,
  P: 'a + BTreePage<K, V>,
{
  let mut cursor = Cursor::new(txn, db)?;

  match cursor.set(txn, key, None)? {
    Some((key_c, _)) => Ok(Box::new(KeyIter {
      cursor,
      txn,
      key: key_c,
    })),
    None => Ok(Box::new(StopIter::<T, K, V>(PhantomData {}))),
  }
}

pub struct StopIter<'a, T: LoadPage, K: PartialEq + Storable + ?Sized, V: Storable + ?Sized>(
  PhantomData<(&'a T, &'a K, &'a V)>,
);

impl<'a, T: LoadPage, K: PartialEq + Storable + ?Sized + 'a, V: Storable + ?Sized + 'a> Iterator
  for StopIter<'a, T, K, V>
{
  type Item = Result<(&'a K, &'a V), T::Error>;
  #[inline]
  fn next(&mut self) -> Option<Self::Item> {
    None
  }
}

pub struct KeyIter<
  'a,
  T: LoadPage,
  K: PartialEq + Storable + ?Sized,
  V: Storable + ?Sized,
  P: BTreePage<K, V>,
> {
  txn: &'a T,
  cursor: Cursor<K, V, P>,
  key: &'a K,
}

impl<
    'a,
    T: LoadPage,
    K: PartialEq + Storable + ?Sized + 'a,
    V: Storable + ?Sized + 'a,
    P: BTreePage<K, V> + 'a,
  > Iterator for KeyIter<'a, T, K, V, P>
{
  type Item = Result<(&'a K, &'a V), T::Error>;
  #[inline]
  fn next(&mut self) -> Option<Self::Item> {
    let entry = self.cursor.next(self.txn).transpose();
    match entry {
      Some(kv) => match kv {
        Ok((k, _)) => {
          if k == self.key {
            Some(kv)
          } else {
            None
          }
        }
        _ => Some(kv),
      },
      _ => entry,
    }
  }
}