#[cfg(test)]
pub mod test {
+ use std::marker::PhantomData;
+
use super::{DefaultSource, Entry, Iter, IterSource, Source};
pub struct TestSource(pub Vec<Entry>);
// 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'
}
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 {
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();
}
}