'Boolean expression for checking if expression matches pattern in Rust

I have a Vec of values and want to filter those that match a certain pattern.
What is the idiomatic way to just check if an expression matches a pattern, without necessarily doing something with the match?

enum Kind {
    A,
    B(char),
}

let vector: Vec<Option<Kind>> = ...;
vector.filter(|item| /* check if item matches pattern Some(Kind::B(_)) */)

I know I can use the match keyword:

vector.filter(|item| match item {
  Some(Kind::B(_)) => true,
  _ => false,
})

or the if let keyword:

vector.filter(|item| {
  if let Some(Kind::B(_)) = item {
    true
  } else {
    false
  }
})

But in both examples, the code still looks bulky because I manually need to provide the true and false constants. I feel like there should be a more elegant way to do that, something similar to the following:

vector.filter(|item| matches(item, Some(Kind::B(_))))


Solution 1:[1]

You can use Option::is_some function. Here is example:

#[derive(Debug)]
enum Kind {
    A,
    B(char),
}

fn main() {
    let vec_of = vec![Some(Kind::A), Some(Kind::B('x')), None, None];

    // let col: Vec<Option<Kind>> = vec_of.into_iter().filter(Option::is_some).collect();
    let col: Vec<Option<Kind>> = vec_of.into_iter().filter(|item| item.is_some()).collect();

    println!("{:?}", col);
}

Commend line is the same as one with .filter(|item| item.is_some()) but shorter. I left longer version too for better understanding.

Rust Playground

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Đorđe Zeljić