//! "Fallible" iterators. //! //! The iterator APIs in the Rust standard library do not support iteration //! that can fail in a first class manner. These iterators are typically modeled //! as iterating over `Result` values; for example, the `Lines` iterator //! returns `io::Result`s. When simply iterating over these types, the //! value being iterated over must be unwrapped in some way before it can be //! used: //! //! ```ignore //! for line in reader.lines() { //! let line = line?; //! // work with line //! } //! ``` //! //! In addition, many of the additional methods on the `Iterator` trait will //! not behave properly in the presence of errors when working with these kinds //! of iterators. For example, if one wanted to count the number of lines of //! text in a `Read`er, this might be a way to go about it: //! //! ```ignore //! let count = reader.lines().count(); //! ``` //! //! This will return the proper value when the reader operates successfully, but //! if it encounters an IO error, the result will either be slightly higher than //! expected if the error is transient, or it may run forever if the error is //! returned repeatedly! //! //! In contrast, a fallible iterator is built around the concept that a call to //! `next` can fail. The trait has an additional `Error` associated type in //! addition to the `Item` type, and `next` returns `Result, //! Self::Error>` rather than `Option`. Methods like `count` return //! `Result`s as well. //! //! This does mean that fallible iterators are incompatible with Rust's `for` //! loop syntax, but `while let` loops offer a similar level of ergonomics: //! //! ```ignore //! while let Some(item) = iter.next()? { //! // work with item //! } //! ``` //! //! ## Fallible closure arguments //! //! Like `Iterator`, many `FallibleIterator` methods take closures as arguments. //! These use the same signatures as their `Iterator` counterparts, except that //! `FallibleIterator` expects the closures to be fallible: they return //! `Result` instead of simply `T`. //! //! For example, the standard library's `Iterator::filter` adapter method //! filters the underlying iterator according to a predicate provided by the //! user, whose return type is `bool`. In `FallibleIterator::filter`, however, //! the predicate returns `Result`: //! //! ``` //! # use std::error::Error; //! # use std::str::FromStr; //! # use fallible_iterator::{convert, FallibleIterator}; //! let numbers = convert("100\n200\nfern\n400".lines().map(Ok::<&str, Box>)); //! let big_numbers = numbers.filter(|n| Ok(u64::from_str(n)? > 100)); //! assert!(big_numbers.count().is_err()); //! ``` #![doc(html_root_url = "https://docs.rs/fallible-iterator/0.2")] #![warn(missing_docs)] #![cfg_attr(feature = "alloc", feature(alloc))] #![no_std] use core::cmp::{self, Ordering}; use core::iter; #[cfg(all(feature = "alloc", not(feature = "std")))] #[cfg_attr(test, macro_use)] extern crate alloc; #[cfg(all(feature = "alloc", not(feature = "std")))] mod imports { pub use alloc::boxed::Box; pub use alloc::collections::btree_map::BTreeMap; pub use alloc::collections::btree_set::BTreeSet; pub use alloc::vec::Vec; } #[cfg(feature = "std")] #[cfg_attr(test, macro_use)] extern crate std; #[cfg(feature = "std")] mod imports { pub use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; pub use std::hash::{BuildHasher, Hash}; pub use std::prelude::v1::*; } #[cfg(any(feature = "std", feature = "alloc"))] use crate::imports::*; #[cfg(any(feature = "std", feature = "alloc"))] #[cfg(test)] mod test; enum FoldStop { Break(T), Err(E), } impl From for FoldStop { #[inline] fn from(e: E) -> FoldStop { FoldStop::Err(e) } } trait ResultExt { fn unpack_fold(self) -> Result; } impl ResultExt for Result> { #[inline] fn unpack_fold(self) -> Result { match self { Ok(v) => Ok(v), Err(FoldStop::Break(v)) => Ok(v), Err(FoldStop::Err(e)) => Err(e), } } } /// An `Iterator`-like trait that allows for calculation of items to fail. pub trait FallibleIterator { /// The type being iterated over. type Item; /// The error type. type Error; /// Advances the iterator and returns the next value. /// /// Returns `Ok(None)` when iteration is finished. /// /// The behavior of calling this method after a previous call has returned /// `Ok(None)` or `Err` is implemenetation defined. fn next(&mut self) -> Result, Self::Error>; /// Returns bounds on the remaining length of the iterator. /// /// Specifically, the first half of the returned tuple is a lower bound and /// the second half is an upper bound. /// /// For the upper bound, `None` indicates that the upper bound is either /// unknown or larger than can be represented as a `usize`. /// /// Both bounds assume that all remaining calls to `next` succeed. That is, /// `next` could return an `Err` in fewer calls than specified by the lower /// bound. /// /// The default implementation returns `(0, None)`, which is correct for /// any iterator. #[inline] fn size_hint(&self) -> (usize, Option) { (0, None) } /// Consumes the iterator, returning the number of remaining items. #[inline] fn count(self) -> Result where Self: Sized, { self.fold(0, |n, _| Ok(n + 1)) } /// Returns the last element of the iterator. #[inline] fn last(self) -> Result, Self::Error> where Self: Sized, { self.fold(None, |_, v| Ok(Some(v))) } /// Returns the `n`th element of the iterator. #[inline] fn nth(&mut self, mut n: usize) -> Result, Self::Error> { while let Some(e) = self.next()? { if n == 0 { return Ok(Some(e)); } n -= 1; } Ok(None) } /// Returns an iterator starting at the same point, but stepping by the given amount at each iteration. /// /// # Panics /// /// Panics if `step` is 0. #[inline] fn step_by(self, step: usize) -> StepBy where Self: Sized, { assert!(step != 0); StepBy { it: self, step: step - 1, first_take: true, } } /// Returns an iterator which yields the elements of this iterator followed /// by another. #[inline] fn chain(self, it: I) -> Chain where I: IntoFallibleIterator, Self: Sized, { Chain { front: self, back: it, state: ChainState::Both, } } /// Returns an iterator that yields pairs of this iterator's and another /// iterator's values. #[inline] fn zip(self, o: I) -> Zip where Self: Sized, I: IntoFallibleIterator, { Zip(self, o.into_fallible_iter()) } /// Returns an iterator which applies a fallible transform to the elements /// of the underlying iterator. #[inline] fn map(self, f: F) -> Map where Self: Sized, F: FnMut(Self::Item) -> Result, { Map { it: self, f: f } } /// Calls a fallible closure on each element of an iterator. #[inline] fn for_each(self, mut f: F) -> Result<(), Self::Error> where Self: Sized, F: FnMut(Self::Item) -> Result<(), Self::Error>, { self.fold((), move |(), item| f(item)) } /// Returns an iterator which uses a predicate to determine which values /// should be yielded. The predicate may fail; such failures are passed to /// the caller. #[inline] fn filter(self, f: F) -> Filter where Self: Sized, F: FnMut(&Self::Item) -> Result, { Filter { it: self, f: f } } /// Returns an iterator which both filters and maps. The closure may fail; /// such failures are passed along to the consumer. #[inline] fn filter_map(self, f: F) -> FilterMap where Self: Sized, F: FnMut(Self::Item) -> Result, Self::Error>, { FilterMap { it: self, f: f } } /// Returns an iterator which yields the current iteration count as well /// as the value. #[inline] fn enumerate(self) -> Enumerate where Self: Sized, { Enumerate { it: self, n: 0 } } /// Returns an iterator that can peek at the next element without consuming /// it. #[inline] fn peekable(self) -> Peekable where Self: Sized, { Peekable { it: self, next: None, } } /// Returns an iterator that skips elements based on a predicate. #[inline] fn skip_while

(self, predicate: P) -> SkipWhile where Self: Sized, P: FnMut(&Self::Item) -> Result, { SkipWhile { it: self, flag: false, predicate, } } /// Returns an iterator that yields elements based on a predicate. #[inline] fn take_while

(self, predicate: P) -> TakeWhile where Self: Sized, P: FnMut(&Self::Item) -> Result, { TakeWhile { it: self, flag: false, predicate, } } /// Returns an iterator which skips the first `n` values of this iterator. #[inline] fn skip(self, n: usize) -> Skip where Self: Sized, { Skip { it: self, n } } /// Returns an iterator that yields only the first `n` values of this /// iterator. #[inline] fn take(self, n: usize) -> Take where Self: Sized, { Take { it: self, remaining: n, } } /// Returns an iterator which applies a stateful map to values of this /// iterator. #[inline] fn scan(self, initial_state: St, f: F) -> Scan where Self: Sized, F: FnMut(&mut St, Self::Item) -> Result, Self::Error>, { Scan { it: self, f, state: initial_state, } } /// Returns an iterator which maps this iterator's elements to iterators, yielding those iterators' values. #[inline] fn flat_map(self, f: F) -> FlatMap where Self: Sized, U: IntoFallibleIterator, F: FnMut(Self::Item) -> Result, { FlatMap { it: self.map(f), cur: None, } } /// Returns an iterator which flattens an iterator of iterators, yielding those iterators' values. #[inline] fn flatten(self) -> Flatten where Self: Sized, Self::Item: IntoFallibleIterator, { Flatten { it: self, cur: None, } } /// Returns an iterator which yields this iterator's elements and ends after /// the first `Ok(None)`. /// /// The behavior of calling `next` after it has previously returned /// `Ok(None)` is normally unspecified. The iterator returned by this method /// guarantees that `Ok(None)` will always be returned. #[inline] fn fuse(self) -> Fuse where Self: Sized, { Fuse { it: self, done: false, } } /// Returns an iterator which passes each element to a closure before returning it. #[inline] fn inspect(self, f: F) -> Inspect where Self: Sized, F: FnMut(&Self::Item) -> Result<(), Self::Error>, { Inspect { it: self, f } } /// Borrow an iterator rather than consuming it. /// /// This is useful to allow the use of iterator adaptors that would /// otherwise consume the value. #[inline] fn by_ref(&mut self) -> &mut Self where Self: Sized, { self } /// Transforms the iterator into a collection. /// /// An `Err` will be returned if any invocation of `next` returns `Err`. #[inline] fn collect(self) -> Result where T: FromFallibleIterator, Self: Sized, { T::from_fallible_iter(self) } /// Transforms the iterator into two collections, partitioning elements by a closure. #[inline] fn partition(self, mut f: F) -> Result<(B, B), Self::Error> where Self: Sized, B: Default + Extend, F: FnMut(&Self::Item) -> Result, { let mut a = B::default(); let mut b = B::default(); self.for_each(|i| { if f(&i)? { a.extend(Some(i)); } else { b.extend(Some(i)); } Ok(()) })?; Ok((a, b)) } /// Applies a function over the elements of the iterator, producing a single /// final value. #[inline] fn fold(mut self, init: B, f: F) -> Result where Self: Sized, F: FnMut(B, Self::Item) -> Result, { self.try_fold(init, f) } /// Applies a function over the elements of the iterator, producing a single final value. /// /// This is used as the "base" of many methods on `FallibleIterator`. #[inline] fn try_fold(&mut self, mut init: B, mut f: F) -> Result where Self: Sized, E: From, F: FnMut(B, Self::Item) -> Result, { while let Some(v) = self.next()? { init = f(init, v)?; } Ok(init) } /// Determines if all elements of this iterator match a predicate. #[inline] fn all(&mut self, mut f: F) -> Result where Self: Sized, F: FnMut(Self::Item) -> Result, { self.try_fold((), |(), v| { if !f(v)? { return Err(FoldStop::Break(false)); } Ok(()) }) .map(|()| true) .unpack_fold() } /// Determines if any element of this iterator matches a predicate. #[inline] fn any(&mut self, mut f: F) -> Result where Self: Sized, F: FnMut(Self::Item) -> Result, { self.try_fold((), |(), v| { if f(v)? { return Err(FoldStop::Break(true)); } Ok(()) }) .map(|()| false) .unpack_fold() } /// Returns the first element of the iterator that matches a predicate. #[inline] fn find(&mut self, mut f: F) -> Result, Self::Error> where Self: Sized, F: FnMut(&Self::Item) -> Result, { self.try_fold((), |(), v| { if f(&v)? { return Err(FoldStop::Break(Some(v))); } Ok(()) }) .map(|()| None) .unpack_fold() } /// Applies a function to the elements of the iterator, returning the first non-`None` result. #[inline] fn find_map(&mut self, f: F) -> Result, Self::Error> where Self: Sized, F: FnMut(Self::Item) -> Result, Self::Error>, { self.filter_map(f).next() } /// Returns the position of the first element of this iterator that matches /// a predicate. The predicate may fail; such failures are returned to the /// caller. #[inline] fn position(&mut self, mut f: F) -> Result, Self::Error> where Self: Sized, F: FnMut(Self::Item) -> Result, { self.try_fold(0, |n, v| { if f(v)? { return Err(FoldStop::Break(Some(n))); } Ok(n + 1) }) .map(|_| None) .unpack_fold() } /// Returns the maximal element of the iterator. #[inline] fn max(self) -> Result, Self::Error> where Self: Sized, Self::Item: Ord, { self.max_by(|a, b| Ok(a.cmp(b))) } /// Returns the element of the iterator which gives the maximum value from /// the function. #[inline] fn max_by_key(mut self, mut f: F) -> Result, Self::Error> where Self: Sized, B: Ord, F: FnMut(&Self::Item) -> Result, { let max = match self.next()? { Some(v) => (f(&v)?, v), None => return Ok(None), }; self.fold(max, |(key, max), v| { let new_key = f(&v)?; if key > new_key { Ok((key, max)) } else { Ok((new_key, v)) } }) .map(|v| Some(v.1)) } /// Returns the element that gives the maximum value with respect to the function. #[inline] fn max_by(mut self, mut f: F) -> Result, Self::Error> where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> Result, { let max = match self.next()? { Some(v) => v, None => return Ok(None), }; self.fold(max, |max, v| { if f(&max, &v)? == Ordering::Greater { Ok(max) } else { Ok(v) } }) .map(Some) } /// Returns the minimal element of the iterator. #[inline] fn min(self) -> Result, Self::Error> where Self: Sized, Self::Item: Ord, { self.min_by(|a, b| Ok(a.cmp(b))) } /// Returns the element of the iterator which gives the minimum value from /// the function. #[inline] fn min_by_key(mut self, mut f: F) -> Result, Self::Error> where Self: Sized, B: Ord, F: FnMut(&Self::Item) -> Result, { let min = match self.next()? { Some(v) => (f(&v)?, v), None => return Ok(None), }; self.fold(min, |(key, min), v| { let new_key = f(&v)?; if key < new_key { Ok((key, min)) } else { Ok((new_key, v)) } }) .map(|v| Some(v.1)) } /// Returns the element that gives the minimum value with respect to the function. #[inline] fn min_by(mut self, mut f: F) -> Result, Self::Error> where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> Result, { let min = match self.next()? { Some(v) => v, None => return Ok(None), }; self.fold(min, |min, v| { if f(&min, &v)? == Ordering::Less { Ok(min) } else { Ok(v) } }) .map(Some) } /// Returns an iterator that yields this iterator's items in the opposite /// order. #[inline] fn rev(self) -> Rev where Self: Sized + DoubleEndedFallibleIterator, { Rev(self) } /// Converts an iterator of pairs into a pair of containers. #[inline] fn unzip(self) -> Result<(FromA, FromB), Self::Error> where Self: Sized + FallibleIterator, FromA: Default + Extend, FromB: Default + Extend, { let mut from_a = FromA::default(); let mut from_b = FromB::default(); self.for_each(|(a, b)| { from_a.extend(Some(a)); from_b.extend(Some(b)); Ok(()) })?; Ok((from_a, from_b)) } /// Returns an iterator which clones all of its elements. #[inline] fn cloned<'a, T>(self) -> Cloned where Self: Sized + FallibleIterator, T: 'a + Clone, { Cloned(self) } /// Returns an iterator which repeas this iterator endlessly. #[inline] fn cycle(self) -> Cycle where Self: Sized + Clone, { Cycle { it: self.clone(), cur: self, } } /// Lexicographically compares the elements of this iterator to that of /// another. #[inline] fn cmp(mut self, other: I) -> Result where Self: Sized, I: IntoFallibleIterator, Self::Item: Ord, { let mut other = other.into_fallible_iter(); loop { match (self.next()?, other.next()?) { (None, None) => return Ok(Ordering::Equal), (None, _) => return Ok(Ordering::Less), (_, None) => return Ok(Ordering::Greater), (Some(x), Some(y)) => match x.cmp(&y) { Ordering::Equal => {} o => return Ok(o), }, } } } /// Lexicographically compares the elements of this iterator to that of /// another. #[inline] fn partial_cmp(mut self, other: I) -> Result, Self::Error> where Self: Sized, I: IntoFallibleIterator, Self::Item: PartialOrd, { let mut other = other.into_fallible_iter(); loop { match (self.next()?, other.next()?) { (None, None) => return Ok(Some(Ordering::Equal)), (None, _) => return Ok(Some(Ordering::Less)), (_, None) => return Ok(Some(Ordering::Greater)), (Some(x), Some(y)) => match x.partial_cmp(&y) { Some(Ordering::Equal) => {} o => return Ok(o), }, } } } /// Determines if the elements of this iterator are equal to those of /// another. #[inline] fn eq(mut self, other: I) -> Result where Self: Sized, I: IntoFallibleIterator, Self::Item: PartialEq, { let mut other = other.into_fallible_iter(); loop { match (self.next()?, other.next()?) { (None, None) => return Ok(true), (None, _) | (_, None) => return Ok(false), (Some(x), Some(y)) => { if x != y { return Ok(false); } } } } } /// Determines if the elements of this iterator are not equal to those of /// another. #[inline] fn ne(mut self, other: I) -> Result where Self: Sized, I: IntoFallibleIterator, Self::Item: PartialEq, { let mut other = other.into_fallible_iter(); loop { match (self.next()?, other.next()?) { (None, None) => return Ok(false), (None, _) | (_, None) => return Ok(true), (Some(x), Some(y)) => { if x != y { return Ok(true); } } } } } /// Determines if the elements of this iterator are lexicographically less /// than those of another. #[inline] fn lt(mut self, other: I) -> Result where Self: Sized, I: IntoFallibleIterator, Self::Item: PartialOrd, { let mut other = other.into_fallible_iter(); loop { match (self.next()?, other.next()?) { (None, None) => return Ok(false), (None, _) => return Ok(true), (_, None) => return Ok(false), (Some(x), Some(y)) => match x.partial_cmp(&y) { Some(Ordering::Less) => return Ok(true), Some(Ordering::Equal) => {} Some(Ordering::Greater) => return Ok(false), None => return Ok(false), }, } } } /// Determines if the elements of this iterator are lexicographically less /// than or equal to those of another. #[inline] fn le(mut self, other: I) -> Result where Self: Sized, I: IntoFallibleIterator, Self::Item: PartialOrd, { let mut other = other.into_fallible_iter(); loop { match (self.next()?, other.next()?) { (None, None) => return Ok(true), (None, _) => return Ok(true), (_, None) => return Ok(false), (Some(x), Some(y)) => match x.partial_cmp(&y) { Some(Ordering::Less) => return Ok(true), Some(Ordering::Equal) => {} Some(Ordering::Greater) => return Ok(false), None => return Ok(false), }, } } } /// Determines if the elements of this iterator are lexicographically /// greater than those of another. #[inline] fn gt(mut self, other: I) -> Result where Self: Sized, I: IntoFallibleIterator, Self::Item: PartialOrd, { let mut other = other.into_fallible_iter(); loop { match (self.next()?, other.next()?) { (None, None) => return Ok(false), (None, _) => return Ok(false), (_, None) => return Ok(true), (Some(x), Some(y)) => match x.partial_cmp(&y) { Some(Ordering::Less) => return Ok(false), Some(Ordering::Equal) => {} Some(Ordering::Greater) => return Ok(true), None => return Ok(false), }, } } } /// Determines if the elements of this iterator are lexicographically /// greater than or equal to those of another. #[inline] fn ge(mut self, other: I) -> Result where Self: Sized, I: IntoFallibleIterator, Self::Item: PartialOrd, { let mut other = other.into_fallible_iter(); loop { match (self.next()?, other.next()?) { (None, None) => return Ok(true), (None, _) => return Ok(false), (_, None) => return Ok(true), (Some(x), Some(y)) => match x.partial_cmp(&y) { Some(Ordering::Less) => return Ok(false), Some(Ordering::Equal) => {} Some(Ordering::Greater) => return Ok(true), None => return Ok(false), }, } } } /// Returns a normal (non-fallible) iterator over `Result`. #[inline] fn iterator(self) -> Iterator where Self: Sized, { Iterator(self) } /// Returns an iterator which applies a transform to the errors of the /// underlying iterator. #[inline] fn map_err(self, f: F) -> MapErr where F: FnMut(Self::Error) -> B, Self: Sized, { MapErr { it: self, f: f } } } impl FallibleIterator for &mut I { type Item = I::Item; type Error = I::Error; #[inline] fn next(&mut self) -> Result, I::Error> { (**self).next() } #[inline] fn size_hint(&self) -> (usize, Option) { (**self).size_hint() } #[inline] fn nth(&mut self, n: usize) -> Result, I::Error> { (**self).nth(n) } } impl DoubleEndedFallibleIterator for &mut I { #[inline] fn next_back(&mut self) -> Result, I::Error> { (**self).next_back() } } #[cfg(any(feature = "std", feature = "alloc"))] impl FallibleIterator for Box { type Item = I::Item; type Error = I::Error; #[inline] fn next(&mut self) -> Result, I::Error> { (**self).next() } #[inline] fn size_hint(&self) -> (usize, Option) { (**self).size_hint() } #[inline] fn nth(&mut self, n: usize) -> Result, I::Error> { (**self).nth(n) } } #[cfg(any(feature = "std", feature = "alloc"))] impl DoubleEndedFallibleIterator for Box { #[inline] fn next_back(&mut self) -> Result, I::Error> { (**self).next_back() } } /// A fallible iterator able to yield elements from both ends. pub trait DoubleEndedFallibleIterator: FallibleIterator { /// Advances the end of the iterator, returning the last value. fn next_back(&mut self) -> Result, Self::Error>; /// Applies a function over the elements of the iterator in reverse order, producing a single final value. #[inline] fn rfold(mut self, init: B, f: F) -> Result where Self: Sized, F: FnMut(B, Self::Item) -> Result, { self.try_rfold(init, f) } /// Applies a function over the elements of the iterator in reverse, producing a single final value. /// /// This is used as the "base" of many methods on `DoubleEndedFallibleIterator`. #[inline] fn try_rfold(&mut self, mut init: B, mut f: F) -> Result where Self: Sized, E: From, F: FnMut(B, Self::Item) -> Result, { while let Some(v) = self.next_back()? { init = f(init, v)?; } Ok(init) } } /// Conversion from a fallible iterator. pub trait FromFallibleIterator: Sized { /// Creates a value from a fallible iterator. fn from_fallible_iter(it: I) -> Result where I: IntoFallibleIterator; } #[cfg(any(feature = "std", feature = "alloc"))] impl FromFallibleIterator for Vec { #[inline] fn from_fallible_iter(it: I) -> Result, I::Error> where I: IntoFallibleIterator, { let it = it.into_fallible_iter(); let mut vec = Vec::with_capacity(it.size_hint().0); it.for_each(|v| Ok(vec.push(v)))?; Ok(vec) } } #[cfg(feature = "std")] impl FromFallibleIterator for HashSet where T: Hash + Eq, S: BuildHasher + Default, { #[inline] fn from_fallible_iter(it: I) -> Result, I::Error> where I: IntoFallibleIterator, { let it = it.into_fallible_iter(); let mut set = HashSet::default(); set.reserve(it.size_hint().0); it.for_each(|v| { set.insert(v); Ok(()) })?; Ok(set) } } #[cfg(feature = "std")] impl FromFallibleIterator<(K, V)> for HashMap where K: Hash + Eq, S: BuildHasher + Default, { #[inline] fn from_fallible_iter(it: I) -> Result, I::Error> where I: IntoFallibleIterator, { let it = it.into_fallible_iter(); let mut map = HashMap::default(); map.reserve(it.size_hint().0); it.for_each(|(k, v)| { map.insert(k, v); Ok(()) })?; Ok(map) } } #[cfg(any(feature = "std", feature = "alloc"))] impl FromFallibleIterator for BTreeSet where T: Ord, { #[inline] fn from_fallible_iter(it: I) -> Result, I::Error> where I: IntoFallibleIterator, { let it = it.into_fallible_iter(); let mut set = BTreeSet::new(); it.for_each(|v| { set.insert(v); Ok(()) })?; Ok(set) } } #[cfg(any(feature = "std", feature = "alloc"))] impl FromFallibleIterator<(K, V)> for BTreeMap where K: Ord, { #[inline] fn from_fallible_iter(it: I) -> Result, I::Error> where I: IntoFallibleIterator, { let it = it.into_fallible_iter(); let mut map = BTreeMap::new(); it.for_each(|(k, v)| { map.insert(k, v); Ok(()) })?; Ok(map) } } /// Conversion into a `FallibleIterator`. pub trait IntoFallibleIterator { /// The elements of the iterator. type Item; /// The error value of the iterator. type Error; /// The iterator. type IntoFallibleIter: FallibleIterator; /// Creates a fallible iterator from a value. fn into_fallible_iter(self) -> Self::IntoFallibleIter; } impl IntoFallibleIterator for I where I: FallibleIterator, { type Item = I::Item; type Error = I::Error; type IntoFallibleIter = I; #[inline] fn into_fallible_iter(self) -> I { self } } /// An iterator which applies a fallible transform to the elements of the /// underlying iterator. #[derive(Clone, Debug)] pub struct Map { it: T, f: F, } impl FallibleIterator for Map where T: FallibleIterator, F: FnMut(T::Item) -> Result, { type Item = B; type Error = T::Error; #[inline] fn next(&mut self) -> Result, T::Error> { match self.it.next() { Ok(Some(v)) => Ok(Some((self.f)(v)?)), Ok(None) => Ok(None), Err(e) => Err(e), } } #[inline] fn size_hint(&self) -> (usize, Option) { self.it.size_hint() } #[inline] fn try_fold(&mut self, init: C, mut f: G) -> Result where E: From, G: FnMut(C, B) -> Result, { let map = &mut self.f; self.it.try_fold(init, |b, v| f(b, map(v)?)) } } impl DoubleEndedFallibleIterator for Map where I: DoubleEndedFallibleIterator, F: FnMut(I::Item) -> Result, { #[inline] fn next_back(&mut self) -> Result, I::Error> { match self.it.next_back() { Ok(Some(v)) => Ok(Some((self.f)(v)?)), Ok(None) => Ok(None), Err(e) => Err(e), } } #[inline] fn try_rfold(&mut self, init: C, mut f: G) -> Result where E: From, G: FnMut(C, B) -> Result, { let map = &mut self.f; self.it.try_rfold(init, |acc, v| f(acc, map(v)?)) } } #[derive(Clone, Debug)] enum ChainState { Both, Front, Back, } /// An iterator which yields the elements of one iterator followed by another. #[derive(Clone, Debug)] pub struct Chain { front: T, back: U, state: ChainState, } impl FallibleIterator for Chain where T: FallibleIterator, U: FallibleIterator, { type Item = T::Item; type Error = T::Error; #[inline] fn next(&mut self) -> Result, T::Error> { match self.state { ChainState::Both => match self.front.next()? { Some(e) => Ok(Some(e)), None => { self.state = ChainState::Back; self.back.next() } }, ChainState::Front => self.front.next(), ChainState::Back => self.back.next(), } } #[inline] fn size_hint(&self) -> (usize, Option) { let front_hint = self.front.size_hint(); let back_hint = self.back.size_hint(); let low = front_hint.0.saturating_add(back_hint.0); let high = match (front_hint.1, back_hint.1) { (Some(f), Some(b)) => f.checked_add(b), _ => None, }; (low, high) } #[inline] fn count(self) -> Result { match self.state { ChainState::Both => Ok(self.front.count()? + self.back.count()?), ChainState::Front => self.front.count(), ChainState::Back => self.back.count(), } } #[inline] fn try_fold(&mut self, init: B, mut f: F) -> Result where E: From, F: FnMut(B, T::Item) -> Result, { match self.state { ChainState::Both => { let init = self.front.try_fold(init, &mut f)?; self.state = ChainState::Back; self.back.try_fold(init, f) } ChainState::Front => self.front.try_fold(init, f), ChainState::Back => self.back.try_fold(init, f), } } #[inline] fn find(&mut self, mut f: F) -> Result, T::Error> where F: FnMut(&T::Item) -> Result, { match self.state { ChainState::Both => match self.front.find(&mut f)? { Some(v) => Ok(Some(v)), None => { self.state = ChainState::Back; self.back.find(f) } }, ChainState::Front => self.front.find(f), ChainState::Back => self.back.find(f), } } #[inline] fn last(self) -> Result, T::Error> { match self.state { ChainState::Both => { self.front.last()?; self.back.last() } ChainState::Front => self.front.last(), ChainState::Back => self.back.last(), } } } impl DoubleEndedFallibleIterator for Chain where T: DoubleEndedFallibleIterator, U: DoubleEndedFallibleIterator, { #[inline] fn next_back(&mut self) -> Result, T::Error> { match self.state { ChainState::Both => match self.back.next_back()? { Some(e) => Ok(Some(e)), None => { self.state = ChainState::Front; self.front.next_back() } }, ChainState::Front => self.front.next_back(), ChainState::Back => self.back.next_back(), } } #[inline] fn try_rfold(&mut self, init: B, mut f: F) -> Result where E: From, F: FnMut(B, T::Item) -> Result, { match self.state { ChainState::Both => { let init = self.back.try_rfold(init, &mut f)?; self.state = ChainState::Front; self.front.try_rfold(init, f) } ChainState::Front => self.front.try_rfold(init, f), ChainState::Back => self.back.try_rfold(init, f), } } } /// An iterator which clones the elements of the underlying iterator. #[derive(Clone, Debug)] pub struct Cloned(I); impl<'a, T, I> FallibleIterator for Cloned where I: FallibleIterator, T: 'a + Clone, { type Item = T; type Error = I::Error; #[inline] fn next(&mut self) -> Result, I::Error> { self.0.next().map(|o| o.cloned()) } #[inline] fn size_hint(&self) -> (usize, Option) { self.0.size_hint() } #[inline] fn try_fold(&mut self, init: B, mut f: F) -> Result where E: From, F: FnMut(B, T) -> Result, { self.0.try_fold(init, |acc, v| f(acc, v.clone())) } } impl<'a, T, I> DoubleEndedFallibleIterator for Cloned where I: DoubleEndedFallibleIterator, T: 'a + Clone, { #[inline] fn next_back(&mut self) -> Result, I::Error> { self.0.next_back().map(|o| o.cloned()) } #[inline] fn try_rfold(&mut self, init: B, mut f: F) -> Result where E: From, F: FnMut(B, T) -> Result, { self.0.try_rfold(init, |acc, v| f(acc, v.clone())) } } /// Converts an `Iterator>` into a `FallibleIterator`. #[inline] pub fn convert(it: I) -> Convert where I: iter::Iterator>, { Convert(it) } /// A fallible iterator that wraps a normal iterator over `Result`s. #[derive(Clone, Debug)] pub struct Convert(I); impl FallibleIterator for Convert where I: iter::Iterator>, { type Item = T; type Error = E; #[inline] fn next(&mut self) -> Result, E> { match self.0.next() { Some(Ok(i)) => Ok(Some(i)), Some(Err(e)) => Err(e), None => Ok(None), } } #[inline] fn size_hint(&self) -> (usize, Option) { self.0.size_hint() } #[inline] fn try_fold(&mut self, init: B, mut f: F) -> Result where E2: From, F: FnMut(B, T) -> Result, { self.0.try_fold(init, |acc, v| f(acc, v?)) } } impl DoubleEndedFallibleIterator for Convert where I: DoubleEndedIterator>, { #[inline] fn next_back(&mut self) -> Result, E> { match self.0.next_back() { Some(Ok(i)) => Ok(Some(i)), Some(Err(e)) => Err(e), None => Ok(None), } } #[inline] fn try_rfold(&mut self, init: B, mut f: F) -> Result where E2: From, F: FnMut(B, T) -> Result, { self.0.try_rfold(init, |acc, v| f(acc, v?)) } } /// An iterator that yields the iteration count as well as the values of the /// underlying iterator. #[derive(Clone, Debug)] pub struct Enumerate { it: I, n: usize, } impl FallibleIterator for Enumerate where I: FallibleIterator, { type Item = (usize, I::Item); type Error = I::Error; #[inline] fn next(&mut self) -> Result, I::Error> { self.it.next().map(|o| { o.map(|e| { let i = self.n; self.n += 1; (i, e) }) }) } #[inline] fn size_hint(&self) -> (usize, Option) { self.it.size_hint() } #[inline] fn count(self) -> Result { self.it.count() } #[inline] fn nth(&mut self, n: usize) -> Result, I::Error> { match self.it.nth(n)? { Some(v) => { let i = self.n + n; self.n = i + 1; Ok(Some((i, v))) } None => Ok(None), } } #[inline] fn try_fold(&mut self, init: B, mut f: F) -> Result where E: From, F: FnMut(B, (usize, I::Item)) -> Result, { let n = &mut self.n; self.it.try_fold(init, |acc, v| { let i = *n; *n += 1; f(acc, (i, v)) }) } } /// An iterator which uses a fallible predicate to determine which values of the /// underlying iterator should be yielded. #[derive(Clone, Debug)] pub struct Filter { it: I, f: F, } impl FallibleIterator for Filter where I: FallibleIterator, F: FnMut(&I::Item) -> Result, { type Item = I::Item; type Error = I::Error; #[inline] fn next(&mut self) -> Result, I::Error> { let filter = &mut self.f; self.it .try_fold((), |(), v| { if filter(&v)? { return Err(FoldStop::Break(Some(v))); } Ok(()) }) .map(|()| None) .unpack_fold() } #[inline] fn size_hint(&self) -> (usize, Option) { (0, self.it.size_hint().1) } #[inline] fn try_fold(&mut self, init: B, mut f: G) -> Result where E: From, G: FnMut(B, I::Item) -> Result, { let predicate = &mut self.f; self.it.try_fold( init, |acc, v| { if predicate(&v)? { f(acc, v) } else { Ok(acc) } }, ) } } impl DoubleEndedFallibleIterator for Filter where I: DoubleEndedFallibleIterator, F: FnMut(&I::Item) -> Result, { #[inline] fn next_back(&mut self) -> Result, I::Error> { let filter = &mut self.f; self.it .try_rfold((), |(), v| { if filter(&v)? { return Err(FoldStop::Break(Some(v))); } Ok(()) }) .map(|()| None) .unpack_fold() } #[inline] fn try_rfold(&mut self, init: B, mut f: G) -> Result where E: From, G: FnMut(B, I::Item) -> Result, { let predicate = &mut self.f; self.it.try_rfold( init, |acc, v| { if predicate(&v)? { f(acc, v) } else { Ok(acc) } }, ) } } /// An iterator which both filters and maps the values of the underlying /// iterator. #[derive(Clone, Debug)] pub struct FilterMap { it: I, f: F, } impl FallibleIterator for FilterMap where I: FallibleIterator, F: FnMut(I::Item) -> Result, I::Error>, { type Item = B; type Error = I::Error; #[inline] fn next(&mut self) -> Result, I::Error> { let map = &mut self.f; self.it .try_fold((), |(), v| match map(v)? { Some(v) => Err(FoldStop::Break(Some(v))), None => Ok(()), }) .map(|()| None) .unpack_fold() } #[inline] fn size_hint(&self) -> (usize, Option) { (0, self.it.size_hint().1) } #[inline] fn try_fold(&mut self, init: C, mut f: G) -> Result where E: From, G: FnMut(C, B) -> Result, { let map = &mut self.f; self.it.try_fold(init, |acc, v| match map(v)? { Some(v) => f(acc, v), None => Ok(acc), }) } } impl DoubleEndedFallibleIterator for FilterMap where I: DoubleEndedFallibleIterator, F: FnMut(I::Item) -> Result, I::Error>, { #[inline] fn next_back(&mut self) -> Result, I::Error> { let map = &mut self.f; self.it .try_rfold((), |(), v| match map(v)? { Some(v) => Err(FoldStop::Break(Some(v))), None => Ok(()), }) .map(|()| None) .unpack_fold() } #[inline] fn try_rfold(&mut self, init: C, mut f: G) -> Result where E: From, G: FnMut(C, B) -> Result, { let map = &mut self.f; self.it.try_rfold(init, |acc, v| match map(v)? { Some(v) => f(acc, v), None => Ok(acc), }) } } /// An iterator which maps each element to another iterator, yielding those iterator's elements. #[derive(Clone, Debug)] pub struct FlatMap where U: IntoFallibleIterator, { it: Map, cur: Option, } impl FallibleIterator for FlatMap where I: FallibleIterator, U: IntoFallibleIterator, F: FnMut(I::Item) -> Result, { type Item = U::Item; type Error = U::Error; #[inline] fn next(&mut self) -> Result, U::Error> { loop { if let Some(it) = &mut self.cur { if let Some(v) = it.next()? { return Ok(Some(v)); } } match self.it.next()? { Some(it) => self.cur = Some(it.into_fallible_iter()), None => return Ok(None), } } } #[inline] fn try_fold(&mut self, init: B, mut f: G) -> Result where E: From, G: FnMut(B, U::Item) -> Result, { let mut acc = init; if let Some(cur) = &mut self.cur { acc = cur.try_fold(acc, &mut f)?; self.cur = None; } let cur = &mut self.cur; self.it.try_fold(acc, |acc, v| { let mut it = v.into_fallible_iter(); match it.try_fold(acc, &mut f) { Ok(acc) => Ok(acc), Err(e) => { *cur = Some(it); Err(e) } } }) } } /// An iterator which flattens an iterator of iterators, yielding those iterators' elements. pub struct Flatten where I: FallibleIterator, I::Item: IntoFallibleIterator, { it: I, cur: Option<::IntoFallibleIter>, } impl Clone for Flatten where I: FallibleIterator + Clone, I::Item: IntoFallibleIterator, ::IntoFallibleIter: Clone, { #[inline] fn clone(&self) -> Flatten { Flatten { it: self.it.clone(), cur: self.cur.clone(), } } } impl FallibleIterator for Flatten where I: FallibleIterator, I::Item: IntoFallibleIterator, { type Item = ::Item; type Error = ::Error; #[inline] fn next(&mut self) -> Result, Self::Error> { loop { if let Some(it) = &mut self.cur { if let Some(v) = it.next()? { return Ok(Some(v)); } } match self.it.next()? { Some(it) => self.cur = Some(it.into_fallible_iter()), None => return Ok(None), } } } #[inline] fn try_fold(&mut self, init: B, mut f: G) -> Result where E: From, G: FnMut(B, Self::Item) -> Result, { let mut acc = init; if let Some(cur) = &mut self.cur { acc = cur.try_fold(acc, &mut f)?; self.cur = None; } let cur = &mut self.cur; self.it.try_fold(acc, |acc, v| { let mut it = v.into_fallible_iter(); match it.try_fold(acc, &mut f) { Ok(acc) => Ok(acc), Err(e) => { *cur = Some(it); Err(e) } } }) } } /// An iterator that yields `Ok(None)` forever after the underlying iterator /// yields `Ok(None)` once. #[derive(Clone, Debug)] pub struct Fuse { it: I, done: bool, } impl FallibleIterator for Fuse where I: FallibleIterator, { type Item = I::Item; type Error = I::Error; #[inline] fn next(&mut self) -> Result, I::Error> { if self.done { return Ok(None); } match self.it.next()? { Some(i) => Ok(Some(i)), None => { self.done = true; Ok(None) } } } #[inline] fn size_hint(&self) -> (usize, Option) { if self.done { (0, Some(0)) } else { self.it.size_hint() } } #[inline] fn count(self) -> Result { if self.done { Ok(0) } else { self.it.count() } } #[inline] fn last(self) -> Result, I::Error> { if self.done { Ok(None) } else { self.it.last() } } #[inline] fn nth(&mut self, n: usize) -> Result, I::Error> { if self.done { Ok(None) } else { let v = self.it.nth(n)?; if v.is_none() { self.done = true; } Ok(v) } } #[inline] fn try_fold(&mut self, init: B, f: F) -> Result where E: From, F: FnMut(B, I::Item) -> Result, { if self.done { Ok(init) } else { self.it.try_fold(init, f) } } } /// An iterator which passes each element to a closure before returning it. #[derive(Clone, Debug)] pub struct Inspect { it: I, f: F, } impl FallibleIterator for Inspect where I: FallibleIterator, F: FnMut(&I::Item) -> Result<(), I::Error>, { type Item = I::Item; type Error = I::Error; #[inline] fn next(&mut self) -> Result, I::Error> { match self.it.next()? { Some(i) => { (self.f)(&i)?; Ok(Some(i)) } None => Ok(None), } } #[inline] fn size_hint(&self) -> (usize, Option) { self.it.size_hint() } #[inline] fn try_fold(&mut self, init: B, mut f: G) -> Result where E: From, G: FnMut(B, I::Item) -> Result, { let inspect = &mut self.f; self.it.try_fold(init, |acc, v| { inspect(&v)?; f(acc, v) }) } } impl DoubleEndedFallibleIterator for Inspect where I: DoubleEndedFallibleIterator, F: FnMut(&I::Item) -> Result<(), I::Error>, { #[inline] fn next_back(&mut self) -> Result, I::Error> { match self.it.next_back()? { Some(i) => { (self.f)(&i)?; Ok(Some(i)) } None => Ok(None), } } #[inline] fn try_rfold(&mut self, init: B, mut f: G) -> Result where E: From, G: FnMut(B, I::Item) -> Result, { let inspect = &mut self.f; self.it.try_rfold(init, |acc, v| { inspect(&v)?; f(acc, v) }) } } /// A normal (non-fallible) iterator which wraps a fallible iterator. #[derive(Clone, Debug)] pub struct Iterator(I); impl iter::Iterator for Iterator where I: FallibleIterator, { type Item = Result; #[inline] fn next(&mut self) -> Option> { match self.0.next() { Ok(Some(v)) => Some(Ok(v)), Ok(None) => None, Err(e) => Some(Err(e)), } } #[inline] fn size_hint(&self) -> (usize, Option) { self.0.size_hint() } } impl DoubleEndedIterator for Iterator where I: DoubleEndedFallibleIterator, { #[inline] fn next_back(&mut self) -> Option> { match self.0.next_back() { Ok(Some(v)) => Some(Ok(v)), Ok(None) => None, Err(e) => Some(Err(e)), } } } /// An iterator which applies a transform to the errors of the underlying /// iterator. #[derive(Clone, Debug)] pub struct MapErr { it: I, f: F, } impl FallibleIterator for MapErr where I: FallibleIterator, F: FnMut(I::Error) -> B, { type Item = I::Item; type Error = B; #[inline] fn next(&mut self) -> Result, B> { self.it.next().map_err(&mut self.f) } #[inline] fn size_hint(&self) -> (usize, Option) { self.it.size_hint() } #[inline] fn count(mut self) -> Result { self.it.count().map_err(&mut self.f) } #[inline] fn last(mut self) -> Result, B> { self.it.last().map_err(&mut self.f) } #[inline] fn nth(&mut self, n: usize) -> Result, B> { self.it.nth(n).map_err(&mut self.f) } #[inline] fn try_fold(&mut self, init: C, mut f: G) -> Result where E: From, G: FnMut(C, I::Item) -> Result, { self.it .try_fold(init, |acc, v| f(acc, v).map_err(MappedErr::Fold)) .map_err(|e| match e { MappedErr::It(e) => (self.f)(e).into(), MappedErr::Fold(e) => e, }) } } impl DoubleEndedFallibleIterator for MapErr where I: DoubleEndedFallibleIterator, F: FnMut(I::Error) -> B, { #[inline] fn next_back(&mut self) -> Result, B> { self.it.next_back().map_err(&mut self.f) } #[inline] fn try_rfold(&mut self, init: C, mut f: G) -> Result where E: From, G: FnMut(C, I::Item) -> Result, { self.it .try_rfold(init, |acc, v| f(acc, v).map_err(MappedErr::Fold)) .map_err(|e| match e { MappedErr::It(e) => (self.f)(e).into(), MappedErr::Fold(e) => e, }) } } enum MappedErr { It(T), Fold(U), } impl From for MappedErr { #[inline] fn from(t: T) -> MappedErr { MappedErr::It(t) } } /// An iterator which can look at the next element without consuming it. #[derive(Clone, Debug)] pub struct Peekable { it: I, next: Option, } impl Peekable where I: FallibleIterator, { /// Returns a reference to the next value without advancing the iterator. #[inline] pub fn peek(&mut self) -> Result, I::Error> { if self.next.is_none() { self.next = self.it.next()?; } Ok(self.next.as_ref()) } } impl FallibleIterator for Peekable where I: FallibleIterator, { type Item = I::Item; type Error = I::Error; #[inline] fn next(&mut self) -> Result, I::Error> { if let Some(next) = self.next.take() { return Ok(Some(next)); } self.it.next() } #[inline] fn size_hint(&self) -> (usize, Option) { let mut hint = self.it.size_hint(); if self.next.is_some() { hint.0 = hint.0.saturating_add(1); hint.1 = hint.1.and_then(|h| h.checked_add(1)); } hint } #[inline] fn try_fold(&mut self, init: B, mut f: F) -> Result where E: From, F: FnMut(B, I::Item) -> Result, { let mut acc = init; if let Some(v) = self.next.take() { acc = f(acc, v)?; } self.it.try_fold(acc, f) } } /// An iterator which yields elements of the underlying iterator in reverse /// order. #[derive(Clone, Debug)] pub struct Rev(I); impl FallibleIterator for Rev where I: DoubleEndedFallibleIterator, { type Item = I::Item; type Error = I::Error; #[inline] fn next(&mut self) -> Result, I::Error> { self.0.next_back() } #[inline] fn size_hint(&self) -> (usize, Option) { self.0.size_hint() } #[inline] fn count(self) -> Result { self.0.count() } #[inline] fn try_fold(&mut self, init: B, f: F) -> Result where E: From, F: FnMut(B, I::Item) -> Result, { self.0.try_rfold(init, f) } } impl DoubleEndedFallibleIterator for Rev where I: DoubleEndedFallibleIterator, { #[inline] fn next_back(&mut self) -> Result, I::Error> { self.0.next() } #[inline] fn try_rfold(&mut self, init: B, f: F) -> Result where E: From, F: FnMut(B, I::Item) -> Result, { self.0.try_fold(init, f) } } /// An iterator which applies a stateful closure. #[derive(Clone, Debug)] pub struct Scan { it: I, f: F, state: St, } impl FallibleIterator for Scan where I: FallibleIterator, F: FnMut(&mut St, I::Item) -> Result, I::Error>, { type Item = B; type Error = I::Error; #[inline] fn next(&mut self) -> Result, I::Error> { match self.it.next()? { Some(v) => (self.f)(&mut self.state, v), None => Ok(None), } } #[inline] fn size_hint(&self) -> (usize, Option) { let hint = self.it.size_hint(); (0, hint.1) } } /// An iterator which skips initial elements. #[derive(Clone, Debug)] pub struct Skip { it: I, n: usize, } impl FallibleIterator for Skip where I: FallibleIterator, { type Item = I::Item; type Error = I::Error; #[inline] fn next(&mut self) -> Result, I::Error> { if self.n == 0 { self.it.next() } else { let n = self.n; self.n = 0; self.it.nth(n) } } #[inline] fn size_hint(&self) -> (usize, Option) { let hint = self.it.size_hint(); ( hint.0.saturating_sub(self.n), hint.1.map(|x| x.saturating_sub(self.n)), ) } } /// An iterator which skips initial elements based on a predicate. #[derive(Clone, Debug)] pub struct SkipWhile { it: I, flag: bool, predicate: P, } impl FallibleIterator for SkipWhile where I: FallibleIterator, P: FnMut(&I::Item) -> Result, { type Item = I::Item; type Error = I::Error; #[inline] fn next(&mut self) -> Result, I::Error> { let flag = &mut self.flag; let pred = &mut self.predicate; self.it.find(move |x| { if *flag || !pred(x)? { *flag = true; Ok(true) } else { Ok(false) } }) } #[inline] fn size_hint(&self) -> (usize, Option) { let hint = self.it.size_hint(); if self.flag { hint } else { (0, hint.1) } } } /// An iterator which steps through the elements of the underlying iterator by a certain amount. #[derive(Clone, Debug)] pub struct StepBy { it: I, step: usize, first_take: bool, } impl FallibleIterator for StepBy where I: FallibleIterator, { type Item = I::Item; type Error = I::Error; #[inline] fn next(&mut self) -> Result, I::Error> { if self.first_take { self.first_take = false; self.it.next() } else { self.it.nth(self.step) } } fn size_hint(&self) -> (usize, Option) { let inner_hint = self.it.size_hint(); if self.first_take { let f = |n| { if n == 0 { 0 } else { 1 + (n - 1) / (self.step + 1) } }; (f(inner_hint.0), inner_hint.1.map(f)) } else { let f = |n| n / (self.step + 1); (f(inner_hint.0), inner_hint.1.map(f)) } } } /// An iterator which yields a limited number of elements from the underlying /// iterator. #[derive(Clone, Debug)] pub struct Take { it: I, remaining: usize, } impl FallibleIterator for Take where I: FallibleIterator, { type Item = I::Item; type Error = I::Error; #[inline] fn next(&mut self) -> Result, I::Error> { if self.remaining == 0 { return Ok(None); } let next = self.it.next(); if let Ok(Some(_)) = next { self.remaining -= 1; } next } #[inline] fn size_hint(&self) -> (usize, Option) { let hint = self.it.size_hint(); ( cmp::min(hint.0, self.remaining), hint.1.map(|n| cmp::min(n, self.remaining)), ) } } /// An iterator which yields elements based on a predicate. #[derive(Clone, Debug)] pub struct TakeWhile { it: I, flag: bool, predicate: P, } impl FallibleIterator for TakeWhile where I: FallibleIterator, P: FnMut(&I::Item) -> Result, { type Item = I::Item; type Error = I::Error; #[inline] fn next(&mut self) -> Result, I::Error> { if self.flag { Ok(None) } else { match self.it.next()? { Some(item) => { if (self.predicate)(&item)? { Ok(Some(item)) } else { self.flag = true; Ok(None) } } None => Ok(None), } } } #[inline] fn size_hint(&self) -> (usize, Option) { if self.flag { (0, Some(0)) } else { let hint = self.it.size_hint(); (0, hint.1) } } } /// An iterator which cycles another endlessly. #[derive(Clone, Debug)] pub struct Cycle { it: I, cur: I, } impl FallibleIterator for Cycle where I: FallibleIterator + Clone, { type Item = I::Item; type Error = I::Error; #[inline] fn next(&mut self) -> Result, I::Error> { match self.cur.next()? { None => { self.cur = self.it.clone(); self.cur.next() } Some(v) => Ok(Some(v)), } } #[inline] fn size_hint(&self) -> (usize, Option) { (usize::max_value(), None) } } /// An iterator that yields pairs of this iterator's and another iterator's /// values. #[derive(Clone, Debug)] pub struct Zip(T, U); impl FallibleIterator for Zip where T: FallibleIterator, U: FallibleIterator, { type Item = (T::Item, U::Item); type Error = T::Error; #[inline] fn next(&mut self) -> Result, T::Error> { match (self.0.next()?, self.1.next()?) { (Some(a), Some(b)) => Ok(Some((a, b))), _ => Ok(None), } } #[inline] fn size_hint(&self) -> (usize, Option) { let a = self.0.size_hint(); let b = self.1.size_hint(); let low = cmp::min(a.0, b.0); let high = match (a.1, b.1) { (Some(a), Some(b)) => Some(cmp::min(a, b)), (Some(a), None) => Some(a), (None, Some(b)) => Some(b), (None, None) => None, }; (low, high) } } fn _is_object_safe(_: &dyn DoubleEndedFallibleIterator) {}