It's slightly more complicated than just pattern-matching.
- In general you have to be careful that if you're returning Poll::Pending, it's after something has registered a wakeup, otherwise your future is going to just stop.
- As a specific case, your match has to be inside a loop so that a state transition results in the new state being polled immediately. You can't just return and expect the caller to poll() you since there will be no wakeup registered that triggers the caller to do so.
- Because futures receive `&mut Self` rather than `Self`, it's difficult to do a state transition where the new state needs to own some properties of the current state. Eg `State::Foo { id: String } -> State::Bar { id: String }` Instead you have to do Option::take / std::mem::replace shenanigans on the state fields, or have an ugly State::Invalid that you can std::mem::replace the whole state with.
- In general you have to be careful that if you're returning Poll::Pending, it's after something has registered a wakeup, otherwise your future is going to just stop.
- As a specific case, your match has to be inside a loop so that a state transition results in the new state being polled immediately. You can't just return and expect the caller to poll() you since there will be no wakeup registered that triggers the caller to do so.
- Because futures receive `&mut Self` rather than `Self`, it's difficult to do a state transition where the new state needs to own some properties of the current state. Eg `State::Foo { id: String } -> State::Bar { id: String }` Instead you have to do Option::take / std::mem::replace shenanigans on the state fields, or have an ugly State::Invalid that you can std::mem::replace the whole state with.