If I have a Result<T, T> it is always possible to get out a T from that. But there is currently no convenient way of doing that.
My current use case is migrating from Atomic*::compare_and_swap to Atomic*::compare_exchange[_weak]. The old return type was just the old value in the atomic. But with compare_exchange[_weak] the return value is Result<T, T> where both the Ok and Err variants contain the old value. For some code I just need to get the old value from this operation. See for example: https://github.com/rust-lang/rust/blob/593fe977a77ad5a7aec23c6cb0f86a3470221670/library/std/src/sync/mpsc/oneshot.rs#L267
I propose adding either a special unwrap method for this:
Since the Ok(_) version of compare_exchange always has a known value (the value of the current argument) it would have been possible to do .unwrap_err_or(current) on my result. But unwrap_err_or does also not exist. And there is also no method for converting Result<T, E> -> Result<E, T> that I can find.
Any way around this problem for my current situation, or would it be a good idea to add some way to easily convert Result<T, T> -> T?
Lol. Great! I completely missed that unwrap_or_else took an FnOnce(E) -> T I assumed/thought it was an FnOnce() -> T. Have not been using it enough. Thank you
I still think Result<T, T> -> T should be easier. But maybe the use case is too exotic
Btw, another possibility is (...).map_or_else(identity, identity).
The (IMO terribly named) map_or_else function is kind-of “almighty” in that you can basically define any operation consuming a Result by value just with map_or_else.
For comparison, the either crate does provide a method called into_inner with this kind of functionality for the Either type (which is pretty similar to Result).
in addition to the above or_patterns within match doesn't require the feature,
so let x = match my_result { Ok(x) | Err(x) => x}; alas rustfmt always wants to split up the lines.
I think its easy to also just add yourself an extension trait, something like
trait Uniformity {
type Inner;
fn uniformity(self) -> Self::Inner;
}
impl<T> Uniformity for Result<T, T> {
type Inner = T;
fn uniformity(self) -> T {
match self { Ok(x) | Err(x) => x}
}
}
I know I can just match it. That's what my example implementation of unwrap_either does. The main problem is that it's very bulky and takes up many lines. I do not look for a solution that is short only on the premise of breaking idiomatic formatting (rustfmt <3).
Adding a trait is only relevant if this is a very common operation in a project. If you have one or a few Result<T, T> -> T conversions it does not make much sense IMO.
The or_pattern is interesting. But it's still not shorter or simpler in a single expression than the already suggested unwrap_or_else(|x| x) which I went with in the end.