import { type Purried, purry } from '../../compositions/purry.js'; import { _isIterable } from '../../controls/_guards.js'; import type { MaybePromise, Series, SyncSeries } from '../../controls/types.js'; function _syncFind( input: SyncSeries, test: ((value: T) => value is S) | ((value: T) => boolean), ): S | T | undefined { for (const value of input) { if (test(value)) return value; } return undefined; } async function _asyncFind>( input: Series, test: ((value: Awaited) => value is S) | ((value: Awaited) => MaybePromise), ): Promise { const awaited = await input; if (_isIterable(awaited)) { for (const value of awaited) { if (await test(await value)) return await value; } } else { for await (const value of awaited) { if (await test(value)) return value; } } return undefined; } export function findSync( input: SyncSeries, test: (value: T) => value is S, ): S | undefined; export function findSync( test: (value: T) => value is S, ): (input: SyncSeries) => S | undefined; export function findSync(input: SyncSeries, test: (value: T) => boolean): T | undefined; export function findSync(test: (value: T) => boolean): (input: SyncSeries) => T | undefined; export function findSync( ...args: Parameters>> ): ReturnType>> { return purry(_syncFind)(...args); } export function findAsync>( input: Series, test: ((value: Awaited) => value is S) | ((value: Awaited) => Promise), ): Promise; export function findAsync>( test: ((value: Awaited) => value is S) | ((value: Awaited) => Promise), ): (input: Series) => Promise; export function findAsync( input: Series, test: (value: Awaited) => MaybePromise, ): Promise; export function findAsync( test: (value: Awaited) => MaybePromise, ): (input: Series) => Promise; export function findAsync>( ...args: Parameters>> ): ReturnType>> { return purry(_asyncFind)(...args); } /** Returns the first met element with the specified test, and undefined otherwise. */ export namespace find { export const sync = findSync; export const async = findAsync; }