about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDylan DPC <dylan.dpc@gmail.com>2021-02-17 23:51:13 +0100
committerGitHub <noreply@github.com>2021-02-17 23:51:13 +0100
commit40e3af5a2131f0f211e2f247faceae4008c94ec9 (patch)
tree0e93f986dc71231a037752a1bad0f143a752a265
parentdb59950b6d9dbadc4824e6dde841d1a085894c89 (diff)
parent404da0bc901b92c2bf74a3c84fb0bd52cbf7f934 (diff)
downloadrust-40e3af5a2131f0f211e2f247faceae4008c94ec9.tar.gz
rust-40e3af5a2131f0f211e2f247faceae4008c94ec9.zip
Rollup merge of #80572 - thomcc:ok_or_err, r=m-ou-se
Add a `Result::into_ok_or_err` method to extract a `T` from `Result<T, T>`

When updating code to handle the semi-recent deprecation of `compare_and_swap` in favor of `compare_exchange`, which returns `Result<T, T>`, I wanted this. I've also wanted it with code using `slice::binary_search` before.

The name (and perhaps the documentation) is the hardest part here, but this name seems consistent with the other Result methods, and equivalently memorable.
-rw-r--r--library/core/src/result.rs35
-rw-r--r--library/core/tests/lib.rs1
-rw-r--r--library/core/tests/result.rs9
3 files changed, 45 insertions, 0 deletions
diff --git a/library/core/src/result.rs b/library/core/src/result.rs
index a43ba5882ed..d8747f8b8d6 100644
--- a/library/core/src/result.rs
+++ b/library/core/src/result.rs
@@ -1276,6 +1276,41 @@ impl<T, E> Result<Result<T, E>, E> {
     }
 }
 
+impl<T> Result<T, T> {
+    /// Returns the [`Ok`] value if `self` is `Ok`, and the [`Err`] value if
+    /// `self` is `Err`.
+    ///
+    /// In other words, this function returns the value (the `T`) of a
+    /// `Result<T, T>`, regardless of whether or not that result is `Ok` or
+    /// `Err`.
+    ///
+    /// This can be useful in conjunction with APIs such as
+    /// [`Atomic*::compare_exchange`], or [`slice::binary_search`][binary_search], but only in
+    /// cases where you don't care if the result was `Ok` or not.
+    ///
+    /// [`Atomic*::compare_exchange`]: crate::sync::atomic::AtomicBool::compare_exchange
+    /// [binary_search]: ../../std/primitive.slice.html#method.binary_search
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(result_into_ok_or_err)]
+    /// let ok: Result<u32, u32> = Ok(3);
+    /// let err: Result<u32, u32> = Err(4);
+    ///
+    /// assert_eq!(ok.into_ok_or_err(), 3);
+    /// assert_eq!(err.into_ok_or_err(), 4);
+    /// ```
+    #[inline]
+    #[unstable(feature = "result_into_ok_or_err", reason = "newly added", issue = "82223")]
+    pub const fn into_ok_or_err(self) -> T {
+        match self {
+            Ok(v) => v,
+            Err(v) => v,
+        }
+    }
+}
+
 // This is a separate function to reduce the code size of the methods
 #[inline(never)]
 #[cold]
diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs
index 40dc6473b7d..34e05760db2 100644
--- a/library/core/tests/lib.rs
+++ b/library/core/tests/lib.rs
@@ -65,6 +65,7 @@
 #![feature(never_type)]
 #![feature(unwrap_infallible)]
 #![feature(option_result_unwrap_unchecked)]
+#![feature(result_into_ok_or_err)]
 #![feature(option_unwrap_none)]
 #![feature(peekable_peek_mut)]
 #![feature(once_cell)]
diff --git a/library/core/tests/result.rs b/library/core/tests/result.rs
index 7aa44c6e593..5fcd7b4d3a3 100644
--- a/library/core/tests/result.rs
+++ b/library/core/tests/result.rs
@@ -96,6 +96,15 @@ fn test_unwrap_or() {
 }
 
 #[test]
+fn test_ok_or_err() {
+    let ok: Result<isize, isize> = Ok(100);
+    let err: Result<isize, isize> = Err(200);
+
+    assert_eq!(ok.into_ok_or_err(), 100);
+    assert_eq!(err.into_ok_or_err(), 200);
+}
+
+#[test]
 fn test_unwrap_or_else() {
     fn handler(msg: &'static str) -> isize {
         if msg == "I got this." { 50 } else { panic!("BadBad") }