Skip to content

Commit 95f909d

Browse files
authored
Merge pull request #19 from FauxFaux/feat/is_done
feat: is_done() ~= .get().is_none()
2 parents 4d8715a + 81a10a9 commit 95f909d

File tree

1 file changed

+148
-25
lines changed

1 file changed

+148
-25
lines changed

src/lib.rs

Lines changed: 148 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@
3838
//! just a required `next` method, operations like `filter` would be impossible to define.
3939
#![doc(html_root_url = "https://docs.rs/streaming-iterator/0.1")]
4040
#![warn(missing_docs)]
41+
// for compatibility down to Rust 1.19 (`dyn` needs 1.27)
42+
#![allow(unknown_lints, bare_trait_objects)]
4143
#![cfg_attr(not(feature = "std"), no_std)]
4244

4345
#[cfg(feature = "std")]
@@ -92,6 +94,11 @@ pub trait StreamingIterator {
9294
(0, None)
9395
}
9496

97+
/// Checks if `get()` will return `None`.
98+
fn is_done(&self) -> bool {
99+
self.get().is_none()
100+
}
101+
95102
/// Determines if all elements of the iterator satisfy a predicate.
96103
#[inline]
97104
fn all<F>(&mut self, mut f: F) -> bool
@@ -223,9 +230,11 @@ pub trait StreamingIterator {
223230
loop {
224231
self.advance();
225232
match self.get() {
226-
Some(i) => if f(i) {
227-
break;
228-
},
233+
Some(i) => {
234+
if f(i) {
235+
break;
236+
}
237+
}
229238
None => break,
230239
}
231240
}
@@ -288,6 +297,10 @@ pub trait StreamingIterator {
288297
/// Creates an iterator which transforms elements of this iterator by passing them to a closure.
289298
///
290299
/// Unlike `map`, this method takes a closure that returns a reference into the original value.
300+
///
301+
/// The mapping function is only guaranteed to be called at some point before an element
302+
/// is actually consumed. This allows an expensive mapping function to be ignored
303+
/// during skipping (e.g. `nth`).
291304
#[inline]
292305
fn map_ref<B: ?Sized, F>(self, f: F) -> MapRef<Self, F>
293306
where
@@ -302,7 +315,7 @@ pub trait StreamingIterator {
302315
fn nth(&mut self, n: usize) -> Option<&Self::Item> {
303316
for _ in 0..n {
304317
self.advance();
305-
if self.get().is_none() {
318+
if self.is_done() {
306319
return None;
307320
}
308321
}
@@ -437,6 +450,11 @@ where
437450
(**self).advance()
438451
}
439452

453+
#[inline]
454+
fn is_done(&self) -> bool {
455+
(**self).is_done()
456+
}
457+
440458
#[inline]
441459
fn get(&self) -> Option<&Self::Item> {
442460
(**self).get()
@@ -465,6 +483,11 @@ where
465483
(**self).advance()
466484
}
467485

486+
#[inline]
487+
fn is_done(&self) -> bool {
488+
(**self).is_done()
489+
}
490+
468491
#[inline]
469492
fn get(&self) -> Option<&Self::Item> {
470493
(**self).get()
@@ -550,7 +573,8 @@ where
550573

551574
match self.state {
552575
BothForward | BothBackward => {
553-
self.state = if self.a.next().is_none() {
576+
self.a.advance();
577+
self.state = if self.a.is_done() {
554578
self.b.advance();
555579
Back
556580
} else {
@@ -562,6 +586,16 @@ where
562586
}
563587
}
564588

589+
#[inline]
590+
fn is_done(&self) -> bool {
591+
use ChainState::*;
592+
593+
match self.state {
594+
BothForward | Front => self.a.is_done(),
595+
BothBackward | Back => self.b.is_done(),
596+
}
597+
}
598+
565599
#[inline]
566600
fn get(&self) -> Option<&Self::Item> {
567601
use ChainState::*;
@@ -602,7 +636,8 @@ where
602636

603637
match self.state {
604638
BothForward | BothBackward => {
605-
self.state = if self.b.next_back().is_none() {
639+
self.b.advance_back();
640+
self.state = if self.b.is_done() {
606641
self.a.advance_back();
607642
Front
608643
} else {
@@ -699,6 +734,11 @@ where
699734
}
700735
}
701736

737+
#[inline]
738+
fn is_done(&self) -> bool {
739+
self.it.is_done()
740+
}
741+
702742
#[inline]
703743
fn get(&self) -> Option<&I::Item> {
704744
self.it.get()
@@ -782,10 +822,12 @@ where
782822
fn advance(&mut self) {
783823
loop {
784824
match self.it.next() {
785-
Some(i) => if let Some(i) = (self.f)(i) {
786-
self.item = Some(i);
787-
break;
788-
},
825+
Some(i) => {
826+
if let Some(i) = (self.f)(i) {
827+
self.item = Some(i);
828+
break;
829+
}
830+
}
789831
None => {
790832
self.item = None;
791833
break;
@@ -827,10 +869,12 @@ where
827869
fn advance_back(&mut self) {
828870
loop {
829871
match self.it.next_back() {
830-
Some(i) => if let Some(i) = (self.f)(i) {
831-
self.item = Some(i);
832-
break;
833-
},
872+
Some(i) => {
873+
if let Some(i) = (self.f)(i) {
874+
self.item = Some(i);
875+
break;
876+
}
877+
}
834878
None => {
835879
self.item = None;
836880
break;
@@ -872,7 +916,13 @@ where
872916

873917
#[inline]
874918
fn advance(&mut self) {
875-
while self.sub_iter.as_mut().and_then(J::next).is_none() {
919+
loop {
920+
if let Some(ref mut iter) = self.sub_iter {
921+
iter.advance();
922+
if !iter.is_done() {
923+
break;
924+
}
925+
}
876926
if let Some(item) = self.it.next() {
877927
self.sub_iter = Some((self.f)(item));
878928
} else {
@@ -881,6 +931,14 @@ where
881931
}
882932
}
883933

934+
#[inline]
935+
fn is_done(&self) -> bool {
936+
match self.sub_iter {
937+
Some(ref iter) => iter.is_done(),
938+
None => true,
939+
}
940+
}
941+
884942
#[inline]
885943
fn get(&self) -> Option<&Self::Item> {
886944
self.sub_iter.as_ref().and_then(J::get)
@@ -982,21 +1040,30 @@ where
9821040
match self.state {
9831041
FuseState::Start => {
9841042
self.it.advance();
985-
self.state = match self.it.get() {
986-
Some(_) => FuseState::Middle,
987-
None => FuseState::End,
1043+
self.state = if self.it.is_done() {
1044+
FuseState::End
1045+
} else {
1046+
FuseState::Middle
9881047
};
9891048
}
9901049
FuseState::Middle => {
9911050
self.it.advance();
992-
if let None = self.it.get() {
1051+
if self.it.is_done() {
9931052
self.state = FuseState::End;
9941053
}
9951054
}
9961055
FuseState::End => {}
9971056
}
9981057
}
9991058

1059+
#[inline]
1060+
fn is_done(&self) -> bool {
1061+
match self.state {
1062+
FuseState::Start | FuseState::End => true,
1063+
FuseState::Middle => false,
1064+
}
1065+
}
1066+
10001067
#[inline]
10011068
fn get(&self) -> Option<&I::Item> {
10021069
match self.state {
@@ -1054,6 +1121,7 @@ where
10541121
}
10551122
}
10561123
}
1124+
10571125
/// A streaming iterator that calls a function with element before yielding it.
10581126
#[derive(Debug)]
10591127
pub struct Inspect<I, F> {
@@ -1074,6 +1142,11 @@ where
10741142
}
10751143
}
10761144

1145+
#[inline]
1146+
fn is_done(&self) -> bool {
1147+
self.it.is_done()
1148+
}
1149+
10771150
fn get(&self) -> Option<&Self::Item> {
10781151
self.it.get()
10791152
}
@@ -1248,6 +1321,11 @@ where
12481321
self.it.advance();
12491322
}
12501323

1324+
#[inline]
1325+
fn is_done(&self) -> bool {
1326+
self.it.is_done()
1327+
}
1328+
12511329
#[inline]
12521330
fn get(&self) -> Option<&B> {
12531331
self.it.get().map(&self.f)
@@ -1341,6 +1419,11 @@ where
13411419
self.n = 0;
13421420
}
13431421

1422+
#[inline]
1423+
fn is_done(&self) -> bool {
1424+
self.it.is_done()
1425+
}
1426+
13441427
#[inline]
13451428
fn get(&self) -> Option<&I::Item> {
13461429
self.it.get()
@@ -1397,6 +1480,11 @@ where
13971480
}
13981481
}
13991482

1483+
#[inline]
1484+
fn is_done(&self) -> bool {
1485+
self.it.is_done()
1486+
}
1487+
14001488
#[inline]
14011489
fn get(&self) -> Option<&I::Item> {
14021490
self.it.get()
@@ -1448,6 +1536,11 @@ where
14481536
}
14491537
}
14501538

1539+
#[inline]
1540+
fn is_done(&self) -> bool {
1541+
self.done || self.it.is_done()
1542+
}
1543+
14511544
#[inline]
14521545
fn get(&self) -> Option<&I::Item> {
14531546
if self.done {
@@ -1491,6 +1584,11 @@ where
14911584
}
14921585
}
14931586

1587+
#[inline]
1588+
fn is_done(&self) -> bool {
1589+
self.done || self.it.is_done()
1590+
}
1591+
14941592
#[inline]
14951593
fn get(&self) -> Option<&I::Item> {
14961594
if self.done {
@@ -1506,12 +1604,14 @@ where
15061604
None
15071605
} else {
15081606
match self.it.next() {
1509-
Some(i) => if (self.f)(i) {
1510-
Some(i)
1511-
} else {
1512-
self.done = true;
1513-
None
1514-
},
1607+
Some(i) => {
1608+
if (self.f)(i) {
1609+
Some(i)
1610+
} else {
1611+
self.done = true;
1612+
None
1613+
}
1614+
}
15151615
None => None,
15161616
}
15171617
}
@@ -1542,6 +1642,11 @@ where
15421642
self.0.advance_back();
15431643
}
15441644

1645+
#[inline]
1646+
fn is_done(&self) -> bool {
1647+
self.0.is_done()
1648+
}
1649+
15451650
#[inline]
15461651
fn get(&self) -> Option<&I::Item> {
15471652
self.0.get()
@@ -1923,6 +2028,24 @@ mod test {
19232028
assert_eq!(it.next(), None);
19242029
}
19252030

2031+
#[test]
2032+
fn is_done_empty() {
2033+
let mut empty = empty::<u8>();
2034+
empty.advance();
2035+
assert!(empty.is_done());
2036+
}
2037+
2038+
#[test]
2039+
fn is_done_map() {
2040+
let items = [1];
2041+
let mut it = convert(items.iter().cloned())
2042+
.map_ref::<u16, _>(|_| panic!("only called during get()"));
2043+
it.advance();
2044+
assert!(!it.is_done());
2045+
it.advance();
2046+
assert!(it.is_done());
2047+
}
2048+
19262049
#[test]
19272050
fn rev() {
19282051
let items = [0, 1, 2, 3];

0 commit comments

Comments
 (0)