// Copyright 2023 Google LLC
// SPDX-License-Identifier: Apache-2.0
#![allow(dead_code)]
#[derive(Debug)]
/// Событие в системе лифта, на которое должен реагировать контроллер.
enum Event {
/// Была нажата кнопка.
ButtonPressed(Button),
/// Кабина прибыла на указанный этаж.
CarArrived(Floor),
/// Двери кабины открылись.
CarDoorOpened,
/// Двери кабины закрылись.
CarDoorClosed,
}
/// Этаж представлен целым числом.
type Floor = i32;
/// Направление движения.
#[derive(Debug)]
enum Direction {
Up,
Down,
}
/// Кнопка, доступная пользователю.
#[derive(Debug)]
enum Button {
/// Кнопка в холле лифта на указанном этаже.
LobbyCall(Direction, Floor),
/// Кнопка этажа внутри кабины.
CarFloor(Floor),
}
/// Кабина прибыла на указанный этаж.
fn car_arrived(floor: i32) -> Event {
Event::CarArrived(floor)
}
/// Двери кабины открылись.
fn car_door_opened() -> Event {
Event::CarDoorOpened
}
/// Двери кабины закрылись.
fn car_door_closed() -> Event {
Event::CarDoorClosed
}
/// Была нажата кнопка направления в холле лифта на указанном этаже.
fn lobby_call_button_pressed(floor: i32, dir: Direction) -> Event {
Event::ButtonPressed(Button::LobbyCall(dir, floor))
}
/// Была нажата кнопка этажа в кабине лифта.
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));
}
Перечисления с данными: варианты перечислений Rust могут содержать данные. CarArrived(Floor) хранит целое число, а ButtonPressed(Button) хранит вложенное перечисление Button. Так Event может представлять богатый набор состояний безопасным для типов способом.
Псевдонимы типов:type Floor = i32 задаёт семантическое имя для i32. Это повышает читаемость, но для компилятора Floor по-прежнему остаётся просто i32.
#[derive(Debug)]: этот атрибут автоматически генерирует код, который форматирует перечисления при выводе через {:?}. Без него пришлось бы вручную реализовать трейт fmt::Debug.
Вложенные перечисления: перечисление Button вложено в Event::ButtonPressed. Такая иерархическая структура распространена в Rust для моделирования сложных предметных областей.
Обратите внимание, что Event::CarDoorOpened — это «вариант-единица» (он не содержит данных), а Event::CarArrived — «кортежный вариант».
Можно обсудить, почему Button — отдельное перечисление, а не просто варианты LobbyCallButtonPressed и CarFloorButtonPressed в Event. Оба подхода корректны, но группировка связанных понятий (например, кнопок) может сделать код чище.