21.6 Matching Enums

Enums are among the most common use cases for pattern matching:

#![allow(unused)]
fn main() {
enum Coin {
    Penny,
    Nickel,
    Dime,
    Quarter,
}

fn value_in_cents(coin: Coin) -> u8 {
    match coin {
        Coin::Penny => 1,
        Coin::Nickel => 5,
        Coin::Dime => 10,
        Coin::Quarter => 25,
    }
}
}

21.6.1 Exhaustiveness in Match Expressions

Rust enforces exhaustiveness: you must handle every variant, or add a wildcard _ to catch any you omit. If you leave out a variant, the compiler will complain.

Example: Matching Custom Enums

enum OperationResult {
    Success(i32),
    Error(String),
}

fn handle_result(result: OperationResult) {
    match result {
        OperationResult::Success(code) => {
            println!("Operation succeeded with code: {}", code);
        }
        OperationResult::Error(msg) => {
            println!("Operation failed: {}", msg);
        }
    }
}

fn main() {
    handle_result(OperationResult::Success(42));
    handle_result(OperationResult::Error(String::from("Network issue")));
}

Option<T> and Result<T, E> are similarly exhaustive:

fn maybe_print_number(opt: Option<i32>) {
    match opt {
        Some(num) => println!("The number is {}", num),
        None => println!("No number provided"),
    }
}

fn divide(a: i32, b: i32) -> Result<i32, &'static str> {
    if b == 0 {
        Err("division by zero")
    } else {
        Ok(a / b)
    }
}

fn main() {
    maybe_print_number(Some(10));
    maybe_print_number(None);
    match divide(10, 2) {
        Ok(result) => println!("Division result: {}", result),
        Err(e) => println!("Error: {}", e),
    }
}