]> git.mikk.net Git - mtbl-rs/commitdiff
WIP attempt to make dyn compatible source abstraction.
authorChris Mikkelson <chris@mikk.net>
Mon, 7 Apr 2025 18:43:59 +0000 (13:43 -0500)
committerChris Mikkelson <chris@mikk.net>
Mon, 7 Apr 2025 18:43:59 +0000 (13:43 -0500)
src/iter.rs
src/merger.rs
src/source.rs

index 201172b95778cc09cf7a34ba9dae44a2b02e956a..9152683bab3e4511b54be2979596f9c9bfe25fbe 100644 (file)
@@ -33,6 +33,12 @@ pub trait SeekableIter: Iterator {
     }
 }
 
+impl<I: SeekableIter + ?Sized> SeekableIter for Box<I> {
+    fn seek(&mut self, key: &[u8]) {
+        self.as_mut().seek(key);
+    }
+}
+
 pub struct PrefixIter<I>
 where
     I: SeekableIter,
index cd7d7b28c7ec2ae7b0796925258230e702ab27b4..4b65716205db17a74960f15964f59c15caef553a 100644 (file)
@@ -165,7 +165,11 @@ mod test {
     #[test]
     fn test_merge() {
         let range = 1..8;
-        let iters: Vec<_> = range.clone().map(test_source).collect();
+        let iters: Vec<_> = range
+            .clone()
+            .map(test_source)
+            .map(|s| s.into_boxed())
+            .collect();
         let s = Merger::from(iters);
         let mut v = Vec::<u8>::new();
         for i in range {
index 79068a754b73b59198bd45416512df5ff7f78550..da59f93a940b60a5011c7dcc3727a5438076f622 100644 (file)
@@ -42,6 +42,36 @@ pub trait Source<'a> {
     {
         FilterSource::new(self, filter_func)
     }
+
+    fn into_boxed(
+        self,
+    ) -> Box<
+        dyn Source<'a, Item = Self::Item, Iter = Box<dyn 'a + SeekableIter<Item = Self::Item>>>
+            + 'a,
+    >
+    where
+        Self: Sized + 'a,
+    {
+        Box::new(BoxedSource::<'a>(self, std::marker::PhantomData))
+    }
+}
+
+impl<'a, S: Source<'a> + ?Sized + 'a> Source<'a> for Box<S> {
+    type Item = S::Item;
+    type Iter = Box<dyn SeekableIter<Item = Self::Item> + 'a>;
+    fn iter(&'a self) -> Self::Iter {
+        Box::new(self.as_ref().iter())
+    }
+}
+
+struct BoxedSource<'a, S: Source<'a>>(S, std::marker::PhantomData<&'a S>);
+impl<'a, S: Source<'a>> Source<'a> for BoxedSource<'a, S> {
+    type Item = S::Item;
+    type Iter = Box<dyn SeekableIter<Item = S::Item> + 'a>;
+
+    fn iter(&'a self) -> Self::Iter {
+        Box::new(self.0.iter())
+    }
 }
 
 pub struct VecIter<'a> {