-
Notifications
You must be signed in to change notification settings - Fork 34
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Alternative variants no clear behavior. #88
Comments
In Rust in general, this enum: #[repr(u8)]
pub enum EncodingFormat {
Postcard = 2,
Json,
MessagePack,
Pickle,
BSON,
CBOR,
CSV,
Bencode,
} is equivalent to this one: #[repr(u8)]
pub enum EncodingFormat {
Postcard = 2,
Json = 3,
MessagePack = 4,
Pickle = 5,
BSON = 6,
CBOR = 7,
CSV = 8,
Bencode = 9,
} Implicit and explicit discriminants work the same. Our attribute doesn't change this. So I think the only real question is whether we treat the attribute as an override (i.e. I'd suggest we should probably treat it as a compile-time error. |
For now, the way I implemented it is like follow: Variants are treated in order top to bottom. The following variants that have no there discriminant explicitly set get one automatically, BUT this auto discriminant is equal to the next ascendent available value (not reserved by any previous variant). If instead a following variant has an explicitly set discriminant, it get that discriminant, and collisons are checked, and id found, it is reported. But I totally understand your approach of let's mimic the default behavior first and let's be more specific. So here is what I suggest:Variants are treated in order top to bottom. The following variants that have no there discriminant explicitly set get one automatically, BUT this auto discriminant is equal to the next ascendent value (we don't care if the value is already marked for a previous variant). We then check for collision and report them, If the users really want to use the alternative values for a previous variant, they will need to explicitly set the discriminant to avoid collision. Example:The following will error and report a collision on #[derive(Copy, Clone, Debug, PartialEq, Eq, TryFromPrimitive)]
#[repr(u8)]
pub enum EncodingFormat {
Postcard = 2,
Json,
MessagePack,
#[num_enum(alternatives = [7,8,10])]
Pickle,
BSON,
CBOR,
CSV,
Bencode,
} The way to fix this would be: #[derive(Copy, Clone, Debug, PartialEq, Eq, TryFromPrimitive)]
#[repr(u8)]
pub enum EncodingFormat {
Postcard = 2,
Json,
MessagePack,
#[num_enum(alternatives = [7,8,10])]
Pickle,
BSON,
CBOR=9,
CSV=11,
Bencode,
} What do you say ? Does it makes sense ? |
Sounds great, thanks! (Also sounds like something we should have better test coverage for than we currently do, both in the happy case and in the conflict case)! |
OK great :) ! |
Ok it's done (without the test). |
PR #89 resolves this. Closing the issue. |
Hi,
While trying to fix #84, I realized that the there is no clear behavior define on how to handle to discriminants attribution to each variants in the case of alternative variants.
If I have an enum, we all agree that unless explicitly set, the discriminants start from 0 and are auto incremented by 1 for each variants. When we meet a variant with a specified discriminant, it gets the said specified discriminant, and the following variants get incremented by one from there.
But what happens if alternative variants are specified ?
Does the following variants have to 1) be explicitly set or 2) if we want to increment from the biggest value or 3) if we want to increment from the last discriminant value but skipping automatically on the taken values.
For example:
Json
= 3,MessagePack
= 4,Pickle
is 5 | 7 | 8 | 10, and now forBSON
?If we pick the 3) way, it would be
BSOM
= 6,CBOR
=9,CSV
=11, andBencode
=12.(Unless an explicit discriminant is set for one of those variants of course. And we need to error on collision also.)
I am in favor of the 3) way.
I am trying to implement it.
The text was updated successfully, but these errors were encountered: