rust-lang / rust-lang/rfcs

Proposal for a macro like `matches!()` that maps extracted value to `Option`

Open
#2,960 5 comments 21 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Markdown
Stars
6.6k
Forks
1.7k
Avg merge
16h 14m
Merged PRs (30d)
1

Description

After the inclusion of the matches macro into std, there are still a lot of similar use cases that it can't be used with:
Those that require extracting a value like this:

    match param {
        ParamSelector::Int(_, TrackParam::Ext(name)) => Some(name),
        _ => None,
    }

These patterns occur frequently (or variations with if-let).
There is currently no concise one-line way to write this.
So I adapted the matches macro to work for these use cases:

#[macro_export]
macro_rules! match_map {
    ($expression:expr, $( $pattern:pat )|+ $( if $guard: expr )? => $ret:expr) => {
        match $expression {
            $( $pattern )|+ $( if $guard )? => Some($ret),
            _ => None
        }
    }
}

enum E { A(i32), B(i32), C }

fn main() {
    assert_eq!(match_map!(E::A(21), E::A(x) | E::B(x) => x * 2), Some(42));
}

https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=a3df83eee3d96f05233d78d00f7bc801

I use this macro as often as matches and think it would be useful to have it in std.


Compared to using the more verbose match/if-let way, this macro also has the benefit of readability, when the value is post-processed using .map(..)/.and_then(..)/.ok_or_else(..) or similar Option methods.

Compare:

    (match param {
        TrackParam::Ext(name) => Some(name),
        _ => None,
    }).and_then(|name| func(name))

and:

    match_map!(param, TrackParam::Ext(name) => name).and_then(|name| func(name))

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reviewing the proposed match_map! macro, its matches! comparison, and the linked Rust Playground examples. Determine whether the proposed extraction and Option mapping belong in std, and what design or RFC decisions are required. Done means the proposal has a settled design and an accepted path forward.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.