21.17 Nested Patterns

Patterns can be nested to match deeply within complex data structures simultaneously.

enum Status {
    Ok,
    Error(String),
}

struct Response {
    status: Status,
    data: Option<Vec<u8>>,
}

fn handle_response(response: Response) {
    match response {
        // Nested pattern: Match Response struct, then Status::Ok, then Some(data)
        Response { status: Status::Ok, data: Some(payload) } => {
            println!("Success with payload size: {} bytes", payload.len());
            // `payload` is the Vec<u8>
        }
        // Match Ok status, but no data
        Response { status: Status::Ok, data: None } => {
            println!("Success with no data.");
        }
        // Match Error status, bind the message, ignore data field
        Response { status: Status::Error(msg), .. } => {
            println!("Operation failed: {}", msg);
            // `msg` is the String from Status::Error
        }
    }
}

fn main() {
    let resp1 = Response { status: Status::Ok, data: Some(vec![1, 2, 3]) };
    let resp2 = Response { status: Status::Ok, data: None };
    let resp3 = Response { status: Status::Error("Timeout".to_string()), data: None };

    handle_response(resp1); // Output: Success with payload size: 3 bytes
    handle_response(resp2); // Output: Success with no data.
    handle_response(resp3); // Output: Operation failed: Timeout
}

This allows highly specific conditions involving multiple levels of a data structure to be expressed clearly in a single match arm.