-
Notifications
You must be signed in to change notification settings - Fork 931
getScalarCodecEnum does not encode an enum to its values in bytes #2319
Comments
So I was writing a regression test and I'm no longer certain that the current behaviour is a bug. Consider the following example: enum ExplicitNumbers {
Zero,
Three = 3,
Four,
Size = 'six',
Nine = 9,
FourtyTwo = 42,
} Whilst the values of the enum will be kept as-is, the keys of the enum is what gets stored and what allows you to have these complex mapping that otherwise wouldn't work — e.g. Even without such string literals, JavaScript values are used for more than just storing bytes and therefore, they likely will need to differ from their byte representation. The issue is that Rust enums act differently and what comes after the equal sign is not a value like in JavaScript but a discriminant whose only purpose is to be used when storing the enum as bytes. So whilst they share the same syntax, their behaviour is different which is why some people might expect the behaviour you're suggesting here. I'm not too sure how to solve this because I do think what you're suggesting should be possible but I don't think JavaScript enums lend themselves well to this use-case. One solution could be to offer another helper function like Wdyt? |
Actually, maybe it's just the case of adding an option like |
TIL this is valid TypeScript... 🫠 enum MyEnum {
Zero = 42,
One = 42,
Two = 42
}
console.log(MyEnum);
// {
// "42": "Two",
// "Zero": 42,
// "One": 42,
// "Two": 42
// } |
Yeah ... it is why I tend to avoid using enums and wanted to instead opt in for, i.e., an object for defining enum codecs. There's a talk (linked below) that goes in-depth into why they're bad. |
…iminators option (#2430) This PR significantly solidifies the implementation of the `getEnumCodec` function by supporting and testing all its edge cases: - Simple numerical enums — `enum { A, B }`. - Explicit numerical enums — `enum { A, B = 5 }`. - Explicit numerical enums with duplicated values — `enum { A = 5, B = 5 }`. - Lexical enums — `enum { A = "A", B = "B" }`. - Hybrid enums — `enum { A = "A", B = 5 }`. Prior to this PR, only simple numerical enums and lexical enums were supported. Additionally, this PR adds a new `useValuesAsDiscriminators` option to the `getEnumCodec` function which, when dealing with explicit numerical enums, stores the value of the enum variant instead of its index. ```ts enum Numbers { One, Five = 5, Six, Nine = 9, } // Without useValuesAsDiscriminators. const codecWithout = getEnumCodec(Numbers); codecWithout.encode(Direction.One); // 0x00 codecWithout.encode(Direction.Five); // 0x01 codecWithout.encode(Direction.Six); // 0x02 codecWithout.encode(Direction.Nine); // 0x03 // With useValuesAsDiscriminators. const codecWith = getEnumCodec(Numbers, { useValuesAsDiscriminators: true }); codecWith.encode(Direction.One); // 0x00 codecWith.encode(Direction.Five); // 0x05 codecWith.encode(Direction.Six); // 0x06 codecWith.encode(Direction.Nine); // 0x09 ``` Note that when using the `useValuesAsDiscriminators` option on an enum that contains a lexical value, an error will be thrown. ```ts enum Lexical { One, Two = 'two', } getEnumCodec(Lexical, { useValuesAsDiscriminators: true }); // Throws an error. ``` Fixes #2319
Because there has been no activity on this issue for 7 days since it was closed, it has been automatically locked. Please open a new issue if it requires a follow up. |
getScalarCodecEnum
does not encode an enum to its values bytes.This issue is a follow-up from #2296.
The text was updated successfully, but these errors were encountered: