Merge "Upgrade either to 1.8.0" am: d56fe52eac am: 51a093df75

Original change: https://android-review.googlesource.com/c/platform/external/rust/crates/either/+/2337602

Change-Id: I3332ba3eb901123f5e115dd09a62e4913324e7ae
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index 1a91ec1..5b9e1d5 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,5 +1,6 @@
 {
   "git": {
-    "sha1": "6d3216446d4828d9fa254a6952b40408fbc9c9bd"
-  }
-}
+    "sha1": "0e1124933c4d6a6ded1ad6137c70c69e23a9d22f"
+  },
+  "path_in_vcs": ""
+}
\ No newline at end of file
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000..905cbf5
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,61 @@
+on:
+  push:
+    branches: [ master ]
+  pull_request:
+    branches: [ master ]
+
+name: CI
+
+jobs:
+  ci:
+    runs-on: ubuntu-latest
+    strategy:
+      fail-fast: false
+      matrix:
+        rust:
+          - 1.36.0  # MSRV
+          - stable
+          - beta
+          - nightly
+        features:
+          - ""
+          - "serde"
+
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v3
+
+      - name: Set up Rust
+        uses: dtolnay/rust-toolchain@master
+        with:
+          toolchain: ${{ matrix.rust }}
+
+      - name: Build (no_std)
+        run: cargo build --no-default-features
+
+      - name: Build
+        run: cargo build --features "${{ matrix.features }}"
+
+      - name: Test
+        run: cargo test --features "${{ matrix.features }}"
+
+      - name: Doc
+        run: cargo doc --features "${{ matrix.features }}"
+
+  clippy:
+    name: Rustfmt and Clippy
+    runs-on: ubuntu-latest
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v3
+
+      - name: Set up nightly Rust
+        uses: dtolnay/rust-toolchain@nightly
+        with:
+          components: rustfmt, clippy
+
+      - name: Rustfmt
+        run: cargo fmt --all -- --check
+
+      - name: Clippy
+        run: cargo clippy  # -- -D warnings
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index f3a3024..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,33 +0,0 @@
-language: rust
-sudo: false
-
-# run builds for all the trains (and more)
-rust:
-  - stable
-  - beta
-  - nightly
-
-branches:
-  only:
-    - master
-# the main build
-script:
-  - |
-      cargo build --features "${FEATURES}" &&
-      cargo test --features "${FEATURES}" &&
-      cargo doc --features "${FEATURES}"
-
-env:
-  matrix:
-    - FEATURES=""
-    - FEATURES="serde"
-
-matrix:
-  include:
-    - rust: 1.12.0
-      env: FEATURES=""
-      before_script:
-        - |
-          cargo generate-lockfile &&
-          cargo update -p serde_json --precise 1.0.0 &&
-          cargo update -p serde --precise 1.0.0
diff --git a/Android.bp b/Android.bp
index 1cbd146..4bd81e9 100644
--- a/Android.bp
+++ b/Android.bp
@@ -42,14 +42,14 @@
     host_supported: true,
     crate_name: "either",
     cargo_env_compat: true,
-    cargo_pkg_version: "1.6.1",
+    cargo_pkg_version: "1.8.0",
     srcs: ["src/lib.rs"],
     test_suites: ["general-tests"],
     auto_gen_config: true,
     test_options: {
         unit_test: true,
     },
-    edition: "2015",
+    edition: "2018",
     features: [
         "default",
         "use_std",
@@ -64,14 +64,18 @@
     host_supported: true,
     crate_name: "either",
     cargo_env_compat: true,
-    cargo_pkg_version: "1.6.1",
+    cargo_pkg_version: "1.8.0",
     srcs: ["src/lib.rs"],
-    edition: "2015",
+    edition: "2018",
     features: [
         "default",
         "use_std",
     ],
+    apex_available: [
+        "//apex_available:platform",
+        "//apex_available:anyapex",
+    ],
 }
 
-//Non fatal errors:
+// Errors when listing tests:
 // error: test
diff --git a/Cargo.toml b/Cargo.toml
index ccf747b..eb1c5b4 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -3,34 +3,46 @@
 # 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
+# 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)
+# If you are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
 
 [package]
+edition = "2018"
+rust-version = "1.36"
 name = "either"
-version = "1.6.1"
+version = "1.8.0"
 authors = ["bluss"]
-description = "The enum `Either` with variants `Left` and `Right` is a general purpose sum type with two cases.\n"
+description = """
+The enum `Either` with variants `Left` and `Right` is a general purpose sum type with two cases.
+"""
 documentation = "https://docs.rs/either/1/"
 readme = "README-crates.io.md"
-keywords = ["data-structure", "no_std"]
-categories = ["data-structures", "no-std"]
+keywords = [
+    "data-structure",
+    "no_std",
+]
+categories = [
+    "data-structures",
+    "no-std",
+]
 license = "MIT/Apache-2.0"
 repository = "https://github.com/bluss/either"
-[package.metadata.docs.rs]
-features = ["serde"]
 
 [package.metadata.release]
 no-dev-version = true
 tag-name = "{{version}}"
+
+[package.metadata.docs.rs]
+features = ["serde"]
+
 [dependencies.serde]
 version = "1.0"
 features = ["derive"]
 optional = true
+
 [dev-dependencies.serde_json]
 version = "1.0.0"
 
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index 5797caf..5d4c933 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -1,7 +1,9 @@
 [package]
 name = "either"
-version = "1.6.1"
+version = "1.8.0"
 authors = ["bluss"]
+edition = "2018"
+rust-version = "1.36"
 
 license = "MIT/Apache-2.0"
 repository = "https://github.com/bluss/either"
diff --git a/METADATA b/METADATA
index 58f339d..5140042 100644
--- a/METADATA
+++ b/METADATA
@@ -1,3 +1,7 @@
+# This project was upgraded with external_updater.
+# Usage: tools/external_updater/updater.sh update rust/crates/either
+# For more info, check https://cs.android.com/android/platform/superproject/+/master:tools/external_updater/README.md
+
 name: "either"
 description: "The enum `Either` with variants `Left` and `Right` is a general purpose sum type with two cases."
 third_party {
@@ -7,13 +11,13 @@
   }
   url {
     type: ARCHIVE
-    value: "https://static.crates.io/crates/either/either-1.6.1.crate"
+    value: "https://static.crates.io/crates/either/either-1.8.0.crate"
   }
-  version: "1.6.1"
+  version: "1.8.0"
   license_type: NOTICE
   last_upgrade_date {
-    year: 2020
+    year: 2022
     month: 12
-    day: 21
+    day: 9
   }
 }
diff --git a/README.rst b/README.rst
index 38d3920..43c156a 100644
--- a/README.rst
+++ b/README.rst
@@ -16,21 +16,52 @@
 
 |build_status|_ |crates|_
 
-.. |build_status| image:: https://travis-ci.org/bluss/either.svg?branch=master
-.. _build_status: https://travis-ci.org/bluss/either
+.. |build_status| image:: https://github.com/bluss/either/workflows/CI/badge.svg?branch=master
+.. _build_status: https://github.com/bluss/either/actions
 
-.. |crates| image:: http://meritbadge.herokuapp.com/either
+.. |crates| image:: https://img.shields.io/crates/v/either.svg
 .. _crates: https://crates.io/crates/either
 
 How to use with cargo::
 
     [dependencies]
-    either = "1.6"
+    either = "1.8"
 
 
 Recent Changes
 --------------
 
+- 1.8.0
+
+  - **MSRV**: ``either`` now requires Rust 1.36 or later.
+
+  - Add new methods ``.as_pin_ref()`` and ``.as_pin_mut()`` to project a
+    pinned ``Either`` as inner ``Pin`` variants, by @cuviper (#77)
+
+  - Implement the ``Future`` trait, by @cuviper (#77)
+
+  - Specialize more methods of the ``io`` traits, by @Kixunil and @cuviper (#75)
+
+- 1.7.0
+
+  - **MSRV**: ``either`` now requires Rust 1.31 or later.
+
+  - Export the macro ``for_both!``, by @thomaseizinger (#58)
+
+  - Implement the ``io::Seek`` trait, by @Kerollmops (#60)
+
+  - Add new method ``.either_into()`` for ``Into`` conversion, by @TonalidadeHidrica (#63)
+
+  - Add new methods ``.factor_ok()``, ``.factor_err()``, and ``.factor_none()``,
+    by @zachs18 (#67)
+
+  - Specialize ``source`` in the ``Error`` implementation, by @thomaseizinger (#69)
+
+  - Specialize more iterator methods and implement the ``FusedIterator`` trait,
+    by @Ten0 (#66) and @cuviper (#71)
+
+  - Specialize ``Clone::clone_from``, by @cuviper (#72)
+
 - 1.6.1
 
   - Add new methods ``.expect_left()``, ``.unwrap_left()``,
@@ -123,7 +154,7 @@
 Dual-licensed to be compatible with the Rust project.
 
 Licensed under the Apache License, Version 2.0
-http://www.apache.org/licenses/LICENSE-2.0 or the MIT license
-http://opensource.org/licenses/MIT, at your
+https://www.apache.org/licenses/LICENSE-2.0 or the MIT license
+https://opensource.org/licenses/MIT, at your
 option. This file may not be copied, modified, or distributed
 except according to those terms.
diff --git a/src/lib.rs b/src/lib.rs
index 3ef249f..9a271c3 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -13,13 +13,10 @@
 //!
 
 #![doc(html_root_url = "https://docs.rs/either/1/")]
-#![cfg_attr(all(not(test), not(feature = "use_std")), no_std)]
-#[cfg(all(not(test), not(feature = "use_std")))]
-extern crate core as std;
+#![no_std]
 
-#[cfg(feature = "serde")]
-#[macro_use]
-extern crate serde;
+#[cfg(any(test, feature = "use_std"))]
+extern crate std;
 
 #[cfg(feature = "serde")]
 pub mod serde_untagged;
@@ -27,18 +24,20 @@
 #[cfg(feature = "serde")]
 pub mod serde_untagged_optional;
 
-use std::convert::{AsMut, AsRef};
-use std::fmt;
-use std::iter;
-use std::ops::Deref;
-use std::ops::DerefMut;
+use core::convert::{AsMut, AsRef};
+use core::fmt;
+use core::future::Future;
+use core::iter;
+use core::ops::Deref;
+use core::ops::DerefMut;
+use core::pin::Pin;
 
 #[cfg(any(test, feature = "use_std"))]
 use std::error::Error;
 #[cfg(any(test, feature = "use_std"))]
-use std::io::{self, BufRead, Read, Write};
+use std::io::{self, BufRead, Read, Seek, SeekFrom, Write};
 
-pub use Either::{Left, Right};
+pub use crate::Either::{Left, Right};
 
 /// The enum `Either` with variants `Left` and `Right` is a general purpose
 /// sum type with two cases.
@@ -46,8 +45,8 @@
 /// The `Either` type is symmetric and treats its variants the same way, without
 /// preference.
 /// (For representing success or error, use the regular `Result` enum instead.)
-#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
-#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
+#[derive(Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
 pub enum Either<L, R> {
     /// A value of type `L`.
     Left(L),
@@ -55,11 +54,36 @@
     Right(R),
 }
 
-macro_rules! either {
+/// Evaluate the provided expression for both [`Either::Left`] and [`Either::Right`].
+///
+/// This macro is useful in cases where both sides of [`Either`] can be interacted with
+/// in the same way even though the don't share the same type.
+///
+/// Syntax: `either::for_both!(` *expression* `,` *pattern* `=>` *expression* `)`
+///
+/// # Example
+///
+/// ```
+/// use either::Either;
+///
+/// fn length(owned_or_borrowed: Either<String, &'static str>) -> usize {
+///     either::for_both!(owned_or_borrowed, s => s.len())
+/// }
+///
+/// fn main() {
+///     let borrowed = Either::Right("Hello world!");
+///     let owned = Either::Left("Hello world!".to_owned());
+///
+///     assert_eq!(length(borrowed), 12);
+///     assert_eq!(length(owned), 12);
+/// }
+/// ```
+#[macro_export]
+macro_rules! for_both {
     ($value:expr, $pattern:pat => $result:expr) => {
         match $value {
-            Either::Left($pattern) => $result,
-            Either::Right($pattern) => $result,
+            $crate::Either::Left($pattern) => $result,
+            $crate::Either::Right($pattern) => $result,
         }
     };
 }
@@ -74,11 +98,10 @@
 /// # Example
 ///
 /// ```
-/// #[macro_use] extern crate either;
 /// use either::{Either, Left, Right};
 ///
 /// fn twice(wrapper: Either<u32, &str>) -> Either<u32, &str> {
-///     let value = try_left!(wrapper);
+///     let value = either::try_left!(wrapper);
 ///     Left(value * 2)
 /// }
 ///
@@ -92,7 +115,7 @@
     ($expr:expr) => {
         match $expr {
             $crate::Left(val) => val,
-            $crate::Right(err) => return $crate::Right(::std::convert::From::from(err)),
+            $crate::Right(err) => return $crate::Right(::core::convert::From::from(err)),
         }
     };
 }
@@ -102,12 +125,29 @@
 macro_rules! try_right {
     ($expr:expr) => {
         match $expr {
-            $crate::Left(err) => return $crate::Left(::std::convert::From::from(err)),
+            $crate::Left(err) => return $crate::Left(::core::convert::From::from(err)),
             $crate::Right(val) => val,
         }
     };
 }
 
+impl<L: Clone, R: Clone> Clone for Either<L, R> {
+    fn clone(&self) -> Self {
+        match self {
+            Left(inner) => Left(inner.clone()),
+            Right(inner) => Right(inner.clone()),
+        }
+    }
+
+    fn clone_from(&mut self, source: &Self) {
+        match (self, source) {
+            (Left(dest), Left(source)) => dest.clone_from(source),
+            (Right(dest), Right(source)) => dest.clone_from(source),
+            (dest, source) => *dest = source.clone(),
+        }
+    }
+}
+
 impl<L, R> Either<L, R> {
     /// Return true if the value is the `Left` variant.
     ///
@@ -217,6 +257,35 @@
         }
     }
 
+    /// Convert `Pin<&Either<L, R>>` to `Either<Pin<&L>, Pin<&R>>`,
+    /// pinned projections of the inner variants.
+    pub fn as_pin_ref(self: Pin<&Self>) -> Either<Pin<&L>, Pin<&R>> {
+        // SAFETY: We can use `new_unchecked` because the `inner` parts are
+        // guaranteed to be pinned, as they come from `self` which is pinned.
+        unsafe {
+            match *Pin::get_ref(self) {
+                Left(ref inner) => Left(Pin::new_unchecked(inner)),
+                Right(ref inner) => Right(Pin::new_unchecked(inner)),
+            }
+        }
+    }
+
+    /// Convert `Pin<&mut Either<L, R>>` to `Either<Pin<&mut L>, Pin<&mut R>>`,
+    /// pinned projections of the inner variants.
+    pub fn as_pin_mut(self: Pin<&mut Self>) -> Either<Pin<&mut L>, Pin<&mut R>> {
+        // SAFETY: `get_unchecked_mut` is fine because we don't move anything.
+        // We can use `new_unchecked` because the `inner` parts are guaranteed
+        // to be pinned, as they come from `self` which is pinned, and we never
+        // offer an unpinned `&mut L` or `&mut R` through `Pin<&mut Self>`. We
+        // also don't have an implementation of `Drop`, nor manual `Unpin`.
+        unsafe {
+            match *Pin::get_unchecked_mut(self) {
+                Left(ref mut inner) => Left(Pin::new_unchecked(inner)),
+                Right(ref mut inner) => Right(Pin::new_unchecked(inner)),
+            }
+        }
+    }
+
     /// Convert `Either<L, R>` to `Either<R, L>`.
     ///
     /// ```
@@ -388,6 +457,7 @@
     /// right.extend(left.into_iter());
     /// assert_eq!(right, Right(vec![1, 2, 3, 4, 5]));
     /// ```
+    #[allow(clippy::should_implement_trait)]
     pub fn into_iter(self) -> Either<L::IntoIter, R::IntoIter>
     where
         L: IntoIterator,
@@ -558,7 +628,7 @@
     /// ```
     pub fn unwrap_left(self) -> L
     where
-        R: std::fmt::Debug,
+        R: core::fmt::Debug,
     {
         match self {
             Either::Left(l) => l,
@@ -589,7 +659,7 @@
     /// ```
     pub fn unwrap_right(self) -> R
     where
-        L: std::fmt::Debug,
+        L: core::fmt::Debug,
     {
         match self {
             Either::Right(r) => r,
@@ -618,7 +688,7 @@
     /// ```
     pub fn expect_left(self, msg: &str) -> L
     where
-        R: std::fmt::Debug,
+        R: core::fmt::Debug,
     {
         match self {
             Either::Left(l) => l,
@@ -647,13 +717,103 @@
     /// ```
     pub fn expect_right(self, msg: &str) -> R
     where
-        L: std::fmt::Debug,
+        L: core::fmt::Debug,
     {
         match self {
             Either::Right(r) => r,
             Either::Left(l) => panic!("{}: {:?}", msg, l),
         }
     }
+
+    /// Convert the contained value into `T`
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// # use either::*;
+    /// // Both u16 and u32 can be converted to u64.
+    /// let left: Either<u16, u32> = Left(3u16);
+    /// assert_eq!(left.either_into::<u64>(), 3u64);
+    /// let right: Either<u16, u32> = Right(7u32);
+    /// assert_eq!(right.either_into::<u64>(), 7u64);
+    /// ```
+    pub fn either_into<T>(self) -> T
+    where
+        L: Into<T>,
+        R: Into<T>,
+    {
+        match self {
+            Either::Left(l) => l.into(),
+            Either::Right(r) => r.into(),
+        }
+    }
+}
+
+impl<L, R> Either<Option<L>, Option<R>> {
+    /// Factors out `None` from an `Either` of [`Option`].
+    ///
+    /// ```
+    /// use either::*;
+    /// let left: Either<_, Option<String>> = Left(Some(vec![0]));
+    /// assert_eq!(left.factor_none(), Some(Left(vec![0])));
+    ///
+    /// let right: Either<Option<Vec<u8>>, _> = Right(Some(String::new()));
+    /// assert_eq!(right.factor_none(), Some(Right(String::new())));
+    /// ```
+    // TODO(MSRV): doc(alias) was stabilized in Rust 1.48
+    // #[doc(alias = "transpose")]
+    pub fn factor_none(self) -> Option<Either<L, R>> {
+        match self {
+            Left(l) => l.map(Either::Left),
+            Right(r) => r.map(Either::Right),
+        }
+    }
+}
+
+impl<L, R, E> Either<Result<L, E>, Result<R, E>> {
+    /// Factors out a homogenous type from an `Either` of [`Result`].
+    ///
+    /// Here, the homogeneous type is the `Err` type of the [`Result`].
+    ///
+    /// ```
+    /// use either::*;
+    /// let left: Either<_, Result<String, u32>> = Left(Ok(vec![0]));
+    /// assert_eq!(left.factor_err(), Ok(Left(vec![0])));
+    ///
+    /// let right: Either<Result<Vec<u8>, u32>, _> = Right(Ok(String::new()));
+    /// assert_eq!(right.factor_err(), Ok(Right(String::new())));
+    /// ```
+    // TODO(MSRV): doc(alias) was stabilized in Rust 1.48
+    // #[doc(alias = "transpose")]
+    pub fn factor_err(self) -> Result<Either<L, R>, E> {
+        match self {
+            Left(l) => l.map(Either::Left),
+            Right(r) => r.map(Either::Right),
+        }
+    }
+}
+
+impl<T, L, R> Either<Result<T, L>, Result<T, R>> {
+    /// Factors out a homogenous type from an `Either` of [`Result`].
+    ///
+    /// Here, the homogeneous type is the `Ok` type of the [`Result`].
+    ///
+    /// ```
+    /// use either::*;
+    /// let left: Either<_, Result<u32, String>> = Left(Err(vec![0]));
+    /// assert_eq!(left.factor_ok(), Err(Left(vec![0])));
+    ///
+    /// let right: Either<Result<u32, Vec<u8>>, _> = Right(Err(String::new()));
+    /// assert_eq!(right.factor_ok(), Err(Right(String::new())));
+    /// ```
+    // TODO(MSRV): doc(alias) was stabilized in Rust 1.48
+    // #[doc(alias = "transpose")]
+    pub fn factor_ok(self) -> Result<T, Either<L, R>> {
+        match self {
+            Left(l) => l.map_err(Either::Left),
+            Right(r) => r.map_err(Either::Right),
+        }
+    }
 }
 
 impl<T, L, R> Either<(T, L), (T, R)> {
@@ -711,7 +871,7 @@
     /// assert_eq!(right.into_inner(), 123);
     /// ```
     pub fn into_inner(self) -> T {
-        either!(self, inner => inner)
+        for_both!(self, inner => inner)
     }
 
     /// Map `f` over the contained value and return the result in the
@@ -747,6 +907,7 @@
 }
 
 /// Convert from `Either` to `Result` with `Right => Ok` and `Left => Err`.
+#[allow(clippy::from_over_into)] // From requires RFC 2451, Rust 1.41
 impl<L, R> Into<Result<R, L>> for Either<L, R> {
     fn into(self) -> Result<R, L> {
         match self {
@@ -765,7 +926,7 @@
     where
         T: IntoIterator<Item = A>,
     {
-        either!(*self, ref mut inner => inner.extend(iter))
+        for_both!(*self, ref mut inner => inner.extend(iter))
     }
 }
 
@@ -778,44 +939,87 @@
     type Item = L::Item;
 
     fn next(&mut self) -> Option<Self::Item> {
-        either!(*self, ref mut inner => inner.next())
+        for_both!(*self, ref mut inner => inner.next())
     }
 
     fn size_hint(&self) -> (usize, Option<usize>) {
-        either!(*self, ref inner => inner.size_hint())
+        for_both!(*self, ref inner => inner.size_hint())
     }
 
     fn fold<Acc, G>(self, init: Acc, f: G) -> Acc
     where
         G: FnMut(Acc, Self::Item) -> Acc,
     {
-        either!(self, inner => inner.fold(init, f))
+        for_both!(self, inner => inner.fold(init, f))
+    }
+
+    fn for_each<F>(self, f: F)
+    where
+        F: FnMut(Self::Item),
+    {
+        for_both!(self, inner => inner.for_each(f))
     }
 
     fn count(self) -> usize {
-        either!(self, inner => inner.count())
+        for_both!(self, inner => inner.count())
     }
 
     fn last(self) -> Option<Self::Item> {
-        either!(self, inner => inner.last())
+        for_both!(self, inner => inner.last())
     }
 
     fn nth(&mut self, n: usize) -> Option<Self::Item> {
-        either!(*self, ref mut inner => inner.nth(n))
+        for_both!(*self, ref mut inner => inner.nth(n))
     }
 
     fn collect<B>(self) -> B
     where
         B: iter::FromIterator<Self::Item>,
     {
-        either!(self, inner => inner.collect())
+        for_both!(self, inner => inner.collect())
+    }
+
+    fn partition<B, F>(self, f: F) -> (B, B)
+    where
+        B: Default + Extend<Self::Item>,
+        F: FnMut(&Self::Item) -> bool,
+    {
+        for_both!(self, inner => inner.partition(f))
     }
 
     fn all<F>(&mut self, f: F) -> bool
     where
         F: FnMut(Self::Item) -> bool,
     {
-        either!(*self, ref mut inner => inner.all(f))
+        for_both!(*self, ref mut inner => inner.all(f))
+    }
+
+    fn any<F>(&mut self, f: F) -> bool
+    where
+        F: FnMut(Self::Item) -> bool,
+    {
+        for_both!(*self, ref mut inner => inner.any(f))
+    }
+
+    fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
+    where
+        P: FnMut(&Self::Item) -> bool,
+    {
+        for_both!(*self, ref mut inner => inner.find(predicate))
+    }
+
+    fn find_map<B, F>(&mut self, f: F) -> Option<B>
+    where
+        F: FnMut(Self::Item) -> Option<B>,
+    {
+        for_both!(*self, ref mut inner => inner.find_map(f))
+    }
+
+    fn position<P>(&mut self, predicate: P) -> Option<usize>
+    where
+        P: FnMut(Self::Item) -> bool,
+    {
+        for_both!(*self, ref mut inner => inner.position(predicate))
     }
 }
 
@@ -825,7 +1029,26 @@
     R: DoubleEndedIterator<Item = L::Item>,
 {
     fn next_back(&mut self) -> Option<Self::Item> {
-        either!(*self, ref mut inner => inner.next_back())
+        for_both!(*self, ref mut inner => inner.next_back())
+    }
+
+    // TODO(MSRV): This was stabilized in Rust 1.37
+    // fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
+    //     for_both!(*self, ref mut inner => inner.nth_back(n))
+    // }
+
+    fn rfold<Acc, G>(self, init: Acc, f: G) -> Acc
+    where
+        G: FnMut(Acc, Self::Item) -> Acc,
+    {
+        for_both!(self, inner => inner.rfold(init, f))
+    }
+
+    fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
+    where
+        P: FnMut(&Self::Item) -> bool,
+    {
+        for_both!(*self, ref mut inner => inner.rfind(predicate))
     }
 }
 
@@ -834,6 +1057,32 @@
     L: ExactSizeIterator,
     R: ExactSizeIterator<Item = L::Item>,
 {
+    fn len(&self) -> usize {
+        for_both!(*self, ref inner => inner.len())
+    }
+}
+
+impl<L, R> iter::FusedIterator for Either<L, R>
+where
+    L: iter::FusedIterator,
+    R: iter::FusedIterator<Item = L::Item>,
+{
+}
+
+/// `Either<L, R>` is a future if both `L` and `R` are futures.
+impl<L, R> Future for Either<L, R>
+where
+    L: Future,
+    R: Future<Output = L::Output>,
+{
+    type Output = L::Output;
+
+    fn poll(
+        self: Pin<&mut Self>,
+        cx: &mut core::task::Context<'_>,
+    ) -> core::task::Poll<Self::Output> {
+        for_both!(self.as_pin_mut(), inner => inner.poll(cx))
+    }
 }
 
 #[cfg(any(test, feature = "use_std"))]
@@ -846,11 +1095,33 @@
     R: Read,
 {
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
-        either!(*self, ref mut inner => inner.read(buf))
+        for_both!(*self, ref mut inner => inner.read(buf))
     }
 
-    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
-        either!(*self, ref mut inner => inner.read_to_end(buf))
+    fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
+        for_both!(*self, ref mut inner => inner.read_exact(buf))
+    }
+
+    fn read_to_end(&mut self, buf: &mut std::vec::Vec<u8>) -> io::Result<usize> {
+        for_both!(*self, ref mut inner => inner.read_to_end(buf))
+    }
+
+    fn read_to_string(&mut self, buf: &mut std::string::String) -> io::Result<usize> {
+        for_both!(*self, ref mut inner => inner.read_to_string(buf))
+    }
+}
+
+#[cfg(any(test, feature = "use_std"))]
+/// `Either<L, R>` implements `Seek` if both `L` and `R` do.
+///
+/// Requires crate feature `"use_std"`
+impl<L, R> Seek for Either<L, R>
+where
+    L: Seek,
+    R: Seek,
+{
+    fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
+        for_both!(*self, ref mut inner => inner.seek(pos))
     }
 }
 
@@ -862,11 +1133,19 @@
     R: BufRead,
 {
     fn fill_buf(&mut self) -> io::Result<&[u8]> {
-        either!(*self, ref mut inner => inner.fill_buf())
+        for_both!(*self, ref mut inner => inner.fill_buf())
     }
 
     fn consume(&mut self, amt: usize) {
-        either!(*self, ref mut inner => inner.consume(amt))
+        for_both!(*self, ref mut inner => inner.consume(amt))
+    }
+
+    fn read_until(&mut self, byte: u8, buf: &mut std::vec::Vec<u8>) -> io::Result<usize> {
+        for_both!(*self, ref mut inner => inner.read_until(byte, buf))
+    }
+
+    fn read_line(&mut self, buf: &mut std::string::String) -> io::Result<usize> {
+        for_both!(*self, ref mut inner => inner.read_line(buf))
     }
 }
 
@@ -880,11 +1159,19 @@
     R: Write,
 {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
-        either!(*self, ref mut inner => inner.write(buf))
+        for_both!(*self, ref mut inner => inner.write(buf))
+    }
+
+    fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
+        for_both!(*self, ref mut inner => inner.write_all(buf))
+    }
+
+    fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> io::Result<()> {
+        for_both!(*self, ref mut inner => inner.write_fmt(fmt))
     }
 
     fn flush(&mut self) -> io::Result<()> {
-        either!(*self, ref mut inner => inner.flush())
+        for_both!(*self, ref mut inner => inner.flush())
     }
 }
 
@@ -894,7 +1181,7 @@
     R: AsRef<Target>,
 {
     fn as_ref(&self) -> &Target {
-        either!(*self, ref inner => inner.as_ref())
+        for_both!(*self, ref inner => inner.as_ref())
     }
 }
 
@@ -905,7 +1192,7 @@
             where L: AsRef<$t>, R: AsRef<$t>
         {
             fn as_ref(&self) -> &$t {
-                either!(*self, ref inner => inner.as_ref())
+                for_both!(*self, ref inner => inner.as_ref())
             }
         }
 
@@ -914,7 +1201,7 @@
             where L: AsMut<$t>, R: AsMut<$t>
         {
             fn as_mut(&mut self) -> &mut $t {
-                either!(*self, ref mut inner => inner.as_mut())
+                for_both!(*self, ref mut inner => inner.as_mut())
             }
         }
     };
@@ -943,7 +1230,7 @@
     R: AsRef<[Target]>,
 {
     fn as_ref(&self) -> &[Target] {
-        either!(*self, ref inner => inner.as_ref())
+        for_both!(*self, ref inner => inner.as_ref())
     }
 }
 
@@ -953,7 +1240,7 @@
     R: AsMut<Target>,
 {
     fn as_mut(&mut self) -> &mut Target {
-        either!(*self, ref mut inner => inner.as_mut())
+        for_both!(*self, ref mut inner => inner.as_mut())
     }
 }
 
@@ -963,7 +1250,7 @@
     R: AsMut<[Target]>,
 {
     fn as_mut(&mut self) -> &mut [Target] {
-        either!(*self, ref mut inner => inner.as_mut())
+        for_both!(*self, ref mut inner => inner.as_mut())
     }
 }
 
@@ -975,7 +1262,7 @@
     type Target = L::Target;
 
     fn deref(&self) -> &Self::Target {
-        either!(*self, ref inner => &*inner)
+        for_both!(*self, ref inner => &**inner)
     }
 }
 
@@ -985,7 +1272,7 @@
     R: DerefMut<Target = L::Target>,
 {
     fn deref_mut(&mut self) -> &mut Self::Target {
-        either!(*self, ref mut inner => &mut *inner)
+        for_both!(*self, ref mut inner => &mut *inner)
     }
 }
 
@@ -996,15 +1283,18 @@
     L: Error,
     R: Error,
 {
-    #[allow(deprecated)]
-    fn description(&self) -> &str {
-        either!(*self, ref inner => inner.description())
+    fn source(&self) -> Option<&(dyn Error + 'static)> {
+        for_both!(*self, ref inner => inner.source())
     }
 
     #[allow(deprecated)]
-    #[allow(unknown_lints, bare_trait_objects)]
-    fn cause(&self) -> Option<&Error> {
-        either!(*self, ref inner => inner.cause())
+    fn description(&self) -> &str {
+        for_both!(*self, ref inner => inner.description())
+    }
+
+    #[allow(deprecated)]
+    fn cause(&self) -> Option<&dyn Error> {
+        for_both!(*self, ref inner => inner.cause())
     }
 }
 
@@ -1013,8 +1303,8 @@
     L: fmt::Display,
     R: fmt::Display,
 {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        either!(*self, ref inner => inner.fmt(f))
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        for_both!(*self, ref inner => inner.fmt(f))
     }
 }
 
@@ -1033,6 +1323,8 @@
 
 #[test]
 fn macros() {
+    use std::string::String;
+
     fn a() -> Either<u32, u32> {
         let x: u32 = try_left!(Right(1337u32));
         Left(x * 2)
@@ -1047,6 +1339,8 @@
 
 #[test]
 fn deref() {
+    use std::string::String;
+
     fn is_str(_: &str) {}
     let value: Either<String, &str> = Left(String::from("test"));
     is_str(&*value);
@@ -1065,6 +1359,37 @@
 }
 
 #[test]
+fn seek() {
+    use std::io;
+
+    let use_empty = false;
+    let mut mockdata = [0x00; 256];
+    for i in 0..256 {
+        mockdata[i] = i as u8;
+    }
+
+    let mut reader = if use_empty {
+        // Empty didn't impl Seek until Rust 1.51
+        Left(io::Cursor::new([]))
+    } else {
+        Right(io::Cursor::new(&mockdata[..]))
+    };
+
+    let mut buf = [0u8; 16];
+    assert_eq!(reader.read(&mut buf).unwrap(), buf.len());
+    assert_eq!(buf, mockdata[..buf.len()]);
+
+    // the first read should advance the cursor and return the next 16 bytes thus the `ne`
+    assert_eq!(reader.read(&mut buf).unwrap(), buf.len());
+    assert_ne!(buf, mockdata[..buf.len()]);
+
+    // if the seek operation fails it should read 16..31 instead of 0..15
+    reader.seek(io::SeekFrom::Start(0)).unwrap();
+    assert_eq!(reader.read(&mut buf).unwrap(), buf.len());
+    assert_eq!(buf, mockdata[..buf.len()]);
+}
+
+#[test]
 fn read_write() {
     use std::io;
 
diff --git a/src/serde_untagged.rs b/src/serde_untagged.rs
index 20de074..72078c3 100644
--- a/src/serde_untagged.rs
+++ b/src/serde_untagged.rs
@@ -6,15 +6,11 @@
 //! but in typical cases Vec<String> would suffice, too.
 //!
 //! ```rust
-//! #[macro_use]
-//! extern crate serde;
-//! // or `use serde::{Serialize, Deserialize};` in newer rust versions.
-//!
 //! # fn main() -> Result<(), Box<dyn std::error::Error>> {
 //! use either::Either;
 //! use std::collections::HashMap;
 //!
-//! #[derive(Serialize, Deserialize, Debug)]
+//! #[derive(serde::Serialize, serde::Deserialize, Debug)]
 //! #[serde(transparent)]
 //! struct IntOrString {
 //!     #[serde(with = "either::serde_untagged")]
@@ -39,7 +35,7 @@
 
 use serde::{Deserialize, Deserializer, Serialize, Serializer};
 
-#[derive(Serialize, Deserialize)]
+#[derive(serde::Serialize, serde::Deserialize)]
 #[serde(untagged)]
 enum Either<L, R> {
     Left(L),
@@ -53,8 +49,8 @@
     R: Serialize,
 {
     let untagged = match this {
-        &super::Either::Left(ref left) => Either::Left(left),
-        &super::Either::Right(ref right) => Either::Right(right),
+        super::Either::Left(left) => Either::Left(left),
+        super::Either::Right(right) => Either::Right(right),
     };
     untagged.serialize(serializer)
 }
diff --git a/src/serde_untagged_optional.rs b/src/serde_untagged_optional.rs
index f0cca36..fb3239a 100644
--- a/src/serde_untagged_optional.rs
+++ b/src/serde_untagged_optional.rs
@@ -6,15 +6,11 @@
 //! but in typical cases Vec<String> would suffice, too.
 //!
 //! ```rust
-//! #[macro_use]
-//! extern crate serde;
-//! // or `use serde::{Serialize, Deserialize};` in newer rust versions.
-//!
 //! # fn main() -> Result<(), Box<dyn std::error::Error>> {
 //! use either::Either;
 //! use std::collections::HashMap;
 //!
-//! #[derive(Serialize, Deserialize, Debug)]
+//! #[derive(serde::Serialize, serde::Deserialize, Debug)]
 //! #[serde(transparent)]
 //! struct IntOrString {
 //!     #[serde(with = "either::serde_untagged_optional")]
@@ -56,9 +52,9 @@
     R: Serialize,
 {
     let untagged = match this {
-        &Some(super::Either::Left(ref left)) => Some(Either::Left(left)),
-        &Some(super::Either::Right(ref right)) => Some(Either::Right(right)),
-        &None => None,
+        Some(super::Either::Left(left)) => Some(Either::Left(left)),
+        Some(super::Either::Right(right)) => Some(Either::Right(right)),
+        None => None,
     };
     untagged.serialize(serializer)
 }