use std::iter::Iterator;
use std::ops::{Deref, DerefMut};
use crate::cursor::Cursor;
use crate::error::Result;
use crate::traits::LmdbResultExt;
use crate::tx::ConstAccessor;
#[derive(Debug)]
#[allow(missing_docs)]
pub enum MaybeOwned<'a, T: 'a> {
Owned(T),
Borrowed(&'a mut T),
}
impl<'a, T: 'a> Deref for MaybeOwned<'a, T> {
type Target = T;
fn deref(&self) -> &T {
match *self {
MaybeOwned::Owned(ref t) => t,
MaybeOwned::Borrowed(ref t) => t,
}
}
}
impl<'a, T: 'a> DerefMut for MaybeOwned<'a, T> {
fn deref_mut(&mut self) -> &mut T {
match *self {
MaybeOwned::Owned(ref mut t) => t,
MaybeOwned::Borrowed(ref mut t) => t,
}
}
}
pub struct CursorIter<'a, 'access: 'a, 'txn: 'access, 'db: 'txn, T> {
cursor: MaybeOwned<'a, Cursor<'txn, 'db>>,
access: &'access ConstAccessor<'txn>,
head: Option<T>,
next: fn(&mut Cursor<'txn, 'db>, &'access ConstAccessor<'txn>) -> Result<T>,
}
impl<'a, 'access: 'a, 'txn: 'access, 'db: 'txn, T> CursorIter<'a, 'access, 'txn, 'db, T> {
pub fn new<H: FnOnce(&mut Cursor<'txn, 'db>, &'access ConstAccessor<'txn>) -> Result<T>>(
mut cursor: MaybeOwned<'a, Cursor<'txn, 'db>>,
access: &'access ConstAccessor<'txn>,
head: H,
next: fn(&mut Cursor<'txn, 'db>, &'access ConstAccessor<'txn>) -> Result<T>,
) -> Result<Self> {
let head_val = head(&mut cursor, access).to_opt()?;
Ok(CursorIter {
cursor,
access,
head: head_val,
next,
})
}
}
impl<'a, 'access: 'a, 'txn: 'access, 'db: 'txn, T> Iterator
for CursorIter<'a, 'access, 'txn, 'db, T>
{
type Item = Result<T>;
fn next(&mut self) -> Option<Result<T>> {
if let Some(head) = self.head.take() {
Some(Ok(head))
} else {
match (self.next)(&mut self.cursor, self.access).to_opt() {
Ok(Some(v)) => Some(Ok(v)),
Ok(None) => None,
Err(err) => Some(Err(err)),
}
}
}
}