11// deno-lint-ignore-file no-slow-types
22// @ts -self-types="../type/enum.d.ts"
33
4+ import { BiMap } from "./bimap.js" ;
5+
46/**
57 * Abstract base class for creating enumeration types in JavaScript
68 * @abstract
1921 */
2022export class Enum {
2123 /** @private @static @type {Map<Function, Map<string, Enum>> } */
22- static #instances = new Map ( ) ;
24+ static #instances = new BiMap ( ) ;
2325
2426 /** @private @static @type {Set<Function> } */
2527 static #frozen = new Set ( ) ;
@@ -50,27 +52,25 @@ export class Enum {
5052 this . #ordinal = this . constructor . size ;
5153
5254 // Register instance
53- if ( ! Enum . #instances. has ( this . constructor ) ) {
54- Enum . #instances. set ( this . constructor , new Map ( ) ) ;
55+ if ( ! Enum . #instances. hasKey ( this . constructor ) ) {
56+ Enum . #instances. set ( this . constructor , new BiMap ( ) ) ;
5557 }
5658
57- const instanceMap = Enum . #instances. get ( this . constructor ) ;
59+ const instanceMap = Enum . #instances. getValue ( this . constructor ) ;
5860
5961 if ( Enum . #frozen. has ( this . constructor ) ) {
6062 throw new Error ( `Cannot add new enum constant ${ name } to frozen enum ${ this . constructor . name } ` ) ;
6163 }
6264
63- if ( instanceMap . has ( name ) ) {
65+ if ( instanceMap . hasKey ( name ) ) {
6466 throw new Error ( `Duplicate enum constant name: ${ name } ` ) ;
6567 }
6668
67- for ( const [ , instance ] of instanceMap ) {
68- if ( instance . value === value ) {
69- throw new Error ( `Duplicate enum value: ${ value } for constant ${ name } ` ) ;
70- }
69+ if ( instanceMap . hasValue ( value ) ) {
70+ throw new Error ( `Duplicate enum value: ${ value } for constant ${ name } ` ) ;
7171 }
7272
73- instanceMap . set ( name , this ) ;
73+ instanceMap . set ( name , value ) ;
7474 }
7575
7676 /**
@@ -110,7 +110,7 @@ export class Enum {
110110 * @returns {Enum[] } Array of all enum constants
111111 */
112112 static values ( ) {
113- const instanceMap = Enum . #instances. get ( this ) || new Map ( ) ;
113+ const instanceMap = Enum . #instances. getValue ( this ) || new Map ( ) ;
114114 return Array . from ( instanceMap . values ( ) ) ;
115115 }
116116
@@ -119,7 +119,7 @@ export class Enum {
119119 * @returns {string[] } Array of all enum constant names
120120 */
121121 static names ( ) {
122- const instanceMap = Enum . #instances. get ( this ) || new Map ( ) ;
122+ const instanceMap = Enum . #instances. getValue ( this ) || new Map ( ) ;
123123 return Array . from ( instanceMap . keys ( ) ) ;
124124 }
125125
@@ -130,11 +130,11 @@ export class Enum {
130130 * @throws {Error } If no constant exists with the given name
131131 */
132132 static valueOf ( name ) {
133- const instanceMap = Enum . #instances. get ( this ) ;
134- if ( ! instanceMap || ! instanceMap . has ( name ) ) {
133+ const instanceMap = Enum . #instances. getValue ( this ) ;
134+ if ( ! instanceMap || ! instanceMap . hasKey ( name ) ) {
135135 throw new Error ( `No enum constant ${ this . name } .${ name } ` ) ;
136136 }
137- return instanceMap . get ( name ) ;
137+ return instanceMap . getValue ( name ) ;
138138 }
139139
140140 /**
@@ -144,11 +144,13 @@ export class Enum {
144144 * @throws {Error } If no constant exists with the given value
145145 */
146146 static fromValue ( value ) {
147- const instance = this . values ( ) . find ( inst => inst . value === value ) ;
148- if ( ! instance ) {
149- throw new Error ( `No enum constant with value ${ value } in ${ this . name } ` ) ;
147+ //const instance = this.values().find(inst => inst.value === value);
148+ const biMap = Enum . #instances. getValue ( this ) ;
149+ if ( ! biMap . hasValue ( value ) ) {
150+ throw new Error ( `No enum constant with value ${ value } in ${ this . name } ` ) ;
150151 }
151- return instance ;
152+ const key = biMap . getKey ( value ) ;
153+ return this [ key ]
152154 }
153155
154156 /**
@@ -230,4 +232,6 @@ export class Enum {
230232 }
231233}
232234
235+
236+
233237// npx -p typescript tsc ./src/enum.js --declaration --allowJs --emitDeclarationOnly --lib ESNext --outDir ./dist
0 commit comments