Rust Fundamentals · 15 XP Pro

Enums with data

Variants can carry values, and each variant may carry something different. There are two shapes of payload: a tuple style with unnamed fields, and a struct style with named fields.

enum Event {
    Quit,                      // no data
    Key(char),                 // one value
    Click { x: i32, y: i32 },  // named fields
}

let e = Event::Click { x: 3, y: 4 };
let k = Event::Key('q');

One type, three different layouts. A function taking an Event handles all of them. To get the data back out, match on the enum and give names to the fields in the pattern:

fn describe(e: Event) -> String {
    match e {
        Event::Quit => String::from("quit"),
        Event::Key(c) => format!("key {c}"),
        Event::Click { x, y } => format!("click at {x},{y}"),
    }
}

Each arm binds the payload to local variables that exist only in that arm.

Your task

The starter defines Shape with a single variant. Everything the tests use must be pub. Add two more variants:

  • Rectangle { width: f64, height: f64 }
  • Triangle(f64, f64), holding the base and then the height

Then write pub fn area(shape: &Shape) -> f64. A circle has area PI * r * r (use std::f64::consts::PI), a rectangle width * height, and a triangle base * height / 2.0. Since you receive a reference, matching on shape still lets you bind the fields directly.

Next lesson →

Sign in to run your code. It's free.