Skip to content

Commit c5a123b

Browse files
LorenzSchuelercuviper
authored andcommitted
add StreamingIteratorMut::flatten and Flatten
1 parent f93531c commit c5a123b

File tree

1 file changed

+69
-1
lines changed

1 file changed

+69
-1
lines changed

src/lib.rs

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
#![warn(missing_docs)]
4141
#![cfg_attr(not(feature = "std"), no_std)]
4242

43-
use core::cmp;
43+
use core::{cmp, marker::PhantomData};
4444

4545
mod sources;
4646
pub use crate::sources::{convert, Convert};
@@ -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, Self::Item>
599+
where
600+
Self: Sized,
601+
Self::Item: StreamingIterator + Sized,
602+
{
603+
Flatten {
604+
iter: self,
605+
_inner: PhantomData,
606+
}
607+
}
595608
}
596609

597610
impl<'a, I: ?Sized> StreamingIteratorMut for &'a mut I
@@ -1259,6 +1272,61 @@ where
12591272
}
12601273
}
12611274

1275+
/// A streaming iterator that flattens nested streaming iterators.
1276+
#[derive(Debug)]
1277+
pub struct Flatten<I, J> {
1278+
iter: I,
1279+
_inner: PhantomData<J>,
1280+
}
1281+
1282+
impl<I, J> StreamingIterator for Flatten<I, J>
1283+
where
1284+
I: StreamingIteratorMut<Item = J>,
1285+
J: StreamingIterator,
1286+
{
1287+
type Item = J::Item;
1288+
1289+
#[inline]
1290+
fn advance(&mut self) {
1291+
loop {
1292+
if let Some(ref mut iter) = self.iter.get_mut() {
1293+
iter.advance();
1294+
if !iter.is_done() {
1295+
break;
1296+
}
1297+
}
1298+
self.iter.advance();
1299+
if self.iter.is_done() {
1300+
break;
1301+
}
1302+
}
1303+
}
1304+
1305+
#[inline]
1306+
fn is_done(&self) -> bool {
1307+
match self.iter.get() {
1308+
Some(iter) => iter.is_done(),
1309+
None => true,
1310+
}
1311+
}
1312+
1313+
#[inline]
1314+
fn get(&self) -> Option<&Self::Item> {
1315+
self.iter.get().and_then(|iter| iter.get())
1316+
}
1317+
}
1318+
1319+
impl<I, J> StreamingIteratorMut for Flatten<I, J>
1320+
where
1321+
I: StreamingIteratorMut<Item = J>,
1322+
J: StreamingIteratorMut,
1323+
{
1324+
#[inline]
1325+
fn get_mut(&mut self) -> Option<&mut Self::Item> {
1326+
self.iter.get_mut().and_then(J::get_mut)
1327+
}
1328+
}
1329+
12621330
/// A regular, non-streaming iterator which both filters and maps elements of a streaming iterator with a closure.
12631331
#[derive(Debug)]
12641332
pub struct FilterMapDeref<I, F> {

0 commit comments

Comments
 (0)