#![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),
}
}
}
pub trait FallibleIterator {
type Item;
type Error;
fn next(&mut self) -> Result<Option<Self::Item>, Self::Error>;
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
(0, None)
}
#[inline]
fn count(self) -> Result<usize, Self::Error>
where
Self: Sized,
{
self.fold(0, |n, _| Ok(n + 1))
}
#[inline]
fn last(self) -> Result<Option<Self::Item>, Self::Error>
where
Self: Sized,
{
self.fold(None, |_, v| Ok(Some(v)))
}
#[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)
}
#[inline]
fn step_by(self, step: usize) -> StepBy<Self>
where
Self: Sized,
{
assert!(step != 0);
StepBy {
it: self,
step: step - 1,
first_take: true,
}
}
#[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,
}
}
#[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())
}
#[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 }
}
#[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))
}
#[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 }
}
#[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 }
}
#[inline]
fn enumerate(self) -> Enumerate<Self>
where
Self: Sized,
{
Enumerate { it: self, n: 0 }
}
#[inline]
fn peekable(self) -> Peekable<Self>
where
Self: Sized,
{
Peekable {
it: self,
next: None,
}
}
#[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,
}
}
#[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,
}
}
#[inline]
fn skip(self, n: usize) -> Skip<Self>
where
Self: Sized,
{
Skip { it: self, n }
}
#[inline]
fn take(self, n: usize) -> Take<Self>
where
Self: Sized,
{
Take {
it: self,
remaining: n,
}
}
#[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,
}
}
#[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,
}
}
#[inline]
fn flatten(self) -> Flatten<Self>
where
Self: Sized,
Self::Item: IntoFallibleIterator<Error = Self::Error>,
{
Flatten {
it: self,
cur: None,
}
}
#[inline]
fn fuse(self) -> Fuse<Self>
where
Self: Sized,
{
Fuse {
it: self,
done: false,
}
}
#[inline]
fn inspect<F>(self, f: F) -> Inspect<Self, F>
where
Self: Sized,
F: FnMut(&Self::Item) -> Result<(), Self::Error>,
{
Inspect { it: self, f }
}
#[inline]
fn by_ref(&mut self) -> &mut Self
where
Self: Sized,
{
self
}
#[inline]
fn collect<T>(self) -> Result<T, Self::Error>
where
T: FromFallibleIterator<Self::Item>,
Self: Sized,
{
T::from_fallible_iter(self)
}
#[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))
}
#[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)
}
#[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)
}
#[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()
}
#[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()
}
#[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()
}
#[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()
}
#[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()
}
#[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)))
}
#[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))
}
#[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)
}
#[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)))
}
#[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))
}
#[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)
}
#[inline]
fn rev(self) -> Rev<Self>
where
Self: Sized + DoubleEndedFallibleIterator,
{
Rev(self)
}
#[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))
}
#[inline]
fn cloned<'a, T>(self) -> Cloned<Self>
where
Self: Sized + FallibleIterator<Item = &'a T>,
T: 'a + Clone,
{
Cloned(self)
}
#[inline]
fn cycle(self) -> Cycle<Self>
where
Self: Sized + Clone,
{
Cycle {
it: self.clone(),
cur: self,
}
}
#[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),
},
}
}
}
#[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),
},
}
}
}
#[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);
}
}
}
}
}
#[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);
}
}
}
}
}
#[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),
},
}
}
}
#[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),
},
}
}
}
#[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),
},
}
}
}
#[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),
},
}
}
}
#[inline]
fn iterator(self) -> Iterator<Self>
where
Self: Sized,
{
Iterator(self)
}
#[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()
}
}
pub trait DoubleEndedFallibleIterator: FallibleIterator {
fn next_back(&mut self) -> Result<Option<Self::Item>, Self::Error>;
#[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)
}
#[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)
}
}
pub trait FromFallibleIterator<T>: Sized {
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)
}
}
pub trait IntoFallibleIterator {
type Item;
type Error;
type IntoFallibleIter: FallibleIterator<Item = Self::Item, Error = Self::Error>;
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
}
}
#[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,
}
#[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),
}
}
}
#[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()))
}
}
#[inline]
pub fn convert<T, E, I>(it: I) -> Convert<I>
where
I: iter::Iterator<Item = Result<T, E>>,
{
Convert(it)
}
#[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?))
}
}
#[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))
})
}
}
#[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)
}
},
)
}
}
#[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),
})
}
}
#[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)
}
}
})
}
}
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)
}
}
})
}
}
#[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)
}
}
}
#[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)
})
}
}
#[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)),
}
}
}
#[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)
}
}
#[derive(Clone, Debug)]
pub struct Peekable<I: FallibleIterator> {
it: I,
next: Option<I::Item>,
}
impl<I> Peekable<I>
where
I: FallibleIterator,
{
#[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)
}
}
#[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)
}
}
#[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)
}
}
#[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)),
)
}
}
#[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)
}
}
}
#[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))
}
}
}
#[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)),
)
}
}
#[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)
}
}
}
#[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)
}
}
#[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 = ()>) {}