date-limits
Version:
Check if a date is before a flexible limit.
101 lines (100 loc) • 3.7 kB
JavaScript
import { generateSequence } from '../sequence';
export class GeneralGenerator {
constructor(config = undefined, startFrom, upperLimit) {
this.config = config;
this.startFrom = startFrom;
this.upperLimit = upperLimit;
//! Static
this._looped = false;
if (config === undefined) {
this._anySkipTo(undefined, upperLimit === 31);
this._nextFn = this._anyNext;
this._skipToFn = this._anySkipTo;
return;
}
if (typeof config === 'number') {
this._staticSkipTo();
this._nextFn = this._staticNext;
this._skipToFn = this._staticSkipTo;
return;
}
if (Array.isArray(config)) {
this._listSkipTo();
this._nextFn = this._listNext;
this._skipToFn = this._listSkipTo;
return;
}
if ('slope' in config) {
this.config = generateSequence(config, upperLimit);
this._listSkipTo();
this._nextFn = this._listNext;
this._skipToFn = this._listSkipTo;
return;
}
config.from ?? (config.from = 1);
config.to ?? (config.to = startFrom);
if (config.from > config.to) {
throw new Error(`Config range cannot contain "from" value higher than "to" value.`);
}
if (config.to > upperLimit) {
config.to = upperLimit;
}
this._rangeSkipTo(this.startFrom, upperLimit === 31);
this._nextFn = this._rangeNext;
this._skipToFn = this._rangeSkipTo;
return;
}
next(reset = false) {
return this._nextFn(reset);
}
skipTo(to = this.startFrom, minusOne = false) {
this._skipToFn(to, minusOne);
}
//! Any
_anyNext(reset) {
if (reset || this._currentNum === 0) {
this._currentNum = this.upperLimit;
return { value: { value: this._currentNum--, looped: !reset }, done: false };
}
return { value: { value: this._currentNum--, looped: false }, done: false };
}
_anySkipTo(to = this.startFrom, minusOne) {
this._currentNum = to - (minusOne ? 1 : 0);
}
_staticNext(_) {
const nextVal = { value: { value: this._currentNum, looped: this._looped }, done: false };
this._looped = true;
return nextVal;
}
_staticSkipTo() {
this._currentNum = this.config;
}
//! List
_listNext(reset) {
const list = this.config;
if (reset || this._currentNum < 0) {
this._currentNum = list.length - 1;
return { value: { value: list[this._currentNum--], looped: !reset }, done: false };
}
return { value: { value: list[this._currentNum--], looped: false }, done: false };
}
_listSkipTo(to = this.startFrom) {
this._currentNum = this.config.findIndex(v => v >= to) - 1;
}
//! Range
_rangeNext(reset) {
const range = this.config;
if (reset || this._currentNum === 0 || this._currentNum < range.from) {
this._currentNum = Math.min(range.to, this.upperLimit);
return { value: { value: this._currentNum--, looped: !reset }, done: false };
}
return { value: { value: this._currentNum--, looped: false }, done: false };
}
_rangeSkipTo(to = this.startFrom, minusOne) {
const range = this.config;
this._currentNum = to - (minusOne ? 1 : 0);
if (this._currentNum > range.to) {
this._currentNum = range.to;
}
}
}