Skip to content

Commit

Permalink
refactor: move out of class
Browse files Browse the repository at this point in the history
  • Loading branch information
joscha committed Sep 28, 2024
1 parent 0e6c4cd commit bd2c6dd
Showing 1 changed file with 37 additions and 37 deletions.
74 changes: 37 additions & 37 deletions lib/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -1252,28 +1252,44 @@ function generateProjectionIndexer(projectionFn) {
};
}

function generateDefaultIndexer() {
this._dynamicBranches = null;
this._bucketIndices = {};
this.types.forEach(function (type, index) {
if (Type.isType(type, 'abstract', 'logical')) {
if (!this._dynamicBranches) {
this._dynamicBranches = [];
function generateDefaultIndexer(types) {
const dynamicBranches = [];
const bucketIndices = {};

const getBranchIndex = (any, index) => {
let logicalBranches = dynamicBranches;
for (let i = 0, l = logicalBranches.length; i < l; i++) {
let branch = logicalBranches[i];
if (branch.type._check(any)) {
if (index === undefined) {
index = branch.index;
} else {
// More than one branch matches the value so we aren't guaranteed to
// infer the correct type. We throw rather than corrupt data. This can
// be fixed by "tightening" the logical types.
throw new Error('ambiguous conversion');
}
}
this._dynamicBranches.push({index, type});
}
return index;
}

types.forEach(function (type, index) {
if (Type.isType(type, 'abstract', 'logical')) {
dynamicBranches.push({index, type});
} else {
let bucket = getTypeBucket(type);
if (this._bucketIndices[bucket] !== undefined) {
if (bucketIndices[bucket] !== undefined) {
throw new Error(`ambiguous unwrapped union: ${j(this)}`);
}
this._bucketIndices[bucket] = index;
bucketIndices[bucket] = index;
}
}, this);
return (val) => {
let index = this._bucketIndices[getValueBucket(val)];
if (this._dynamicBranches) {
let index = bucketIndices[getValueBucket(val)];
if (dynamicBranches.length) {
// Slower path, we must run the value through all branches.
index = this._getBranchIndex(val, index);
index = getBranchIndex(val, index);
}
return index;
};
Expand Down Expand Up @@ -1310,30 +1326,12 @@ class UnwrappedUnionType extends UnionType {
}
}
this._getIndex = _projectionFn
? generateProjectionIndexer(projectionFn)
? generateProjectionIndexer(_projectionFn)
: generateDefaultIndexer.bind(this)(this.types);

Object.freeze(this);
}

_getBranchIndex (any, index) {
let logicalBranches = this._dynamicBranches;
for (let i = 0, l = logicalBranches.length; i < l; i++) {
let branch = logicalBranches[i];
if (branch.type._check(any)) {
if (index === undefined) {
index = branch.index;
} else {
// More than one branch matches the value so we aren't guaranteed to
// infer the correct type. We throw rather than corrupt data. This can
// be fixed by "tightening" the logical types.
throw new Error('ambiguous conversion');
}
}
}
return index;
}

_check (val, flags, hook, path) {
let index = this._getIndex(val);
let b = index !== undefined;
Expand Down Expand Up @@ -1393,16 +1391,18 @@ class UnwrappedUnionType extends UnionType {
// Using the `coerceBuffers` option can cause corruption and erroneous
// failures with unwrapped unions (in rare cases when the union also
// contains a record which matches a buffer's JSON representation).
if (isJsonBuffer(val) && this._bucketIndices.buffer !== undefined) {
index = this._bucketIndices.buffer;
} else {
index = this._getIndex(val);
if (isJsonBuffer(val)) {
let bufIndex = this.types.findIndex(t => getTypeBucket(t) === 'buffer');
if (bufIndex !== -1) {
index = bufIndex;
}
}
index ??= this._getIndex(val);
break;
case 2:
// Decoding from JSON, we must unwrap the value.
if (val === null) {
index = this._bucketIndices['null'];
index = this._getIndex(null);
} else if (typeof val === 'object') {
let keys = Object.keys(val);
if (keys.length === 1) {
Expand Down

0 comments on commit bd2c6dd

Please sign in to comment.