use adar::prelude::*;
use std::{process::Command, thread::sleep, time::Duration};
#[StateEnum]
#[ReflectEnum] enum TrafficLight {
Go,
GetReady,
StopIfSafe,
Stop,
}
impl TrafficLight {
const YELLOW_DURATION: Duration = Duration::from_secs(1);
const GO_STOP_DURATION: Duration = Duration::from_secs(2);
}
impl Machine for TrafficLight {
fn on_transition(&mut self, new_state: &Self::States, _context: &mut Self::Context) {
Command::new("clear")
.status()
.expect("Failed to clear the screen!");
println!("{}", new_state.name());
}
}
impl State for Go {
fn on_enter(&mut self, _context: &mut Self::Context) {
println!("⚫\n⚫\n🟢");
}
fn on_update(&mut self, _context: &mut Self::Context) -> Option<Self::States> {
sleep(TrafficLight::GO_STOP_DURATION);
Some(StopIfSafe.into())
}
}
impl State for GetReady {
fn on_enter(&mut self, _context: &mut Self::Context) {
println!("🔴\n🟡\n⚫");
}
fn on_update(&mut self, _context: &mut Self::Context) -> Option<Self::States> {
sleep(TrafficLight::YELLOW_DURATION);
Some(Go.into())
}
}
impl State for StopIfSafe {
fn on_enter(&mut self, _context: &mut Self::Context) {
println!("⚫\n🟡\n⚫");
}
fn on_update(&mut self, _context: &mut Self::Context) -> Option<Self::States> {
sleep(TrafficLight::YELLOW_DURATION);
Some(Stop.into())
}
}
impl State for Stop {
fn on_enter(&mut self, _context: &mut Self::Context) {
println!("🔴\n⚫\n⚫")
}
fn on_update(&mut self, _context: &mut Self::Context) -> Option<Self::States> {
sleep(TrafficLight::GO_STOP_DURATION);
Some(GetReady.into())
}
}
fn main() {
StateMachine::new(Stop).run();
}