]> git.mikk.net Git - mtbl-rs/commitdiff
WIP of attempt to make a generic source
authorChris Mikkelson <cmikk@fsi.io>
Sat, 20 Jul 2024 01:56:22 +0000 (20:56 -0500)
committerChris Mikkelson <cmikk@fsi.io>
Sat, 20 Jul 2024 01:56:22 +0000 (20:56 -0500)
src/source.rs

index 4672f9c945ca786d26f48e8b3cd9e57b49010302..c6262b0c38b038ec2c4088f82b9a9ce2cfa72a08 100644 (file)
@@ -1,5 +1,4 @@
 use crate::Entry;
-use std::io;
 use std::iter::Iterator;
 use std::marker::PhantomData;
 
@@ -117,14 +116,14 @@ impl<I: Iter> Iter for RangeIter<I> {
     }
 }
 
-struct WrapSource<'a, S: Source<'a> + Ranges<'a>>(S, PhantomData<&'a S>);
-impl<'a, S: Source<'a> + Ranges<'a>> Source<'a> for WrapSource<'a, S> {
+pub struct WrapSource<'a, S: Source<'a> + Ranges<'a> + 'a>(S, PhantomData<&'a S>);
+impl<'a, S: Source<'a> + Ranges<'a> + 'a> Source<'a> for WrapSource<'a, S> {
     type It = Box<dyn Iter + 'a>;
     fn iter(&'a self) -> Self::It {
         Box::new(self.0.iter())
     }
 }
-impl<'a, S: Source<'a> + Ranges<'a>> Ranges<'a> for WrapSource<'a, S> {
+impl<'a, S: Source<'a> + Ranges<'a> + 'a> Ranges<'a> for WrapSource<'a, S> {
     type Get = Box<dyn Iter + 'a>;
     type Prefix = Box<dyn Iter + 'a>;
     type Range = Box<dyn Iter + 'a>;
@@ -139,13 +138,18 @@ impl<'a, S: Source<'a> + Ranges<'a>> Ranges<'a> for WrapSource<'a, S> {
         Box::new(self.0.get_range(start, end))
     }
 }
+impl<'a, S: Source<'a> + Ranges<'a> + 'a> GenSource<'a> for WrapSource<'a, S> {}
 
-struct GenericSource<'a>(
-    Box<dyn Source<'a, It = Box<dyn Iter + 'a>> + 'a>,
-    PhantomData<&'a u8>,
-);
+trait GenSource<'a>:
+    Source<'a, It = Box<dyn Iter + 'a>>
+    + Ranges<'a, Get = Box<dyn Iter + 'a>, Prefix = Box<dyn Iter + 'a>, Range = Box<dyn Iter + 'a>>
+{
+}
+
+struct GenericSource<'a>(Box<dyn GenSource<'a> + 'a>, PhantomData<&'a u8>);
 impl<'a> GenericSource<'a> {
     fn from<S: Source<'a> + Ranges<'a> + 'a>(source: S) -> Self {
+        panic!("GenericSource::from running");
         GenericSource(Box::new(WrapSource(source, PhantomData)), PhantomData)
     }
 }
@@ -156,11 +160,24 @@ impl<'a> Source<'a> for GenericSource<'a> {
         self.0.iter()
     }
 }
-impl<'a> DefaultRanges for GenericSource<'a> {}
+impl<'a> Ranges<'a> for GenericSource<'a> {
+    type Get = Box<dyn Iter + 'a>;
+    type Prefix = Box<dyn Iter + 'a>;
+    type Range = Box<dyn Iter + 'a>;
+    fn get(&'a self, key: &[u8]) -> Self::Get {
+        self.0.get(key)
+    }
+    fn get_prefix(&'a self, prefix: &[u8]) -> Self::Prefix {
+        self.0.get_prefix(prefix)
+    }
+    fn get_range(&'a self, start: &[u8], end: &[u8]) -> Self::Range {
+        self.0.get_range(start, end)
+    }
+}
 
 #[cfg(test)]
 pub mod test {
-    use super::{DefaultRanges, Entry, Iter, Ranges, Source};
+    use super::{DefaultRanges, Entry, GenericSource, Iter, Ranges, Source};
 
     pub struct TestSource(pub Vec<Entry>);
 
@@ -216,7 +233,13 @@ pub mod test {
 
     #[test]
     fn test_source_iter() {
+        // WrapSource used directly works, as does test_source()
+        // let s = WrapSource(test_source(), PhantomData);
         let s = test_source();
+        // But if wrapped in GenericSource, complains of
+        //     borrowed value does not live long enough
+        // at the first s.iter() call
+        let _ = GenericSource::from(test_source());
         assert_eq!(
             Vec::from_iter(s.iter().map(|e| e.value[0])),
             vec![0, 1, 2, 3, 4]