seekable_iterator/
lender_adapter.rs

1use lender::{Lend, Lender, Lending};
2
3use crate::seekable::delegate_seekable;
4use crate::{
5    comparator::Comparator, lending_iterator_support::LentItem,
6    pooled::PooledIterator, seekable::Seekable,
7};
8use crate::cursor::{CursorLendingIterator, CursorPooledIterator};
9
10
11/// An adapter for [`CursorLendingIterator`] which implements [`lender::Lender`].
12///
13/// To avoid conflicts between `Lender::next` and `CursorLendingIterator::next`,
14/// the `CursorLendingIterator` is not implemented for the adapter; however,
15/// the other cursor methods (`valid`, `current`, `prev`) are implemented, and [`Seekable`]
16/// is implemented if `I: Seekable`.
17#[derive(Debug, Clone, PartialEq, Eq)]
18#[cfg_attr(docsrs, doc(cfg(feature = "lender")))]
19pub struct LenderAdapter<I>(I);
20
21impl<I> LenderAdapter<I> {
22    #[inline]
23    #[must_use]
24    pub(crate) const fn new(iter: I) -> Self {
25        Self(iter)
26    }
27
28    /// Convert the adapter back into the inner iterator.
29    #[inline]
30    #[must_use]
31    pub fn into_inner(self) -> I {
32        self.0
33    }
34}
35
36impl<'lend, I: CursorLendingIterator> Lending<'lend> for LenderAdapter<I> {
37    type Lend = LentItem<'lend, I>;
38}
39
40impl<I: CursorLendingIterator> Lender for LenderAdapter<I> {
41    #[inline]
42    fn next(&mut self) -> Option<Lend<'_, Self>> {
43        self.0.next()
44    }
45}
46
47impl<I: CursorLendingIterator> LenderAdapter<I> {
48    /// Determine whether the iterator is currently at any value in the collection.
49    ///
50    /// See [`CursorLendingIterator::valid()`].
51    #[inline]
52    #[must_use]
53    pub fn valid(&self) -> bool {
54        self.0.valid()
55    }
56
57    /// Get the current value the iterator is at.
58    ///
59    /// See [`CursorLendingIterator::current()`].
60    #[inline]
61    #[must_use]
62    pub fn current(&self) -> Option<Lend<'_, Self>> {
63        self.0.current()
64    }
65
66    /// Move the iterator one position back, and return the entry at that position.
67    /// Returns `None` if the iterator was at the first entry.
68    ///
69    /// See [`CursorLendingIterator::prev()`].
70    #[inline]
71    #[must_use]
72    pub fn prev(&mut self) -> Option<Lend<'_, Self>> {
73        self.0.prev()
74    }
75}
76
77delegate_seekable!(LenderAdapter.0);
78
79/// An adapter for [`PooledIterator`] which implements [`lender::Lender`].
80///
81/// To avoid conflicts between `Lender::next` and `PooledIterator::next`,
82/// the `PooledIterator` is not implemented for the adapter; however, the other cursor methods
83/// (`valid`, `current`, `prev`) are implemented if `I: CursorPooledIterator`, and [`Seekable`]
84/// is implemented if `I: Seekable`.
85#[derive(Debug, Clone, PartialEq, Eq)]
86#[cfg_attr(docsrs, doc(cfg(feature = "lender")))]
87pub struct PooledLenderAdapter<I: PooledIterator> {
88    iter: I,
89    item: Option<I::Item>,
90}
91
92impl<I: PooledIterator> PooledLenderAdapter<I> {
93    #[inline]
94    #[must_use]
95    pub(crate) const fn new(iter: I) -> Self {
96        Self {
97            iter,
98            item: None,
99        }
100    }
101
102    /// Convert the adapter back into the inner iterator.
103    #[inline]
104    #[must_use]
105    pub fn into_inner(self) -> I {
106        self.iter
107    }
108}
109
110impl<'lend, I: PooledIterator> Lending<'lend> for PooledLenderAdapter<I> {
111    type Lend = &'lend I::Item;
112}
113
114impl<I: PooledIterator> Lender for PooledLenderAdapter<I> {
115    #[inline]
116    fn next(&mut self) -> Option<Lend<'_, Self>> {
117        // Make sure any previous item is dropped
118        self.item = None;
119        self.item = self.iter.next();
120        self.item.as_ref()
121    }
122}
123
124impl<I: CursorPooledIterator> PooledLenderAdapter<I> {
125    /// Determine whether the iterator is currently at any value in the collection.
126    ///
127    /// See [`CursorPooledIterator::valid()`].
128    #[inline]
129    #[must_use]
130    pub fn valid(&self) -> bool {
131        self.iter.valid()
132    }
133
134    /// Get the current value the iterator is at.
135    ///
136    /// This is cheap, and does not require getting a new buffer.
137    ///
138    /// See [`CursorPooledIterator::current()`].
139    #[inline]
140    #[must_use]
141    pub const fn current(&self) -> Option<Lend<'_, Self>> {
142        self.item.as_ref()
143    }
144
145    /// Move the iterator one position back, and return the entry at that position.
146    /// Returns `None` if the iterator was at the first entry.
147    ///
148    /// See [`CursorPooledIterator::prev()`].
149    #[inline]
150    #[must_use]
151    pub fn prev(&mut self) -> Option<Lend<'_, Self>> {
152        // Make sure any previous item is dropped
153        self.item = None;
154        self.item = self.iter.prev();
155        self.item.as_ref()
156    }
157}
158
159delegate_seekable!(PooledLenderAdapter.iter PooledIterator);