How to Use the Typestate Pattern for Compile-Time State Machines

Implement the typestate pattern in Rust by using enums to represent states and restricting method access to valid state transitions.

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();
}