]> git.mikk.net Git - mtbl-rs/commitdiff
generic sources working, sort of, in test
authorChris Mikkelson <cmikk@fsi.io>
Mon, 22 Jul 2024 13:58:21 +0000 (08:58 -0500)
committerChris Mikkelson <cmikk@fsi.io>
Mon, 22 Jul 2024 13:58:21 +0000 (08:58 -0500)
src/source.rs

index ee341bd7472d78923433bc122f36f20f16e7ef9c..d1e98a18e6bb20d50abb6259ca48c9b39aec1a04 100644 (file)
@@ -118,6 +118,8 @@ impl<I: Iter> Iter for RangeIter<I> {
 
 #[cfg(test)]
 pub mod test {
+    use std::marker::PhantomData;
+
     use super::{DefaultSource, Entry, Iter, IterSource, Source};
 
     pub struct TestSource(pub Vec<Entry>);
@@ -189,7 +191,10 @@ pub mod test {
         // let w = SourceWrapper(test_source(), PhantomData);
         // let s: &dyn GenSource = &w;
 
-        let s = GenSourceS::from(test_source());
+        let ts = test_source();
+        let ws = SourceWrapper(ts, PhantomData);
+        let s: &dyn GenSource = &ws;
+
         //let s = test_source();
 
         // borrowed value 's' doesn't live long enough'
@@ -222,13 +227,11 @@ pub mod test {
     }
 
     type GenIter<'a> = Box<dyn Iter + 'a>;
-    struct GenSourceS<'a> {
-        inner: Box<
-            dyn Source<'a, It = GenIter, Get = GenIter, Prefix = GenIter, Range = GenIter> + 'a,
-        >,
+    trait GenSource<'a>:
+        Source<'a, It = GenIter<'a>, Get = GenIter<'a>, Prefix = GenIter<'a>, Range = GenIter<'a>>
+    {
     }
-    use std::marker::PhantomData;
-    struct SourceWrapper<'a, S: Source<'a>>(S, PhantomData<&'a u8>);
+    struct SourceWrapper<'a, S: Source<'a>>(S, PhantomData<&'a S>);
     impl<'a, S: Source<'a>> IterSource<'a> for SourceWrapper<'a, S> {
         type It = GenIter<'a>;
         fn iter(&'a self) -> Self::It {
@@ -249,40 +252,41 @@ pub mod test {
             Box::new(self.0.get_range(start, end))
         }
     }
+    impl<'a, S: Source<'a>> GenSource<'a> for SourceWrapper<'a, S> {}
 
-    impl<'a> GenSourceS<'a> {
-        fn from<S: Source<'a> + 'a>(source: S) -> Self {
-            GenSourceS {
-                inner: Box::new(SourceWrapper(source, PhantomData)),
-            }
-        }
-    }
-    impl<'a> IterSource<'a> for GenSourceS<'a> {
+    struct GSource<'a>(&'a dyn GenSource<'a>);
+    impl<'a> IterSource<'a> for GSource<'a> {
         type It = GenIter<'a>;
         fn iter(&'a self) -> Self::It {
-            Box::new(self.inner.iter())
+            self.0.iter()
         }
     }
-    impl<'a> Source<'a> for GenSourceS<'a> {
-        type Get = GenIter<'a>;
-        fn get(&'a self, key: &[u8]) -> Self::Get {
-            Box::new(self.inner.get(key))
-        }
-        type Prefix = GenIter<'a>;
-        fn get_prefix(&'a self, prefix: &[u8]) -> Self::Prefix {
-            Box::new(self.inner.get_prefix(prefix))
-        }
-        type Range = GenIter<'a>;
-        fn get_range(&'a self, start: &[u8], end: &[u8]) -> Self::Range {
-            Box::new(self.inner.get_range(start, end))
-        }
-    }
-
+    impl<'a> DefaultSource<'a> for GSource<'a> {}
+
+    // Note: lesson learned here is:
+    //   1) Box lifetime is still testing my understanding
+    //   2) Mixed mergers / generic iteration is still doable
+    //      with a struct wrapping `&'a dyn GenSource<'a>`,
+    //      requiring the concrete Source to be separately
+    //      managed.
+    //   3) In practice, this would amount to
+    //        s1 = Vec::<Source1>::new();
+    //        s2 = Vec::<Source2>::new();
+    //        ws1 = s1.map(|s| GenWrap::from(s));
+    //        ws2 = s2.map(|s| GenWrap::from(s));
+    //        combined = Vec::new()
+    //        ws1.for_each(|s| combined.push(GenSource(s)));
+    //        ws2.for_each(|s| combined.push(GenSource(s)));
+    //        s = Merger::from(combined);
     #[test]
     fn test_dyn_source() {
-        let b = GenSourceS::from(test_source());
-        {
-            b.iter();
-        }
+        use crate::merger::Merger;
+        let mut v = Vec::<GSource>::new();
+        let ts = test_source();
+        let ws = SourceWrapper(ts, PhantomData);
+        v.push(GSource(&ws));
+        //let gs: &dyn GenSource = &ws;
+        let gs = Merger::from(v);
+        gs.iter();
     }
 }