use crate::dupsort::DupsortIter;
use crate::filter::FilterIter;
+use crate::map::MapIter;
use crate::merge::MergeIter;
use crate::Entry;
use std::cmp::Ordering;
{
FilterIter::new(self, filter_func)
}
+
+ fn map_func<F, O>(self, map_func: F) -> MapIter<Self, F, O>
+ where
+ F: FnMut(Self::Item) -> O,
+ Self: Sized,
+ {
+ MapIter::new(self, map_func)
+ }
}
impl<I: SeekableIter + ?Sized> SeekableIter for Box<I> {
--- /dev/null
+use crate::{SeekableIter, Source};
+
+pub struct MapIter<I, F, O>
+where
+ I: SeekableIter,
+ F: FnMut(I::Item) -> O,
+{
+ iter: I,
+ mapf: F,
+}
+
+impl<I, F, O> MapIter<I, F, O>
+where
+ I: SeekableIter,
+ F: FnMut(I::Item) -> O,
+{
+ pub fn new(iter: I, mapf: F) -> Self {
+ Self { iter, mapf }
+ }
+}
+
+impl<I, F, O> Iterator for MapIter<I, F, O>
+where
+ I: SeekableIter,
+ F: FnMut(I::Item) -> O,
+{
+ type Item = O;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ let item = self.iter.next()?;
+ Some((self.mapf)(item))
+ }
+}
+
+impl<I, F, O> SeekableIter for MapIter<I, F, O>
+where
+ I: SeekableIter,
+ F: FnMut(I::Item) -> O,
+{
+ fn seek(&mut self, key: &[u8]) {
+ self.iter.seek(key);
+ }
+}
+
+pub struct MapSource<S, O>
+where
+ S: Source,
+{
+ source: S,
+ #[allow(clippy::type_complexity)]
+ map: Box<dyn Fn(S::Item) -> O>,
+}
+
+impl<S, O> MapSource<S, O>
+where
+ S: Source,
+{
+ pub fn new<F>(source: S, map: F) -> Self
+ where
+ F: Fn(S::Item) -> O + 'static,
+ {
+ Self {
+ source,
+ map: Box::new(map),
+ }
+ }
+}
+
+impl<S, O> Source for MapSource<S, O>
+where
+ S: Source,
+{
+ type Item = O;
+ fn iter(&self) -> impl SeekableIter<Item = Self::Item> {
+ self.source.iter().map_func(&self.map)
+ }
+}
+
+#[cfg(test)]
+mod test {
+ use crate::source::test_source::TestSource;
+ use crate::Entry;
+ use crate::Source;
+
+ struct CompVec(Vec<u8>);
+ impl PartialEq<[u8]> for CompVec {
+ fn eq(&self, other: &[u8]) -> bool {
+ self.0.as_slice().eq(other)
+ }
+ }
+ impl PartialOrd<[u8]> for CompVec {
+ fn partial_cmp(&self, other: &[u8]) -> Option<std::cmp::Ordering> {
+ self.0.as_slice().partial_cmp(other)
+ }
+ }
+
+ #[test]
+ fn test_mapsource() {
+ let ts = TestSource((0u8..10).map(|i| Entry::new(vec![i], vec![])).collect())
+ .map(|e| CompVec(Vec::from(e.key())));
+ assert_eq!(
+ ts.iter().map(|cv| cv.0).collect::<Vec<_>>(),
+ (0u8..10).map(|i| vec![i]).collect::<Vec<_>>()
+ );
+ assert_eq!(
+ ts.get_range(&[2u8], &[7u8])
+ .map(|cv| cv.0)
+ .collect::<Vec<_>>(),
+ (2u8..8)
+ .map(|i| {
+ println!("{i}");
+ vec![i]
+ })
+ .collect::<Vec<_>>()
+ )
+ }
+}
use crate::dupsort::DupsortSource;
use crate::filter::FilterSource;
use crate::iter::{PrefixIter, RangeIter};
+use crate::map::MapSource;
use crate::merge::MergeSource;
use crate::{Entry, SeekableIter};
FilterSource::new(self, filter_func)
}
+ fn map<F, O>(self, map_func: F) -> MapSource<Self, O>
+ where
+ Self: Sized,
+ F: Fn(Self::Item) -> O + 'static,
+ {
+ MapSource::new(self, map_func)
+ }
+
fn into_boxed(self) -> Box<dyn DynSource<Item = Self::Item>>
where
Self: Sized + 'static,