Skip to content

05 · Enums and Match

enum defines a type with a fixed set of variants. Variants can carry data. match deconstructs an enum exhaustively — the compiler rejects any match that doesn’t cover all variants, so a new variant added to an enum surfaces every unhandled callsite at compile time.

enums.cssl
enum Shape {
Circle { radius: f32 },
Rectangle { width: f32, height: f32 },
Triangle { base: f32, height: f32 },
}
fn area(s: Shape) -> f32 {
match s {
Shape::Circle { radius } => 3.14159 * radius * radius,
Shape::Rectangle { width, height } => width * height,
Shape::Triangle { base, height } => 0.5 * base * height,
}
}
fn describe(s: &Shape) -> str {
match s {
Shape::Circle { .. } => "a circle",
Shape::Rectangle { .. } => "a rectangle",
Shape::Triangle { .. } => "a triangle",
}
}
fn main() !io {
let shapes = [
Shape::Circle { radius: 2.0 },
Shape::Rectangle { width: 4.0, height: 3.0 },
Shape::Triangle { base: 6.0, height: 4.0 },
];
for s in shapes {
println!("{} has area {:.2}", describe(&s), area(s));
}
}
a circle has area 12.57
a rectangle has area 12.00
a triangle has area 12.00

Match arms are checked for exhaustiveness at compile time. The { .. } pattern ignores all fields — useful for the description branch where only the variant matters. Adding a fourth variant Shape::Ellipse would immediately break the area function with a compile error at the unhandled arm.


Next → 06 · Effects