]> git.mikk.net Git - mtbl-rs/commitdiff
Rename Iter to "entries" to avoid confusion with iterator.
authorChris Mikkelson <cmikk@fsi.io>
Sun, 7 Apr 2024 20:01:41 +0000 (15:01 -0500)
committerChris Mikkelson <cmikk@fsi.io>
Sun, 7 Apr 2024 20:01:41 +0000 (15:01 -0500)
Entries implements IntoIterator.

src/iter.rs

index c95f8445c1784ab8fded79df94975bd399aea765..e4155afeb4e1cae6509906ef9d3744fac7a653a7 100644 (file)
@@ -3,17 +3,20 @@ use std::cell::RefCell;
 use std::iter::Iterator;
 use std::rc::Rc;
 
-pub trait Entries: Iterator<Item = Entry> + Sized {
+pub trait Entries: IntoIterator<Item = Entry> + Sized {
     fn seek<T: AsRef<[u8]>>(&mut self, key: T);
 
-    fn wrap_iter<F: FnOnce(IterCell<Self>) -> O, O: Iterator<Item = Entry>>(
+    fn iter_next(&mut self) -> Option<Entry>;
+
+    fn wrap_iter<F: FnOnce(Iter<IterCell<Self>>) -> O, O: Iterator<Item = Entry>>(
         self,
         f: F,
     ) -> impl Entries {
-        let it = IterCell::new(self);
+        let b = IterCell::new(self);
+        let it = f(b.clone().into_iter());
         WrapIter {
-            inner: it.clone(),
-            outer: f(it),
+            inner: b,
+            outer: it,
         }
     }
 
@@ -30,29 +33,45 @@ pub trait Entries: Iterator<Item = Entry> + Sized {
     }
 }
 
+// Simple iter wrapper for iter_next
+pub struct Iter<T: Entries>(T);
+
+impl<T: Entries> Iterator for Iter<T> {
+    type Item = Entry;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        self.0.iter_next()
+    }
+}
+
 // WrapIter
 
 pub struct IterCell<I: Entries> {
-    ic: Rc<RefCell<I>>
+    ic: Rc<RefCell<I>>,
 }
 
 impl<I: Entries> Clone for IterCell<I> {
     fn clone(&self) -> Self {
-        IterCell{ic: self.ic.clone()}
+        IterCell {
+            ic: self.ic.clone(),
+        }
     }
 }
 
 impl<I: Entries> IterCell<I> {
     fn new(i: I) -> IterCell<I> {
-        IterCell{ic: Rc::new(RefCell::new(i))}
+        IterCell {
+            ic: Rc::new(RefCell::new(i)),
+        }
     }
 }
 
-impl<I: Entries> Iterator for IterCell<I> {
+impl<I: Entries> IntoIterator for IterCell<I> {
     type Item = Entry;
+    type IntoIter = Iter<IterCell<I>>;
 
-    fn next(&mut self) -> Option<Entry> {
-        self.ic.borrow_mut().next()
+    fn into_iter(self) -> Self::IntoIter {
+        Iter(self)
     }
 }
 
@@ -60,19 +79,23 @@ impl<I: Entries> Entries for IterCell<I> {
     fn seek<T: AsRef<[u8]>>(&mut self, key: T) {
         self.ic.borrow_mut().seek(key);
     }
-}
 
+    fn iter_next(&mut self) -> Option<Entry> {
+        self.ic.borrow_mut().iter_next()
+    }
+}
 
-struct WrapIter<I: Entries, O: Iterator<Item = Entry>> {
-    inner: IterCell<I>,
+struct WrapIter<E: Entries, O: Iterator<Item = Entry>> {
+    inner: IterCell<E>,
     outer: O,
 }
 
-impl<I: Entries, O: Iterator<Item = Entry>> Iterator for WrapIter<I, O> {
+impl<I: Entries, O: Iterator<Item = Entry>> IntoIterator for WrapIter<I, O> {
     type Item = Entry;
+    type IntoIter = Iter<WrapIter<I, O>>;
 
-    fn next(&mut self) -> Option<Self::Item> {
-        self.outer.next()
+    fn into_iter(self) -> Self::IntoIter {
+        Iter(self)
     }
 }
 
@@ -80,6 +103,10 @@ impl<I: Entries, O: Iterator<Item = Entry>> Entries for WrapIter<I, O> {
     fn seek<T: AsRef<[u8]>>(&mut self, key: T) {
         self.inner.seek(key)
     }
+
+    fn iter_next(&mut self) -> Option<Self::Item> {
+        self.outer.next()
+    }
 }
 
 // FilterSeek
@@ -91,29 +118,22 @@ pub enum FilterSeekResult {
 }
 pub use FilterSeekResult::*;
 
-struct FilterSeek<I: Iterator<Item = Entry>, F: FnMut(&Entry, &mut Vec<u8>) -> FilterSeekResult> {
+struct FilterSeek<I: Entries, F: FnMut(&Entry, &mut Vec<u8>) -> FilterSeekResult> {
     inner: I,
     filter_func: F,
     seek_key: Vec<u8>,
 }
 
-impl<I, F> Iterator for FilterSeek<I, F>
+impl<I, F> IntoIterator for FilterSeek<I, F>
 where
     F: FnMut(&Entry, &mut Vec<u8>) -> FilterSeekResult,
     I: Entries<Item = Entry>,
 {
     type Item = Entry;
+    type IntoIter = Iter<FilterSeek<I, F>>;
 
-    fn next(&mut self) -> Option<Entry> {
-        self.seek_key.clear();
-        while let Some(e) = self.inner.next() {
-            match (self.filter_func)(&e, &mut self.seek_key) {
-                Skip => continue,
-                Keep => return Some(e),
-                Seek => self.inner.seek(self.seek_key.as_slice()),
-            }
-        }
-        None
+    fn into_iter(self) -> Self::IntoIter {
+        Iter(self)
     }
 }
 
@@ -125,6 +145,18 @@ where
     fn seek<T: AsRef<[u8]>>(&mut self, key: T) {
         self.inner.seek(key.as_ref());
     }
+
+    fn iter_next(&mut self) -> Option<Entry> {
+        self.seek_key.clear();
+        while let Some(e) = self.inner.iter_next() {
+            match (self.filter_func)(&e, &mut self.seek_key) {
+                Skip => continue,
+                Keep => return Some(e),
+                Seek => self.inner.seek(self.seek_key.as_slice()),
+            }
+        }
+        None
+    }
 }
 
 #[cfg(test)]
@@ -133,10 +165,16 @@ mod test {
 
     struct TestIter(u8);
 
-    impl Iterator for TestIter {
+    impl IntoIterator for TestIter {
         type Item = Entry;
+        type IntoIter = Iter<TestIter>;
+        fn into_iter(self) -> Self::IntoIter {
+            Iter(self)
+        }
+    }
 
-        fn next(&mut self) -> Option<Entry> {
+    impl Entries for TestIter {
+        fn iter_next(&mut self) -> Option<Entry> {
             match self.0 {
                 255 => None,
                 _ => {
@@ -146,9 +184,7 @@ mod test {
                 }
             }
         }
-    }
 
-    impl Entries for TestIter {
         fn seek<T: AsRef<[u8]>>(&mut self, kr: T) {
             self.0 = kr.as_ref()[0];
         }
@@ -169,6 +205,7 @@ mod test {
                 }
                 FilterSeekResult::Keep
             })
+            .into_iter()
             .filter(|e| e.key[0] % 5 == 0)
             .collect();
         println!("\n\nTEST: iter_filter");
@@ -181,7 +218,7 @@ mod test {
         let ti = TestIter(0);
         let mut mi = ti.wrap_iter(|i| i.filter(|e| e.key[0] % 2 == 0));
         mi.seek(&[100]);
-        let v: Vec<Entry> = mi.collect();
+        let v: Vec<Entry> = mi.into_iter().collect();
         println!("\n\nTEST: iter_wrap");
         println!("{:?}", v);
     }