Variant Payloads

You can define richer enums where the variants carry data. You can then use the match statement to extract the data from each variant:

  1. enum WebEvent {
  2. PageLoad, // Variant without payload
  3. KeyPress(char), // Tuple struct variant
  4. Click { x: i64, y: i64 }, // Full struct variant
  5. }
  6. #[rustfmt::skip]
  7. fn inspect(event: WebEvent) {
  8. match event {
  9. WebEvent::PageLoad => println!("page loaded"),
  10. WebEvent::KeyPress(c) => println!("pressed '{c}'"),
  11. WebEvent::Click { x, y } => println!("clicked at x={x}, y={y}"),
  12. }
  13. }
  14. fn main() {
  15. let load = WebEvent::PageLoad;
  16. let press = WebEvent::KeyPress('x');
  17. let click = WebEvent::Click { x: 20, y: 80 };
  18. inspect(load);
  19. inspect(press);
  20. inspect(click);
  21. }
  • In the above example, accessing the char in KeyPress, or x and y in Click only works within a match or an if let statement.
  • match and if let inspect a hidden discriminant field in the enum.
  • It is possible to retrieve the discriminant by calling std::mem::discriminant()
    • This is useful, for example, if implementing PartialEq for structs where comparing field values doesn’t affect equality.
  • WebEvent::Click { ... } is not exactly the same as WebEvent::Click(Click) with a top level struct Click { ... }. The inlined version cannot implement traits, for example.