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;
}
|