import ISerializer, { InputOf, OutputOf, JSONOutputOf } from "./ISerializer"; import varuint from "./varuint"; type TInput = InputOf[]; type TOutput = OutputOf[]; type TJSONOutput = JSONOutputOf[]; export class VectorSerializer extends ISerializer, TOutput, TJSONOutput> { constructor(public readonly serializer: T) { super(); } toJSON(value: TInput): TJSONOutput { return value.map((element) => this.serializer.toJSON(element)); } fromJSON(value: TJSONOutput): TOutput { return value.map((element) => this.serializer.fromJSON(element)); } toBuffer(value: TInput): Buffer { return Buffer.concat([ varuint.toBuffer(value.length), ...value.map((element) => this.serializer.toBuffer(element)), ]); } readFromBuffer(buffer: Buffer, offset: number = 0): { res: TOutput, newOffset: number } { const { res: length, newOffset: from } = varuint.readFromBuffer(buffer, offset); let it = from; if (length.gt(Number.MAX_SAFE_INTEGER)) throw new Error('unprocessable vector length'); const res = new Array(length.toNumber()).fill(null).map(() => { const { res: element, newOffset } = this.serializer.readFromBuffer(buffer, it); it = newOffset; return element; }); return { res, newOffset: it }; } } export default function vector(serializer: T): VectorSerializer { return new VectorSerializer(serializer); }