iter-tools-es
Version:
The iterable toolbox
143 lines (120 loc) • 2.72 kB
JavaScript
const {
split
} = require('./symbols.js');
const {
IterableIterator
} = require('./iterable-iterator.js');
const {
Peekerator
} = require('./peekerator.js');
class PartIterator extends IterableIterator {
constructor(partsIterator) {
super();
this.partsIterator = partsIterator;
this.inactive = false;
this.done = false;
}
assertActive() {
if (this.inactive && !this.done) {
throw new Error('Cannot take from this split part. It is no longer the active part.');
}
}
next() {
const {
spliterator
} = this.partsIterator;
const {
current
} = spliterator;
this.assertActive();
if (this.done || current.done || current.value === split) {
this.done = true;
this.partsIterator.maybeReturnSource();
return {
value: undefined,
done: true
};
} else {
spliterator.advance();
return current;
}
}
return() {
this.done = true;
this.partsIterator.maybeReturnSource();
return {
value: undefined,
done: true
};
}
throw() {
return this.return();
}
}
exports.PartIterator = PartIterator;
class PartsIterator extends IterableIterator {
constructor(source, strategy, options) {
super();
this.source = source;
this.strategy = strategy;
this.options = options;
this.initialized = false;
this.returned = false;
this.spliterator = null;
this.currentPart = null;
this.splitStep = null;
}
init() {
this.initialized = true;
const {
source,
strategy,
options
} = this;
this.spliterator = Peekerator.from(strategy(split, options, source));
}
maybeReturnSource() {
if (this.spliterator && this.returned && this.currentPart.done) {
this.spliterator.return();
}
}
next() {
if (!this.initialized) this.init();
const {
spliterator
} = this;
if (spliterator.done) {
return {
value: undefined,
done: true
};
}
if (this.currentPart !== null) {
if (spliterator.value !== split || spliterator.current === this.splitStep) {
this.currentPart.inactive = true;
while (!spliterator.done && spliterator.value !== split) {
spliterator.advance();
}
}
spliterator.advance();
}
this.splitStep = spliterator.current;
this.currentPart = new PartIterator(this);
return {
value: this.currentPart,
done: false
};
}
return(value) {
this.returned = true;
this.maybeReturnSource();
return {
value,
done: true
};
}
throw() {
return this.return();
}
}
exports.PartsIterator = PartsIterator;