Idea: is_some_and/is_none_or

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.

3 Likes

There’s always https://doc.rust-lang.org/nightly/std/option/enum.Option.html#method.filter so you can write .filter(...).is_some().

2 Likes

What about the existing Option::map_or?

The names, to me, did not feel immediately evocative of their functions. An is_ function doesn’t suggest to me a function taking a predicate.

I think it would make sense to put functions like these in a standalone crate first, and see how much usage they get.

4 Likes

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.