UNPKG

@jsonjoy.com/json-type

Version:

High-performance JSON Pointer implementation

158 lines (157 loc) 5.95 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.TupleType = void 0; const tslib_1 = require("tslib"); const schema = tslib_1.__importStar(require("../../schema")); const printTree_1 = require("tree-dump/lib/printTree"); const validate_1 = require("../../schema/validate"); const constants_1 = require("../../constants"); const CborEncoderCodegenContext_1 = require("../../codegen/binary/CborEncoderCodegenContext"); const JsExpression_1 = require("@jsonjoy.com/util/lib/codegen/util/JsExpression"); const AbstractType_1 = require("./AbstractType"); class TupleType extends AbstractType_1.AbstractType { constructor(types, options) { super(); this.types = types; this.schema = { ...schema.s.Tuple(), ...options }; } getSchema() { return { ...this.schema, types: this.types.map((type) => type.getSchema()), }; } toJsonSchema(ctx) { const jsonSchema = { type: 'array', prefixItems: this.types.map((type) => type.toJsonSchema(ctx)), items: false, ...super.toJsonSchema(ctx), }; return jsonSchema; } getOptions() { const { kind, types, ...options } = this.schema; return options; } validateSchema() { const schema = this.getSchema(); (0, validate_1.validateTType)(schema, 'tup'); const { types } = schema; if (!Array.isArray(types)) throw new Error('TYPES_TYPE'); if (!types.length) throw new Error('TYPES_LENGTH'); for (const type of this.types) type.validateSchema(); } codegenValidator(ctx, path, r) { const err = ctx.err(constants_1.ValidationError.TUP, path); const types = this.types; ctx.js(/* js */ `if (!Array.isArray(${r}) || ${r}.length !== ${types.length}) return ${err};`); for (let i = 0; i < this.types.length; i++) { const rv = ctx.codegen.getRegister(); ctx.js(/* js */ `var ${rv} = ${r}[${i}];`); types[i].codegenValidator(ctx, [...path, i], rv); } ctx.emitCustomValidators(this, path, r); } codegenJsonTextEncoder(ctx, value) { ctx.writeText('['); const types = this.types; const length = types.length; const last = length - 1; for (let i = 0; i < last; i++) { types[i].codegenJsonTextEncoder(ctx, new JsExpression_1.JsExpression(() => `${value.use()}[${i}]`)); ctx.writeText(','); } types[last].codegenJsonTextEncoder(ctx, new JsExpression_1.JsExpression(() => `${value.use()}[${last}]`)); ctx.writeText(']'); } codegenBinaryEncoder(ctx, value) { const types = this.types; const length = types.length; ctx.blob(ctx.gen((encoder) => { encoder.writeArrHdr(length); })); const r = ctx.codegen.r(); ctx.js(/* js */ `var ${r} = ${value.use()};`); for (let i = 0; i < length; i++) if (ctx instanceof CborEncoderCodegenContext_1.CborEncoderCodegenContext) types[i].codegenCborEncoder(ctx, new JsExpression_1.JsExpression(() => `${r}[${i}]`)); else types[i].codegenMessagePackEncoder(ctx, new JsExpression_1.JsExpression(() => `${r}[${i}]`)); } codegenCborEncoder(ctx, value) { this.codegenBinaryEncoder(ctx, value); } codegenMessagePackEncoder(ctx, value) { this.codegenBinaryEncoder(ctx, value); } codegenJsonEncoder(ctx, value) { const codegen = ctx.codegen; const expr = new JsExpression_1.JsExpression(() => `${rItem}`); const r = codegen.var(value.use()); const rItem = codegen.var(); ctx.blob(ctx.gen((encoder) => { encoder.writeStartArr(); })); const types = this.types; const length = types.length; const arrSepBlob = ctx.gen((encoder) => { encoder.writeArrSeparator(); }); for (let i = 0; i < length; i++) { const type = types[i]; const isLast = i === length - 1; codegen.js(`${rItem} = ${r}[${i}];`); type.codegenJsonEncoder(ctx, expr); if (!isLast) ctx.blob(arrSepBlob); } ctx.blob(ctx.gen((encoder) => { encoder.writeEndArr(); })); } codegenCapacityEstimator(ctx, value) { const codegen = ctx.codegen; const r = codegen.var(value.use()); const types = this.types; const overhead = 5 /* MaxEncodingOverhead.Array */ + 1 /* MaxEncodingOverhead.ArrayElement */ * types.length; ctx.inc(overhead); for (let i = 0; i < types.length; i++) { const type = types[i]; const fn = type.compileCapacityEstimator({ system: ctx.options.system, name: ctx.options.name, }); const rFn = codegen.linkDependency(fn); codegen.js(`size += ${rFn}(${r}[${i}]);`); } } random() { return this.types.map((type) => type.random()); } toTypeScriptAst() { return { node: 'TupleType', elements: this.types.map((type) => type.toTypeScriptAst()), }; } toJson(value, system = this.system) { const types = this.types; const length = types.length; if (!length) return '[]'; const last = length - 1; let str = '['; for (let i = 0; i < last; i++) str += types[i].toJson(value[i], system) + ','; str += types[last].toJson(value[last], system); return (str + ']'); } toString(tab = '') { return super.toString(tab) + (0, printTree_1.printTree)(tab, [...this.types.map((type) => (tab) => type.toString(tab))]); } } exports.TupleType = TupleType;