From: Chris Mikkelson Date: Sat, 20 Jul 2024 01:56:22 +0000 (-0500) Subject: WIP of attempt to make a generic source X-Git-Url: https://git.mikk.net/?a=commitdiff_plain;h=40ad30a64225e8733821b47687af82dc800e2a0e;p=mtbl-rs WIP of attempt to make a generic source --- diff --git a/src/source.rs b/src/source.rs index 4672f9c..c6262b0 100644 --- a/src/source.rs +++ b/src/source.rs @@ -1,5 +1,4 @@ use crate::Entry; -use std::io; use std::iter::Iterator; use std::marker::PhantomData; @@ -117,14 +116,14 @@ impl Iter for RangeIter { } } -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; 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; type Prefix = Box; type Range = Box; @@ -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> + 'a>, - PhantomData<&'a u8>, -); +trait GenSource<'a>: + Source<'a, It = Box> + + Ranges<'a, Get = Box, Prefix = Box, Range = Box> +{ +} + +struct GenericSource<'a>(Box + 'a>, PhantomData<&'a u8>); impl<'a> GenericSource<'a> { fn from + 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; + type Prefix = Box; + type Range = Box; + 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); @@ -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]