import { isFunction } from './assertion'
import { AnyFunction } from './types'

/** Calls each provided function with the same set of arguments. Useful for merging multiple callbacks. */
export function callAll(...fns: (AnyFunction | undefined)[]) {
  return (...args: any[]) => fns.forEach(fn => typeof fn === 'function' && fn(...args))
}

// Used as a safe default to be called when no function is provided.
export function noop() {}

/**
 * If given value is a function, it's called with any additional arguments provided.
 * Otherwise, the provided value is returned directly.
 */
export function runIfFn<T, U>(valueOrFn: T | ((...fnArgs: U[]) => T), ...args: U[]): T {
  return isFunction(valueOrFn) ? valueOrFn(...args) : valueOrFn
}
