// Copyright 2023 Google LLC
// SPDX-License-Identifier: Apache-2.0
#![allow(dead_code)]
#[derive(Debug)]
/// An event in the elevator system that the controller must react to.
enum Event {
/// A button was pressed.
ButtonPressed(Button),
/// The car has arrived at the given floor.
CarArrived(Floor),
/// The car's doors have opened.
CarDoorOpened,
/// The car's doors have closed.
CarDoorClosed,
}
/// A floor is represented as an integer.
type Floor = i32;
/// A direction of travel.
#[derive(Debug)]
enum Direction {
Up,
Down,
}
/// A user-accessible button.
#[derive(Debug)]
enum Button {
/// A button in the elevator lobby on the given floor.
LobbyCall(Direction, Floor),
/// A floor button within the car.
CarFloor(Floor),
}
/// The car has arrived on the given floor.
fn car_arrived(floor: i32) -> Event {
Event::CarArrived(floor)
}
/// The car doors have opened.
fn car_door_opened() -> Event {
Event::CarDoorOpened
}
/// The car doors have closed.
fn car_door_closed() -> Event {
Event::CarDoorClosed
}
/// A directional button was pressed in an elevator lobby on the given floor.
fn lobby_call_button_pressed(floor: i32, dir: Direction) -> Event {
Event::ButtonPressed(Button::LobbyCall(dir, floor))
}
/// A floor button was pressed in the elevator car.
fn car_floor_button_pressed(floor: i32) -> Event {
Event::ButtonPressed(Button::CarFloor(floor))
}
fn main() {
println!(
"A ground floor passenger has pressed the up button: {:?}",
lobby_call_button_pressed(0, Direction::Up)
);
println!("The car has arrived on the ground floor: {:?}", car_arrived(0));
println!("The car door opened: {:?}", car_door_opened());
println!(
"A passenger has pressed the 3rd floor button: {:?}",
car_floor_button_pressed(3)
);
println!("The car door closed: {:?}", car_door_closed());
println!("The car has arrived on the 3rd floor: {:?}", car_arrived(3));
}
Enums with Data: Rust enum variants can carry data. CarArrived(Floor)
carries an integer, and ButtonPressed(Button) carries a nested Button
enum. This allows Event to represent a rich set of states in a type-safe
way.
Type Aliases:type Floor = i32 gives a semantic name to i32. This
improves readability, but Floor is still just an i32 to the compiler.
#[derive(Debug)]: We use this attribute to automatically generate code
to format the enums for printing with {:?}. Without this, we would have to
manually implement the fmt::Debug trait.
Nested Enums: The Button enum is nested inside Event::ButtonPressed.
This hierarchical structure is common in Rust for modeling complex domains.
Note that Event::CarDoorOpened is a “unit variant” (it carries no data),
while Event::CarArrived is a “tuple variant”.
You might discuss why Button is a separate enum rather than just having
LobbyCallButtonPressed and CarFloorButtonPressed variants on Event. Both
are valid, but grouping related concepts (like buttons) can make the code
cleaner.