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.