| //! "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<T, E>` values; for example, the `Lines` iterator |
| //! returns `io::Result<String>`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<Option<Self::Item>, |
| //! Self::Error>` rather than `Option<Self::Item>`. 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<T, Self::Error>` 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<bool, Self::Error>`: |
| //! |
| //! ``` |
| //! # 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<Error>>)); |
| //! 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<T, E> { |
| Break(T), |
| Err(E), |
| } |
| |
| impl<T, E> From<E> for FoldStop<T, E> { |
| #[inline] |
| fn from(e: E) -> FoldStop<T, E> { |
| FoldStop::Err(e) |
| } |
| } |
| |
| trait ResultExt<T, E> { |
| fn unpack_fold(self) -> Result<T, E>; |
| } |
| |
| impl<T, E> ResultExt<T, E> for Result<T, FoldStop<T, E>> { |
| #[inline] |
| fn unpack_fold(self) -> Result<T, E> { |
| 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<Option<Self::Item>, 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<usize>) { |
| (0, None) |
| } |
| |
| /// Consumes the iterator, returning the number of remaining items. |
| #[inline] |
| fn count(self) -> Result<usize, Self::Error> |
| where |
| Self: Sized, |
| { |
| self.fold(0, |n, _| Ok(n + 1)) |
| } |
| |
| /// Returns the last element of the iterator. |
| #[inline] |
| fn last(self) -> Result<Option<Self::Item>, 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<Option<Self::Item>, 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<Self> |
| 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<I>(self, it: I) -> Chain<Self, I> |
| where |
| I: IntoFallibleIterator<Item = Self::Item, Error = Self::Error>, |
| 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<I>(self, o: I) -> Zip<Self, I::IntoFallibleIter> |
| where |
| Self: Sized, |
| I: IntoFallibleIterator<Error = Self::Error>, |
| { |
| Zip(self, o.into_fallible_iter()) |
| } |
| |
| /// Returns an iterator which applies a fallible transform to the elements |
| /// of the underlying iterator. |
| #[inline] |
| fn map<F, B>(self, f: F) -> Map<Self, F> |
| where |
| Self: Sized, |
| F: FnMut(Self::Item) -> Result<B, Self::Error>, |
| { |
| Map { it: self, f: f } |
| } |
| |
| /// Calls a fallible closure on each element of an iterator. |
| #[inline] |
| fn for_each<F>(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<F>(self, f: F) -> Filter<Self, F> |
| where |
| Self: Sized, |
| F: FnMut(&Self::Item) -> Result<bool, Self::Error>, |
| { |
| 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<B, F>(self, f: F) -> FilterMap<Self, F> |
| where |
| Self: Sized, |
| F: FnMut(Self::Item) -> Result<Option<B>, 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<Self> |
| 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<Self> |
| where |
| Self: Sized, |
| { |
| Peekable { |
| it: self, |
| next: None, |
| } |
| } |
| |
| /// Returns an iterator that skips elements based on a predicate. |
| #[inline] |
| fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P> |
| where |
| Self: Sized, |
| P: FnMut(&Self::Item) -> Result<bool, Self::Error>, |
| { |
| SkipWhile { |
| it: self, |
| flag: false, |
| predicate, |
| } |
| } |
| |
| /// Returns an iterator that yields elements based on a predicate. |
| #[inline] |
| fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P> |
| where |
| Self: Sized, |
| P: FnMut(&Self::Item) -> Result<bool, Self::Error>, |
| { |
| 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<Self> |
| 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<Self> |
| where |
| Self: Sized, |
| { |
| Take { |
| it: self, |
| remaining: n, |
| } |
| } |
| |
| /// Returns an iterator which applies a stateful map to values of this |
| /// iterator. |
| #[inline] |
| fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F> |
| where |
| Self: Sized, |
| F: FnMut(&mut St, Self::Item) -> Result<Option<B>, 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<U, F>(self, f: F) -> FlatMap<Self, U, F> |
| where |
| Self: Sized, |
| U: IntoFallibleIterator<Error = Self::Error>, |
| F: FnMut(Self::Item) -> Result<U, Self::Error>, |
| { |
| 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<Self> |
| where |
| Self: Sized, |
| Self::Item: IntoFallibleIterator<Error = Self::Error>, |
| { |
| 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<Self> |
| where |
| Self: Sized, |
| { |
| Fuse { |
| it: self, |
| done: false, |
| } |
| } |
| |
| /// Returns an iterator which passes each element to a closure before returning it. |
| #[inline] |
| fn inspect<F>(self, f: F) -> Inspect<Self, F> |
| 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<T>(self) -> Result<T, Self::Error> |
| where |
| T: FromFallibleIterator<Self::Item>, |
| Self: Sized, |
| { |
| T::from_fallible_iter(self) |
| } |
| |
| /// Transforms the iterator into two collections, partitioning elements by a closure. |
| #[inline] |
| fn partition<B, F>(self, mut f: F) -> Result<(B, B), Self::Error> |
| where |
| Self: Sized, |
| B: Default + Extend<Self::Item>, |
| F: FnMut(&Self::Item) -> Result<bool, Self::Error>, |
| { |
| 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<B, F>(mut self, init: B, f: F) -> Result<B, Self::Error> |
| where |
| Self: Sized, |
| F: FnMut(B, Self::Item) -> Result<B, Self::Error>, |
| { |
| 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<B, E, F>(&mut self, mut init: B, mut f: F) -> Result<B, E> |
| where |
| Self: Sized, |
| E: From<Self::Error>, |
| F: FnMut(B, Self::Item) -> Result<B, E>, |
| { |
| 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<F>(&mut self, mut f: F) -> Result<bool, Self::Error> |
| where |
| Self: Sized, |
| F: FnMut(Self::Item) -> Result<bool, Self::Error>, |
| { |
| 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<F>(&mut self, mut f: F) -> Result<bool, Self::Error> |
| where |
| Self: Sized, |
| F: FnMut(Self::Item) -> Result<bool, Self::Error>, |
| { |
| 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<F>(&mut self, mut f: F) -> Result<Option<Self::Item>, Self::Error> |
| where |
| Self: Sized, |
| F: FnMut(&Self::Item) -> Result<bool, Self::Error>, |
| { |
| 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<B, F>(&mut self, f: F) -> Result<Option<B>, Self::Error> |
| where |
| Self: Sized, |
| F: FnMut(Self::Item) -> Result<Option<B>, 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<F>(&mut self, mut f: F) -> Result<Option<usize>, Self::Error> |
| where |
| Self: Sized, |
| F: FnMut(Self::Item) -> Result<bool, Self::Error>, |
| { |
| 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<Option<Self::Item>, 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<B, F>(mut self, mut f: F) -> Result<Option<Self::Item>, Self::Error> |
| where |
| Self: Sized, |
| B: Ord, |
| F: FnMut(&Self::Item) -> Result<B, Self::Error>, |
| { |
| 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<F>(mut self, mut f: F) -> Result<Option<Self::Item>, Self::Error> |
| where |
| Self: Sized, |
| F: FnMut(&Self::Item, &Self::Item) -> Result<Ordering, Self::Error>, |
| { |
| 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<Option<Self::Item>, 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<B, F>(mut self, mut f: F) -> Result<Option<Self::Item>, Self::Error> |
| where |
| Self: Sized, |
| B: Ord, |
| F: FnMut(&Self::Item) -> Result<B, Self::Error>, |
| { |
| 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<F>(mut self, mut f: F) -> Result<Option<Self::Item>, Self::Error> |
| where |
| Self: Sized, |
| F: FnMut(&Self::Item, &Self::Item) -> Result<Ordering, Self::Error>, |
| { |
| 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<Self> |
| where |
| Self: Sized + DoubleEndedFallibleIterator, |
| { |
| Rev(self) |
| } |
| |
| /// Converts an iterator of pairs into a pair of containers. |
| #[inline] |
| fn unzip<A, B, FromA, FromB>(self) -> Result<(FromA, FromB), Self::Error> |
| where |
| Self: Sized + FallibleIterator<Item = (A, B)>, |
| FromA: Default + Extend<A>, |
| FromB: Default + Extend<B>, |
| { |
| 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<Self> |
| where |
| Self: Sized + FallibleIterator<Item = &'a T>, |
| T: 'a + Clone, |
| { |
| Cloned(self) |
| } |
| |
| /// Returns an iterator which repeas this iterator endlessly. |
| #[inline] |
| fn cycle(self) -> Cycle<Self> |
| where |
| Self: Sized + Clone, |
| { |
| Cycle { |
| it: self.clone(), |
| cur: self, |
| } |
| } |
| |
| /// Lexicographically compares the elements of this iterator to that of |
| /// another. |
| #[inline] |
| fn cmp<I>(mut self, other: I) -> Result<Ordering, Self::Error> |
| where |
| Self: Sized, |
| I: IntoFallibleIterator<Item = Self::Item, Error = Self::Error>, |
| 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<I>(mut self, other: I) -> Result<Option<Ordering>, Self::Error> |
| where |
| Self: Sized, |
| I: IntoFallibleIterator<Error = Self::Error>, |
| Self::Item: PartialOrd<I::Item>, |
| { |
| 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<I>(mut self, other: I) -> Result<bool, Self::Error> |
| where |
| Self: Sized, |
| I: IntoFallibleIterator<Error = Self::Error>, |
| Self::Item: PartialEq<I::Item>, |
| { |
| 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<I>(mut self, other: I) -> Result<bool, Self::Error> |
| where |
| Self: Sized, |
| I: IntoFallibleIterator<Error = Self::Error>, |
| Self::Item: PartialEq<I::Item>, |
| { |
| 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<I>(mut self, other: I) -> Result<bool, Self::Error> |
| where |
| Self: Sized, |
| I: IntoFallibleIterator<Error = Self::Error>, |
| Self::Item: PartialOrd<I::Item>, |
| { |
| 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<I>(mut self, other: I) -> Result<bool, Self::Error> |
| where |
| Self: Sized, |
| I: IntoFallibleIterator<Error = Self::Error>, |
| Self::Item: PartialOrd<I::Item>, |
| { |
| 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<I>(mut self, other: I) -> Result<bool, Self::Error> |
| where |
| Self: Sized, |
| I: IntoFallibleIterator<Error = Self::Error>, |
| Self::Item: PartialOrd<I::Item>, |
| { |
| 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<I>(mut self, other: I) -> Result<bool, Self::Error> |
| where |
| Self: Sized, |
| I: IntoFallibleIterator<Error = Self::Error>, |
| Self::Item: PartialOrd<I::Item>, |
| { |
| 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<Item, Error>`. |
| #[inline] |
| fn iterator(self) -> Iterator<Self> |
| where |
| Self: Sized, |
| { |
| Iterator(self) |
| } |
| |
| /// Returns an iterator which applies a transform to the errors of the |
| /// underlying iterator. |
| #[inline] |
| fn map_err<B, F>(self, f: F) -> MapErr<Self, F> |
| where |
| F: FnMut(Self::Error) -> B, |
| Self: Sized, |
| { |
| MapErr { it: self, f: f } |
| } |
| } |
| |
| impl<I: FallibleIterator + ?Sized> FallibleIterator for &mut I { |
| type Item = I::Item; |
| type Error = I::Error; |
| |
| #[inline] |
| fn next(&mut self) -> Result<Option<I::Item>, I::Error> { |
| (**self).next() |
| } |
| |
| #[inline] |
| fn size_hint(&self) -> (usize, Option<usize>) { |
| (**self).size_hint() |
| } |
| |
| #[inline] |
| fn nth(&mut self, n: usize) -> Result<Option<I::Item>, I::Error> { |
| (**self).nth(n) |
| } |
| } |
| |
| impl<I: DoubleEndedFallibleIterator + ?Sized> DoubleEndedFallibleIterator for &mut I { |
| #[inline] |
| fn next_back(&mut self) -> Result<Option<I::Item>, I::Error> { |
| (**self).next_back() |
| } |
| } |
| |
| #[cfg(any(feature = "std", feature = "alloc"))] |
| impl<I: FallibleIterator + ?Sized> FallibleIterator for Box<I> { |
| type Item = I::Item; |
| type Error = I::Error; |
| |
| #[inline] |
| fn next(&mut self) -> Result<Option<I::Item>, I::Error> { |
| (**self).next() |
| } |
| |
| #[inline] |
| fn size_hint(&self) -> (usize, Option<usize>) { |
| (**self).size_hint() |
| } |
| |
| #[inline] |
| fn nth(&mut self, n: usize) -> Result<Option<I::Item>, I::Error> { |
| (**self).nth(n) |
| } |
| } |
| |
| #[cfg(any(feature = "std", feature = "alloc"))] |
| impl<I: DoubleEndedFallibleIterator + ?Sized> DoubleEndedFallibleIterator for Box<I> { |
| #[inline] |
| fn next_back(&mut self) -> Result<Option<I::Item>, 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<Option<Self::Item>, Self::Error>; |
| |
| /// Applies a function over the elements of the iterator in reverse order, producing a single final value. |
| #[inline] |
| fn rfold<B, F>(mut self, init: B, f: F) -> Result<B, Self::Error> |
| where |
| Self: Sized, |
| F: FnMut(B, Self::Item) -> Result<B, Self::Error>, |
| { |
| 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<B, E, F>(&mut self, mut init: B, mut f: F) -> Result<B, E> |
| where |
| Self: Sized, |
| E: From<Self::Error>, |
| F: FnMut(B, Self::Item) -> Result<B, E>, |
| { |
| while let Some(v) = self.next_back()? { |
| init = f(init, v)?; |
| } |
| Ok(init) |
| } |
| } |
| |
| /// Conversion from a fallible iterator. |
| pub trait FromFallibleIterator<T>: Sized { |
| /// Creates a value from a fallible iterator. |
| fn from_fallible_iter<I>(it: I) -> Result<Self, I::Error> |
| where |
| I: IntoFallibleIterator<Item = T>; |
| } |
| |
| #[cfg(any(feature = "std", feature = "alloc"))] |
| impl<T> FromFallibleIterator<T> for Vec<T> { |
| #[inline] |
| fn from_fallible_iter<I>(it: I) -> Result<Vec<T>, I::Error> |
| where |
| I: IntoFallibleIterator<Item = T>, |
| { |
| 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<T, S> FromFallibleIterator<T> for HashSet<T, S> |
| where |
| T: Hash + Eq, |
| S: BuildHasher + Default, |
| { |
| #[inline] |
| fn from_fallible_iter<I>(it: I) -> Result<HashSet<T, S>, I::Error> |
| where |
| I: IntoFallibleIterator<Item = T>, |
| { |
| 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<K, V, S> FromFallibleIterator<(K, V)> for HashMap<K, V, S> |
| where |
| K: Hash + Eq, |
| S: BuildHasher + Default, |
| { |
| #[inline] |
| fn from_fallible_iter<I>(it: I) -> Result<HashMap<K, V, S>, I::Error> |
| where |
| I: IntoFallibleIterator<Item = (K, V)>, |
| { |
| 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<T> FromFallibleIterator<T> for BTreeSet<T> |
| where |
| T: Ord, |
| { |
| #[inline] |
| fn from_fallible_iter<I>(it: I) -> Result<BTreeSet<T>, I::Error> |
| where |
| I: IntoFallibleIterator<Item = T>, |
| { |
| 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<K, V> FromFallibleIterator<(K, V)> for BTreeMap<K, V> |
| where |
| K: Ord, |
| { |
| #[inline] |
| fn from_fallible_iter<I>(it: I) -> Result<BTreeMap<K, V>, I::Error> |
| where |
| I: IntoFallibleIterator<Item = (K, V)>, |
| { |
| 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<Item = Self::Item, Error = Self::Error>; |
| |
| /// Creates a fallible iterator from a value. |
| fn into_fallible_iter(self) -> Self::IntoFallibleIter; |
| } |
| |
| impl<I> 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<T, F> { |
| it: T, |
| f: F, |
| } |
| |
| impl<T, F, B> FallibleIterator for Map<T, F> |
| where |
| T: FallibleIterator, |
| F: FnMut(T::Item) -> Result<B, T::Error>, |
| { |
| type Item = B; |
| type Error = T::Error; |
| |
| #[inline] |
| fn next(&mut self) -> Result<Option<B>, 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<usize>) { |
| self.it.size_hint() |
| } |
| |
| #[inline] |
| fn try_fold<C, E, G>(&mut self, init: C, mut f: G) -> Result<C, E> |
| where |
| E: From<T::Error>, |
| G: FnMut(C, B) -> Result<C, E>, |
| { |
| let map = &mut self.f; |
| self.it.try_fold(init, |b, v| f(b, map(v)?)) |
| } |
| } |
| |
| impl<B, F, I> DoubleEndedFallibleIterator for Map<I, F> |
| where |
| I: DoubleEndedFallibleIterator, |
| F: FnMut(I::Item) -> Result<B, I::Error>, |
| { |
| #[inline] |
| fn next_back(&mut self) -> Result<Option<B>, 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<C, E, G>(&mut self, init: C, mut f: G) -> Result<C, E> |
| where |
| E: From<I::Error>, |
| G: FnMut(C, B) -> Result<C, E>, |
| { |
| 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<T, U> { |
| front: T, |
| back: U, |
| state: ChainState, |
| } |
| |
| impl<T, U> FallibleIterator for Chain<T, U> |
| where |
| T: FallibleIterator, |
| U: FallibleIterator<Item = T::Item, Error = T::Error>, |
| { |
| type Item = T::Item; |
| type Error = T::Error; |
| |
| #[inline] |
| fn next(&mut self) -> Result<Option<T::Item>, 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<usize>) { |
| 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<usize, T::Error> { |
| 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<B, E, F>(&mut self, init: B, mut f: F) -> Result<B, E> |
| where |
| E: From<T::Error>, |
| F: FnMut(B, T::Item) -> Result<B, E>, |
| { |
| 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<F>(&mut self, mut f: F) -> Result<Option<T::Item>, T::Error> |
| where |
| F: FnMut(&T::Item) -> Result<bool, T::Error>, |
| { |
| 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<Option<T::Item>, T::Error> { |
| match self.state { |
| ChainState::Both => { |
| self.front.last()?; |
| self.back.last() |
| } |
| ChainState::Front => self.front.last(), |
| ChainState::Back => self.back.last(), |
| } |
| } |
| } |
| |
| impl<T, U> DoubleEndedFallibleIterator for Chain<T, U> |
| where |
| T: DoubleEndedFallibleIterator, |
| U: DoubleEndedFallibleIterator<Item = T::Item, Error = T::Error>, |
| { |
| #[inline] |
| fn next_back(&mut self) -> Result<Option<T::Item>, 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<B, E, F>(&mut self, init: B, mut f: F) -> Result<B, E> |
| where |
| E: From<T::Error>, |
| F: FnMut(B, T::Item) -> Result<B, E>, |
| { |
| 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>(I); |
| |
| impl<'a, T, I> FallibleIterator for Cloned<I> |
| where |
| I: FallibleIterator<Item = &'a T>, |
| T: 'a + Clone, |
| { |
| type Item = T; |
| type Error = I::Error; |
| |
| #[inline] |
| fn next(&mut self) -> Result<Option<T>, I::Error> { |
| self.0.next().map(|o| o.cloned()) |
| } |
| |
| #[inline] |
| fn size_hint(&self) -> (usize, Option<usize>) { |
| self.0.size_hint() |
| } |
| |
| #[inline] |
| fn try_fold<B, E, F>(&mut self, init: B, mut f: F) -> Result<B, E> |
| where |
| E: From<I::Error>, |
| F: FnMut(B, T) -> Result<B, E>, |
| { |
| self.0.try_fold(init, |acc, v| f(acc, v.clone())) |
| } |
| } |
| |
| impl<'a, T, I> DoubleEndedFallibleIterator for Cloned<I> |
| where |
| I: DoubleEndedFallibleIterator<Item = &'a T>, |
| T: 'a + Clone, |
| { |
| #[inline] |
| fn next_back(&mut self) -> Result<Option<T>, I::Error> { |
| self.0.next_back().map(|o| o.cloned()) |
| } |
| |
| #[inline] |
| fn try_rfold<B, E, F>(&mut self, init: B, mut f: F) -> Result<B, E> |
| where |
| E: From<I::Error>, |
| F: FnMut(B, T) -> Result<B, E>, |
| { |
| self.0.try_rfold(init, |acc, v| f(acc, v.clone())) |
| } |
| } |
| |
| /// Converts an `Iterator<Item = Result<T, E>>` into a `FallibleIterator<Item = T, Error = E>`. |
| #[inline] |
| pub fn convert<T, E, I>(it: I) -> Convert<I> |
| where |
| I: iter::Iterator<Item = Result<T, E>>, |
| { |
| Convert(it) |
| } |
| |
| /// A fallible iterator that wraps a normal iterator over `Result`s. |
| #[derive(Clone, Debug)] |
| pub struct Convert<I>(I); |
| |
| impl<T, E, I> FallibleIterator for Convert<I> |
| where |
| I: iter::Iterator<Item = Result<T, E>>, |
| { |
| type Item = T; |
| type Error = E; |
| |
| #[inline] |
| fn next(&mut self) -> Result<Option<T>, 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<usize>) { |
| self.0.size_hint() |
| } |
| |
| #[inline] |
| fn try_fold<B, E2, F>(&mut self, init: B, mut f: F) -> Result<B, E2> |
| where |
| E2: From<E>, |
| F: FnMut(B, T) -> Result<B, E2>, |
| { |
| self.0.try_fold(init, |acc, v| f(acc, v?)) |
| } |
| } |
| |
| impl<T, E, I> DoubleEndedFallibleIterator for Convert<I> |
| where |
| I: DoubleEndedIterator<Item = Result<T, E>>, |
| { |
| #[inline] |
| fn next_back(&mut self) -> Result<Option<T>, E> { |
| match self.0.next_back() { |
| Some(Ok(i)) => Ok(Some(i)), |
| Some(Err(e)) => Err(e), |
| None => Ok(None), |
| } |
| } |
| |
| #[inline] |
| fn try_rfold<B, E2, F>(&mut self, init: B, mut f: F) -> Result<B, E2> |
| where |
| E2: From<E>, |
| F: FnMut(B, T) -> Result<B, E2>, |
| { |
| 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<I> { |
| it: I, |
| n: usize, |
| } |
| |
| impl<I> FallibleIterator for Enumerate<I> |
| where |
| I: FallibleIterator, |
| { |
| type Item = (usize, I::Item); |
| type Error = I::Error; |
| |
| #[inline] |
| fn next(&mut self) -> Result<Option<(usize, I::Item)>, 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<usize>) { |
| self.it.size_hint() |
| } |
| |
| #[inline] |
| fn count(self) -> Result<usize, I::Error> { |
| self.it.count() |
| } |
| |
| #[inline] |
| fn nth(&mut self, n: usize) -> Result<Option<(usize, I::Item)>, 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<B, E, F>(&mut self, init: B, mut f: F) -> Result<B, E> |
| where |
| E: From<I::Error>, |
| F: FnMut(B, (usize, I::Item)) -> Result<B, E>, |
| { |
| 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<I, F> { |
| it: I, |
| f: F, |
| } |
| |
| impl<I, F> FallibleIterator for Filter<I, F> |
| where |
| I: FallibleIterator, |
| F: FnMut(&I::Item) -> Result<bool, I::Error>, |
| { |
| type Item = I::Item; |
| type Error = I::Error; |
| |
| #[inline] |
| fn next(&mut self) -> Result<Option<I::Item>, 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<usize>) { |
| (0, self.it.size_hint().1) |
| } |
| |
| #[inline] |
| fn try_fold<B, E, G>(&mut self, init: B, mut f: G) -> Result<B, E> |
| where |
| E: From<I::Error>, |
| G: FnMut(B, I::Item) -> Result<B, E>, |
| { |
| let predicate = &mut self.f; |
| self.it.try_fold( |
| init, |
| |acc, v| { |
| if predicate(&v)? { |
| f(acc, v) |
| } else { |
| Ok(acc) |
| } |
| }, |
| ) |
| } |
| } |
| |
| impl<I, F> DoubleEndedFallibleIterator for Filter<I, F> |
| where |
| I: DoubleEndedFallibleIterator, |
| F: FnMut(&I::Item) -> Result<bool, I::Error>, |
| { |
| #[inline] |
| fn next_back(&mut self) -> Result<Option<I::Item>, 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<B, E, G>(&mut self, init: B, mut f: G) -> Result<B, E> |
| where |
| E: From<I::Error>, |
| G: FnMut(B, I::Item) -> Result<B, E>, |
| { |
| 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<I, F> { |
| it: I, |
| f: F, |
| } |
| |
| impl<B, I, F> FallibleIterator for FilterMap<I, F> |
| where |
| I: FallibleIterator, |
| F: FnMut(I::Item) -> Result<Option<B>, I::Error>, |
| { |
| type Item = B; |
| type Error = I::Error; |
| |
| #[inline] |
| fn next(&mut self) -> Result<Option<B>, 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<usize>) { |
| (0, self.it.size_hint().1) |
| } |
| |
| #[inline] |
| fn try_fold<C, E, G>(&mut self, init: C, mut f: G) -> Result<C, E> |
| where |
| E: From<I::Error>, |
| G: FnMut(C, B) -> Result<C, E>, |
| { |
| let map = &mut self.f; |
| self.it.try_fold(init, |acc, v| match map(v)? { |
| Some(v) => f(acc, v), |
| None => Ok(acc), |
| }) |
| } |
| } |
| |
| impl<B, I, F> DoubleEndedFallibleIterator for FilterMap<I, F> |
| where |
| I: DoubleEndedFallibleIterator, |
| F: FnMut(I::Item) -> Result<Option<B>, I::Error>, |
| { |
| #[inline] |
| fn next_back(&mut self) -> Result<Option<B>, 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<C, E, G>(&mut self, init: C, mut f: G) -> Result<C, E> |
| where |
| E: From<I::Error>, |
| G: FnMut(C, B) -> Result<C, E>, |
| { |
| 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<I, U, F> |
| where |
| U: IntoFallibleIterator, |
| { |
| it: Map<I, F>, |
| cur: Option<U::IntoFallibleIter>, |
| } |
| |
| impl<I, U, F> FallibleIterator for FlatMap<I, U, F> |
| where |
| I: FallibleIterator, |
| U: IntoFallibleIterator<Error = I::Error>, |
| F: FnMut(I::Item) -> Result<U, I::Error>, |
| { |
| type Item = U::Item; |
| type Error = U::Error; |
| |
| #[inline] |
| fn next(&mut self) -> Result<Option<U::Item>, 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<B, E, G>(&mut self, init: B, mut f: G) -> Result<B, E> |
| where |
| E: From<U::Error>, |
| G: FnMut(B, U::Item) -> Result<B, E>, |
| { |
| 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<I> |
| where |
| I: FallibleIterator, |
| I::Item: IntoFallibleIterator, |
| { |
| it: I, |
| cur: Option<<I::Item as IntoFallibleIterator>::IntoFallibleIter>, |
| } |
| |
| impl<I> Clone for Flatten<I> |
| where |
| I: FallibleIterator + Clone, |
| I::Item: IntoFallibleIterator, |
| <I::Item as IntoFallibleIterator>::IntoFallibleIter: Clone, |
| { |
| #[inline] |
| fn clone(&self) -> Flatten<I> { |
| Flatten { |
| it: self.it.clone(), |
| cur: self.cur.clone(), |
| } |
| } |
| } |
| |
| impl<I> FallibleIterator for Flatten<I> |
| where |
| I: FallibleIterator, |
| I::Item: IntoFallibleIterator<Error = I::Error>, |
| { |
| type Item = <I::Item as IntoFallibleIterator>::Item; |
| type Error = <I::Item as IntoFallibleIterator>::Error; |
| |
| #[inline] |
| fn next(&mut self) -> Result<Option<Self::Item>, 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<B, E, G>(&mut self, init: B, mut f: G) -> Result<B, E> |
| where |
| E: From<Self::Error>, |
| G: FnMut(B, Self::Item) -> Result<B, E>, |
| { |
| 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<I> { |
| it: I, |
| done: bool, |
| } |
| |
| impl<I> FallibleIterator for Fuse<I> |
| where |
| I: FallibleIterator, |
| { |
| type Item = I::Item; |
| type Error = I::Error; |
| |
| #[inline] |
| fn next(&mut self) -> Result<Option<I::Item>, 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<usize>) { |
| if self.done { |
| (0, Some(0)) |
| } else { |
| self.it.size_hint() |
| } |
| } |
| |
| #[inline] |
| fn count(self) -> Result<usize, I::Error> { |
| if self.done { |
| Ok(0) |
| } else { |
| self.it.count() |
| } |
| } |
| |
| #[inline] |
| fn last(self) -> Result<Option<I::Item>, I::Error> { |
| if self.done { |
| Ok(None) |
| } else { |
| self.it.last() |
| } |
| } |
| |
| #[inline] |
| fn nth(&mut self, n: usize) -> Result<Option<I::Item>, 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<B, E, F>(&mut self, init: B, f: F) -> Result<B, E> |
| where |
| E: From<I::Error>, |
| F: FnMut(B, I::Item) -> Result<B, E>, |
| { |
| 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<I, F> { |
| it: I, |
| f: F, |
| } |
| |
| impl<I, F> FallibleIterator for Inspect<I, F> |
| where |
| I: FallibleIterator, |
| F: FnMut(&I::Item) -> Result<(), I::Error>, |
| { |
| type Item = I::Item; |
| type Error = I::Error; |
| |
| #[inline] |
| fn next(&mut self) -> Result<Option<I::Item>, I::Error> { |
| match self.it.next()? { |
| Some(i) => { |
| (self.f)(&i)?; |
| Ok(Some(i)) |
| } |
| None => Ok(None), |
| } |
| } |
| |
| #[inline] |
| fn size_hint(&self) -> (usize, Option<usize>) { |
| self.it.size_hint() |
| } |
| |
| #[inline] |
| fn try_fold<B, E, G>(&mut self, init: B, mut f: G) -> Result<B, E> |
| where |
| E: From<I::Error>, |
| G: FnMut(B, I::Item) -> Result<B, E>, |
| { |
| let inspect = &mut self.f; |
| self.it.try_fold(init, |acc, v| { |
| inspect(&v)?; |
| f(acc, v) |
| }) |
| } |
| } |
| |
| impl<I, F> DoubleEndedFallibleIterator for Inspect<I, F> |
| where |
| I: DoubleEndedFallibleIterator, |
| F: FnMut(&I::Item) -> Result<(), I::Error>, |
| { |
| #[inline] |
| fn next_back(&mut self) -> Result<Option<I::Item>, I::Error> { |
| match self.it.next_back()? { |
| Some(i) => { |
| (self.f)(&i)?; |
| Ok(Some(i)) |
| } |
| None => Ok(None), |
| } |
| } |
| |
| #[inline] |
| fn try_rfold<B, E, G>(&mut self, init: B, mut f: G) -> Result<B, E> |
| where |
| E: From<I::Error>, |
| G: FnMut(B, I::Item) -> Result<B, E>, |
| { |
| 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>(I); |
| |
| impl<I> iter::Iterator for Iterator<I> |
| where |
| I: FallibleIterator, |
| { |
| type Item = Result<I::Item, I::Error>; |
| |
| #[inline] |
| fn next(&mut self) -> Option<Result<I::Item, I::Error>> { |
| 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<usize>) { |
| self.0.size_hint() |
| } |
| } |
| |
| impl<I> DoubleEndedIterator for Iterator<I> |
| where |
| I: DoubleEndedFallibleIterator, |
| { |
| #[inline] |
| fn next_back(&mut self) -> Option<Result<I::Item, I::Error>> { |
| 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<I, F> { |
| it: I, |
| f: F, |
| } |
| |
| impl<B, F, I> FallibleIterator for MapErr<I, F> |
| where |
| I: FallibleIterator, |
| F: FnMut(I::Error) -> B, |
| { |
| type Item = I::Item; |
| type Error = B; |
| |
| #[inline] |
| fn next(&mut self) -> Result<Option<I::Item>, B> { |
| self.it.next().map_err(&mut self.f) |
| } |
| |
| #[inline] |
| fn size_hint(&self) -> (usize, Option<usize>) { |
| self.it.size_hint() |
| } |
| |
| #[inline] |
| fn count(mut self) -> Result<usize, B> { |
| self.it.count().map_err(&mut self.f) |
| } |
| |
| #[inline] |
| fn last(mut self) -> Result<Option<I::Item>, B> { |
| self.it.last().map_err(&mut self.f) |
| } |
| |
| #[inline] |
| fn nth(&mut self, n: usize) -> Result<Option<I::Item>, B> { |
| self.it.nth(n).map_err(&mut self.f) |
| } |
| |
| #[inline] |
| fn try_fold<C, E, G>(&mut self, init: C, mut f: G) -> Result<C, E> |
| where |
| E: From<B>, |
| G: FnMut(C, I::Item) -> Result<C, E>, |
| { |
| 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<B, F, I> DoubleEndedFallibleIterator for MapErr<I, F> |
| where |
| I: DoubleEndedFallibleIterator, |
| F: FnMut(I::Error) -> B, |
| { |
| #[inline] |
| fn next_back(&mut self) -> Result<Option<I::Item>, B> { |
| self.it.next_back().map_err(&mut self.f) |
| } |
| |
| #[inline] |
| fn try_rfold<C, E, G>(&mut self, init: C, mut f: G) -> Result<C, E> |
| where |
| E: From<B>, |
| G: FnMut(C, I::Item) -> Result<C, E>, |
| { |
| 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<T, U> { |
| It(T), |
| Fold(U), |
| } |
| |
| impl<T, U> From<T> for MappedErr<T, U> { |
| #[inline] |
| fn from(t: T) -> MappedErr<T, U> { |
| MappedErr::It(t) |
| } |
| } |
| |
| /// An iterator which can look at the next element without consuming it. |
| #[derive(Clone, Debug)] |
| pub struct Peekable<I: FallibleIterator> { |
| it: I, |
| next: Option<I::Item>, |
| } |
| |
| impl<I> Peekable<I> |
| where |
| I: FallibleIterator, |
| { |
| /// Returns a reference to the next value without advancing the iterator. |
| #[inline] |
| pub fn peek(&mut self) -> Result<Option<&I::Item>, I::Error> { |
| if self.next.is_none() { |
| self.next = self.it.next()?; |
| } |
| |
| Ok(self.next.as_ref()) |
| } |
| } |
| |
| impl<I> FallibleIterator for Peekable<I> |
| where |
| I: FallibleIterator, |
| { |
| type Item = I::Item; |
| type Error = I::Error; |
| |
| #[inline] |
| fn next(&mut self) -> Result<Option<I::Item>, I::Error> { |
| if let Some(next) = self.next.take() { |
| return Ok(Some(next)); |
| } |
| |
| self.it.next() |
| } |
| |
| #[inline] |
| fn size_hint(&self) -> (usize, Option<usize>) { |
| 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<B, E, F>(&mut self, init: B, mut f: F) -> Result<B, E> |
| where |
| E: From<I::Error>, |
| F: FnMut(B, I::Item) -> Result<B, E>, |
| { |
| 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>(I); |
| |
| impl<I> FallibleIterator for Rev<I> |
| where |
| I: DoubleEndedFallibleIterator, |
| { |
| type Item = I::Item; |
| type Error = I::Error; |
| |
| #[inline] |
| fn next(&mut self) -> Result<Option<I::Item>, I::Error> { |
| self.0.next_back() |
| } |
| |
| #[inline] |
| fn size_hint(&self) -> (usize, Option<usize>) { |
| self.0.size_hint() |
| } |
| |
| #[inline] |
| fn count(self) -> Result<usize, I::Error> { |
| self.0.count() |
| } |
| |
| #[inline] |
| fn try_fold<B, E, F>(&mut self, init: B, f: F) -> Result<B, E> |
| where |
| E: From<I::Error>, |
| F: FnMut(B, I::Item) -> Result<B, E>, |
| { |
| self.0.try_rfold(init, f) |
| } |
| } |
| |
| impl<I> DoubleEndedFallibleIterator for Rev<I> |
| where |
| I: DoubleEndedFallibleIterator, |
| { |
| #[inline] |
| fn next_back(&mut self) -> Result<Option<I::Item>, I::Error> { |
| self.0.next() |
| } |
| |
| #[inline] |
| fn try_rfold<B, E, F>(&mut self, init: B, f: F) -> Result<B, E> |
| where |
| E: From<I::Error>, |
| F: FnMut(B, I::Item) -> Result<B, E>, |
| { |
| self.0.try_fold(init, f) |
| } |
| } |
| |
| /// An iterator which applies a stateful closure. |
| #[derive(Clone, Debug)] |
| pub struct Scan<I, St, F> { |
| it: I, |
| f: F, |
| state: St, |
| } |
| |
| impl<B, I, St, F> FallibleIterator for Scan<I, St, F> |
| where |
| I: FallibleIterator, |
| F: FnMut(&mut St, I::Item) -> Result<Option<B>, I::Error>, |
| { |
| type Item = B; |
| type Error = I::Error; |
| |
| #[inline] |
| fn next(&mut self) -> Result<Option<B>, I::Error> { |
| match self.it.next()? { |
| Some(v) => (self.f)(&mut self.state, v), |
| None => Ok(None), |
| } |
| } |
| |
| #[inline] |
| fn size_hint(&self) -> (usize, Option<usize>) { |
| let hint = self.it.size_hint(); |
| (0, hint.1) |
| } |
| } |
| |
| /// An iterator which skips initial elements. |
| #[derive(Clone, Debug)] |
| pub struct Skip<I> { |
| it: I, |
| n: usize, |
| } |
| |
| impl<I> FallibleIterator for Skip<I> |
| where |
| I: FallibleIterator, |
| { |
| type Item = I::Item; |
| type Error = I::Error; |
| |
| #[inline] |
| fn next(&mut self) -> Result<Option<I::Item>, 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<usize>) { |
| 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<I, P> { |
| it: I, |
| flag: bool, |
| predicate: P, |
| } |
| |
| impl<I, P> FallibleIterator for SkipWhile<I, P> |
| where |
| I: FallibleIterator, |
| P: FnMut(&I::Item) -> Result<bool, I::Error>, |
| { |
| type Item = I::Item; |
| type Error = I::Error; |
| |
| #[inline] |
| fn next(&mut self) -> Result<Option<I::Item>, 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<usize>) { |
| 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<I> { |
| it: I, |
| step: usize, |
| first_take: bool, |
| } |
| |
| impl<I> FallibleIterator for StepBy<I> |
| where |
| I: FallibleIterator, |
| { |
| type Item = I::Item; |
| type Error = I::Error; |
| |
| #[inline] |
| fn next(&mut self) -> Result<Option<I::Item>, 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<usize>) { |
| 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<I> { |
| it: I, |
| remaining: usize, |
| } |
| |
| impl<I> FallibleIterator for Take<I> |
| where |
| I: FallibleIterator, |
| { |
| type Item = I::Item; |
| type Error = I::Error; |
| |
| #[inline] |
| fn next(&mut self) -> Result<Option<I::Item>, 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<usize>) { |
| 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<I, P> { |
| it: I, |
| flag: bool, |
| predicate: P, |
| } |
| |
| impl<I, P> FallibleIterator for TakeWhile<I, P> |
| where |
| I: FallibleIterator, |
| P: FnMut(&I::Item) -> Result<bool, I::Error>, |
| { |
| type Item = I::Item; |
| type Error = I::Error; |
| |
| #[inline] |
| fn next(&mut self) -> Result<Option<I::Item>, 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<usize>) { |
| 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<I> { |
| it: I, |
| cur: I, |
| } |
| |
| impl<I> FallibleIterator for Cycle<I> |
| where |
| I: FallibleIterator + Clone, |
| { |
| type Item = I::Item; |
| type Error = I::Error; |
| |
| #[inline] |
| fn next(&mut self) -> Result<Option<I::Item>, 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>) { |
| (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>(T, U); |
| |
| impl<T, U> FallibleIterator for Zip<T, U> |
| where |
| T: FallibleIterator, |
| U: FallibleIterator<Error = T::Error>, |
| { |
| type Item = (T::Item, U::Item); |
| type Error = T::Error; |
| |
| #[inline] |
| fn next(&mut self) -> Result<Option<(T::Item, U::Item)>, 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<usize>) { |
| 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<Item = (), Error = ()>) {} |