#![doc(html_root_url = "https://sfackler.github.io/rust-fallible-iterator/doc/v0.1.0")]
use std::cmp;
pub trait FallibleIterator {
type Item;
type Error;
fn next(&mut self) -> Result<Option<Self::Item>, Self::Error>;
fn size_hint(&self) -> (usize, Option<usize>) {
(0, None)
}
fn by_ref(&mut self) -> &mut Self where Self: Sized {
self
}
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,
}
}
fn cloned<'a, T>(self) -> Cloned<Self>
where Self: Sized + FallibleIterator<Item = &'a T>,
T: 'a + Clone
{
Cloned(self)
}
fn count(mut self) -> Result<usize, Self::Error> where Self: Sized {
let mut count = 0;
while let Some(_) = try!(self.next()) {
count += 1;
}
Ok(count)
}
fn collect<T>(self) -> Result<T, Self::Error> where
T: FromFallibleIterator<Self::Item>,
Self: Sized
{
T::from_fallible_iterator(self)
}
fn enumerate(self) -> Enumerate<Self> where Self: Sized {
Enumerate {
it: self,
n: 0,
}
}
fn fuse(self) -> Fuse<Self> where Self: Sized {
Fuse {
it: self,
done: false,
}
}
fn last(mut self) -> Result<Option<Self::Item>, Self::Error> where Self: Sized {
let mut last = None;
while let Some(e) = try!(self.next()) {
last = Some(e);
}
Ok(last)
}
fn map<B, F>(self, f: F) -> Map<Self, F>
where F: FnMut(Self::Item) -> B,
Self: Sized
{
Map {
it: self,
f: f,
}
}
fn nth(&mut self, mut n: usize) -> Result<Option<Self::Item>, Self::Error> {
let mut it = self.take(n);
while let Some(e) = try!(it.next()) {
if n == 0 {
return Ok(Some(e));
}
n -= 1;
}
Ok(None)
}
fn peekable(self) -> Peekable<Self> where Self: Sized {
Peekable {
it: self,
next: None,
}
}
fn rev(self) -> Rev<Self> where Self: Sized + DoubleEndedFallibleIterator {
Rev(self)
}
fn take(self, n: usize) -> Take<Self> where Self: Sized {
Take {
it: self,
remaining: n,
}
}
}
impl<'a, I: FallibleIterator + ?Sized> FallibleIterator for &'a mut I {
type Item = I::Item;
type Error = I::Error;
fn next(&mut self) -> Result<Option<I::Item>, I::Error> {
(**self).next()
}
fn size_hint(&self) -> (usize, Option<usize>) {
(**self).size_hint()
}
}
impl<'a, I: DoubleEndedFallibleIterator + ?Sized> DoubleEndedFallibleIterator for &'a mut I {
fn next_back(&mut self) -> Result<Option<I::Item>, I::Error> {
(**self).next_back()
}
}
impl<I: FallibleIterator + ?Sized> FallibleIterator for Box<I> {
type Item = I::Item;
type Error = I::Error;
fn next(&mut self) -> Result<Option<I::Item>, I::Error> {
(**self).next()
}
fn size_hint(&self) -> (usize, Option<usize>) {
(**self).size_hint()
}
}
impl<I: DoubleEndedFallibleIterator + ?Sized> DoubleEndedFallibleIterator for Box<I> {
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>;
}
pub trait FromFallibleIterator<T>: Sized {
fn from_fallible_iterator<I>(it: I) -> Result<Self, I::Error>
where I: FallibleIterator<Item = T>;
}
impl<T> FromFallibleIterator<T> for Vec<T> {
fn from_fallible_iterator<I>(mut it: I) -> Result<Self, I::Error>
where I: FallibleIterator<Item = T>
{
let mut vec = Vec::with_capacity(it.size_hint().0);
while let Some(v) = try!(it.next()) {
vec.push(v);
}
Ok(vec)
}
}
pub trait IntoFallibleIterator {
type Item;
type Error;
type IntoIter: FallibleIterator<Item = Self::Item, Error = Self::Error>;
fn into_fallible_iterator(self) -> Self::IntoIter;
}
impl<I> IntoFallibleIterator for I
where I: FallibleIterator
{
type Item = I::Item;
type Error = I::Error;
type IntoIter = I;
fn into_fallible_iterator(self) -> I {
self
}
}
#[derive(Debug)]
enum ChainState {
Both,
Front,
Back,
}
#[derive(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;
fn next(&mut self) -> Result<Option<T::Item>, T::Error> {
match self.state {
ChainState::Both => {
match try!(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(),
}
}
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)
}
fn count(self) -> Result<usize, T::Error> {
match self.state {
ChainState::Both => Ok(try!(self.front.count()) + try!(self.back.count())),
ChainState::Front => self.front.count(),
ChainState::Back => self.back.count(),
}
}
}
impl<T, U> DoubleEndedFallibleIterator for Chain<T, U>
where T: DoubleEndedFallibleIterator,
U: DoubleEndedFallibleIterator<Item = T::Item, Error = T::Error>
{
fn next_back(&mut self) -> Result<Option<T::Item>, T::Error> {
match self.state {
ChainState::Both => {
match try!(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(),
}
}
}
#[derive(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;
fn next(&mut self) -> Result<Option<T>, I::Error> {
self.0.next().map(|o| o.cloned())
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.0.size_hint()
}
fn count(self) -> Result<usize, I::Error> {
self.0.count()
}
}
impl<'a, T, I> DoubleEndedFallibleIterator for Cloned<I>
where I: DoubleEndedFallibleIterator<Item = &'a T>,
T: 'a + Clone
{
fn next_back(&mut self) -> Result<Option<T>, I::Error> {
self.0.next_back().map(|o| o.cloned())
}
}
pub fn convert<T, E, I>(it: I) -> Convert<I> where I: Iterator<Item = Result<T, E>> {
Convert(it)
}
#[derive(Debug)]
pub struct Convert<I>(I);
impl<T, E, I: Iterator<Item = Result<T, E>>> FallibleIterator for Convert<I> {
type Item = T;
type Error = E;
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),
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.0.size_hint()
}
}
#[derive(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;
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)
})
})
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.it.size_hint()
}
fn count(self) -> Result<usize, I::Error> {
self.it.count()
}
}
#[derive(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;
fn next(&mut self) -> Result<Option<I::Item>, I::Error> {
if self.done {
return Ok(None);
}
match self.it.next() {
Ok(Some(i)) => Ok(Some(i)),
Ok(None) => {
self.done = true;
Ok(None)
}
Err(e) => Err(e),
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.it.size_hint()
}
}
impl<T, E, I: DoubleEndedIterator<Item = Result<T, E>>> DoubleEndedFallibleIterator for Convert<I> {
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),
}
}
}
#[derive(Debug)]
pub struct Map<I, F> {
it: I,
f: F,
}
impl<B, F, I> FallibleIterator for Map<I, F>
where I: FallibleIterator,
F: FnMut(I::Item) -> B
{
type Item = B;
type Error = I::Error;
fn next(&mut self) -> Result<Option<B>, I::Error> {
self.it.next().map(|o| o.map(|i| (self.f)(i)))
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.it.size_hint()
}
fn count(self) -> Result<usize, I::Error> {
self.it.count()
}
}
impl<B, F, I> DoubleEndedFallibleIterator for Map<I, F>
where I: DoubleEndedFallibleIterator,
F: FnMut(I::Item) -> B
{
fn next_back(&mut self) -> Result<Option<B>, I::Error> {
self.it.next_back().map(|o| o.map(|i| (self.f)(i)))
}
}
#[derive(Debug)]
pub struct Peekable<I: FallibleIterator> {
it: I,
next: Option<I::Item>,
}
impl<I> Peekable<I> where I: FallibleIterator {
pub fn peek(&mut self) -> Result<Option<&I::Item>, I::Error> {
if self.next.is_none() {
self.next = try!(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;
fn next(&mut self) -> Result<Option<I::Item>, I::Error> {
if let Some(next) = self.next.take() {
return Ok(Some(next));
}
self.it.next()
}
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
}
}
#[derive(Debug)]
pub struct Rev<I>(I);
impl<I> FallibleIterator for Rev<I> where I: DoubleEndedFallibleIterator {
type Item = I::Item;
type Error = I::Error;
fn next(&mut self) -> Result<Option<I::Item>, I::Error> {
self.0.next_back()
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.0.size_hint()
}
fn count(self) -> Result<usize, I::Error> {
self.0.count()
}
}
impl<I> DoubleEndedFallibleIterator for Rev<I> where I: DoubleEndedFallibleIterator {
fn next_back(&mut self) -> Result<Option<I::Item>, I::Error> {
self.0.next()
}
}
#[derive(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;
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
}
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)))
}
}
#[cfg(test)]
mod test {
use super::*;
fn _is_object_safe(_: &FallibleIterator<Item = (), Error = ()>) {}
}