// Copyright 2021 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only /* eslint-disable max-classes-per-file */ export function map( iterable: Iterable, fn: (value: T) => ResultT ): Iterable { return new MapIterable(iterable, fn); } class MapIterable implements Iterable { constructor( private readonly iterable: Iterable, private readonly fn: (value: T) => ResultT ) {} [Symbol.iterator](): Iterator { return new MapIterator(this.iterable[Symbol.iterator](), this.fn); } } class MapIterator implements Iterator { constructor( private readonly iterator: Iterator, private readonly fn: (value: T) => ResultT ) {} next(): IteratorResult { const nextIteration = this.iterator.next(); if (nextIteration.done) { return nextIteration; } return { done: false, value: this.fn(nextIteration.value), }; } } export function take(iterable: Iterable, amount: number): Iterable { return new TakeIterable(iterable, amount); } class TakeIterable implements Iterable { constructor( private readonly iterable: Iterable, private readonly amount: number ) {} [Symbol.iterator](): Iterator { return new TakeIterator(this.iterable[Symbol.iterator](), this.amount); } } class TakeIterator implements Iterator { constructor(private readonly iterator: Iterator, private amount: number) {} next(): IteratorResult { const nextIteration = this.iterator.next(); if (nextIteration.done || this.amount === 0) { return { done: true, value: undefined }; } this.amount -= 1; return nextIteration; } }