From: Chris Mikkelson Date: Fri, 12 Apr 2024 19:15:10 +0000 (-0500) Subject: iter: Genericize repeated IntoIterator implementations X-Git-Url: https://git.mikk.net/?a=commitdiff_plain;h=73e8ebf301f6a1c7d4d676b4b149f2b9d2d0b611;p=mtbl-rs iter: Genericize repeated IntoIterator implementations Introduce 'Seekable' wrapper to bring common 'return Iter' logic to one place. --- diff --git a/src/iter.rs b/src/iter.rs index 56b4ad4..8b75171 100644 --- a/src/iter.rs +++ b/src/iter.rs @@ -3,49 +3,68 @@ use std::cell::RefCell; use std::iter::Iterator; use std::rc::Rc; -pub trait Entries: IntoIterator + Sized { - fn seek>(&mut self, key: T); +pub trait Entries: Sized { + fn seek>(&mut self, key: K); fn iter_next(&mut self) -> Option; fn wrap_iter>) -> O, O: Iterator>( self, f: F, - ) -> impl Entries { + ) -> Seekable> { let b = IterCell::new(self); let it = f(b.clone().into_iter()); - WrapIter { + Seekable(WrapIter { inner: b, outer: it, - } + }) } - // provided methods - fn filter(self, filter: F) -> impl Entries + + fn filter(self, filter: F) -> Seekable> where F: FnMut(&Entry, &mut Vec) -> FilterAction, { - Filter { + Seekable(Filter { inner: self, filter_func: filter, seek_key: Vec::new(), - } + }) + } +} + +pub struct Seekable(T); + +impl IntoIterator for Seekable { + type Item = Entry; + type IntoIter = Iter; + + fn into_iter(self) -> Self::IntoIter { + Iter(self.0) + } +} + +impl Entries for Seekable { + fn seek>(&mut self, key: K) { + self.0.seek(key) + } + + fn iter_next(&mut self) -> Option { + self.0.iter_next() } } -// Simple iter wrapper for iter_next pub struct Iter(T); impl Iterator for Iter { type Item = Entry; - fn next(&mut self) -> Option { + fn next(&mut self) -> Option { self.0.iter_next() } } // WrapIter - pub struct IterCell { ic: Rc>, } @@ -85,26 +104,17 @@ impl Entries for IterCell { } } -struct WrapIter> { +pub struct WrapIter> { inner: IterCell, outer: O, } -impl> IntoIterator for WrapIter { - type Item = Entry; - type IntoIter = Iter>; - - fn into_iter(self) -> Self::IntoIter { - Iter(self) - } -} - impl> Entries for WrapIter { fn seek>(&mut self, key: T) { self.inner.seek(key) } - fn iter_next(&mut self) -> Option { + fn iter_next(&mut self) -> Option { self.outer.next() } } @@ -118,29 +128,16 @@ pub enum FilterAction { } pub use FilterAction::*; -struct Filter) -> FilterAction> { +pub struct Filter) -> FilterAction> { inner: I, filter_func: F, seek_key: Vec, } -impl IntoIterator for Filter -where - F: FnMut(&Entry, &mut Vec) -> FilterAction, - I: Entries, -{ - type Item = Entry; - type IntoIter = Iter>; - - fn into_iter(self) -> Self::IntoIter { - Iter(self) - } -} - impl Entries for Filter where + I: Entries, F: FnMut(&Entry, &mut Vec) -> FilterAction, - I: Entries, { fn seek>(&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; - fn into_iter(self) -> Self::IntoIter { - Iter(self) - } - } - impl Entries for TestIter { fn iter_next(&mut self) -> Option { match self.0 {