Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | 19x 19x 1x 1x 19x 1x 1x 1x 1x 3x 3x 3x 3x 3x 3x 3x 1x 2x 2x 2x 1x 1x 2x 2x 1x 1x 1x 2x 2x 1x | import { define } from "../define"; import { OneOfFactory } from "../types"; export class InvalidOneOfType extends Error { constructor(readonly type: number) { super(`Invalid oneOf type (${type})`); } } export const oneOf: OneOfFactory = (headSd, typeToSerdes) => { const types = Object.keys( typeToSerdes ) as (keyof typeof typeToSerdes)[]; const typeToInt = mapKeysToIndexes(types); const intToType = swapKeysAndValues(typeToInt); return define( (ctx, data) => { const i = typeToInt[data.type]; headSd.ser(ctx, i); const serdes = typeToSerdes[data.type]; serdes.ser(ctx, data.value); }, (ctx) => { const i = headSd.des(ctx); const type = intToType[i]; if (type === undefined) { throw new InvalidOneOfType(i); } const serdes = typeToSerdes[type]; const value = serdes.des(ctx); return { type, value }; } ); }; type Key = string | number | symbol; function mapKeysToIndexes<T extends Key>( keys: T[] ): Record<T, number> { const result: Record<T, number> = {} as Record<T, number>; for (let i = 0; i < keys.length; ++i) { const e = keys[i]; result[e] = i; } return result; } function swapKeysAndValues<K extends Key, V extends Key>( obj: Record<K, V> ): Record<V, K> { const result: Record<V, K> = {} as Record<V, K>; for (const k of Object.keys(obj) as K[]) { const v = obj[k]; result[v] = k; } return result; } |