From: Chris Mikkelson Date: Mon, 22 Jul 2024 13:58:21 +0000 (-0500) Subject: generic sources working, sort of, in test X-Git-Url: https://git.mikk.net/?a=commitdiff_plain;h=0100af18fb33271a758d5a351f549aa393cf6dec;p=mtbl-rs generic sources working, sort of, in test --- diff --git a/src/source.rs b/src/source.rs index ee341bd..d1e98a1 100644 --- a/src/source.rs +++ b/src/source.rs @@ -118,6 +118,8 @@ impl Iter for RangeIter { #[cfg(test)] pub mod test { + use std::marker::PhantomData; + use super::{DefaultSource, Entry, Iter, IterSource, Source}; pub struct TestSource(pub Vec); @@ -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; - 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 + '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::::new(); + // s2 = Vec::::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::::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(); } }