use crate::*;
use std::borrow::Cow;
use std::marker;
pub struct RoIter<'txn, KC, DC> {
cursor: RoCursor<'txn>,
move_on_first: bool,
_phantom: marker::PhantomData<(KC, DC)>,
}
impl<'txn, KC, DC> RoIter<'txn, KC, DC> {
pub(crate) fn new(cursor: RoCursor<'txn>) -> RoIter<'txn, KC, DC> {
RoIter { cursor, move_on_first: true, _phantom: marker::PhantomData }
}
pub fn remap_types<KC2, DC2>(self) -> RoIter<'txn, KC2, DC2> {
RoIter {
cursor: self.cursor,
move_on_first: self.move_on_first,
_phantom: marker::PhantomData::default(),
}
}
pub fn remap_key_type<KC2>(self) -> RoIter<'txn, KC2, DC> {
self.remap_types::<KC2, DC>()
}
pub fn remap_data_type<DC2>(self) -> RoIter<'txn, KC, DC2> {
self.remap_types::<KC, DC2>()
}
pub fn lazily_decode_data(self) -> RoIter<'txn, KC, LazyDecode<DC>> {
self.remap_types::<KC, LazyDecode<DC>>()
}
}
impl<'txn, KC, DC> Iterator for RoIter<'txn, KC, DC>
where
KC: BytesDecode<'txn>,
DC: BytesDecode<'txn>,
{
type Item = Result<(KC::DItem, DC::DItem)>;
fn next(&mut self) -> Option<Self::Item> {
let result = if self.move_on_first {
self.move_on_first = false;
self.cursor.move_on_first()
} else {
self.cursor.move_on_next()
};
match result {
Ok(Some((key, data))) => match (KC::bytes_decode(key), DC::bytes_decode(data)) {
(Some(key), Some(data)) => Some(Ok((key, data))),
(_, _) => Some(Err(Error::Decoding)),
},
Ok(None) => None,
Err(e) => Some(Err(e)),
}
}
fn last(mut self) -> Option<Self::Item> {
let result = if self.move_on_first {
self.cursor.move_on_last()
} else {
match (self.cursor.current(), self.cursor.move_on_last()) {
(Ok(Some((ckey, _))), Ok(Some((key, data)))) if ckey != key => {
Ok(Some((key, data)))
},
(Ok(_), Ok(_)) => Ok(None),
(Err(e), _) | (_, Err(e)) => Err(e),
}
};
match result {
Ok(Some((key, data))) => match (KC::bytes_decode(key), DC::bytes_decode(data)) {
(Some(key), Some(data)) => Some(Ok((key, data))),
(_, _) => Some(Err(Error::Decoding)),
},
Ok(None) => None,
Err(e) => Some(Err(e)),
}
}
}
pub struct RwIter<'txn, KC, DC> {
cursor: RwCursor<'txn>,
move_on_first: bool,
_phantom: marker::PhantomData<(KC, DC)>,
}
impl<'txn, KC, DC> RwIter<'txn, KC, DC> {
pub(crate) fn new(cursor: RwCursor<'txn>) -> RwIter<'txn, KC, DC> {
RwIter { cursor, move_on_first: true, _phantom: marker::PhantomData }
}
pub fn del_current(&mut self) -> Result<bool> {
self.cursor.del_current()
}
pub fn put_current<'a>(&mut self, key: &'a KC::EItem, data: &'a DC::EItem) -> Result<bool>
where
KC: BytesEncode<'a>,
DC: BytesEncode<'a>,
{
let key_bytes: Cow<[u8]> = KC::bytes_encode(&key).ok_or(Error::Encoding)?;
let data_bytes: Cow<[u8]> = DC::bytes_encode(&data).ok_or(Error::Encoding)?;
self.cursor.put_current(&key_bytes, &data_bytes)
}
pub fn append<'a>(&mut self, key: &'a KC::EItem, data: &'a DC::EItem) -> Result<()>
where
KC: BytesEncode<'a>,
DC: BytesEncode<'a>,
{
let key_bytes: Cow<[u8]> = KC::bytes_encode(&key).ok_or(Error::Encoding)?;
let data_bytes: Cow<[u8]> = DC::bytes_encode(&data).ok_or(Error::Encoding)?;
self.cursor.append(&key_bytes, &data_bytes)
}
pub fn remap_types<KC2, DC2>(self) -> RwIter<'txn, KC2, DC2> {
RwIter {
cursor: self.cursor,
move_on_first: self.move_on_first,
_phantom: marker::PhantomData::default(),
}
}
pub fn remap_key_type<KC2>(self) -> RwIter<'txn, KC2, DC> {
self.remap_types::<KC2, DC>()
}
pub fn remap_data_type<DC2>(self) -> RwIter<'txn, KC, DC2> {
self.remap_types::<KC, DC2>()
}
pub fn lazily_decode_data(self) -> RwIter<'txn, KC, LazyDecode<DC>> {
self.remap_types::<KC, LazyDecode<DC>>()
}
}
impl<'txn, KC, DC> Iterator for RwIter<'txn, KC, DC>
where
KC: BytesDecode<'txn>,
DC: BytesDecode<'txn>,
{
type Item = Result<(KC::DItem, DC::DItem)>;
fn next(&mut self) -> Option<Self::Item> {
let result = if self.move_on_first {
self.move_on_first = false;
self.cursor.move_on_first()
} else {
self.cursor.move_on_next()
};
match result {
Ok(Some((key, data))) => match (KC::bytes_decode(key), DC::bytes_decode(data)) {
(Some(key), Some(data)) => Some(Ok((key, data))),
(_, _) => Some(Err(Error::Decoding)),
},
Ok(None) => None,
Err(e) => Some(Err(e)),
}
}
fn last(mut self) -> Option<Self::Item> {
let result = if self.move_on_first {
self.cursor.move_on_last()
} else {
match (self.cursor.current(), self.cursor.move_on_last()) {
(Ok(Some((ckey, _))), Ok(Some((key, data)))) if ckey != key => {
Ok(Some((key, data)))
},
(Ok(_), Ok(_)) => Ok(None),
(Err(e), _) | (_, Err(e)) => Err(e),
}
};
match result {
Ok(Some((key, data))) => match (KC::bytes_decode(key), DC::bytes_decode(data)) {
(Some(key), Some(data)) => Some(Ok((key, data))),
(_, _) => Some(Err(Error::Decoding)),
},
Ok(None) => None,
Err(e) => Some(Err(e)),
}
}
}
pub struct RoRevIter<'txn, KC, DC> {
cursor: RoCursor<'txn>,
move_on_last: bool,
_phantom: marker::PhantomData<(KC, DC)>,
}
impl<'txn, KC, DC> RoRevIter<'txn, KC, DC> {
pub(crate) fn new(cursor: RoCursor<'txn>) -> RoRevIter<'txn, KC, DC> {
RoRevIter { cursor, move_on_last: true, _phantom: marker::PhantomData }
}
pub fn remap_types<KC2, DC2>(self) -> RoRevIter<'txn, KC2, DC2> {
RoRevIter {
cursor: self.cursor,
move_on_last: self.move_on_last,
_phantom: marker::PhantomData::default(),
}
}
pub fn remap_key_type<KC2>(self) -> RoRevIter<'txn, KC2, DC> {
self.remap_types::<KC2, DC>()
}
pub fn remap_data_type<DC2>(self) -> RoRevIter<'txn, KC, DC2> {
self.remap_types::<KC, DC2>()
}
pub fn lazily_decode_data(self) -> RoRevIter<'txn, KC, LazyDecode<DC>> {
self.remap_types::<KC, LazyDecode<DC>>()
}
}
impl<'txn, KC, DC> Iterator for RoRevIter<'txn, KC, DC>
where
KC: BytesDecode<'txn>,
DC: BytesDecode<'txn>,
{
type Item = Result<(KC::DItem, DC::DItem)>;
fn next(&mut self) -> Option<Self::Item> {
let result = if self.move_on_last {
self.move_on_last = false;
self.cursor.move_on_last()
} else {
self.cursor.move_on_prev()
};
match result {
Ok(Some((key, data))) => match (KC::bytes_decode(key), DC::bytes_decode(data)) {
(Some(key), Some(data)) => Some(Ok((key, data))),
(_, _) => Some(Err(Error::Decoding)),
},
Ok(None) => None,
Err(e) => Some(Err(e)),
}
}
fn last(mut self) -> Option<Self::Item> {
let result = if self.move_on_last {
self.cursor.move_on_first()
} else {
match (self.cursor.current(), self.cursor.move_on_first()) {
(Ok(Some((ckey, _))), Ok(Some((key, data)))) if ckey != key => {
Ok(Some((key, data)))
},
(Ok(_), Ok(_)) => Ok(None),
(Err(e), _) | (_, Err(e)) => Err(e),
}
};
match result {
Ok(Some((key, data))) => match (KC::bytes_decode(key), DC::bytes_decode(data)) {
(Some(key), Some(data)) => Some(Ok((key, data))),
(_, _) => Some(Err(Error::Decoding)),
},
Ok(None) => None,
Err(e) => Some(Err(e)),
}
}
}
pub struct RwRevIter<'txn, KC, DC> {
cursor: RwCursor<'txn>,
move_on_last: bool,
_phantom: marker::PhantomData<(KC, DC)>,
}
impl<'txn, KC, DC> RwRevIter<'txn, KC, DC> {
pub(crate) fn new(cursor: RwCursor<'txn>) -> RwRevIter<'txn, KC, DC> {
RwRevIter { cursor, move_on_last: true, _phantom: marker::PhantomData }
}
pub fn del_current(&mut self) -> Result<bool> {
self.cursor.del_current()
}
pub fn put_current<'a>(&mut self, key: &'a KC::EItem, data: &'a DC::EItem) -> Result<bool>
where
KC: BytesEncode<'a>,
DC: BytesEncode<'a>,
{
let key_bytes: Cow<[u8]> = KC::bytes_encode(&key).ok_or(Error::Encoding)?;
let data_bytes: Cow<[u8]> = DC::bytes_encode(&data).ok_or(Error::Encoding)?;
self.cursor.put_current(&key_bytes, &data_bytes)
}
pub fn append<'a>(&mut self, key: &'a KC::EItem, data: &'a DC::EItem) -> Result<()>
where
KC: BytesEncode<'a>,
DC: BytesEncode<'a>,
{
let key_bytes: Cow<[u8]> = KC::bytes_encode(&key).ok_or(Error::Encoding)?;
let data_bytes: Cow<[u8]> = DC::bytes_encode(&data).ok_or(Error::Encoding)?;
self.cursor.append(&key_bytes, &data_bytes)
}
pub fn remap_types<KC2, DC2>(self) -> RwRevIter<'txn, KC2, DC2> {
RwRevIter {
cursor: self.cursor,
move_on_last: self.move_on_last,
_phantom: marker::PhantomData::default(),
}
}
pub fn remap_key_type<KC2>(self) -> RwRevIter<'txn, KC2, DC> {
self.remap_types::<KC2, DC>()
}
pub fn remap_data_type<DC2>(self) -> RwRevIter<'txn, KC, DC2> {
self.remap_types::<KC, DC2>()
}
pub fn lazily_decode_data(self) -> RwRevIter<'txn, KC, LazyDecode<DC>> {
self.remap_types::<KC, LazyDecode<DC>>()
}
}
impl<'txn, KC, DC> Iterator for RwRevIter<'txn, KC, DC>
where
KC: BytesDecode<'txn>,
DC: BytesDecode<'txn>,
{
type Item = Result<(KC::DItem, DC::DItem)>;
fn next(&mut self) -> Option<Self::Item> {
let result = if self.move_on_last {
self.move_on_last = false;
self.cursor.move_on_last()
} else {
self.cursor.move_on_prev()
};
match result {
Ok(Some((key, data))) => match (KC::bytes_decode(key), DC::bytes_decode(data)) {
(Some(key), Some(data)) => Some(Ok((key, data))),
(_, _) => Some(Err(Error::Decoding)),
},
Ok(None) => None,
Err(e) => Some(Err(e)),
}
}
fn last(mut self) -> Option<Self::Item> {
let result = if self.move_on_last {
self.cursor.move_on_first()
} else {
match (self.cursor.current(), self.cursor.move_on_first()) {
(Ok(Some((ckey, _))), Ok(Some((key, data)))) if ckey != key => {
Ok(Some((key, data)))
},
(Ok(_), Ok(_)) => Ok(None),
(Err(e), _) | (_, Err(e)) => Err(e),
}
};
match result {
Ok(Some((key, data))) => match (KC::bytes_decode(key), DC::bytes_decode(data)) {
(Some(key), Some(data)) => Some(Ok((key, data))),
(_, _) => Some(Err(Error::Decoding)),
},
Ok(None) => None,
Err(e) => Some(Err(e)),
}
}
}