Import fallible-iterator-0.2.0

Change-Id: Ifea46292d69894ba84fea5a82bb9afa58b874905
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
new file mode 100644
index 0000000..37ca5ef
--- /dev/null
+++ b/.cargo_vcs_info.json
@@ -0,0 +1,5 @@
+{
+  "git": {
+    "sha1": "03b701c04b37fcd1ab1045c4623542606abf378b"
+  }
+}
diff --git a/.circleci/config.yml b/.circleci/config.yml
new file mode 100644
index 0000000..cf9d2e4
--- /dev/null
+++ b/.circleci/config.yml
@@ -0,0 +1,60 @@
+restore_registry: &RESTORE_REGISTRY
+  restore_cache:
+    key: registry
+save_registry: &SAVE_REGISTRY
+  save_cache:
+    key: registry-{{ .BuildNum }}
+    paths:
+    - /usr/local/cargo/registry/index
+deps_key: &DEPS_KEY
+  key: deps-{{ checksum "~/rust-version" }}-{{ checksum "Cargo.lock" }}
+restore_deps: &RESTORE_DEPS
+  restore_cache:
+    <<: *DEPS_KEY
+save_deps: &SAVE_DEPS
+  save_cache:
+    <<: *DEPS_KEY
+    paths:
+    - target
+    - /usr/local/cargo/registry/cache
+
+version: 2
+jobs:
+  stable:
+    docker:
+    - image: rust:1.33.0
+    environment:
+      RUSTFLAGS: -D warnings
+    working_directory: ~/build
+    steps:
+    - checkout
+    - *RESTORE_REGISTRY
+    - run: cargo generate-lockfile
+    - *SAVE_REGISTRY
+    - run: rustc --version > ~/rust-version
+    - *RESTORE_DEPS
+    - run: cargo test
+    - run: cargo test --features std
+    - *SAVE_DEPS
+  nightly:
+    docker:
+    - image: rustlang/rust:nightly
+    environment:
+      RUSTFLAGS: -D warnings
+    working_directory: ~/build
+    steps:
+    - checkout
+    - *RESTORE_REGISTRY
+    - run: cargo generate-lockfile
+    - *SAVE_REGISTRY
+    - run: rustc --version > ~/rust-version
+    - *RESTORE_DEPS
+    - run: cargo test --features alloc
+    - *SAVE_DEPS
+
+workflows:
+  version: 2
+  tests:
+    jobs:
+    - stable
+    - nightly
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..03814ae
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+target
+Cargo.lock
+.idea/
+*.iml
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..c2cb0c6
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,26 @@
+# Change Log
+
+## [Unreleased]
+
+## [v0.2.0] - 2019-03-10
+
+### Changed
+
+* All closures used by adaptor methods now return `Result`s.
+* `FromFallibleIterator::from_fallible_iterator` has been renamed to `from_fallible_iter` and now takes an
+    `IntoFallibleIterator`.
+* `IntoFallibleIterator::into_fallible_iterator` has been renamed to `into_fallible_iter`.
+* `IntoFallibleIterator::IntoIter` has been renamed to `IntoFallibleIter`.
+
+### Removed
+
+* `FallibleIterator::and_then` has been removed as `FallibleIterator::map` is now equivalent.
+
+### Added
+
+* Added `step_by`, `for_each`, `skip_while`, `take_while`, `skip`, `scan`, `flat_map`, `flatten`, `inspect`,
+    `partition`, `find_map`, `max_by`, `min_by`, `unzip`, `cycle`, and `try_fold` to `FallibleIterator`.
+* Added `rfold` and `try_rfold` to `DoubleEndedFallibleIterator`.
+
+[Unreleased]: https://github.com/sfackler/rust-fallible-iterator/compare/v0.2.0...master
+[v0.2.0]: https://github.com/sfackler/rust-fallible-iterator/compare/v0.1.5...v0.2.0
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644
index 0000000..b7a15c1
--- /dev/null
+++ b/Cargo.toml
@@ -0,0 +1,27 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g. crates.io) dependencies
+#
+# If you believe there's an error in this file please file an
+# issue against the rust-lang/cargo repository. If you're
+# editing this file be aware that the upstream Cargo.toml
+# will likely look very different (and much more reasonable)
+
+[package]
+edition = "2018"
+name = "fallible-iterator"
+version = "0.2.0"
+authors = ["Steven Fackler <[email protected]>"]
+description = "Fallible iterator traits"
+readme = "README.md"
+categories = ["algorithms", "no-std"]
+license = "MIT/Apache-2.0"
+repository = "https://github.com/sfackler/rust-fallible-iterator"
+
+[features]
+alloc = []
+default = ["std"]
+std = []
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
new file mode 100644
index 0000000..e8fd7e9
--- /dev/null
+++ b/Cargo.toml.orig
@@ -0,0 +1,15 @@
+[package]
+name = "fallible-iterator"
+version = "0.2.0"
+authors = ["Steven Fackler <[email protected]>"]
+edition = "2018"
+license = "MIT/Apache-2.0"
+description = "Fallible iterator traits"
+repository = "https://github.com/sfackler/rust-fallible-iterator"
+readme = "README.md"
+categories = ["algorithms", "no-std"]
+
+[features]
+alloc = []
+std = []
+default = ["std"]
diff --git a/LICENSE-APACHE b/LICENSE-APACHE
new file mode 100644
index 0000000..8f71f43
--- /dev/null
+++ b/LICENSE-APACHE
@@ -0,0 +1,202 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "{}"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright {yyyy} {name of copyright owner}
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
diff --git a/LICENSE-MIT b/LICENSE-MIT
new file mode 100644
index 0000000..a7cfbe0
--- /dev/null
+++ b/LICENSE-MIT
@@ -0,0 +1,19 @@
+Copyright (c) 2015 The rust-openssl-verify Developers
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..e7a4af2
--- /dev/null
+++ b/README.md
@@ -0,0 +1,15 @@
+# rust-fallible-iterator
+
+[![CircleCI](https://circleci.com/gh/sfackler/rust-fallible-iterator.svg?style=shield)](https://circleci.com/gh/sfackler/rust-fallible-iterator)
+
+[Documentation](https://sfackler.github.io/rust-fallible-iterator/doc/v0.1.3/fallible_iterator)
+
+"Fallible" iterators for Rust.
+
+## Features
+
+If the `std` or `alloc` features are enabled, this crate provides implementations for
+`Box`, `Vec`, `BTreeMap`, and `BTreeSet`. If the `std` feature is enabled, this crate
+additionally provides implementations for `HashMap` and `HashSet`.
+
+If the `std` feature is disabled, this crate does not depend on `libstd`.
diff --git a/src/lib.rs b/src/lib.rs
new file mode 100644
index 0000000..f5f77b2
--- /dev/null
+++ b/src/lib.rs
@@ -0,0 +1,2606 @@
+//! "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 = ()>) {}
diff --git a/src/test.rs b/src/test.rs
new file mode 100644
index 0000000..f7627c4
--- /dev/null
+++ b/src/test.rs
@@ -0,0 +1,455 @@
+use core::iter;
+use core::ops::Range;
+
+use super::{convert, FallibleIterator, Vec};
+
+#[test]
+fn all() {
+    assert!(convert([0, 1, 2, 3].iter().map(Ok::<&u32, ()>))
+        .all(|&i| Ok(i < 4))
+        .unwrap());
+    assert!(!convert([0, 1, 2, 4].iter().map(Ok::<&u32, ()>))
+        .all(|&i| Ok(i < 4))
+        .unwrap());
+    assert!(convert([0, 1, 2, 4].iter().map(Ok::<&u32, ()>))
+        .all(|_| Err(()))
+        .is_err());
+}
+
+#[test]
+fn any() {
+    assert!(convert([0, 1, 2, 3].iter().map(Ok::<&u32, ()>))
+        .any(|&i| Ok(i == 3))
+        .unwrap());
+    assert!(!convert([0, 1, 2, 4].iter().map(Ok::<&u32, ()>))
+        .any(|&i| Ok(i == 3))
+        .unwrap());
+    assert!(convert([0, 1, 2, 4].iter().map(Ok::<&u32, ()>))
+        .any(|_| Err(()))
+        .is_err());
+}
+
+#[test]
+fn chain() {
+    let a = convert(vec![0, 1, 2, 3].into_iter().map(Ok::<u32, ()>));
+    let b = convert(vec![4, 5, 6, 7].into_iter().map(Ok::<u32, ()>));
+    let it = a.chain(b);
+
+    assert_eq!(it.collect::<Vec<_>>().unwrap(), [0, 1, 2, 3, 4, 5, 6, 7]);
+
+    let a = convert(vec![0, 1, 2, 3].into_iter().map(Ok::<u32, ()>));
+    let b = convert(vec![4, 5, 6, 7].into_iter().map(Ok::<u32, ()>));
+    let it = a.chain(b).rev();
+
+    assert_eq!(it.collect::<Vec<_>>().unwrap(), [7, 6, 5, 4, 3, 2, 1, 0]);
+}
+
+#[test]
+fn count() {
+    assert_eq!(
+        convert([0, 1, 2, 3].iter().map(Ok::<&u32, ()>))
+            .count()
+            .unwrap(),
+        4
+    );
+
+    let it = Some(Ok(1)).into_iter().chain(iter::repeat(Err(())));
+    assert!(convert(it).count().is_err());
+}
+
+#[test]
+fn enumerate() {
+    let it = convert(vec![5, 6, 7, 8].into_iter().map(Ok::<u32, ()>)).enumerate();
+
+    assert_eq!(
+        it.collect::<Vec<_>>().unwrap(),
+        [(0, 5), (1, 6), (2, 7), (3, 8)]
+    );
+}
+
+#[test]
+fn filter() {
+    let it = convert(vec![0, 1, 2, 3].into_iter().map(Ok::<u32, u32>));
+    let it = it.filter(|&x| if x % 2 == 0 { Ok(x % 3 == 0) } else { Err(x) });
+
+    assert_eq!(it.clone().collect::<Vec<_>>(), Err(1));
+    assert_eq!(it.rev().collect::<Vec<_>>(), Err(3));
+
+    let it = convert(vec![0, 2, 4, 6].into_iter().map(Ok::<u32, u32>));
+    let it = it.filter(|&x| if x % 2 == 0 { Ok(x % 3 == 0) } else { Err(x) });
+
+    assert_eq!(it.clone().collect::<Vec<_>>(), Ok(vec![0, 6]));
+    assert_eq!(it.rev().collect::<Vec<_>>(), Ok(vec![6, 0]))
+}
+
+#[test]
+fn filter_map() {
+    fn twos_and_threes(x: u32) -> Result<Option<u32>, u32> {
+        if x % 2 == 0 {
+            Ok(Some(x + 10))
+        } else if x % 3 == 0 {
+            Ok(None)
+        } else {
+            Err(x)
+        }
+    }
+
+    let it = convert(vec![0, 1, 2, 3, 4, 5, 6].into_iter().map(Ok::<u32, u32>))
+        .filter_map(twos_and_threes);
+
+    assert_eq!(it.clone().collect::<Vec<_>>(), Err(1));
+    assert_eq!(it.rev().collect::<Vec<_>>(), Err(5));
+
+    let it =
+        convert(vec![0, 2, 3, 4, 6].into_iter().map(Ok::<u32, u32>)).filter_map(twos_and_threes);
+
+    assert_eq!(it.clone().collect::<Vec<_>>(), Ok(vec![10, 12, 14, 16]));
+    assert_eq!(it.rev().collect::<Vec<_>>(), Ok(vec![16, 14, 12, 10]));
+}
+
+#[test]
+fn find() {
+    let mut it = convert(vec![0, 1, 2, 3].into_iter().map(Ok::<u32, u32>));
+
+    assert_eq!(it.find(|x| Ok(x % 2 == 1)), Ok(Some(1)));
+    assert_eq!(it.next(), Ok(Some(2)));
+
+    let it = convert(vec![0, 1, 2, 3].into_iter().map(Ok::<u32, u32>));
+    assert_eq!(
+        it.clone()
+            .find(|&x| if x == 2 { Err(29) } else { Ok(false) }),
+        Err(29)
+    );
+    assert_eq!(
+        it.clone()
+            .find(|&x| if x == 2 { Err(29) } else { Ok(true) }),
+        Ok(Some(0))
+    );
+    assert_eq!(
+        it.clone()
+            .rev()
+            .find(|&x| if x == 2 { Err(29) } else { Ok(false) }),
+        Err(29)
+    );
+    assert_eq!(
+        it.rev().find(|&x| if x == 2 { Err(29) } else { Ok(true) }),
+        Ok(Some(3))
+    );
+}
+
+#[test]
+fn fold() {
+    fn add_smol(a: u32, b: u32) -> Result<u32, u32> {
+        if b <= 2 {
+            Ok(a + b)
+        } else {
+            Err(b)
+        }
+    }
+
+    let it = convert(vec![0, 1, 3, 2].into_iter().map(Ok::<u32, u32>));
+    assert_eq!(it.fold(0, add_smol), Err(3));
+
+    let it = convert(vec![0, 1, 2, 1].into_iter().map(Ok::<u32, u32>));
+    assert_eq!(it.fold(0, add_smol), Ok(4));
+}
+
+#[test]
+fn for_each() {
+    let it = convert(vec![0, 1, 2, 3].into_iter().map(Ok::<u32, ()>));
+
+    let mut acc = vec![];
+    it.for_each(|n| {
+        acc.push(n);
+        Ok(())
+    })
+    .unwrap();
+    assert_eq!(acc, vec![0, 1, 2, 3]);
+}
+
+#[test]
+fn iterator() {
+    let it = convert(
+        "ab cd"
+            .chars()
+            .map(|c| if c.is_whitespace() { Err(()) } else { Ok(c) }),
+    );
+
+    assert!(it.clone().count().is_err());
+    assert!(it.clone().rev().count().is_err());
+    assert_eq!(it.clone().iterator().count(), 5);
+    assert_eq!(it.clone().iterator().rev().count(), 5);
+}
+
+#[test]
+fn last() {
+    let it = convert(vec![0, 1, 2, 3].into_iter().map(Ok::<u32, ()>));
+    assert_eq!(it.last().unwrap(), Some(3));
+}
+
+#[test]
+fn map() {
+    let it = convert(vec![0, 1, 2, 3, 4].into_iter().map(Ok::<u32, ()>)).map(|n| Ok(n * 2));
+    assert_eq!(it.clone().collect::<Vec<_>>().unwrap(), [0, 2, 4, 6, 8]);
+    assert_eq!(it.rev().collect::<Vec<_>>().unwrap(), [8, 6, 4, 2, 0]);
+
+    let it = convert(vec![0, 1, 2, 3, 4].into_iter().map(Ok::<u32, ()>)).map(|n| {
+        if n == 2 {
+            Err(())
+        } else {
+            Ok(n * 2)
+        }
+    });
+
+    {
+        let mut it = it.clone();
+        assert_eq!(it.next(), Ok(Some(0)));
+        assert_eq!(it.next(), Ok(Some(2)));
+        assert_eq!(it.next(), Err(()));
+    }
+
+    {
+        let mut it = it.rev();
+        assert_eq!(it.next(), Ok(Some(8)));
+        assert_eq!(it.next(), Ok(Some(6)));
+        assert_eq!(it.next(), Err(()));
+    }
+}
+
+#[test]
+fn map_err() {
+    let it = convert(
+        vec![0, 1, 2, 3]
+            .into_iter()
+            .map(|n| if n % 2 == 0 { Ok(n) } else { Err(n) }),
+    );
+
+    assert_eq!(it.clone().collect::<Vec<_>>(), Err(1));
+    assert_eq!(it.rev().collect::<Vec<_>>(), Err(3));
+}
+
+#[test]
+fn max() {
+    let it = convert(vec![0, 3, 1, -10].into_iter().map(Ok::<i32, ()>));
+    assert_eq!(it.max().unwrap(), Some(3));
+}
+
+#[test]
+fn max_by_key() {
+    let it = convert(vec![0, 3, 1, -10].into_iter().map(Ok::<i32, i32>));
+    assert_eq!(it.clone().max_by_key(|&i| Ok(-i)), Ok(Some(-10)));
+    // Exercise failure both on the first item, and later.
+    assert_eq!(it.clone().max_by_key(|&i| Err::<i32, _>(i)), Err(0));
+    assert_eq!(
+        it.clone()
+            .max_by_key(|&i| if i > 0 { Err(i) } else { Ok(-i) }),
+        Err(3)
+    );
+}
+
+#[test]
+fn max_by() {
+    let it = convert(vec![0, 3, 1, -10].into_iter().map(Ok::<i32, ()>));
+    assert_eq!(it.max_by(|a, b| Ok(b.cmp(a))), Ok(Some(-10)));
+}
+
+#[test]
+fn min() {
+    let it = convert(vec![0, 3, -10, 1].into_iter().map(Ok::<i32, ()>));
+    assert_eq!(it.min().unwrap(), Some(-10));
+}
+
+#[test]
+fn min_by_key() {
+    let it = convert(vec![0, 3, 1, -10].into_iter().map(Ok::<i32, i32>));
+    assert_eq!(it.clone().min_by_key(|&i| Ok(-i)), Ok(Some(3)));
+    // Exercise failure both on the first item, and later.
+    assert_eq!(it.clone().min_by_key(|&i| Err::<i32, _>(i)), Err(0));
+    assert_eq!(
+        it.clone()
+            .min_by_key(|&i| if i > 0 { Err(i) } else { Ok(-i) }),
+        Err(3)
+    );
+}
+
+#[test]
+fn min_by() {
+    let it = convert(vec![0, 3, 1, -10].into_iter().map(Ok::<i32, ()>));
+    assert_eq!(it.min_by(|a, b| Ok(b.cmp(a))), Ok(Some(3)));
+}
+
+#[test]
+fn nth() {
+    let mut it = convert(vec![0, 1, 2, 3].into_iter().map(Ok::<i32, ()>));
+    assert_eq!(it.nth(1).unwrap(), Some(1));
+    assert_eq!(it.nth(0).unwrap(), Some(2));
+    assert_eq!(it.nth(2).unwrap(), None);
+}
+
+#[test]
+fn peekable() {
+    let mut it = convert(vec![0, 1].into_iter().map(Ok::<i32, ()>)).peekable();
+    assert_eq!(it.peek().unwrap(), Some(&0));
+    assert_eq!(it.peek().unwrap(), Some(&0));
+    assert_eq!(it.next().unwrap(), Some(0));
+    assert_eq!(it.next().unwrap(), Some(1));
+    assert_eq!(it.peek().unwrap(), None);
+    assert_eq!(it.next().unwrap(), None);
+}
+
+#[test]
+fn position() {
+    let mut it = convert(vec![1, 2, 3, 4].into_iter().map(Ok::<i32, ()>));
+    assert_eq!(it.position(|n| Ok(n == 2)).unwrap(), Some(1));
+    assert_eq!(it.position(|n| Ok(n == 3)).unwrap(), Some(0));
+    assert_eq!(it.position(|n| Ok(n == 5)).unwrap(), None);
+
+    let it = convert(vec![1, 2, 3, 4].into_iter().map(Ok::<i32, i32>));
+    assert_eq!(
+        it.clone()
+            .position(|n| if n == 3 { Err(42) } else { Ok(n == 2) }),
+        Ok(Some(1))
+    );
+    assert_eq!(
+        it.clone()
+            .position(|n| if n == 3 { Err(42) } else { Ok(n == 4) }),
+        Err(42)
+    );
+}
+
+#[test]
+fn scan() {
+    let it = convert(vec![1, 2, 3, 4].into_iter().map(Ok::<i32, ()>)).scan(0, |st, v| {
+        if v > 3 {
+            Ok(None)
+        } else {
+            *st += v;
+            Ok(Some(-*st))
+        }
+    });
+    assert_eq!(it.collect::<Vec<_>>(), Ok(vec![-1, -3, -6]));
+}
+
+#[test]
+fn skip() {
+    let it = convert(vec![1, 2, 3, 4].into_iter().map(Ok::<i32, ()>));
+    assert_eq!(it.clone().skip(0).collect::<Vec<_>>(), Ok(vec![1, 2, 3, 4]));
+    assert_eq!(it.clone().skip(2).collect::<Vec<_>>(), Ok(vec![3, 4]));
+    assert_eq!(it.clone().skip(4).collect::<Vec<_>>(), Ok(vec![]));
+}
+
+#[test]
+fn skip_while() {
+    let it = convert(vec![1, 2, 3, 4, 1].into_iter().map(Ok::<i32, ()>));
+    assert_eq!(
+        it.clone().skip_while(|x| Ok(*x < 1)).collect::<Vec<_>>(),
+        Ok(vec![1, 2, 3, 4, 1])
+    );
+    assert_eq!(
+        it.clone().skip_while(|x| Ok(*x < 3)).collect::<Vec<_>>(),
+        Ok(vec![3, 4, 1])
+    );
+    assert_eq!(
+        it.clone().skip_while(|x| Ok(*x < 5)).collect::<Vec<_>>(),
+        Ok(vec![])
+    );
+}
+
+#[test]
+fn step_by() {
+    let it = convert(
+        vec![0, 1, 2, 3, 4, 5, 6, 7, 8]
+            .into_iter()
+            .map(Ok::<i32, ()>),
+    )
+    .step_by(3);
+    assert_eq!(it.collect::<Vec<_>>(), Ok(vec![0, 3, 6]));
+}
+
+#[test]
+fn take() {
+    let it = convert(vec![0, 1, 2, 3].into_iter().map(Ok::<i32, ()>)).take(2);
+    assert_eq!(it.collect::<Vec<_>>().unwrap(), [0, 1]);
+}
+
+#[test]
+fn take_while() {
+    let it = convert(vec![0, 1, 2, 3, 0].into_iter().map(Ok::<i32, ()>));
+    assert_eq!(
+        it.clone().take_while(|x| Ok(*x < 0)).collect::<Vec<_>>(),
+        Ok(vec![])
+    );
+    assert_eq!(
+        it.clone().take_while(|x| Ok(*x < 2)).collect::<Vec<_>>(),
+        Ok(vec![0, 1])
+    );
+    assert_eq!(
+        it.clone().take_while(|x| Ok(*x < 4)).collect::<Vec<_>>(),
+        Ok(vec![0, 1, 2, 3, 0])
+    );
+}
+
+#[test]
+fn flat_map() {
+    let it = convert(vec![0..1, 0..0, 1..5].into_iter().map(Ok::<Range<i32>, ()>))
+        .flat_map(|r| Ok(convert(r.map(Ok::<i32, ()>))));
+    assert_eq!(it.collect::<Vec<_>>(), Ok(vec![0, 1, 2, 3, 4]));
+}
+
+#[test]
+fn flatten() {
+    let it = convert(
+        vec![0..1, 0..0, 1..5]
+            .into_iter()
+            .map(|r| convert(r.map(Ok::<i32, ()>)))
+            .map(Ok::<_, ()>),
+    )
+    .flatten();
+    assert_eq!(it.collect::<Vec<_>>(), Ok(vec![0, 1, 2, 3, 4]));
+}
+
+#[test]
+fn inspect() {
+    let mut buf = vec![];
+    let it = convert(vec![0, 1, 2, 3].into_iter().map(Ok::<i32, ()>)).inspect(|v| Ok(buf.push(*v)));
+    it.count().unwrap();
+    assert_eq!(buf, vec![0, 1, 2, 3]);
+}
+
+#[test]
+fn partition() {
+    let it = convert(vec![0, 1, 2, 3].into_iter().map(Ok::<i32, ()>));
+    let (even, odd): (Vec<i32>, Vec<i32>) = it.partition(|i| Ok(*i % 2 == 0)).unwrap();
+    assert_eq!(even, vec![0, 2]);
+    assert_eq!(odd, vec![1, 3]);
+}
+
+#[test]
+fn find_map() {
+    let mut it = convert(vec![0, 1, 2, 3].into_iter().map(Ok::<i32, ()>));
+    assert_eq!(
+        it.find_map(|v| match v {
+            2 => Ok(Some("hi")),
+            _ => Ok(None),
+        }),
+        Ok(Some("hi"))
+    );
+}
+
+#[test]
+fn unzip() {
+    let it = convert(
+        vec![(0, 0), (1, -1), (2, -2), (3, -3)]
+            .into_iter()
+            .map(Ok::<_, ()>),
+    );
+    let (pos, neg): (Vec<i32>, Vec<i32>) = it.unzip().unwrap();
+    assert_eq!(pos, vec![0, 1, 2, 3]);
+    assert_eq!(neg, vec![0, -1, -2, -3]);
+}
+
+#[test]
+fn cycle() {
+    let it = convert(vec![0, 1, 2, 3].into_iter().map(Ok::<i32, ()>)).cycle();
+    assert_eq!(it.take(6).clone().collect::<Vec<_>>(), Ok(vec![0, 1, 2, 3, 0, 1]));
+}