elevator_core/components/service_mode.rs
1//! Service mode component for elevator operational modes.
2
3use serde::{Deserialize, Serialize};
4
5/// Operational service mode for an elevator, orthogonal to [`ElevatorPhase`](super::ElevatorPhase).
6///
7/// Normal is the default. Modes modify how simulation phases behave without
8/// replacing `ElevatorPhase` — an elevator in any service mode may occupy
9/// any phase (`Idle`, `MovingToStop`, `Repositioning`, etc.). `Independent`
10/// elevators are excluded from automatic dispatch and repositioning, so in
11/// practice they only move under direct API control.
12#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
13#[non_exhaustive]
14pub enum ServiceMode {
15 /// Normal operation: dispatch assigns stops, doors auto-cycle.
16 #[default]
17 Normal,
18 /// Independent mode: elevator is excluded from dispatch and repositioning.
19 /// Consumer controls movement via direct API calls.
20 Independent,
21 /// Inspection mode: reduced speed, doors hold open indefinitely.
22 /// Speed is reduced by [`Elevator::inspection_speed_factor`](super::Elevator::inspection_speed_factor).
23 Inspection,
24 /// Manual mode: elevator is driven by direct velocity commands from the
25 /// game (see
26 /// [`Simulation::set_target_velocity`](crate::sim::Simulation::set_target_velocity)
27 /// and [`Simulation::emergency_stop`](crate::sim::Simulation::emergency_stop)).
28 /// Excluded from dispatch and repositioning; doors follow the manual
29 /// door-control API. Can stop at any position — the elevator is not
30 /// required to align with a configured stop.
31 Manual,
32}
33
34impl ServiceMode {
35 /// `true` if elevators in this mode are skipped by the automatic
36 /// dispatch and repositioning phases.
37 ///
38 /// Returns `true` for [`Independent`](Self::Independent) and
39 /// [`Manual`](Self::Manual), which both hand elevator movement over
40 /// to the consumer.
41 #[must_use]
42 pub const fn is_dispatch_excluded(self) -> bool {
43 matches!(self, Self::Independent | Self::Manual)
44 }
45}
46
47impl std::fmt::Display for ServiceMode {
48 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
49 match self {
50 Self::Normal => write!(f, "Normal"),
51 Self::Independent => write!(f, "Independent"),
52 Self::Inspection => write!(f, "Inspection"),
53 Self::Manual => write!(f, "Manual"),
54 }
55 }
56}