]> git.mikk.net Git - mtbl-rs/commitdiff
iter: Genericize repeated IntoIterator implementations
authorChris Mikkelson <cmikk@fsi.io>
Fri, 12 Apr 2024 19:15:10 +0000 (14:15 -0500)
committerChris Mikkelson <cmikk@fsi.io>
Fri, 12 Apr 2024 19:15:10 +0000 (14:15 -0500)
Introduce 'Seekable<T: Entries>' wrapper to bring common
'return Iter<T>' logic to one place.

src/iter.rs

index 56b4ad492bbbcfbac19a4a2c78e3e91b908f5ef7..8b75171d474a9fc0e732347311d47fb2da0faf4f 100644 (file)
@@ -3,49 +3,68 @@ use std::cell::RefCell;
 use std::iter::Iterator;
 use std::rc::Rc;
 
-pub trait Entries: IntoIterator<Item = Entry> + Sized {
-    fn seek<T: AsRef<[u8]>>(&mut self, key: T);
+pub trait Entries: Sized {
+    fn seek<K: AsRef<[u8]>>(&mut self, key: K);
 
     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 {
+    ) -> Seekable<WrapIter<Self, O>> {
         let b = IterCell::new(self);
         let it = f(b.clone().into_iter());
-        WrapIter {
+        Seekable(WrapIter {
             inner: b,
             outer: it,
-        }
+        })
     }
 
-    // provided methods
-    fn filter<F>(self, filter: F) -> impl Entries
+
+    fn filter<F>(self, filter: F) -> Seekable<Filter<Self, F>>
     where
         F: FnMut(&Entry, &mut Vec<u8>) -> FilterAction,
     {
-        Filter {
+        Seekable(Filter {
             inner: self,
             filter_func: filter,
             seek_key: Vec::new(),
-        }
+        })
+    }
+}
+
+pub struct Seekable<T: Entries>(T);
+
+impl<T: Entries> IntoIterator for Seekable<T> {
+    type Item = Entry;
+    type IntoIter = Iter<T>;
+
+    fn into_iter(self) -> Self::IntoIter {
+       Iter(self.0)
+    }
+}
+
+impl<T: Entries> Entries for Seekable<T> {
+    fn seek<K: AsRef<[u8]>>(&mut self, key: K) {
+       self.0.seek(key)
+    }
+
+    fn iter_next(&mut self) -> Option<Entry> {
+       self.0.iter_next()
     }
 }
 
-// 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> {
+    fn next(&mut self) -> Option<Entry> {
         self.0.iter_next()
     }
 }
 
 // WrapIter
-
 pub struct IterCell<I: Entries> {
     ic: Rc<RefCell<I>>,
 }
@@ -85,26 +104,17 @@ impl<I: Entries> Entries for IterCell<I> {
     }
 }
 
-struct WrapIter<E: Entries, O: Iterator<Item = Entry>> {
+pub struct WrapIter<E: Entries, O: Iterator<Item = Entry>> {
     inner: IterCell<E>,
     outer: O,
 }
 
-impl<I: Entries, O: Iterator<Item = Entry>> IntoIterator for WrapIter<I, O> {
-    type Item = Entry;
-    type IntoIter = Iter<WrapIter<I, O>>;
-
-    fn into_iter(self) -> Self::IntoIter {
-        Iter(self)
-    }
-}
-
 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> {
+    fn iter_next(&mut self) -> Option<Entry> {
         self.outer.next()
     }
 }
@@ -118,29 +128,16 @@ pub enum FilterAction {
 }
 pub use FilterAction::*;
 
-struct Filter<I: Entries, F: FnMut(&Entry, &mut Vec<u8>) -> FilterAction> {
+pub struct Filter<I: Entries, F: FnMut(&Entry, &mut Vec<u8>) -> FilterAction> {
     inner: I,
     filter_func: F,
     seek_key: Vec<u8>,
 }
 
-impl<I, F> IntoIterator for Filter<I, F>
-where
-    F: FnMut(&Entry, &mut Vec<u8>) -> FilterAction,
-    I: Entries<Item = Entry>,
-{
-    type Item = Entry;
-    type IntoIter = Iter<Filter<I, F>>;
-
-    fn into_iter(self) -> Self::IntoIter {
-        Iter(self)
-    }
-}
-
 impl<I, F> Entries for Filter<I, F>
 where
+    I: Entries,
     F: FnMut(&Entry, &mut Vec<u8>) -> FilterAction,
-    I: Entries<Item = Entry>,
 {
     fn seek<T: AsRef<[u8]>>(&mut self, key: T) {
         self.inner.seek(key.as_ref());
@@ -165,14 +162,6 @@ mod test {
 
     struct TestIter(u8);
 
-    impl IntoIterator for TestIter {
-        type Item = Entry;
-        type IntoIter = Iter<TestIter>;
-        fn into_iter(self) -> Self::IntoIter {
-            Iter(self)
-        }
-    }
-
     impl Entries for TestIter {
         fn iter_next(&mut self) -> Option<Entry> {
             match self.0 {