seekable_iterator/
lending_iterator_adapter.rs

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