I recently found myself needing to do the following
match opt {
None => Ok(()),
Some(e) => Err(e)
}
But I think it would be nice to do this with opt.err_or(())
It seems odd to me that the following exist
Option::ok_or
Option::ok_or_else
But not the corresponding
Option::err_or
Option::err_or_else
I feel like they belong for both completeness sake, and usefulness. (Albeit this is the first time I have needed them, and I have used the others a lot more often).
This is odd. Usually Some(ok) is the success case, so you use ok_or(err). I haven’t seen Some(err).
I’m afraid it’d encourage functions returning Option<Error> instead of Result<(), Error>, and that would end up working backwards with the ? operator.
That is a good point. Interestingly, I need it for the very case of a function returning a Result<(), Error>. My use case is where I am parallelizing a task on a bunch of data and end up with an iterator of Results. I then
fn my_function() -> Result<(), Error> {
// some setup code ...
let (tx, rx) = std::sync::mpsc::channel();
// some code to spawn threads and parallelize stuff ...
rx.iter()
.take(elements.len())
.filter_map(Result::err)
.next()
.err_or(())
}
I’m sure there might be better way of doing what I want to do, but this is how I ended up with wanting Option::err_or.
.map(|_| ()).collect() does what you want. Collect has special handling for Results (stops on first error) and special handling for () (it knows to flatten them).
well, I did not know about the existing methods literally named “transpose”. I might also have used the word in error somewhat.
Option::ok_or turns Some into Ok and None into Err. Result::ok turns Ok into Some and Err into None. What I wanted in the past was what’s described in the match in the first post: Some becomes Err, and None becomes Ok (and the similar inverse for Result to Option).
fn my_function() -> Result<(), Error> {
// some setup code ...
let (tx, rx) = std::sync::mpsc::channel();
// some code to spawn threads and parallelize stuff ...
use std::ops::Not;
rx.iter()
.take(elements.len())
.filter_map(Result::err)
.next()
.ok_or(())
.not()
}
I admit you can read it, but it still seems odd.
My main argument for Option::err_or() and Option::err_or_else would be that Result::err() already exists and adding them would make the API less surprising.