Reputation: 1637
It seems there is no way of such one-line conversion using std
.
I do not like this kind of verbosity:
match my_bool {
true => Ok(()),
false => Err(MyError::False),
}
I would like to use a one-liner, for example:
let my_bool = true;
let my_option = my_bool.to_option(MyObject{}); // true => MyObject{}, false => None
let my_result = my_bool.to_result(MyObject{}, MyError{}); // true => MyObject{}, false => MyError{}
What is the shortest piece of code for doing that?
Upvotes: 59
Views: 30582
Reputation: 5449
As an alternative to the standard library functions. The then
crate provides some
and some_with
methods on booleans.
use then::Some
// returns Some(value) if my_bool is true
my_bool.some(value);
// returns Some(value_fn()) if my_bool is true
my_bool.some_with(value_fn);
Disclaimer: I wrote this crate because I find it annoying that my_bool.some_with(value)
is longer than my_bool.some(|| value)
. And using the _with
suffix is more consistent with the Rust naming for lazily evaluated functions.
Upvotes: 1
Reputation: 8357
bool.then_some()
does this:
let my_bool = true;
let my_option = my_bool.then_some(MyObject{});
let my_result = my_bool.then_some(MyObject{}).ok_or(MyError{});
At the time of writing, this is still part of the experimental bool_to_option
feature.
Update: As of Rust 1.62, this feature has been stabilized.
Upvotes: 38
Reputation: 13518
As of Rust 1.50 you can use bool::then
:
assert_eq!(false.then(|| val), None);
assert_eq!(true.then(|| val), Some(val));
You can convert it to a Result
by chaining Option::ok_or
:
assert_eq!(false.then(|| val).ok_or(err), Err(err));
assert_eq!(true.then(|| val).ok_or(err), Ok(val));
As of Rust 1.62, you can use bool::then_some
and pass a value directly instead of creating a closure:
assert_eq!(false.then_some(val), None);
assert_eq!(true.then_some(val), Some(val));
Alternatively, you can use Option::filter
:
assert_eq!(Some(obj).filter(|_| false), None);
assert_eq!(Some(obj).filter(|_| true).ok_or(err), Ok(obj));
Upvotes: 72
Reputation: 88576
This answer is somewhat outdated. Starting with Rust 1.50, you can use the built-in bool::then
. See the other answers above for more information.
There is the boolinator
crate. It defines the extension trait Boolinator
for bool
which adds a couple of useful methods. Example:
use boolinator::Boolinator;
my_bool.as_some(MyObject {}); // Option<MyObject>
my_bool.as_result(MyObject {}, MyError {}); // Result<MyObject, MyError>
A true
value leads to Some(_)
or Ok(_)
, while a false
value leads to None
or Err(_)
.
There is an issue about adding functionality like this to std
on the RFCs repository, but it doesn't look like it's happening anytime soon.
Upvotes: 19
Reputation: 430574
Use an if
expression:
if my_bool { Ok(()) } else { Err(MyError::False) }
Upvotes: 8