Rust Pattern Matching Is Beautiful

I’ve been working on a Rust side project lately and as I always do when I write Rust code, I find myself loving pattern matching even more than I did before. It seems like such a simple thing, sort of just a better if statement, but the more you use it, the more you realize just how powerful and elegant it really is.

One example from this project is the need to parse a piece of text to determine if a user is adding or removing a tag. If they specify an argument like +work it means they are adding the work tag, and -home would indicate they are removing the home tag.

This might look something like this:

pub fn parse_tag(text: &String) -> Option<(Operator, String)> {
    let mut chars = text.chars();
    let operator = match chars.next() {
        Some('+') => Operator::Add,
        Some('-') => Operator::Remove,
        _ => return None,
    };

    return match chars.next() {
        Some(' ') | None => None,
        Some(_) => Some((operator, text[1..].to_string())),
    };
}

In the first match statement, we check the first character for the + or - sign, and set the operator variable to the appropriate value. However, if the first character is neither of those, the value is not a tag, and we can return None from within the match statement and the entire function will stop. This might seem trivial, but the alternative is assigning the operator variable to None, then performing additional logic to return in our function.

The second match statement shows another great feature: multiple match patterns. If there are no more characters in the text, or the next character is whitespace, we want to return None from our function. However, we don’t have to list these as separate match “arms”, instead we can combine them with | keeping our code extremely simple and easy to understand.