trait State {
type NextState;
fn transition(self) -> Self::NextState;
}
In this example one consumes the current state to yield the next state (one could use From/TryFrom, but I don't think that makes sense semantically, imo).The advantage of this approach is that if you design your State types such that they can only be constructed by transitioning from a previous state, you cannot write code where your program is accidentally in an invalid state. You also never need to match against an enum.