I sometimes need to write conditions on Option<T>
, and most likely result in something like .map(|x| ..).unwrap_or(false)
or .as_ref().map(|x| ..).unwrap_or(true)
. Quick search in the rust-lang/rust for unwrap_or\((?:true|false)\)
will find a sufficient amount of instances of the pattern.
Isn’t it good to provide more concise methods, namely is_some_and
and it’s de Morgan dual, is_none_or
? Although .as_ref().map(|x| ..).unwrap_or(false)
is not very much verbose, .is_some_and(|x| ..)
will make the intention clear.
This is the implementation in my mind (as a standalone library):
pub trait OptionExt<T> {
fn is_some_and<'a, F>(&'a self, f: F) -> bool where F: FnOnce(&'a T) -> bool, T: 'a;
fn is_none_or<'a, F>(&'a self, f: F) -> bool where F: FnOnce(&'a T) -> bool, T: 'a;
}
impl<T> OptionExt<T> for Option<T> {
fn is_some_and<'a, F>(&'a self, f: F) -> bool where F: FnOnce(&'a T) -> bool {
match *self {
Some(ref inner) => f(inner),
None => false,
}
}
fn is_none_or<'a, F>(&'a self, f: F) -> bool where F: FnOnce(&'a T) -> bool {
match *self {
Some(ref inner) => f(inner),
None => true,
}
}
}
I’d like to prepare PRs to include these in libcore
. Before that, I want to get advice on whether these are suitable for libcore
and whether we need an RFC instead.