Skip to content

Commit 0831788

Browse files
committed
Add map_deref and filter_map_deref
1 parent 8e7b44a commit 0831788

File tree

1 file changed

+123
-0
lines changed

1 file changed

+123
-0
lines changed

src/lib.rs

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,16 @@ pub trait StreamingIterator {
193193
}
194194
}
195195

196+
/// Creates a regular, non-streaming iterator which both filters and maps by applying a closure to elements.
197+
#[inline]
198+
fn filter_map_deref<B, F>(self, f: F) -> FilterMapDeref<Self, F>
199+
where
200+
Self: Sized,
201+
F: FnMut(&Self::Item) -> Option<B>,
202+
{
203+
FilterMapDeref { it: self, f }
204+
}
205+
196206
/// Returns the first element of the iterator that satisfies the predicate.
197207
#[inline]
198208
fn find<F>(&mut self, mut f: F) -> Option<&Self::Item>
@@ -255,6 +265,16 @@ pub trait StreamingIterator {
255265
}
256266
}
257267

268+
/// Creates a regular, non-streaming iterator which transforms elements of this iterator by passing them to a closure.
269+
#[inline]
270+
fn map_deref<B, F>(self, f: F) -> MapDeref<Self, F>
271+
where
272+
Self: Sized,
273+
F: FnMut(&Self::Item) -> B,
274+
{
275+
MapDeref { it: self, f }
276+
}
277+
258278
/// Creates an iterator which transforms elements of this iterator by passing them to a closure.
259279
///
260280
/// Unlike `map`, this method takes a closure that returns a reference into the original value.
@@ -1013,6 +1033,47 @@ where
10131033
}
10141034
}
10151035

1036+
/// An regular, non-streaming iterator which both filters and maps elements of a streaming iterator with a closure.
1037+
#[derive(Debug)]
1038+
pub struct FilterMapDeref<I, F> {
1039+
it: I,
1040+
f: F,
1041+
}
1042+
1043+
impl<I, B, F> Iterator for FilterMapDeref<I, F>
1044+
where
1045+
I: StreamingIterator,
1046+
F: FnMut(&I::Item) -> Option<B>,
1047+
{
1048+
type Item = B;
1049+
1050+
fn next(&mut self) -> Option<Self::Item> {
1051+
while let Some(item) = self.it.next() {
1052+
if let Some(mapped) = (self.f)(item) {
1053+
return Some(mapped);
1054+
}
1055+
}
1056+
1057+
None
1058+
}
1059+
}
1060+
1061+
impl<I, B, F> DoubleEndedIterator for FilterMapDeref<I, F>
1062+
where
1063+
I: DoubleEndedStreamingIterator,
1064+
F: FnMut(&I::Item) -> Option<B>,
1065+
{
1066+
fn next_back(&mut self) -> Option<B> {
1067+
while let Some(item) = self.it.next_back() {
1068+
if let Some(mapped) = (self.f)(item) {
1069+
return Some(mapped);
1070+
}
1071+
}
1072+
1073+
None
1074+
}
1075+
}
1076+
10161077
#[derive(Copy, Clone, Debug)]
10171078
enum FuseState {
10181079
Start,
@@ -1213,6 +1274,42 @@ where
12131274
}
12141275
}
12151276

1277+
/// A regular, non-streaming iterator which transforms the elements of a streaming iterator.
1278+
#[derive(Debug)]
1279+
pub struct MapDeref<I, F> {
1280+
it: I,
1281+
f: F,
1282+
}
1283+
1284+
impl<I, B, F> Iterator for MapDeref<I, F>
1285+
where
1286+
I: StreamingIterator,
1287+
F: FnMut(&I::Item) -> B,
1288+
{
1289+
type Item = B;
1290+
1291+
#[inline]
1292+
fn next(&mut self) -> Option<Self::Item> {
1293+
self.it.next().map(&mut self.f)
1294+
}
1295+
1296+
#[inline]
1297+
fn size_hint(&self) -> (usize, Option<usize>) {
1298+
self.it.size_hint()
1299+
}
1300+
}
1301+
1302+
impl<I, B, F> DoubleEndedIterator for MapDeref<I, F>
1303+
where
1304+
I: DoubleEndedStreamingIterator,
1305+
F: FnMut(&I::Item) -> B,
1306+
{
1307+
#[inline]
1308+
fn next_back(&mut self) -> Option<Self::Item> {
1309+
self.it.next_back().map(&mut self.f)
1310+
}
1311+
}
1312+
12161313
/// A streaming iterator which transforms the elements of a streaming iterator.
12171314
#[derive(Debug)]
12181315
pub struct MapRef<I, F> {
@@ -1611,6 +1708,17 @@ mod test {
16111708
assert_eq!(it.get(), None);
16121709
}
16131710

1711+
fn test_deref<I>(mut it: I, expected: &[I::Item])
1712+
where
1713+
I: Iterator,
1714+
I::Item: Sized + PartialEq + Debug,
1715+
{
1716+
for item in expected {
1717+
assert_eq!(it.next().as_ref(), Some(item));
1718+
}
1719+
assert_eq!(it.next(), None)
1720+
}
1721+
16141722
#[test]
16151723
fn all() {
16161724
let items = [0, 1, 2];
@@ -1769,6 +1877,13 @@ mod test {
17691877
test(it, &items);
17701878
}
17711879

1880+
#[test]
1881+
fn map_deref() {
1882+
let items = [0, 1];
1883+
let it = convert(items.iter().map(|&i| i as usize)).map_deref(|&i| i as i32);
1884+
test_deref(it, &items);
1885+
}
1886+
17721887
#[test]
17731888
fn map_ref() {
17741889
#[derive(Clone)]
@@ -1803,6 +1918,14 @@ mod test {
18031918
test(it, &[0, 2, 4])
18041919
}
18051920

1921+
#[test]
1922+
fn filter_map_deref() {
1923+
let items = [0u8, 1, 1, 2, 4];
1924+
let it =
1925+
convert(items.iter()).filter_map_deref(|&&i| if i % 2 == 0 { Some(i) } else { None });
1926+
test_deref(it, &[0, 2, 4])
1927+
}
1928+
18061929
#[test]
18071930
fn find() {
18081931
let items = [0, 1];

0 commit comments

Comments
 (0)