|
|
|
'use strict';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* SelectValue - Wraps and pairs an arbitrary value with a reducer.
|
|
|
|
* @class SelectValue
|
|
|
|
* @param {any} value An arbitrary value to store within.
|
|
|
|
* @param {(Function|null)} resolve The reducer.
|
|
|
|
*/
|
|
|
|
class SelectValue {
|
|
|
|
constructor(value, resolve = null) {
|
|
|
|
this.value = value;
|
|
|
|
if (resolve !== null) this.resolve = resolve;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
SelectValue.prototype.resolve = () => null;
|
|
|
|
|
|
|
|
class SelectIterable {
|
|
|
|
constructor(values, conditionals) {
|
|
|
|
this.values = values.map(value => value instanceof SelectValue ? value : new SelectValue(value));
|
|
|
|
this.conditionals = conditionals;
|
|
|
|
}
|
|
|
|
for(predicate, consequent) {
|
|
|
|
return new SelectIterable(this.values, [...this.conditionals, { predicate, consequent }]);
|
|
|
|
}
|
|
|
|
forField(...pairs) {
|
|
|
|
var pair;
|
|
|
|
var callback;
|
|
|
|
var even;
|
|
|
|
for (
|
|
|
|
// beforeBegin:
|
|
|
|
var loc = 0;
|
|
|
|
// beforeEvery:
|
|
|
|
even = loc % 2 === 0,
|
|
|
|
// breakPredicate:
|
|
|
|
loc < pairs.length;
|
|
|
|
// afterEvery:
|
|
|
|
loc++
|
|
|
|
) {
|
|
|
|
pair = this.conditionals[this.conditionals.length];
|
|
|
|
if (pair.length === 2) {
|
|
|
|
this.conditionals.push({});
|
|
|
|
};
|
|
|
|
callback = conditionals[loc];
|
|
|
|
if (typeof callback === "object") {
|
|
|
|
if (Array.isArray(callback)) {
|
|
|
|
pair.predicate = callback[0];
|
|
|
|
pair.consequent = callback[0];
|
|
|
|
} else {
|
|
|
|
Object.assign(pair, {
|
|
|
|
predicate: callback.predicate,
|
|
|
|
consequent: callback.consequent
|
|
|
|
});
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (even) pair.predicate = callback;
|
|
|
|
if (!even) pair.consequent = callback;
|
|
|
|
}
|
|
|
|
return new SelectIterable(this.values, [...this.conditionals, ...conditionals]);
|
|
|
|
}
|
|
|
|
subsetOf(value, consequent) {
|
|
|
|
return this.for(this.value.every(element => element in this.value))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* eslint-disable-next-line func-names */
|
|
|
|
SelectIterable.prototype.resolve = function (...args) {
|
|
|
|
return this.values.map(item => {
|
|
|
|
const resolve = this.conditionals.find(tuple => tuple.predicate(item.value) ? tuple.consequent : null);
|
|
|
|
return resolve ? resolve.consequent(...args, this.value) : () => null;
|
|
|
|
}, this);
|
|
|
|
};
|
|
|
|
|
|
|
|
class Select extends SelectValue {
|
|
|
|
constructor(value, resolve) {
|
|
|
|
super(value, resolve);
|
|
|
|
this.iterable = typeof value === "object" && Symbol.iterator in value;
|
|
|
|
}
|
|
|
|
for(predicate, consequent) {
|
|
|
|
if (this.iterable) {
|
|
|
|
return new SelectIterable(Array.from(this.value), [{ predicate, consequent }]);
|
|
|
|
}
|
|
|
|
if (predicate(this.value)) return new Select(this.value, consequent);
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
is(value, consequent) {
|
|
|
|
return this.for(value === this.value, consequent);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
module.exports = Select;
|