import { PipeBody, PipeFunction } from "../../pipables"; import { isArrayLikeStrict } from "../../types/internal"; import { tryGetCountDirect } from "./count"; import { asLinq, LinqWrapper } from "../linqWrapper"; import { IntermediateLinqWrapper } from "../internal"; import { BuiltInLinqTraits, TryGetCountDirectSymbol, TryUnwrapUnorderedSymbol } from "../traits"; export function reverse(): PipeBody, LinqWrapper> { return target => { if (target instanceof ReverseLinqWrapper) { // Reverse + Reverse --> Original return asLinq(target.__state.iterable as Iterable); } return new ReverseLinqWrapper({ iterable: target.unwrap(), }); }; } reverse satisfies PipeFunction; interface ReverseIteratorState { readonly iterable: Iterable; } class ReverseLinqWrapper extends IntermediateLinqWrapper> implements BuiltInLinqTraits { public override *[Symbol.iterator](): Iterator { const { iterable } = this.__state; const array = isArrayLikeStrict(iterable) ? iterable : [...iterable]; for (let i = array.length - 1; i >= 0; i--) { yield array[i]; } } public [TryGetCountDirectSymbol](): number | undefined { return asLinq(this.__state.iterable).$(tryGetCountDirect()); } public [TryUnwrapUnorderedSymbol](): Iterable { return this.__state.iterable; } }