UNPKG

@jsonjoy.com/json-type

Version:

High-performance JSON Pointer implementation

111 lines (110 loc) 4.33 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.OrType = void 0; const tslib_1 = require("tslib"); const schema = tslib_1.__importStar(require("../../schema")); const printTree_1 = require("tree-dump/lib/printTree"); const constants_1 = require("../../constants"); const CborEncoderCodegenContext_1 = require("../../codegen/binary/CborEncoderCodegenContext"); const JsonEncoderCodegenContext_1 = require("../../codegen/binary/JsonEncoderCodegenContext"); const MessagePackEncoderCodegenContext_1 = require("../../codegen/binary/MessagePackEncoderCodegenContext"); const json_expression_1 = require("@jsonjoy.com/json-expression"); const operators_1 = require("@jsonjoy.com/json-expression/lib/operators"); const Vars_1 = require("@jsonjoy.com/json-expression/lib/Vars"); const discriminator_1 = require("../discriminator"); const AbsType_1 = require("./AbsType"); class OrType extends AbsType_1.AbsType { constructor(types, options) { super(); this.types = types; this.__discriminator = undefined; this.schema = { ...schema.s.Or(), ...options, discriminator: options?.discriminator ?? discriminator_1.Discriminator.createExpression(types), }; } getSchema() { return { ...this.schema, types: this.types.map((type) => type.getSchema()), }; } getOptions() { const { kind, types, ...options } = this.schema; return options; } options(options) { Object.assign(this.schema, options); return this; } discriminator() { if (this.__discriminator) return this.__discriminator; const expr = this.schema.discriminator; if (!expr || (expr[0] === 'num' && expr[1] === 0)) throw new Error('NO_DISCRIMINATOR'); const codegen = new json_expression_1.JsonExpressionCodegen({ expression: expr, operators: operators_1.operatorsMap, }); const fn = codegen.run().compile(); return (this.__discriminator = (data) => +fn(new Vars_1.Vars(data))); } codegenValidator(ctx, path, r) { const types = this.types; const codegen = ctx.codegen; const length = types.length; if (length === 1) { types[0].codegenValidator(ctx, path, r); return; } const discriminator = this.discriminator(); const d = codegen.linkDependency(discriminator); codegen.switch(`${d}(${r})`, types.map((type, index) => [ index, () => { type.codegenValidator(ctx, path, r); }, ]), () => { const err = ctx.err(constants_1.ValidationError.OR, path); ctx.js(`return ${err}`); }); } codegenJsonTextEncoder(ctx, value) { ctx.js(/* js */ `s += stringify(${value.use()});`); } codegenBinaryEncoder(ctx, value) { const codegen = ctx.codegen; const discriminator = this.discriminator(); const d = codegen.linkDependency(discriminator); const types = this.types; codegen.switch(`${d}(${value.use()})`, types.map((type, index) => [ index, () => { if (ctx instanceof CborEncoderCodegenContext_1.CborEncoderCodegenContext) type.codegenCborEncoder(ctx, value); else if (ctx instanceof MessagePackEncoderCodegenContext_1.MessagePackEncoderCodegenContext) type.codegenMessagePackEncoder(ctx, value); else if (ctx instanceof JsonEncoderCodegenContext_1.JsonEncoderCodegenContext) type.codegenJsonEncoder(ctx, value); }, ])); } codegenCborEncoder(ctx, value) { this.codegenBinaryEncoder(ctx, value); } codegenMessagePackEncoder(ctx, value) { this.codegenBinaryEncoder(ctx, value); } codegenJsonEncoder(ctx, value) { this.codegenBinaryEncoder(ctx, value); } toJson(value, system = this.system) { return JSON.stringify(value); } toString(tab = '') { return super.toString(tab) + (0, printTree_1.printTree)(tab, [...this.types.map((type) => (tab) => type.toString(tab))]); } } exports.OrType = OrType;