4 ms·
It's still a gotcha in Rust, I've seen code like: #[non_exhaustive] pub enum Protocol { Tcp, Udp, Other(u16), } It allows you to still match
by kpcyrd 2y ago
It's still a gotcha in Rust, I've seen code like:
#[non_exhaustive]
pub enum Protocol {
Tcp,
Udp,
Other(u16),
}
It allows you to still match on the unrecognized case (like `Protocol::Other(1)`, which is nice), but an additional enum variant may eliminate that case, if our enum gets extended to:
#[non_exhaustive]
pub enum Protocol {
Tcp,
Udp,
Icmp,
Other(u16),
}
Even though we can add additional variants in a semver-nonbreaking way due to `#[non_exhaustive]`, other people's code may now be broken until they've changed `Protocol::Other(1)` to `Protocol::Icmp`.
Having had this in the back of my head for quite some time, I think instead of an `Other` case there should be two methods, one returns an `Option<Protocol>` and the other one returns the `u16` representation. Unless there's a match on one of your expected cases your default branch would inspect the raw numeric type, which would keep working even if that case is added to the enum.
- remram 2y agoYou can't use non_exhaustive and Other. If you have an Other then it's exhaustive. This design is wrong.