Skip to content

Tracking Issue for Option::is_some_and and Result::is_{ok,err}_and #93050

Closed

Description

@m-ou-se

Feature gate: #![feature(is_some_and)]

This is a tracking issue for Option::is_some_and, Result::is_ok_and and Result::is_err_and.

Public API

impl<T> Option<T> {
    pub fn is_some_and(self, f: impl FnOnce(T) -> bool) -> bool;
}

impl<T, E> Result<T, E> {
    pub fn is_ok_and(self, f: impl FnOnce(T) -> bool) -> bool;
    pub fn is_err_and(self, f: impl FnOnce(E) -> bool) -> bool;
}

Steps / History

Unresolved Questions

Activity

  1. added
    T-libs-api[DEPRECATED; DO NOT USE]
    C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFC
    on Jan 18, 2022
  2. the8472 commented on Jan 18, 2022

    @the8472
    Member

    What are the use-cases? And won't that largely be covered by if-let chains?

    if let Some(foo) = opt && foo > bar {
       
    }
  3. m-ou-se commented on Jan 18, 2022

    @m-ou-se
    MemberAuthor

    Lots of functions on Option and Result are already 'covered' by match or if let, but it's still very useful to have methods for the most common cases. It makes things more readable and less verbose, and also easier to write (especially with auto completion).

    let deadline_passed = optional_deadline.is_some_with(|d| d < now);
    
    let deadline_passed = matches!(optional_deadline, Some(d) if d < now);
    
    let deadline_passed = if let Some(d) = optional_deadline && d < now { true } else { false };
  4. the8472 commented on Jan 18, 2022

    @the8472
    Member

    I assume deadline_passedwould then flow into another if in which case one could do an if-let-chain (once that's stable) directly rather than having a separate variable for that. I mean as I understand it the purpose of if-let-chain is to make such towers of conditionals more readable.
    Maybe it's useful inside a filter closure? But then one could flatten() first and then filter instead.

    I think a code example with a bit more context that would benefit from this and wouldn't be replaced by if-let-chain in the future would be helpful.

    Naming. Alternatives:

    Or maybe just is? Assuming we want to spend our small budget of meaningful two-letter words on this.
    But I like is_some_and since it is consistent with the way the if is written.

  5. camsteffen commented on Jan 18, 2022

    @camsteffen
    Contributor

    is or any name ending in "is" will not flow well with function names in the argument: opt.and_is(char::is_lowercase), dog.and_is(Dog::has_a_bone), etc.

    is_some_and flows better. I would consider the shorter some_and as well.

  6. m-ou-se commented on Jan 18, 2022

    @m-ou-se
    MemberAuthor

    I assume deadline_passedwould then flow into another if in which case one could do an if-let-chain (once that's stable) directly rather than having a separate variable for that.

    This example about a deadline: Option<Instant> comes directly from code I worked on recently. Checking some condition on a Some is a pattern that occurs reguarly there. In some cases it's just used in an if directly, but in many cases the value is stored in some struct first, or used by multiple ifs, or passed to a function, serialized and sent over a socket, etc. In some cases it's only used in a single if, but part of a much more complicated condition. Various parts of that condition are first assigned to named bools to keep things clear. (Just like why people use matches!() rather than a match or if let in some situations. Or x.is_some() rather than if let Some(_) = x. Or x.then() instead of if x {}. And so on.)

    Or maybe just is?

    I've added is and has to the alternatives.

  7. m-ou-se commented on Jan 18, 2022

    @m-ou-se
    MemberAuthor

    There are 117 cases of .map_or(false, in the compiler/ directory in the rust repository. Most of them are probably good examples of use cases for these methods.

  8. jakoschiko commented on Jan 19, 2022

    @jakoschiko
    Contributor

    The name is_some_and would allow us to add its counterpart is_none_or in the future.

  9. m-ou-se commented on Jan 22, 2022

    @m-ou-se
    MemberAuthor

    is_some_and

    After thinking about it a bit more, I like this name. It very clearly states that it first checks is_some, and then also checks a condition afterwards.

  10. camsteffen commented on Mar 7, 2022

    @camsteffen
    Contributor

    FWIW this was attempted in #75298.

  11. added a commit that references this issue on Mar 11, 2022
  12. added a commit that references this issue on Mar 13, 2022
  13. changed the title [-]Tracking Issue for Option::is_some_with and Result::is_{ok,err}_with[/-] [+]Tracking Issue for Option::is_some_and and Result::is_{ok,err}_and[/+] on Mar 29, 2022
  14. jam1garner commented on May 4, 2022

    @jam1garner
    Contributor

    As someone who finds map_or both overly verbose for this (I need this version far more than the general case of map_or) and generally unpleasant (due to argument order not matching the name, although I 100% understand that decision even if I don't love it) I would be thrilled for this.

    I think the worry about overlap with if/let is valid but for filtering and other combinators this composes really well (having played with it some now)

    Also +1 to is_some_and for the name, very much a fan

  15. 94 remaining items

  16. jplatte commented on Apr 5, 2023

    @jplatte
    Contributor

    Is this just waiting for somebody to create a stabilization PR? I can probably do that if so.

  17. Amanieu commented on Apr 5, 2023

    @Amanieu
    Member

    Is this just waiting for somebody to create a stabilization PR? I can probably do that if so.

    Yes. Feel free to go ahead.

  18. asquared31415 commented on Apr 6, 2023

    @asquared31415
    Contributor

    The description of this API in this tracking issue and in #110019 say that the closure takes &T but the implementation has the closure taking T.

  19. Amanieu commented on Apr 6, 2023

    @Amanieu
    Member

    We had a second FCP to change the closure to take T, but it seems that we forgot to update the issue description. I've just updated it.

  20. jplatte commented on Apr 7, 2023

    @jplatte
    Contributor

    I totally forgot about all that.. Well I guess I will live with it. The draft PR to show that it made is_some_and calls "nicer" unfortunately didn't show any places where taking ownership of of the inner value was necessary, but maybe there are a few and it would probably be pretty annoying for some people for the combinator to not be applicable therethr same way I find the extra as_ref annoying where it is needed..

  21. added a commit that references this issue on Apr 7, 2023
    b6f6104
  22. added a commit that references this issue on May 8, 2023
  23. wrenger commented on May 19, 2023

    @wrenger

    Well, I don't know if these functions are really that essential. These checks can be made in several different ways.

    let data = Some("foo");
    
    if data == Some("foo") {
        //...
    }
    if data.is_some_and(|inner| inner == "foo") {
        //...
    }
    if let Some(inner) = data && inner == "foo" {
        //...
    }
    if matches!(data, Some(inner) if inner == "foo") {
        //...
    }

    The first might only be desirable in some cases, but the third one with let-chains #53667 is a little bit more legible, in my opinion.

  24. tnblumer commented on Jun 5, 2023

    @tnblumer

    In which version should we expect this feature? I thought it was going to be in 1.70.0, but apparently not.

  25. RalfJung commented on Jun 6, 2023

    @RalfJung
    Member
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCT-libs-api[DEPRECATED; DO NOT USE]disposition-mergeThis issue / PR is in PFCP or FCP with a disposition to merge it.finished-final-comment-periodThe final comment period is finished for this PR / Issue.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions