#![doc(html_root_url = "https://docs.rs/fallible-streaming-iterator/0.1")]
#![warn(missing_docs)]
#![cfg_attr(not(feature = "std"), no_std)]
#[cfg(feature = "std")]
extern crate core;
use core::cmp;
use core::marker::PhantomData;
pub trait FallibleStreamingIterator {
type Item: ?Sized;
type Error;
fn advance(&mut self) -> Result<(), Self::Error>;
fn get(&self) -> Option<&Self::Item>;
#[inline]
fn next(&mut self) -> Result<Option<&Self::Item>, Self::Error> {
self.advance()?;
Ok((*self).get())
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
(0, None)
}
#[inline]
fn all<F>(&mut self, mut f: F) -> Result<bool, Self::Error>
where
Self: Sized,
F: FnMut(&Self::Item) -> bool,
{
while let Some(e) = self.next()? {
if !f(e) {
return Ok(false);
}
}
Ok(true)
}
#[inline]
fn any<F>(&mut self, mut f: F) -> Result<bool, Self::Error>
where
Self: Sized,
F: FnMut(&Self::Item) -> bool,
{
self.all(|e| !f(e)).map(|r| !r)
}
#[inline]
fn by_ref(&mut self) -> &mut Self
where
Self: Sized,
{
self
}
#[inline]
fn count(mut self) -> Result<usize, Self::Error>
where
Self: Sized,
{
let mut count = 0;
while let Some(_) = self.next()? {
count += 1;
}
Ok(count)
}
#[inline]
fn filter<F>(self, f: F) -> Filter<Self, F>
where
Self: Sized,
F: FnMut(&Self::Item) -> bool,
{
Filter { it: self, f: f }
}
#[inline]
fn find<F>(&mut self, mut f: F) -> Result<Option<&Self::Item>, Self::Error>
where
Self: Sized,
F: FnMut(&Self::Item) -> bool,
{
loop {
self.advance()?;
match self.get() {
Some(v) => {
if f(v) {
break;
}
}
None => break,
}
}
Ok((*self).get())
}
#[inline]
fn for_each<F>(mut self, mut f: F) -> Result<(), Self::Error>
where
Self: Sized,
F: FnMut(&Self::Item),
{
while let Some(value) = self.next()? {
f(value);
}
Ok(())
}
#[inline]
fn fuse(self) -> Fuse<Self>
where
Self: Sized,
{
Fuse {
it: self,
state: FuseState::Start,
}
}
#[inline]
fn map<F, B>(self, f: F) -> Map<Self, F, B>
where
Self: Sized,
F: FnMut(&Self::Item) -> B,
{
Map {
it: self,
f: f,
value: None,
}
}
#[inline]
fn map_ref<F, B: ?Sized>(self, f: F) -> MapRef<Self, F>
where
Self: Sized,
F: Fn(&Self::Item) -> &B,
{
MapRef { it: self, f: f }
}
#[inline]
fn map_err<F, B>(self, f: F) -> MapErr<Self, F>
where
Self: Sized,
F: Fn(Self::Error) -> B,
{
MapErr { it: self, f: f }
}
#[inline]
fn nth(&mut self, n: usize) -> Result<Option<&Self::Item>, Self::Error> {
for _ in 0..n {
self.advance()?;
if let None = self.get() {
return Ok(None);
}
}
self.next()
}
#[inline]
fn position<F>(&mut self, mut f: F) -> Result<Option<usize>, Self::Error>
where
Self: Sized,
F: FnMut(&Self::Item) -> bool,
{
let mut pos = 0;
while let Some(v) = self.next()? {
if f(v) {
return Ok(Some(pos));
}
pos += 1;
}
Ok(None)
}
#[inline]
fn skip(self, n: usize) -> Skip<Self>
where
Self: Sized,
{
Skip { it: self, n: n }
}
#[inline]
fn skip_while<F>(self, f: F) -> SkipWhile<Self, F>
where
Self: Sized,
F: FnMut(&Self::Item) -> bool,
{
SkipWhile {
it: self,
f: f,
done: false,
}
}
#[inline]
fn take(self, n: usize) -> Take<Self>
where
Self: Sized,
{
Take {
it: self,
n: n,
done: false,
}
}
#[inline]
fn take_while<F>(self, f: F) -> TakeWhile<Self, F>
where
Self: Sized,
F: FnMut(&Self::Item) -> bool,
{
TakeWhile {
it: self,
f: f,
done: false,
}
}
}
pub trait DoubleEndedFallibleStreamingIterator: FallibleStreamingIterator {
fn advance_back(&mut self) -> Result<(), Self::Error>;
#[inline]
fn next_back(&mut self) -> Result<Option<&Self::Item>, Self::Error> {
self.advance_back()?;
Ok((*self).get())
}
}
impl<'a, I: ?Sized> FallibleStreamingIterator for &'a mut I
where
I: FallibleStreamingIterator,
{
type Item = I::Item;
type Error = I::Error;
#[inline]
fn advance(&mut self) -> Result<(), I::Error> {
(**self).advance()
}
#[inline]
fn get(&self) -> Option<&I::Item> {
(**self).get()
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
(**self).size_hint()
}
#[inline]
fn next(&mut self) -> Result<Option<&I::Item>, I::Error> {
(**self).next()
}
}
#[cfg(feature = "std")]
impl<I: ?Sized> FallibleStreamingIterator for Box<I>
where
I: FallibleStreamingIterator,
{
type Item = I::Item;
type Error = I::Error;
#[inline]
fn advance(&mut self) -> Result<(), I::Error> {
(**self).advance()
}
#[inline]
fn get(&self) -> Option<&I::Item> {
(**self).get()
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
(**self).size_hint()
}
#[inline]
fn next(&mut self) -> Result<Option<&I::Item>, I::Error> {
(**self).next()
}
}
pub fn convert<'a, I, T, E>(it: I) -> Convert<'a, I, T>
where
I: Iterator<Item = Result<&'a T, E>>,
{
Convert { it: it, item: None }
}
pub struct Convert<'a, I, T: 'a> {
it: I,
item: Option<&'a T>,
}
impl<'a, I, T, E> FallibleStreamingIterator for Convert<'a, I, T>
where
I: Iterator<Item = Result<&'a T, E>>,
{
type Item = T;
type Error = E;
#[inline]
fn advance(&mut self) -> Result<(), E> {
self.item = match self.it.next() {
Some(Ok(v)) => Some(v),
Some(Err(e)) => return Err(e),
None => None,
};
Ok(())
}
#[inline]
fn get(&self) -> Option<&T> {
self.item
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.it.size_hint()
}
}
impl<'a, I, T, E> DoubleEndedFallibleStreamingIterator for Convert<'a, I, T>
where
I: DoubleEndedIterator<Item = Result<&'a T, E>>,
{
#[inline]
fn advance_back(&mut self) -> Result<(), E> {
self.item = match self.it.next_back() {
Some(Ok(v)) => Some(v),
Some(Err(e)) => return Err(e),
None => None,
};
Ok(())
}
}
pub fn empty<T, E>() -> Empty<T, E> {
Empty(PhantomData)
}
pub struct Empty<T, E>(PhantomData<(T, E)>);
impl<T, E> FallibleStreamingIterator for Empty<T, E> {
type Item = T;
type Error = E;
#[inline]
fn advance(&mut self) -> Result<(), E> {
Ok(())
}
#[inline]
fn get(&self) -> Option<&T> {
None
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
(0, Some(0))
}
}
impl<T, E> DoubleEndedFallibleStreamingIterator for Empty<T, E> {
#[inline]
fn advance_back(&mut self) -> Result<(), E> {
Ok(())
}
}
pub struct Filter<I, F> {
it: I,
f: F,
}
impl<I, F> FallibleStreamingIterator for Filter<I, F>
where
I: FallibleStreamingIterator,
F: FnMut(&I::Item) -> bool,
{
type Item = I::Item;
type Error = I::Error;
#[inline]
fn advance(&mut self) -> Result<(), I::Error> {
while let Some(i) = self.it.next()? {
if (self.f)(i) {
break;
}
}
Ok(())
}
#[inline]
fn get(&self) -> Option<&I::Item> {
self.it.get()
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
(0, self.it.size_hint().1)
}
}
#[derive(Copy, Clone)]
enum FuseState {
Start,
Middle,
End,
}
pub struct Fuse<I> {
it: I,
state: FuseState,
}
impl<I> FallibleStreamingIterator for Fuse<I>
where
I: FallibleStreamingIterator,
{
type Item = I::Item;
type Error = I::Error;
#[inline]
fn advance(&mut self) -> Result<(), I::Error> {
match self.state {
FuseState::Start => {
match self.it.next() {
Ok(Some(_)) => self.state = FuseState::Middle,
Ok(None) => self.state = FuseState::End,
Err(e) => {
self.state = FuseState::End;
return Err(e);
}
};
}
FuseState::Middle => match self.it.next() {
Ok(Some(_)) => {}
Ok(None) => self.state = FuseState::End,
Err(e) => {
self.state = FuseState::End;
return Err(e);
}
},
FuseState::End => {}
}
Ok(())
}
#[inline]
fn get(&self) -> Option<&I::Item> {
match self.state {
FuseState::Middle => self.it.get(),
FuseState::Start | FuseState::End => None,
}
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.it.size_hint()
}
#[inline]
fn next(&mut self) -> Result<Option<&I::Item>, I::Error> {
match self.state {
FuseState::Start => match self.it.next() {
Ok(Some(v)) => {
self.state = FuseState::Middle;
Ok(Some(v))
}
Ok(None) => {
self.state = FuseState::End;
Ok(None)
}
Err(e) => {
self.state = FuseState::End;
Err(e)
}
},
FuseState::Middle => match self.it.next() {
Ok(Some(v)) => Ok(Some(v)),
Ok(None) => {
self.state = FuseState::End;
Ok(None)
}
Err(e) => {
self.state = FuseState::End;
Err(e)
}
},
FuseState::End => Ok(None),
}
}
}
pub struct Map<I, F, B> {
it: I,
f: F,
value: Option<B>,
}
impl<I, F, B> FallibleStreamingIterator for Map<I, F, B>
where
I: FallibleStreamingIterator,
F: FnMut(&I::Item) -> B,
{
type Item = B;
type Error = I::Error;
#[inline]
fn advance(&mut self) -> Result<(), I::Error> {
self.value = self.it.next()?.map(&mut self.f);
Ok(())
}
#[inline]
fn get(&self) -> Option<&B> {
self.value.as_ref()
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.it.size_hint()
}
}
impl<I, F, B> DoubleEndedFallibleStreamingIterator for Map<I, F, B>
where
I: DoubleEndedFallibleStreamingIterator,
F: FnMut(&I::Item) -> B,
{
#[inline]
fn advance_back(&mut self) -> Result<(), I::Error> {
self.value = self.it.next_back()?.map(&mut self.f);
Ok(())
}
}
pub struct MapRef<I, F> {
it: I,
f: F,
}
impl<I, F, B: ?Sized> FallibleStreamingIterator for MapRef<I, F>
where
I: FallibleStreamingIterator,
F: Fn(&I::Item) -> &B,
{
type Item = B;
type Error = I::Error;
#[inline]
fn advance(&mut self) -> Result<(), I::Error> {
self.it.advance()
}
#[inline]
fn get(&self) -> Option<&B> {
self.it.get().map(&self.f)
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.it.size_hint()
}
}
impl<I, F, B: ?Sized> DoubleEndedFallibleStreamingIterator for MapRef<I, F>
where
I: DoubleEndedFallibleStreamingIterator,
F: Fn(&I::Item) -> &B,
{
#[inline]
fn advance_back(&mut self) -> Result<(), I::Error> {
self.it.advance_back()
}
}
pub struct MapErr<I, F> {
it: I,
f: F,
}
impl<I, F, B> FallibleStreamingIterator for MapErr<I, F>
where
I: FallibleStreamingIterator,
F: Fn(I::Error) -> B,
{
type Item = I::Item;
type Error = B;
#[inline]
fn advance(&mut self) -> Result<(), B> {
self.it.advance().map_err(&mut self.f)
}
#[inline]
fn get(&self) -> Option<&I::Item> {
self.it.get()
}
#[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()
}
}
impl<I, F, B> DoubleEndedFallibleStreamingIterator for MapErr<I, F>
where
I: DoubleEndedFallibleStreamingIterator,
F: Fn(I::Error) -> B,
{
#[inline]
fn advance_back(&mut self) -> Result<(), B> {
self.it.advance_back().map_err(&mut self.f)
}
#[inline]
fn next_back(&mut self) -> Result<Option<&I::Item>, B> {
self.it.next_back().map_err(&mut self.f)
}
}
pub struct Skip<I> {
it: I,
n: usize,
}
impl<I> FallibleStreamingIterator for Skip<I>
where
I: FallibleStreamingIterator,
{
type Item = I::Item;
type Error = I::Error;
#[inline]
fn advance(&mut self) -> Result<(), I::Error> {
for _ in 0..self.n {
if let None = self.it.next()? {
return Ok(());
}
}
self.n = 0;
self.advance()
}
#[inline]
fn get(&self) -> Option<&I::Item> {
self.it.get()
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let hint = self.it.size_hint();
(
hint.0.saturating_sub(self.n),
hint.1.map(|h| h.saturating_sub(self.n)),
)
}
}
pub struct SkipWhile<I, F> {
it: I,
f: F,
done: bool,
}
impl<I, F> FallibleStreamingIterator for SkipWhile<I, F>
where
I: FallibleStreamingIterator,
F: FnMut(&I::Item) -> bool,
{
type Item = I::Item;
type Error = I::Error;
#[inline]
fn advance(&mut self) -> Result<(), I::Error> {
if !self.done {
self.done = true;
let f = &mut self.f;
self.it.find(|i| !f(i)).map(|_| ())
} else {
self.it.advance()
}
}
#[inline]
fn get(&self) -> Option<&I::Item> {
self.it.get()
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let hint = self.it.size_hint();
if self.done {
hint
} else {
(0, hint.1)
}
}
}
pub struct Take<I> {
it: I,
n: usize,
done: bool,
}
impl<I> FallibleStreamingIterator for Take<I>
where
I: FallibleStreamingIterator,
{
type Item = I::Item;
type Error = I::Error;
#[inline]
fn advance(&mut self) -> Result<(), I::Error> {
if self.n != 0 {
self.it.advance()?;
self.n -= 1;
} else {
self.done = true;
}
Ok(())
}
#[inline]
fn get(&self) -> Option<&I::Item> {
if self.done {
None
} else {
self.it.get()
}
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let (lower, upper) = self.it.size_hint();
let lower = cmp::min(lower, self.n);
let upper = match upper {
Some(x) if x < self.n => Some(x),
_ => Some(self.n)
};
(lower, upper)
}
}
pub struct TakeWhile<I, F> {
it: I,
f: F,
done: bool,
}
impl<I, F> FallibleStreamingIterator for TakeWhile<I, F>
where
I: FallibleStreamingIterator,
F: FnMut(&I::Item) -> bool,
{
type Item = I::Item;
type Error = I::Error;
#[inline]
fn advance(&mut self) -> Result<(), I::Error> {
if let Some(v) = self.it.next()? {
if !(self.f)(v) {
self.done = true;
}
}
Ok(())
}
#[inline]
fn get(&self) -> Option<&I::Item> {
if self.done {
None
} else {
self.it.get()
}
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
if self.done {
(0, Some(0))
} else {
(0, self.it.size_hint().1)
}
}
}
#[cfg(test)]
mod test {
use super::*;
fn _is_object_safe(_: &FallibleStreamingIterator<Item = (), Error = ()>) {}
fn _is_object_safe_double(_: &DoubleEndedFallibleStreamingIterator<Item = (), Error = ()>) {}
}