@v4fire/core
Version:
V4Fire core library
161 lines (128 loc) • 3.66 kB
text/typescript
/*!
* V4Fire Core
* https://github.com/V4Fire/Core
*
* Released under the MIT license
* https://github.com/V4Fire/Core/blob/master/LICENSE
*/
/**
* [[include:core/iter/README.md]]
* @packageDocumentation
*/
import Range from 'core/range';
/**
* Creates an infinite iterator and returns it.
* If the passed value is true, the created iterator will produce values from zero to the positive infinity.
* Otherwise, from zero to the negative infinity.
*
* @param obj
*/
export function intoIter(obj: boolean): IterableIterator<number>;
/**
* Creates an empty iterator and returns it
* @param obj
*/
export function intoIter(obj: null | undefined): IterableIterator<undefined>;
/**
* Creates an iterator from zero to the passed number (non including) and returns it
* @param obj
*/
// eslint-disable-next-line @typescript-eslint/unified-signatures
export function intoIter(obj: number): IterableIterator<number>;
/**
* Creates an iterator over the passed string by graphical letters
* @param obj
*/
export function intoIter(obj: string): IterableIterator<string>;
/**
* Creates an iterator over values from the specified dictionary and returns it
* @param obj
*/
export function intoIter<T extends Dictionary>(obj: T): IterableIterator<DictionaryType<T>>;
/**
* Creates an iterator over values from the specified array-like object and returns it
* @param obj
*/
export function intoIter<T = unknown>(obj: ArrayLike<T>): IterableIterator<T>;
/**
* Creates an iterator from the passed generator function and returns it
* @param obj
*/
export function intoIter<T = unknown>(obj: GeneratorFunction): IterableIterator<T>;
/**
* Creates an iterator from the passed async generator function and returns it
* @param obj
*/
export function intoIter<T = unknown>(obj: AsyncGeneratorFunction): AsyncIterableIterator<T>;
/**
* Creates a new iterator based on the specified iterable structure and returns it
* @param obj
*/
export function intoIter<T extends Iterable<any>>(obj: T): IterableIterator<IterableType<T>>;
/**
* Creates a new async iterator based on the specified async iterable structure and returns it
* @param obj
*/
export function intoIter<T extends AsyncIterable<any>>(obj: T): AsyncIterableIterator<IterableType<T>>;
export function intoIter(obj: unknown): IterableIterator<unknown> | AsyncIterableIterator<unknown> {
if (obj == null) {
return [].values();
}
if (obj === true) {
return new Range(0, Infinity).values();
}
if (obj === false) {
return new Range(0, -Infinity).values();
}
if (Object.isNumber(obj)) {
return new Range(0, [obj]).values();
}
if (Object.isString(obj)) {
return obj.letters();
}
if (Object.isGenerator(obj) || Object.isAsyncGenerator(obj)) {
return intoIter(Object.cast(obj()));
}
if (Object.isArrayLike(obj)) {
let
cursor = 0;
const
objLength = obj.length;
return {
[Symbol.iterator]() {
return this;
},
next(): IteratorResult<unknown> {
const done = cursor === objLength;
const res = {
value: (cursor < objLength) ? obj[cursor] : undefined,
done
};
if (!done) {
cursor++;
}
return res;
}
};
}
if (typeof obj === 'object') {
const
isSyncIter = Object.isIterable(obj);
if (isSyncIter || Object.isAsyncIterable(obj)) {
const
key = isSyncIter ? Symbol.iterator : Symbol.asyncIterator,
iter = obj[key]();
if ('return' in obj || 'throw' in obj) {
return Object.cast({
[key]() {
return this;
},
next: iter.next.bind(iter)
});
}
return iter;
}
return Object.values(obj).values();
}
return [obj].values();
}