@@ -3,33 +3,43 @@ import { unsigned } from '../utils/varint.js'
3
3
import { createCodec , CODEC_TYPES } from '../codec.js'
4
4
import type { DecodeFunction , EncodeFunction , EncodingLengthFunction , Codec } from '../codec.js'
5
5
6
- export function enumeration < T > ( e : T ) : Codec < T > {
7
- const encodingLength : EncodingLengthFunction < string > = function enumEncodingLength ( val : string ) {
8
- const keys = Object . keys ( e )
9
- const index = keys . indexOf ( val )
6
+ export function enumeration < T > ( v : any ) : Codec < T > {
7
+ function findValue ( val : string | number ) : number {
8
+ if ( v [ val . toString ( ) ] == null ) {
9
+ throw new Error ( 'Invalid enum value' )
10
+ }
11
+
12
+ if ( typeof val === 'number' ) {
13
+ return val
14
+ }
15
+
16
+ return v [ val ]
17
+ }
10
18
11
- return unsigned . encodingLength ( index )
19
+ const encodingLength : EncodingLengthFunction < number | string > = function enumEncodingLength ( val ) {
20
+ return unsigned . encodingLength ( findValue ( val ) )
12
21
}
13
22
14
- const encode : EncodeFunction < string > = function enumEncode ( val ) {
15
- const keys = Object . keys ( e )
16
- const index = keys . indexOf ( val )
17
- const buf = new Uint8Array ( unsigned . encodingLength ( index ) )
23
+ const encode : EncodeFunction < number | string > = function enumEncode ( val ) {
24
+ const enumValue = findValue ( val )
18
25
19
- unsigned . encode ( index , buf )
26
+ const buf = new Uint8Array ( unsigned . encodingLength ( enumValue ) )
27
+ unsigned . encode ( enumValue , buf )
20
28
21
29
return buf
22
30
}
23
31
24
- const decode : DecodeFunction < string > = function enumDecode ( buf , offset ) {
25
- const index = unsigned . decode ( buf , offset )
26
- const keys = Object . keys ( e )
32
+ const decode : DecodeFunction < number | string > = function enumDecode ( buf , offset ) {
33
+ const value = unsigned . decode ( buf , offset )
34
+ const strValue = value . toString ( )
27
35
28
- if ( keys [ index ] == null ) {
29
- throw new Error ( 'Could not find enum key for value' )
36
+ // Use the reverse mapping to look up the enum key for the stored value
37
+ // https://www.typescriptlang.org/docs/handbook/enums.html#reverse-mappings
38
+ if ( v [ strValue ] == null ) {
39
+ throw new Error ( 'Invalid enum value' )
30
40
}
31
41
32
- return keys [ index ]
42
+ return v [ strValue ]
33
43
}
34
44
35
45
// @ts -expect-error yeah yeah
0 commit comments