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.
This commit is contained in:
Dylan DPC 2021-02-17 23:51:13 +01:00 committed by GitHub
commit 40e3af5a21
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 45 additions and 0 deletions

View File

@ -1276,6 +1276,41 @@ pub fn flatten(self) -> Result<T, 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]

View File

@ -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)]

View File

@ -95,6 +95,15 @@ fn test_unwrap_or() {
assert_eq!(ok_err.unwrap_or(50), 50);
}
#[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 {