scontainers
Version:
A container/collection/iterator library for JavaScript, comfortable to use, performant and versatile.
148 lines (106 loc) • 3.14 kB
JavaScript
;
function _implSymbol(target, sym, value) {
Object.defineProperty(target, sym, {
value,
configurable: true
});
return target[sym];
}
function _getSymbol(targetSymName, ...traitSets) {
let symbol;
traitSets.forEach(traitSet => {
const sym = traitSet[targetSymName];
if (typeof sym === 'symbol') {
if (!!symbol && symbol !== sym) {
throw new Error(`Symbol ${targetSymName} offered by multiple trait sets.`);
}
symbol = sym;
}
});
if (!symbol) {
throw new Error(`No trait set is providing symbol ${targetSymName}.`);
}
return symbol;
}
function _testTraitSet(traitSet) {
if (!traitSet || typeof traitSet === 'boolean' || typeof traitSet === 'number' || typeof traitSet === 'string') {
throw new Error(`${traitSet} cannot be used as a trait set.`);
}
}
const {
traits,
toStr
} = require('../utils.js');
_testTraitSet(traits.utils);
_testTraitSet(traits.scontainers);
_testTraitSet(traits.semantics);
const _implTraits = _getSymbol("implTraits", traits.utils, traits.scontainers, traits.semantics);
const _values = _getSymbol("values", traits.utils, traits.scontainers, traits.semantics);
const _forEach = _getSymbol("forEach", traits.utils, traits.scontainers, traits.semantics);
const _describeScontainer = _getSymbol("describeScontainer", traits.utils, traits.scontainers, traits.semantics);
const _implCoreGenerators = _getSymbol("implCoreGenerators", traits.utils, traits.scontainers, traits.semantics);
const _member = _getSymbol("member", traits.utils, traits.scontainers, traits.semantics);
const _implCoreTraits = _getSymbol("implCoreTraits", traits.utils, traits.scontainers, traits.semantics);
const _map = _getSymbol("map", traits.utils, traits.scontainers, traits.semantics);
const _collect = _getSymbol("collect", traits.utils, traits.scontainers, traits.semantics);
traits.scontainers[_implTraits](Array, {
from(collection) {
// TODO: this function should be specialized, just like the rest of what this lib does...
if (collection[_values]) {
return Array.from(collection[_values]());
} else if (collection[_forEach]) {
const array = new Array();
collection[_forEach](value => void array.push(value));
return array;
}
throw new Error(`${collection} not iterable`);
}
});
Array[_describeScontainer]({
argKeys: []
});
Array[_implCoreGenerators]({
nToKey(n) {
return n;
},
keyToN(key) {
return key;
},
nthUnchecked(n) {
return this.self[_member](n, true);
},
// add: nope
len(compiler) {
return this.self[_member](`length`);
}
});
Array[_implCoreTraits]({
len() {
return this.length;
},
nthUnchecked(n) {
return this[n];
},
nToKey(n) {
return n;
},
keyToN(key) {
return key;
},
setNth(n, value) {
this[n] = value;
},
truncate(n) {
this.length = n;
},
add(value) {
this.push(value);
},
clear() {
this.length = 0;
},
toString() {
return `[${this[_map](value => toStr.call(value))[_collect](Array).join(', ')}]`;
}
});
module.exports = Array;