Use Pattern Matching and Destructuring

Sources:
https://doc.rust-lang.org/book/ch18-01-all-the-places-for-patterns.html

Rust's pattern matching is powerful and it can destructure complex data types.

Slice Destructuring

fn main() {
    let array = [0, 1, 2];
    let [a, b, c] = array;

    println!("{}, {}, {}", a, b, c);
}

Subslice Destructuring

fn slice_pattern(array: &[i32]) {
    match array {
        [] => println!("Empty array"),
        [x0] => println!("One element: {}", x0),
        [x0, y @ .., xn] => println!("First: {}, Last: {}, Middle: {:?}", x0, xn, y),
    }
}

fn main() {
    slice_pattern(&[]);
    slice_pattern(&[0]);
    slice_pattern(&[0, 1, 2, 3, 4]);
}

struct, enum, Tuple Destructuring

struct ExStruct<'a> {
    field1: i32,
    field2: &'a str,
}

enum ExEnum<'a> {
    Variant(ExStruct<'a>),
}

fn main() {
    // Tuple destructuring
    let ex_tuple = (1, 2, 3);
    let (x, y, z) = ex_tuple;

    println!("x: {}, y: {}, z: {}", x, y, z);

    // `struct` destructuring
    let ex_struct = ExStruct {
        field1: 1,
        field2: "string",
    };

    let ExStruct { field1: i, field2: s } = ex_struct;
    let ExStruct { field1, field2 } = ex_struct;

    println!("field1: {}, field2: {}", i, s);
    println!("field1: {}, field2: {}", field1, field2);

    // Nested `enum` & `struct` destructuring
    let ex_enum = ExEnum::Variant(ex_struct);

    let ExEnum::Variant(ExStruct { field1, field2 }) = ex_enum;
    println!("field1: {}, field2: {}", field1, field2);
}

Reference Destructuring

fn main() {
    let mut x = 32;

    match x {
        ref x_ref => println!("Reference: {:?}", x_ref),
    }

    match x {
        ref mut x_mut_ref => println!("Mutable reference: {:?}", x_mut_ref),
    }
}