I have a state machine written in Rust which needs to perform the same action for two states.
Both states are variants of an enum but contain a different number of elements.
match self.state {
RunState::ACCUMULATE(byte, count) | RunState::ESCAPE(count) => todo!(),
_ => todo!()
}
The example is invalid source code because byte is not bound in all patterns.
This could be solved by binding byte to a literal zero in the second pattern but i don't know how to archive that.
I`am currently matching both patterns separately which leads to code duplication which i would like to avoid.
Thank you for your attention.
Patterns are designed to match by structure and bind variables based on the value being matched. It is not designed to introduce arbitrary bindings. You should use separate match arms and perhaps use a helper function if you're concerned about duplication:
match self.state {
RunState::ACCUMULATE(byte, count) => helper(byte, count),
RunState::ESCAPE(count) => helper(0, count),
...
}
Or you can introduce a function for your enum that returns the needed values like:
impl RunState {
fn to_parts(&self) -> (u8, usize) { // or Option<(u8, usize)> if its not applicable to all
match self.state {
RunState::ACCUMULATE(byte, count) => (byte, count),
RunState::ESCAPE(count) => (0, count),
...
}
}
}
You can solve your issue by not binding byte in any branch:
match self.state {
RunState::ACCUMULATE(_, count) | RunState::ESCAPE(count) => todo!(),
_ => todo!()
}
If you need byte in the ACCUMULATE case, then the code isn't strictly speaking the same for both, but this can be accomplished with an extra step to extract byte:
match self.state {
RunState::ACCUMULATE(_, count) | RunState::ESCAPE(count) => {
let byte = if let RunState::ACCUMULATE (byte, _) = self.state { byte } else { 0 };
todo!()
},
_ => todo!()
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With