Skip to content

Commit 8f433f6

Browse files
authored
Merge pull request #27 from LorenzSchueler/master
add StreamingIteratorMut::flatten
2 parents a0f4ee0 + 0cd6466 commit 8f433f6

File tree

1 file changed

+115
-0
lines changed

1 file changed

+115
-0
lines changed

src/lib.rs

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -592,6 +592,19 @@ pub trait StreamingIteratorMut: StreamingIterator {
592592
{
593593
MapDerefMut { it: self, f }
594594
}
595+
596+
/// Creates an iterator which flattens nested streaming iterators.
597+
#[inline]
598+
fn flatten(self) -> Flatten<Self>
599+
where
600+
Self: Sized,
601+
Self::Item: StreamingIterator,
602+
{
603+
Flatten {
604+
iter: self,
605+
first: true,
606+
}
607+
}
595608
}
596609

597610
impl<'a, I: ?Sized> StreamingIteratorMut for &'a mut I
@@ -1268,6 +1281,80 @@ where
12681281
}
12691282
}
12701283

1284+
/// A streaming iterator that flattens nested streaming iterators.
1285+
#[derive(Debug)]
1286+
pub struct Flatten<I> {
1287+
iter: I,
1288+
first: bool,
1289+
}
1290+
1291+
impl<I> StreamingIterator for Flatten<I>
1292+
where
1293+
I: StreamingIteratorMut,
1294+
I::Item: StreamingIterator,
1295+
{
1296+
type Item = <I::Item as StreamingIterator>::Item;
1297+
1298+
#[inline]
1299+
fn advance(&mut self) {
1300+
if self.first {
1301+
self.first = false;
1302+
self.iter.advance();
1303+
}
1304+
while let Some(iter) = self.iter.get_mut() {
1305+
iter.advance();
1306+
if !iter.is_done() {
1307+
break;
1308+
}
1309+
self.iter.advance(); // since we got Some, self.iter is not done and can be advanced
1310+
}
1311+
}
1312+
1313+
#[inline]
1314+
fn is_done(&self) -> bool {
1315+
match self.iter.get() {
1316+
Some(iter) => iter.is_done(),
1317+
None => true,
1318+
}
1319+
}
1320+
1321+
#[inline]
1322+
fn get(&self) -> Option<&Self::Item> {
1323+
self.iter.get().and_then(I::Item::get)
1324+
}
1325+
1326+
#[inline]
1327+
fn fold<Acc, Fold>(self, init: Acc, mut fold: Fold) -> Acc
1328+
where
1329+
Self: Sized,
1330+
Fold: FnMut(Acc, &Self::Item) -> Acc,
1331+
{
1332+
self.iter
1333+
.fold_mut(init, |acc, item| item.fold(acc, &mut fold))
1334+
}
1335+
}
1336+
1337+
impl<I> StreamingIteratorMut for Flatten<I>
1338+
where
1339+
I: StreamingIteratorMut,
1340+
I::Item: StreamingIteratorMut,
1341+
{
1342+
#[inline]
1343+
fn get_mut(&mut self) -> Option<&mut Self::Item> {
1344+
self.iter.get_mut().and_then(I::Item::get_mut)
1345+
}
1346+
1347+
#[inline]
1348+
fn fold_mut<Acc, Fold>(self, init: Acc, mut fold: Fold) -> Acc
1349+
where
1350+
Self: Sized,
1351+
Fold: FnMut(Acc, &mut Self::Item) -> Acc,
1352+
{
1353+
self.iter
1354+
.fold_mut(init, |acc, item| item.fold_mut(acc, &mut fold))
1355+
}
1356+
}
1357+
12711358
/// A regular, non-streaming iterator which both filters and maps elements of a streaming iterator with a closure.
12721359
#[derive(Debug)]
12731360
pub struct FilterMapDeref<I, F> {
@@ -2549,6 +2636,34 @@ mod test {
25492636
test(it, &[0, 1, 2, 3, 4, 5]);
25502637
}
25512638

2639+
#[test]
2640+
fn flatten() {
2641+
let mut items = [
2642+
convert_ref([].as_ref()),
2643+
convert_ref([1].as_ref()),
2644+
convert_ref([].as_ref()),
2645+
convert_ref([2, 3].as_ref()),
2646+
convert_ref([].as_ref()),
2647+
];
2648+
let it = convert_mut(&mut items).flatten();
2649+
2650+
test(it, &[1, 2, 3]);
2651+
}
2652+
2653+
#[test]
2654+
fn flatten_unsized() {
2655+
type DynI32 = dyn StreamingIterator<Item = i32>;
2656+
let mut items = [
2657+
&mut once(1) as &mut DynI32,
2658+
&mut empty(),
2659+
&mut convert(2..=3),
2660+
];
2661+
let iters = items.iter_mut().map(|iter| &mut **iter);
2662+
let it = convert_mut(iters).flatten();
2663+
2664+
test(it, &[1, 2, 3]);
2665+
}
2666+
25522667
#[test]
25532668
fn nth() {
25542669
let items = [0, 1];

0 commit comments

Comments
 (0)