Pre-RFC: Option::none_if()

I had cases where I got an Option's Some(x) , which I wanted to convert to None in case x is in a given state. For example, Some<String> which should be converted to None in case the string is empty:

fn none_if_string_is_empty(param: Option<String>) -> Option<String> {
    param.and_then(|s| if s.is_empty() { None } else { Some(s) })
}

fn main() {
    assert_eq!(
        none_if_string_is_empty(Some("Hello, world".to_owned())),
        Some("Hello, world".to_owned())
    );
    assert_eq!(none_if_string_is_empty(Some("".to_owned())), None);
    assert_eq!(none_if_string_is_empty(None), None);
}

I noticed this pattern is rather common, and I find the current implementation a bit cumbersome. For that reason I would like to suggest to add a syntactic sugar for such test, called Option::none_if:

// pub const fn none_if<U, F>(self, f: F) -> Option<U>
// where
//     F: ~const FnOnce(T) -> Option<U>,
//     F: ~const Drop,
// {
//     match self {
//         Some(x) => if f(x) { None } else { Some(x) },
//         None => None,
//     }
// }

fn none_if_string_is_empty_with_none_if(param: Option<String>) -> Option<String> {
    param.none_if(|s| s.is_empty())
}

I would like to get some feedback in this suggestion. Thanks!

Option::filter seems to do the job here (you just have to negate the condition).

6 Likes

Are you aware of Option::filter?

4 Likes

Oh, that is exactly what I wanted, and of course the naming is much better. Thanks for answering. Could you please close this discussion?

1 Like