You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

83 lines
2.4 KiB
JavaScript

"use strict";
const generateValidator = require("./generate-validator");
const guardedSet = require("./guarded-collections/set");
const guardedMap = require("./guarded-collections/map");
const guardedArray = require("./guarded-collections/array");
module.exports = function generateDescriptor(rule, key, allowSlot = false) {
if (rule._isTypeRule === true) {
let validator = generateValidator(rule, key);
if (rule._collectionType != null) {
let guardedCollectionFactory;
if (rule._collectionType === "set") {
guardedCollectionFactory = guardedSet;
} else if (rule._collectionType === "map") {
guardedCollectionFactory = guardedMap;
} else if (rule._collectionType === "array") {
guardedCollectionFactory = guardedArray;
} else {
throw new Error(`Unknown collection type: ${rule._collectionType}`);
}
let valueGuard = generateValidator(rule._itemType);
let keyGuard = (rule._keyType != null) ? generateValidator(rule._keyType) : null;
return [key, {
enumerable: true,
get: function () {
return this._data[key];
},
set: function (value) {
if (allowSlot && value != null && value._isSlotRule === true) {
this._data[key] = value;
} else {
let validationResult = validator.call(this, value);
if (validationResult === true) {
if (value == null) {
this._data[key] = value;
} else {
this._data[key] = guardedCollectionFactory(value, valueGuard, keyGuard, this);
}
} else if (validationResult._default !== undefined) {
this._data[key] = guardedCollectionFactory(validationResult._default, valueGuard, keyGuard, this);
} else {
throw validationResult;
}
}
}
}];
} else {
return [key, {
enumerable: true,
get: function () {
return this._data[key];
},
set: function (value) {
if (allowSlot && value != null && value._isSlotRule === true) {
this._data[key] = value;
} else {
let validationResult = validator.call(this, value);
if (validationResult === true) {
this._data[key] = value;
} else if (validationResult._default !== undefined) {
this._data[key] = validationResult._default;
} else {
throw validationResult;
}
}
}
}];
}
} else {
/* TODO: Does this cause a slowdown compared to merging in these props with Object.assign later? */
return [key, {
value: rule
}];
}
};