#![allow(unreachable_patterns)]
use crate::components::{CallDirection, Direction, ElevatorPhase, ServiceMode};
#[must_use]
pub const fn elevator_phase(phase: ElevatorPhase) -> &'static str {
match phase {
ElevatorPhase::Idle => "idle",
ElevatorPhase::MovingToStop(_) => "moving",
ElevatorPhase::Repositioning(_) => "repositioning",
ElevatorPhase::DoorOpening => "door-opening",
ElevatorPhase::Loading => "loading",
ElevatorPhase::DoorClosing => "door-closing",
ElevatorPhase::Stopped => "stopped",
_ => "unknown",
}
}
#[must_use]
pub const fn service_mode(mode: ServiceMode) -> &'static str {
match mode {
ServiceMode::Normal => "normal",
ServiceMode::Independent => "independent",
ServiceMode::Inspection => "inspection",
ServiceMode::Manual => "manual",
ServiceMode::OutOfService | _ => "out-of-service",
}
}
#[must_use]
pub fn parse_service_mode(label: &str) -> Option<ServiceMode> {
match label {
"normal" => Some(ServiceMode::Normal),
"independent" => Some(ServiceMode::Independent),
"inspection" => Some(ServiceMode::Inspection),
"manual" => Some(ServiceMode::Manual),
"out-of-service" => Some(ServiceMode::OutOfService),
_ => None,
}
}
#[must_use]
pub const fn direction(dir: Direction) -> &'static str {
match dir {
Direction::Up => "up",
Direction::Down => "down",
Direction::Either | _ => "either",
}
}
pub fn parse_call_direction(label: &str) -> Result<CallDirection, String> {
match label {
"up" => Ok(CallDirection::Up),
"down" => Ok(CallDirection::Down),
other => Err(format!("direction must be 'up' or 'down', got {other:?}")),
}
}
#[cfg(test)]
#[allow(clippy::expect_used)]
mod tests {
use super::*;
#[test]
fn elevator_phase_label_covers_every_variant() {
assert_eq!(elevator_phase(ElevatorPhase::Idle), "idle");
assert_eq!(
elevator_phase(ElevatorPhase::MovingToStop(
crate::entity::EntityId::default()
)),
"moving"
);
assert_eq!(
elevator_phase(ElevatorPhase::Repositioning(
crate::entity::EntityId::default()
)),
"repositioning"
);
assert_eq!(elevator_phase(ElevatorPhase::DoorOpening), "door-opening");
assert_eq!(elevator_phase(ElevatorPhase::Loading), "loading");
assert_eq!(elevator_phase(ElevatorPhase::DoorClosing), "door-closing");
assert_eq!(elevator_phase(ElevatorPhase::Stopped), "stopped");
}
#[test]
fn service_mode_round_trips() {
for mode in [
ServiceMode::Normal,
ServiceMode::Independent,
ServiceMode::Inspection,
ServiceMode::Manual,
ServiceMode::OutOfService,
] {
let label = service_mode(mode);
assert_eq!(
parse_service_mode(label),
Some(mode),
"round-trip failed for {mode:?} via label {label:?}",
);
}
}
#[test]
fn parse_service_mode_rejects_unknown() {
assert_eq!(parse_service_mode(""), None);
assert_eq!(parse_service_mode("Normal"), None); assert_eq!(parse_service_mode("offline"), None);
}
#[test]
fn direction_label_strings() {
assert_eq!(direction(Direction::Up), "up");
assert_eq!(direction(Direction::Down), "down");
assert_eq!(direction(Direction::Either), "either");
}
#[test]
fn parse_call_direction_accepts_only_up_and_down() {
assert_eq!(parse_call_direction("up").expect("ok"), CallDirection::Up);
assert_eq!(
parse_call_direction("down").expect("ok"),
CallDirection::Down
);
assert!(parse_call_direction("either").is_err());
assert!(parse_call_direction("UP").is_err());
assert!(parse_call_direction("").is_err());
}
}