Use the typestate pattern by encoding valid states as distinct enum variants and restricting methods to specific states via impl blocks, ensuring invalid transitions fail at compile time.
enum State {
New,
Ready,
Done,
}
struct Machine {
state: State,
}
impl Machine {
fn new() -> Self { Machine { state: State::New } }
fn start(&mut self) { self.state = State::Ready; }
}
impl Machine {
fn run(&mut self) {
match self.state {
State::Ready => self.state = State::Done,
_ => panic!("Machine not ready"),
}
}
}
fn main() {
let mut m = Machine::new();
m.start();
m.run();
}