@jsonjoy.com/json-type
Version:
High-performance JSON Pointer implementation
111 lines (110 loc) • 4.33 kB
JavaScript
;
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;