]> git.mikk.net Git - mtbl-rs/commitdiff
map values only; generic keys too complex
authorChris Mikkelson <cmikk@fsi.io>
Mon, 17 Jun 2024 02:08:38 +0000 (21:08 -0500)
committerChris Mikkelson <cmikk@fsi.io>
Mon, 17 Jun 2024 02:08:38 +0000 (21:08 -0500)
src/seekable.rs
src/seekable/filter_map.rs

index 94aa3163129069127b480fc575530bb612b58304..ffa8161a5b02dceef08e7f4e0dd54c668e835f94 100644 (file)
@@ -3,7 +3,7 @@ mod filter_map;
 mod merge;
 mod vec;
 use coalesce::Coalesce;
-use filter_map::FilterMap;
+use filter_map::FilterMapValue;
 use merge::Merger;
 pub use vec::SeekableVec;
 
@@ -14,11 +14,11 @@ pub trait Seekable: Sized {
     fn next(&mut self) -> Option<(Self::Key, Self::Value)>;
     fn seek(&mut self, key: &Self::Key);
 
-    fn filter_map<F, V>(self, func: F) -> FilterMap<Self, F, V>
+    fn filter_mapv<F, V>(self, func: F) -> FilterMapValue<Self, F, V>
     where
         F: FnMut(&Self::Key, Self::Value, &mut Self) -> Option<V>,
     {
-        FilterMap { next: self, func }
+        FilterMapValue { next: self, func }
     }
 
     fn merge<L>(iter: L) -> Merger<Self>
index 2246f6b0925877b20db8d005fa5c3feb2b1e157a..586868edefc5079a21997a75c2994cd53aa7911b 100644 (file)
@@ -1,6 +1,6 @@
 use crate::seekable::{Iter, Seekable};
 
-pub struct FilterMap<S, F, V>
+pub struct FilterMapValue<S, F, V>
 where
     S: Seekable,
     F: FnMut(&S::Key, S::Value, &mut S) -> Option<V>,
@@ -9,7 +9,7 @@ where
     pub(crate) func: F,
 }
 
-impl<S, F, V> IntoIterator for FilterMap<S, F, V>
+impl<S, F, V> IntoIterator for FilterMapValue<S, F, V>
 where
     S: Seekable,
     F: FnMut(&S::Key, S::Value, &mut S) -> Option<V>,
@@ -21,7 +21,7 @@ where
     }
 }
 
-impl<S, F, V> Seekable for FilterMap<S, F, V>
+impl<S, F, V> Seekable for FilterMapValue<S, F, V>
 where
     S: Seekable,
     F: FnMut(&S::Key, S::Value, &mut S) -> Option<V>,
@@ -47,6 +47,56 @@ where
     }
 }
 
+pub struct FilterMapKey<S, F, FS, K>
+where
+    S: Seekable,
+    F: FnMut(&S::Key, &S::Value, &mut S) -> Option<K>,
+    FS: FnMut(&K, &mut S),
+{
+    pub(crate) next: S,
+    pub(crate) func: F,
+    pub(crate) seekfunc: FS,
+}
+
+impl<S, F, FS, K> IntoIterator for FilterMapKey<S, F, FS, K>
+where
+    S: Seekable,
+    F: FnMut(&S::Key, &S::Value, &mut S) -> Option<K>,
+    FS: FnMut(&K, &mut S),
+{
+    type Item = (K, S::Value);
+    type IntoIter = Iter<Self>;
+    fn into_iter(self) -> Self::IntoIter {
+        Iter(self)
+    }
+}
+
+impl<S, F, FS, K> Seekable for FilterMapKey<S, F, FS, K>
+where
+    S: Seekable,
+    F: FnMut(&S::Key, &S::Value, &mut S) -> Option<K>,
+    FS: FnMut(&K, &mut S),
+{
+    type Key = K;
+    type Value = S::Value;
+
+    fn next(&mut self) -> Option<(Self::Key, Self::Value)> {
+        loop {
+            match self.next.next() {
+                None => return None,
+                Some((k, v)) => {
+                    if let Some(newk) = (self.func)(&k, &v, &mut self.next) {
+                        return Some((newk, v));
+                    }
+                }
+            }
+        }
+    }
+    fn seek(&mut self, key: &Self::Key) {
+        (self.seekfunc)(key, &mut self.next);
+    }
+}
+
 #[cfg(test)]
 mod test {
     use crate::seekable::SeekableVec;
@@ -59,7 +109,7 @@ mod test {
         let sv = SeekableVec::from(v.clone().into_iter().collect::<Vec<i32>>());
         v.sort();
         assert_eq!(
-            sv.filter_map(|_k, _v, _s| Some("hello"))
+            sv.filter_mapv(|_k, _v, _s| Some("hello"))
                 .into_iter()
                 .cmp(v.into_iter().map(|i| (i, "hello"))),
             Ordering::Equal
@@ -72,7 +122,7 @@ mod test {
             .into_iter()
             .map(|i| (i, "foo"))
             .collect::<Vec<(i32, &str)>>();
-        let mut sv = SeekableVec::from(v.clone()).filter_map(|k, _v, s| {
+        let mut sv = SeekableVec::from(v.clone()).filter_mapv(|k, _v, s| {
             if k % 5 == 0 {
                 return None;
             }