UNPKG

@rimbu/bimap

Version:

A bidirectional immutable Map of keys and values for TypeScript

110 lines (91 loc) 2.95 kB
import { BiMapBuilder, BiMapEmpty, BiMapNonEmptyImpl, } from '@rimbu/bimap/custom'; import type { BiMap } from '@rimbu/bimap'; import type { RMap } from '@rimbu/collection-types/map'; import type { ArrayNonEmpty } from '@rimbu/common'; import { Reducer, type StreamSource } from '@rimbu/stream'; import { isEmptyStreamSourceInstance } from '@rimbu/stream/custom'; export class BiMapContext<UK, UV, Tp extends BiMap.Types = BiMap.Types> implements BiMap.Context<UK, UV> { constructor( readonly keyValueContext: RMap.Context<UK>, readonly valueKeyContext: RMap.Context<UV> ) {} get typeTag(): 'BiMap' { return 'BiMap'; } get _types(): Tp { return undefined as any; } readonly _empty: BiMap<any, any> = Object.freeze( new BiMapEmpty<any, any>(this) ); readonly empty = <K extends UK, V extends UV>(): BiMap<K, V> => { return this._empty; }; readonly of: any = <K, V>( ...entries: ArrayNonEmpty<readonly [K, V]> ): [K, V] extends [UK, UV] ? BiMap.NonEmpty<K, V> : never => { return this.from(entries); }; readonly from = <K, V>( ...sources: ArrayNonEmpty<StreamSource<readonly [K, V]>> ): [K, V] extends [UK, UV] ? BiMap<K, V> | any : never => { if (sources.length === 1) { const source = sources[0]; if (source instanceof BiMapNonEmptyImpl && source.context === this) return source as any; } let builder: BiMap.Builder<K, V> = this.builder() as any; let i = -1; const length = sources.length; while (++i < length) { const source = sources[i]; if (isEmptyStreamSourceInstance(source)) continue; if ( builder.isEmpty && source instanceof BiMapNonEmptyImpl && source.context === this ) { if (i === length - 1) return source as any; builder = source.toBuilder(); continue; } builder.addEntries(source); } return builder.build() as any; }; readonly builder = <K extends UK, V extends UV>(): BiMap.Builder<K, V> => { return new BiMapBuilder(this as unknown as BiMapContext<K, V>); }; readonly reducer = <K extends UK, V extends UV>( source?: StreamSource<readonly [K, V]> ): Reducer<readonly [K, V], BiMap<K, V>> => { return Reducer.create( () => undefined === source ? this.builder<K, V>() : (this.from(source) as BiMap<K, V>).toBuilder(), (builder, entry) => { builder.addEntry(entry); return builder; }, (builder) => builder.build() ); }; createNonEmptyImpl<K extends UK, V extends UV>( keyValueMap: RMap.NonEmpty<K, V>, valueKeyMap: RMap.NonEmpty<V, K> ): BiMapNonEmptyImpl<K, V> { return new BiMapNonEmptyImpl(this as any, keyValueMap, valueKeyMap); } createBuilder<K extends UK, V extends UV>( source?: BiMapNonEmptyImpl<K, V> ): BiMapBuilder<K, V> { return new BiMapBuilder(this as any, source); } }