I recently discovered bool::then
, and found it very useful for writing (in my opinion) clearer code that more concisely expresses my intent.
fn functional_string(condition: bool) -> Option<String> {
condition.then(|| String::from("Functional!"))
}
fn imperative_string(condition: bool) -> Option<String> {
if condition {
Some(String::from("Imperative!"))
} else {
None
}
}
In a way, bool::then
is similar to Option::map
.
fn functional_path(path: Option<&Path>) -> Option<std::io::Result<PathBuf>> {
path.map(std::path::absolute)
}
fn imperative_path(path: Option<&Path>) -> Option<std::io::Result<PathBuf>> {
if let Some(path) = path {
Some(std::path::absolute(path))
} else {
None
}
}
These two functions create a nice symmetry.
However, there is no equivalent for Option::unwrap_or_default
. This is another useful function that I find myself reaching for quite often. You can, of course, call then
followed by unwrap_or_default
, or just handle it imperatively:
fn functional_vec(condition: bool) -> Vec<String> {
condition.then(|| vec![String::from("Functional!")]).unwrap_or_default()
}
fn imperative_vec(condition: bool) -> Vec<String> {
if condition {
vec![String::from("Functional!")]
} else {
Vec::new()
}
}
Ideally, I'd like for there to be something along the lines of bool::then_or_default
, which would operate similarly to bool::then -> Option::unwrap_or_default
.
fn hypothetical_vec(condition: bool) -> Vec<String> {
condition.then_or_default(|| vec![String::from("Hypothetical!")])
}
The crate bool_ext implements this, and a lot more. They named their version bool::map_or_default
.
I don't know how useful this would be, but there could also be something like a bool::if
method that behaves vaguely like Option::map_or_else
...
fn hypothetical_if(condition:bool) -> &'static str {
condition.if(|| "True!", || "False!")
}
This is kind of like a functional version of a ternary statement. Not sure I like it, honestly.
I understand that this is a pretty niche use case, but in my opinion, bool::then_or_default
would be nice to have in the situations it comes up.
Option
has several other methods that might be worth mirroring for bool
- a couple were mentioned on this IRLO post.